1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include <corewindow.h>
9 #include "base/logging.h"
10 #include "ui/gfx/geometry/safe_integer_conversions.h"
11 #include "ui/gfx/win/msg_util.h"
13 #pragma comment(lib, "shell32.lib")
15 EXTERN_C IMAGE_DOS_HEADER __ImageBase
;
16 // Even though we only create a single window, we need to keep this
17 // count because of the hidden window used by the UI message loop of
19 int g_window_count
= 0;
21 const wchar_t kAshWin7AppId
[] = L
"Google.Chrome.AshWin7.1";
22 const wchar_t kAshWin7CoreWindowHandler
[] = L
"CoreWindowHandler";
23 extern float GetModernUIScale();
24 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
, WPARAM wparam
,
27 HWND
CreateMetroTopLevelWindow(const RECT
& work_area
) {
28 HINSTANCE hInst
= reinterpret_cast<HINSTANCE
>(&__ImageBase
);
30 wcex
.cbSize
= sizeof(wcex
);
31 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
32 wcex
.lpfnWndProc
= WndProc
;
35 wcex
.hInstance
= hInst
;
36 wcex
.hIcon
= LoadIcon(::GetModuleHandle(NULL
), L
"IDR_MAINFRAME");
37 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
38 wcex
.hbrBackground
= (HBRUSH
)(COLOR_INACTIVECAPTION
+1);
39 wcex
.lpszMenuName
= 0;
40 wcex
.lpszClassName
= L
"Windows.UI.Core.CoreWindow";
41 wcex
.hIconSm
= LoadIcon(::GetModuleHandle(NULL
), L
"IDR_MAINFRAME");
43 HWND hwnd
= ::CreateWindowExW(0,
44 MAKEINTATOM(::RegisterClassExW(&wcex
)),
46 WS_POPUP
| WS_VISIBLE
| WS_MINIMIZEBOX
,
47 work_area
.top
, work_area
.left
,
48 work_area
.right
, work_area
.bottom
,
49 NULL
, NULL
, hInst
, NULL
);
53 typedef winfoundtn::ITypedEventHandler
<
54 winapp::Core::CoreApplicationView
*,
55 winapp::Activation::IActivatedEventArgs
*> ActivatedHandler
;
57 typedef winfoundtn::ITypedEventHandler
<
58 winui::Core::CoreWindow
*,
59 winui::Core::WindowActivatedEventArgs
*> WindowActivatedHandler
;
61 typedef winfoundtn::ITypedEventHandler
<
62 winui::Core::CoreWindow
*,
63 winui::Core::AutomationProviderRequestedEventArgs
*>
64 AutomationProviderHandler
;
66 typedef winfoundtn::ITypedEventHandler
<
67 winui::Core::CoreWindow
*,
68 winui::Core::CharacterReceivedEventArgs
*> CharEventHandler
;
70 typedef winfoundtn::ITypedEventHandler
<
71 winui::Core::CoreWindow
*,
72 winui::Core::CoreWindowEventArgs
*> CoreWindowEventHandler
;
74 typedef winfoundtn::ITypedEventHandler
<
75 winui::Core::CoreWindow
*,
76 winui::Core::InputEnabledEventArgs
*> InputEnabledEventHandler
;
78 typedef winfoundtn::ITypedEventHandler
<
79 winui::Core::CoreWindow
*,
80 winui::Core::KeyEventArgs
*> KeyEventHandler
;
82 typedef winfoundtn::ITypedEventHandler
<
83 winui::Core::CoreWindow
*,
84 winui::Core::PointerEventArgs
*> PointerEventHandler
;
86 typedef winfoundtn::ITypedEventHandler
<
87 winui::Core::CoreWindow
*,
88 winui::Core::WindowSizeChangedEventArgs
*> SizeChangedHandler
;
90 typedef winfoundtn::ITypedEventHandler
<
91 winui::Core::CoreWindow
*,
92 winui::Core::TouchHitTestingEventArgs
*> TouchHitTestHandler
;
94 typedef winfoundtn::ITypedEventHandler
<
95 winui::Core::CoreWindow
*,
96 winui::Core::VisibilityChangedEventArgs
*> VisibilityChangedHandler
;
98 typedef winfoundtn::ITypedEventHandler
<
99 winui::Core::CoreDispatcher
*,
100 winui::Core::AcceleratorKeyEventArgs
*> AcceleratorKeyEventHandler
;
102 // This interface is implemented by classes which handle mouse and keyboard
107 virtual ~InputHandler() {}
109 virtual bool HandleKeyboardMessage(const MSG
& msg
) = 0;
110 virtual bool HandleMouseMessage(const MSG
& msg
) = 0;
113 DISALLOW_COPY_AND_ASSIGN(InputHandler
);
116 // This class implements the winrt interfaces corresponding to mouse input.
117 class MouseEvent
: public mswr::RuntimeClass
<
118 winui::Core::IPointerEventArgs
,
119 winui::Input::IPointerPoint
,
120 winui::Input::IPointerPointProperties
,
121 windevs::Input::IPointerDevice
> {
123 MouseEvent(const MSG
& msg
)
127 // IPointerEventArgs implementation.
128 virtual HRESULT STDMETHODCALLTYPE
get_CurrentPoint(
129 winui::Input::IPointerPoint
** point
) {
130 return QueryInterface(winui::Input::IID_IPointerPoint
,
131 reinterpret_cast<void**>(point
));
134 virtual HRESULT STDMETHODCALLTYPE
get_KeyModifiers(
135 winsys::VirtualKeyModifiers
* modifiers
) {
139 virtual HRESULT STDMETHODCALLTYPE
GetIntermediatePoints(
140 winfoundtn::Collections::IVector
<winui::Input::PointerPoint
*>** points
) {
144 // IPointerPoint implementation.
145 virtual HRESULT STDMETHODCALLTYPE
get_PointerDevice(
146 windevs::Input::IPointerDevice
** pointer_device
) {
147 return QueryInterface(windevs::Input::IID_IPointerDevice
,
148 reinterpret_cast<void**>(pointer_device
));
151 virtual HRESULT STDMETHODCALLTYPE
get_Position(winfoundtn::Point
* position
) {
152 static float scale
= GetModernUIScale();
153 // Scale down the points here as they are scaled up on the other side.
154 position
->X
= gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_
.lParam
) / scale
);
155 position
->Y
= gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_
.lParam
) / scale
);
159 virtual HRESULT STDMETHODCALLTYPE
get_PointerId(uint32
* pointer_id
) {
161 // Implement this properly.
166 virtual HRESULT STDMETHODCALLTYPE
get_Timestamp(uint64
* timestamp
) {
167 *timestamp
= msg_
.time
;
171 virtual HRESULT STDMETHODCALLTYPE
get_Properties(
172 winui::Input::IPointerPointProperties
** properties
) {
173 return QueryInterface(winui::Input::IID_IPointerPointProperties
,
174 reinterpret_cast<void**>(properties
));
177 virtual HRESULT STDMETHODCALLTYPE
get_RawPosition(
178 winfoundtn::Point
* position
) {
182 virtual HRESULT STDMETHODCALLTYPE
get_FrameId(uint32
* frame_id
) {
186 virtual HRESULT STDMETHODCALLTYPE
get_IsInContact(boolean
* in_contact
) {
190 // IPointerPointProperties implementation.
191 virtual HRESULT STDMETHODCALLTYPE
get_PointerUpdateKind(
192 winui::Input::PointerUpdateKind
* update_kind
) {
194 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
196 if (msg_
.message
== WM_LBUTTONDOWN
) {
197 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonPressed
;
198 } else if (msg_
.message
== WM_RBUTTONDOWN
) {
199 *update_kind
= winui::Input::PointerUpdateKind_RightButtonPressed
;
200 } else if (msg_
.message
== WM_MBUTTONDOWN
) {
201 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonPressed
;
202 } else if (msg_
.message
== WM_LBUTTONUP
) {
203 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonReleased
;
204 } else if (msg_
.message
== WM_RBUTTONUP
) {
205 *update_kind
= winui::Input::PointerUpdateKind_RightButtonReleased
;
206 } else if (msg_
.message
== WM_MBUTTONUP
) {
207 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonReleased
;
212 virtual HRESULT STDMETHODCALLTYPE
get_IsLeftButtonPressed(
213 boolean
* left_button_pressed
) {
214 *left_button_pressed
= msg_
.wParam
& MK_LBUTTON
? true : false;
218 virtual HRESULT STDMETHODCALLTYPE
get_IsRightButtonPressed(
219 boolean
* right_button_pressed
) {
220 *right_button_pressed
= msg_
.wParam
& MK_RBUTTON
? true : false;
224 virtual HRESULT STDMETHODCALLTYPE
get_IsMiddleButtonPressed(
225 boolean
* middle_button_pressed
) {
226 *middle_button_pressed
= msg_
.wParam
& MK_MBUTTON
? true : false;
230 virtual HRESULT STDMETHODCALLTYPE
get_IsHorizontalMouseWheel(
231 boolean
* is_horizontal_mouse_wheel
) {
232 *is_horizontal_mouse_wheel
=
233 (msg_
.message
== WM_MOUSEHWHEEL
) ? true : false;
237 virtual HRESULT STDMETHODCALLTYPE
get_MouseWheelDelta(int* delta
) {
238 if (msg_
.message
== WM_MOUSEWHEEL
|| msg_
.message
== WM_MOUSEHWHEEL
) {
239 *delta
= GET_WHEEL_DELTA_WPARAM(msg_
.wParam
);
246 virtual HRESULT STDMETHODCALLTYPE
get_Pressure(float* pressure
) {
250 virtual HRESULT STDMETHODCALLTYPE
get_IsInverted(boolean
* inverted
) {
254 virtual HRESULT STDMETHODCALLTYPE
get_IsEraser(boolean
* is_eraser
) {
258 virtual HRESULT STDMETHODCALLTYPE
get_Orientation(float* orientation
) {
262 virtual HRESULT STDMETHODCALLTYPE
get_XTilt(float* x_tilt
) {
266 virtual HRESULT STDMETHODCALLTYPE
get_YTilt(float* y_tilt
) {
270 virtual HRESULT STDMETHODCALLTYPE
get_Twist(float* twist
) {
274 virtual HRESULT STDMETHODCALLTYPE
get_ContactRect(winfoundtn::Rect
* rect
) {
278 virtual HRESULT STDMETHODCALLTYPE
get_ContactRectRaw(winfoundtn::Rect
* rect
) {
282 virtual HRESULT STDMETHODCALLTYPE
get_TouchConfidence(boolean
* confidence
) {
286 virtual HRESULT STDMETHODCALLTYPE
get_IsPrimary(boolean
* is_primary
) {
290 virtual HRESULT STDMETHODCALLTYPE
get_IsInRange(boolean
* is_in_range
) {
294 virtual HRESULT STDMETHODCALLTYPE
get_IsCanceled(boolean
* is_canceled
) {
298 virtual HRESULT STDMETHODCALLTYPE
get_IsBarrelButtonPressed(
299 boolean
* is_barrel_button_pressed
) {
303 virtual HRESULT STDMETHODCALLTYPE
get_IsXButton1Pressed(
304 boolean
* is_xbutton1_pressed
) {
308 virtual HRESULT STDMETHODCALLTYPE
get_IsXButton2Pressed(
309 boolean
* is_xbutton2_pressed
) {
313 virtual HRESULT STDMETHODCALLTYPE
HasUsage(uint32 usage_page
,
315 boolean
* has_usage
) {
319 virtual HRESULT STDMETHODCALLTYPE
GetUsageValue(uint32 usage_page
,
321 int32
* usage_value
) {
325 // IPointerDevice implementation.
326 virtual HRESULT STDMETHODCALLTYPE
get_PointerDeviceType(
327 windevs::Input::PointerDeviceType
* device_type
) {
328 if (msg_
.message
== WM_TOUCH
) {
329 *device_type
= windevs::Input::PointerDeviceType_Touch
;
331 *device_type
= windevs::Input::PointerDeviceType_Mouse
;
336 virtual HRESULT STDMETHODCALLTYPE
get_IsIntegrated(boolean
* is_integrated
) {
340 virtual HRESULT STDMETHODCALLTYPE
get_MaxContacts(uint32
* contacts
) {
344 virtual HRESULT STDMETHODCALLTYPE
get_PhysicalDeviceRect(
345 winfoundtn::Rect
* rect
) {
349 virtual HRESULT STDMETHODCALLTYPE
get_ScreenRect(winfoundtn::Rect
* rect
) {
353 virtual HRESULT STDMETHODCALLTYPE
get_SupportedUsages(
354 winfoundtn::Collections::IVectorView
<
355 windevs::Input::PointerDeviceUsage
>** usages
) {
362 DISALLOW_COPY_AND_ASSIGN(MouseEvent
);
365 // This class implements the winrt interfaces needed to support keyboard
366 // character and system character messages.
367 class KeyEvent
: public mswr::RuntimeClass
<
368 winui::Core::IKeyEventArgs
,
369 winui::Core::ICharacterReceivedEventArgs
,
370 winui::Core::IAcceleratorKeyEventArgs
> {
372 KeyEvent(const MSG
& msg
)
375 // IKeyEventArgs implementation.
376 virtual HRESULT STDMETHODCALLTYPE
get_VirtualKey(
377 winsys::VirtualKey
* virtual_key
) {
378 *virtual_key
= static_cast<winsys::VirtualKey
>(msg_
.wParam
);
382 virtual HRESULT STDMETHODCALLTYPE
get_KeyStatus(
383 winui::Core::CorePhysicalKeyStatus
* key_status
) {
384 // As per msdn documentation for the keyboard messages.
385 key_status
->RepeatCount
= msg_
.lParam
& 0x0000FFFF;
386 key_status
->ScanCode
= (msg_
.lParam
>> 16) & 0x00FF;
387 key_status
->IsExtendedKey
= (msg_
.lParam
& (1 << 24));
388 key_status
->IsMenuKeyDown
= (msg_
.lParam
& (1 << 29));
389 key_status
->WasKeyDown
= (msg_
.lParam
& (1 << 30));
390 key_status
->IsKeyReleased
= (msg_
.lParam
& (1 << 31));
394 // ICharacterReceivedEventArgs implementation.
395 virtual HRESULT STDMETHODCALLTYPE
get_KeyCode(uint32
* key_code
) {
396 *key_code
= msg_
.wParam
;
400 // IAcceleratorKeyEventArgs implementation.
401 virtual HRESULT STDMETHODCALLTYPE
get_EventType(
402 winui::Core::CoreAcceleratorKeyEventType
* event_type
) {
403 if (msg_
.message
== WM_SYSKEYDOWN
) {
404 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown
;
405 } else if (msg_
.message
== WM_SYSKEYUP
) {
406 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp
;
407 } else if (msg_
.message
== WM_SYSCHAR
) {
408 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemCharacter
;
417 // The following classes are the emulation of the WinRT system as exposed
418 // to metro applications. There is one application (ICoreApplication) which
419 // contains a series of Views (ICoreApplicationView) each one of them
420 // containing a CoreWindow which represents a surface that can drawn to
421 // and that receives events.
423 // Here is the general dependency hierachy in terms of interfaces:
425 // IFrameworkViewSource --> IFrameworkView
428 // ---------------------------------------------------------------------
431 // ICoreApplication ICoreApplicationView
434 // ICoreWindow -----> ICoreWindowInterop
438 // ICoreDispatcher <==> real HWND
440 class CoreDispatcherEmulation
:
441 public mswr::RuntimeClass
<
442 winui::Core::ICoreDispatcher
,
443 winui::Core::ICoreAcceleratorKeys
> {
445 CoreDispatcherEmulation(InputHandler
* input_handler
)
446 : input_handler_(input_handler
),
447 accelerator_key_event_handler_(NULL
) {}
449 // ICoreDispatcher implementation:
450 virtual HRESULT STDMETHODCALLTYPE
get_HasThreadAccess(boolean
* value
) {
454 virtual HRESULT STDMETHODCALLTYPE
ProcessEvents(
455 winui::Core::CoreProcessEventsOption options
) {
456 // We don't support the other message pump modes. So we basically enter a
457 // traditional message loop that we only exit a teardown.
458 if (options
!= winui::Core::CoreProcessEventsOption_ProcessUntilQuit
)
462 while((::GetMessage(&msg
, NULL
, 0, 0) != 0) && g_window_count
> 0) {
463 ProcessInputMessage(msg
);
464 ::TranslateMessage(&msg
);
465 ::DispatchMessage(&msg
);
467 // TODO(cpu): figure what to do with msg.WParam which we would normally
472 virtual HRESULT STDMETHODCALLTYPE
RunAsync(
473 winui::Core::CoreDispatcherPriority priority
,
474 winui::Core::IDispatchedHandler
*agileCallback
,
475 ABI::Windows::Foundation::IAsyncAction
** asyncAction
) {
479 virtual HRESULT STDMETHODCALLTYPE
RunIdleAsync(
480 winui::Core::IIdleDispatchedHandler
*agileCallback
,
481 winfoundtn::IAsyncAction
** asyncAction
) {
485 // ICoreAcceleratorKeys implementation:
486 virtual HRESULT STDMETHODCALLTYPE
add_AcceleratorKeyActivated(
487 AcceleratorKeyEventHandler
* handler
,
488 EventRegistrationToken
*pCookie
) {
489 accelerator_key_event_handler_
= handler
;
490 accelerator_key_event_handler_
->AddRef();
494 virtual HRESULT STDMETHODCALLTYPE
remove_AcceleratorKeyActivated(
495 EventRegistrationToken cookie
) {
496 accelerator_key_event_handler_
->Release();
497 accelerator_key_event_handler_
= NULL
;
502 bool ProcessInputMessage(const MSG
& msg
) {
503 // Poor man's way of dispatching input events.
505 if (input_handler_
) {
506 if ((msg
.message
>= WM_KEYFIRST
) && (msg
.message
<= WM_KEYLAST
)) {
507 if ((msg
.message
== WM_SYSKEYDOWN
) || (msg
.message
== WM_SYSKEYUP
) ||
508 msg
.message
== WM_SYSCHAR
) {
509 ret
= HandleSystemKeys(msg
);
511 ret
= input_handler_
->HandleKeyboardMessage(msg
);
513 } else if ((msg
.message
>= WM_MOUSEFIRST
) &&
514 (msg
.message
<= WM_MOUSELAST
)) {
515 ret
= input_handler_
->HandleMouseMessage(msg
);
521 bool HandleSystemKeys(const MSG
& msg
) {
522 mswr::ComPtr
<winui::Core::IAcceleratorKeyEventArgs
> event_args
;
523 event_args
= mswr::Make
<KeyEvent
>(msg
);
524 accelerator_key_event_handler_
->Invoke(this, event_args
.Get());
528 InputHandler
* input_handler_
;
529 AcceleratorKeyEventHandler
* accelerator_key_event_handler_
;
532 class CoreWindowEmulation
533 : public mswr::RuntimeClass
<
534 mswr::RuntimeClassFlags
<mswr::WinRtClassicComMix
>,
535 winui::Core::ICoreWindow
, ICoreWindowInterop
>,
536 public InputHandler
{
538 CoreWindowEmulation(winapp::Core::IFrameworkView
* app_view
)
540 mouse_moved_handler_(NULL
),
541 mouse_capture_lost_handler_(NULL
),
542 mouse_pressed_handler_(NULL
),
543 mouse_released_handler_(NULL
),
544 mouse_entered_handler_(NULL
),
545 mouse_exited_handler_(NULL
),
546 mouse_wheel_changed_handler_(NULL
),
547 key_down_handler_(NULL
),
548 key_up_handler_(NULL
),
549 character_received_handler_(NULL
),
551 window_activated_handler_(NULL
) {
552 dispatcher_
= mswr::Make
<CoreDispatcherEmulation
>(this);
554 // Unless we select our own AppUserModelID the shell might confuse us
555 // with the app launcher one and we get the wrong taskbar button and icon.
556 ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId
);
558 RECT work_area
= {0};
559 ::SystemParametersInfo(SPI_GETWORKAREA
, 0, &work_area
, 0);
560 if (::IsDebuggerPresent()) {
563 work_area
.right
= 1600;
564 work_area
.bottom
= 900;
567 core_hwnd_
= CreateMetroTopLevelWindow(work_area
);
568 ::SetProp(core_hwnd_
, kAshWin7CoreWindowHandler
, this);
571 ~CoreWindowEmulation() {
573 ::RemoveProp(core_hwnd_
, kAshWin7CoreWindowHandler
);
574 ::DestroyWindow(core_hwnd_
);
578 // ICoreWindow implementation:
579 virtual HRESULT STDMETHODCALLTYPE
get_AutomationHostProvider(
580 IInspectable
** value
) {
584 virtual HRESULT STDMETHODCALLTYPE
get_Bounds(
585 winfoundtn::Rect
* value
) {
587 if (!::GetClientRect(core_hwnd_
, &rect
))
589 value
->Width
= rect
.right
;
590 value
->Height
= rect
.bottom
;
594 virtual HRESULT STDMETHODCALLTYPE
get_CustomProperties(
595 winfoundtn::Collections::IPropertySet
** value
) {
599 virtual HRESULT STDMETHODCALLTYPE
get_Dispatcher(
600 winui::Core::ICoreDispatcher
** value
) {
601 return dispatcher_
.CopyTo(value
);
604 virtual HRESULT STDMETHODCALLTYPE
get_FlowDirection(
605 winui::Core::CoreWindowFlowDirection
* value
) {
609 virtual HRESULT STDMETHODCALLTYPE
put_FlowDirection(
610 winui::Core::CoreWindowFlowDirection value
) {
614 virtual HRESULT STDMETHODCALLTYPE
get_IsInputEnabled(
619 virtual HRESULT STDMETHODCALLTYPE
put_IsInputEnabled(
624 virtual HRESULT STDMETHODCALLTYPE
get_PointerCursor(
625 winui::Core::ICoreCursor
** value
) {
629 virtual HRESULT STDMETHODCALLTYPE
put_PointerCursor(
630 winui::Core::ICoreCursor
* value
) {
634 virtual HRESULT STDMETHODCALLTYPE
get_PointerPosition(
635 winfoundtn::Point
* value
) {
639 virtual HRESULT STDMETHODCALLTYPE
get_Visible(
644 virtual HRESULT STDMETHODCALLTYPE
Activate(void) {
645 // After we fire OnActivate on the View, Chrome calls us back here.
649 virtual HRESULT STDMETHODCALLTYPE
Close(void) {
650 ::PostMessage(core_hwnd_
, WM_CLOSE
, 0, 0);
655 virtual HRESULT STDMETHODCALLTYPE
GetAsyncKeyState(
656 ABI::Windows::System::VirtualKey virtualKey
,
657 winui::Core::CoreVirtualKeyStates
* KeyState
) {
661 virtual HRESULT STDMETHODCALLTYPE
GetKeyState(
662 ABI::Windows::System::VirtualKey virtualKey
,
663 winui::Core::CoreVirtualKeyStates
* KeyState
) {
667 virtual HRESULT STDMETHODCALLTYPE
ReleasePointerCapture(void) {
671 virtual HRESULT STDMETHODCALLTYPE
SetPointerCapture(void) {
675 virtual HRESULT STDMETHODCALLTYPE
add_Activated(
676 WindowActivatedHandler
* handler
,
677 EventRegistrationToken
* pCookie
) {
678 window_activated_handler_
= handler
;
683 virtual HRESULT STDMETHODCALLTYPE
remove_Activated(
684 EventRegistrationToken cookie
) {
685 window_activated_handler_
->Release();
686 window_activated_handler_
= NULL
;
690 virtual HRESULT STDMETHODCALLTYPE
add_AutomationProviderRequested(
691 AutomationProviderHandler
* handler
,
692 EventRegistrationToken
* cookie
) {
696 virtual HRESULT STDMETHODCALLTYPE
remove_AutomationProviderRequested(
697 EventRegistrationToken cookie
) {
701 virtual HRESULT STDMETHODCALLTYPE
add_CharacterReceived(
702 CharEventHandler
* handler
,
703 EventRegistrationToken
* pCookie
) {
704 character_received_handler_
= handler
;
705 character_received_handler_
->AddRef();
709 virtual HRESULT STDMETHODCALLTYPE
remove_CharacterReceived(
710 EventRegistrationToken cookie
) {
711 character_received_handler_
->Release();
712 character_received_handler_
= NULL
;
716 virtual HRESULT STDMETHODCALLTYPE
add_Closed(
717 CoreWindowEventHandler
* handler
,
718 EventRegistrationToken
* pCookie
) {
722 virtual HRESULT STDMETHODCALLTYPE
remove_Closed(
723 EventRegistrationToken cookie
) {
727 virtual HRESULT STDMETHODCALLTYPE
add_InputEnabled(
728 InputEnabledEventHandler
* handler
,
729 EventRegistrationToken
* pCookie
) {
733 virtual HRESULT STDMETHODCALLTYPE
remove_InputEnabled(
734 EventRegistrationToken cookie
) {
738 virtual HRESULT STDMETHODCALLTYPE
add_KeyDown(
739 KeyEventHandler
* handler
,
740 EventRegistrationToken
* pCookie
) {
741 key_down_handler_
= handler
;
742 key_down_handler_
->AddRef();
746 virtual HRESULT STDMETHODCALLTYPE
remove_KeyDown(
747 EventRegistrationToken cookie
) {
748 key_down_handler_
->Release();
749 key_down_handler_
= NULL
;
753 virtual HRESULT STDMETHODCALLTYPE
add_KeyUp(
754 KeyEventHandler
* handler
,
755 EventRegistrationToken
* pCookie
) {
756 key_up_handler_
= handler
;
757 key_up_handler_
->AddRef();
761 virtual HRESULT STDMETHODCALLTYPE
remove_KeyUp(
762 EventRegistrationToken cookie
) {
763 key_up_handler_
->Release();
764 key_up_handler_
= NULL
;
768 virtual HRESULT STDMETHODCALLTYPE
add_PointerCaptureLost(
769 PointerEventHandler
* handler
,
770 EventRegistrationToken
* cookie
) {
771 mouse_capture_lost_handler_
= handler
;
775 virtual HRESULT STDMETHODCALLTYPE
remove_PointerCaptureLost(
776 EventRegistrationToken cookie
) {
777 mouse_capture_lost_handler_
= NULL
;
781 virtual HRESULT STDMETHODCALLTYPE
add_PointerEntered(
782 PointerEventHandler
* handler
,
783 EventRegistrationToken
* cookie
) {
784 mouse_entered_handler_
= handler
;
788 virtual HRESULT STDMETHODCALLTYPE
remove_PointerEntered(
789 EventRegistrationToken cookie
) {
790 mouse_entered_handler_
= NULL
;
794 virtual HRESULT STDMETHODCALLTYPE
add_PointerExited(
795 PointerEventHandler
* handler
,
796 EventRegistrationToken
* cookie
) {
797 mouse_exited_handler_
= handler
;
801 virtual HRESULT STDMETHODCALLTYPE
remove_PointerExited(
802 EventRegistrationToken cookie
) {
803 mouse_exited_handler_
= NULL
;
807 virtual HRESULT STDMETHODCALLTYPE
add_PointerMoved(
808 PointerEventHandler
* handler
,
809 EventRegistrationToken
* cookie
) {
810 mouse_moved_handler_
= handler
;
811 mouse_moved_handler_
->AddRef();
815 virtual HRESULT STDMETHODCALLTYPE
remove_PointerMoved(
816 EventRegistrationToken cookie
) {
817 mouse_moved_handler_
->Release();
818 mouse_moved_handler_
= NULL
;
822 virtual HRESULT STDMETHODCALLTYPE
add_PointerPressed(
823 PointerEventHandler
* handler
,
824 EventRegistrationToken
* cookie
) {
825 mouse_pressed_handler_
= handler
;
826 mouse_pressed_handler_
->AddRef();
830 virtual HRESULT STDMETHODCALLTYPE
remove_PointerPressed(
831 EventRegistrationToken cookie
) {
832 mouse_pressed_handler_
->Release();
833 mouse_pressed_handler_
= NULL
;
837 virtual HRESULT STDMETHODCALLTYPE
add_PointerReleased(
838 PointerEventHandler
* handler
,
839 EventRegistrationToken
* cookie
) {
840 mouse_released_handler_
= handler
;
841 mouse_released_handler_
->AddRef();
845 virtual HRESULT STDMETHODCALLTYPE
remove_PointerReleased(
846 EventRegistrationToken cookie
) {
847 mouse_released_handler_
->Release();
848 mouse_released_handler_
= NULL
;
852 virtual HRESULT STDMETHODCALLTYPE
add_TouchHitTesting(
853 TouchHitTestHandler
* handler
,
854 EventRegistrationToken
* pCookie
) {
858 virtual HRESULT STDMETHODCALLTYPE
remove_TouchHitTesting(
859 EventRegistrationToken cookie
) {
863 virtual HRESULT STDMETHODCALLTYPE
add_PointerWheelChanged(
864 PointerEventHandler
* handler
,
865 EventRegistrationToken
* cookie
) {
866 mouse_wheel_changed_handler_
= handler
;
867 mouse_wheel_changed_handler_
->AddRef();
871 virtual HRESULT STDMETHODCALLTYPE
remove_PointerWheelChanged(
872 EventRegistrationToken cookie
) {
873 mouse_wheel_changed_handler_
->Release();
874 mouse_wheel_changed_handler_
= NULL
;
878 virtual HRESULT STDMETHODCALLTYPE
add_SizeChanged(
879 SizeChangedHandler
* handler
,
880 EventRegistrationToken
* pCookie
) {
881 // TODO(cpu): implement this.
885 virtual HRESULT STDMETHODCALLTYPE
remove_SizeChanged(
886 EventRegistrationToken cookie
) {
890 virtual HRESULT STDMETHODCALLTYPE
add_VisibilityChanged(
891 VisibilityChangedHandler
* handler
,
892 EventRegistrationToken
* pCookie
) {
896 virtual HRESULT STDMETHODCALLTYPE
remove_VisibilityChanged(
897 EventRegistrationToken cookie
) {
901 // ICoreWindowInterop implementation:
902 virtual HRESULT STDMETHODCALLTYPE
get_WindowHandle(HWND
* hwnd
) {
909 virtual HRESULT STDMETHODCALLTYPE
put_MessageHandled(
915 virtual bool HandleKeyboardMessage(const MSG
& msg
) OVERRIDE
{
916 switch (msg
.message
) {
919 mswr::ComPtr
<winui::Core::IKeyEventArgs
> event_args
;
920 event_args
= mswr::Make
<KeyEvent
>(msg
);
921 KeyEventHandler
* handler
= NULL
;
922 if (msg
.message
== WM_KEYDOWN
) {
923 handler
= key_down_handler_
;
925 handler
= key_up_handler_
;
927 handler
->Invoke(this, event_args
.Get());
934 mswr::ComPtr
<winui::Core::ICharacterReceivedEventArgs
> event_args
;
935 event_args
= mswr::Make
<KeyEvent
>(msg
);
936 character_received_handler_
->Invoke(this, event_args
.Get());
946 virtual bool HandleMouseMessage(const MSG
& msg
) OVERRIDE
{
947 PointerEventHandler
* handler
= NULL
;
948 mswr::ComPtr
<winui::Core::IPointerEventArgs
> event_args
;
949 event_args
= mswr::Make
<MouseEvent
>(msg
);
950 switch (msg
.message
) {
952 handler
= mouse_moved_handler_
;
955 case WM_LBUTTONDOWN
: {
958 handler
= mouse_pressed_handler_
;
965 handler
= mouse_released_handler_
;
969 case WM_MOUSEWHEEL
: {
971 handler
= mouse_wheel_changed_handler_
;
979 handler
->Invoke(this, event_args
.Get());
983 void OnWindowActivated() {
984 if (window_activated_handler_
)
985 window_activated_handler_
->Invoke(this, NULL
);
989 PointerEventHandler
* mouse_moved_handler_
;
990 PointerEventHandler
* mouse_capture_lost_handler_
;
991 PointerEventHandler
* mouse_pressed_handler_
;
992 PointerEventHandler
* mouse_released_handler_
;
993 PointerEventHandler
* mouse_entered_handler_
;
994 PointerEventHandler
* mouse_exited_handler_
;
995 PointerEventHandler
* mouse_wheel_changed_handler_
;
996 KeyEventHandler
* key_down_handler_
;
997 KeyEventHandler
* key_up_handler_
;
998 CharEventHandler
* character_received_handler_
;
1000 mswr::ComPtr
<winui::Core::ICoreDispatcher
> dispatcher_
;
1001 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
1002 WindowActivatedHandler
* window_activated_handler_
;
1005 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
,
1006 WPARAM wparam
, LPARAM lparam
) {
1011 // HIWORD(wparam) is 1 if the window is minimized.
1012 bool active
= (LOWORD(wparam
) != WA_INACTIVE
) && !HIWORD(wparam
);
1014 CoreWindowEmulation
* core_window_handler
=
1015 reinterpret_cast<CoreWindowEmulation
*>(
1016 ::GetProp(hwnd
, kAshWin7CoreWindowHandler
));
1017 if (core_window_handler
)
1018 core_window_handler
->OnWindowActivated();
1020 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1026 hdc
= ::BeginPaint(hwnd
, &ps
);
1027 ::EndPaint(hwnd
, &ps
);
1030 ::DestroyWindow(hwnd
);
1034 if (!g_window_count
)
1035 ::PostQuitMessage(0);
1037 // Always allow Chrome to set the cursor.
1041 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1046 class ActivatedEvent
1047 : public mswr::RuntimeClass
<winapp::Activation::IActivatedEventArgs
> {
1049 ActivatedEvent(winapp::Activation::ActivationKind activation_kind
)
1050 : activation_kind_(activation_kind
) {
1053 virtual HRESULT STDMETHODCALLTYPE
get_Kind(
1054 winapp::Activation::ActivationKind
*value
) {
1055 *value
= activation_kind_
;
1059 virtual HRESULT STDMETHODCALLTYPE
get_PreviousExecutionState(
1060 winapp::Activation::ApplicationExecutionState
*value
) {
1061 *value
= winapp::Activation::ApplicationExecutionState_ClosedByUser
;
1065 virtual HRESULT STDMETHODCALLTYPE
get_SplashScreen(
1066 winapp::Activation::ISplashScreen
**value
) {
1071 winapp::Activation::ActivationKind activation_kind_
;
1074 class CoreApplicationViewEmulation
1075 : public mswr::RuntimeClass
<winapp::Core::ICoreApplicationView
> {
1077 CoreApplicationViewEmulation(winapp::Core::IFrameworkView
* app_view
) {
1078 core_window_
= mswr::Make
<CoreWindowEmulation
>(app_view
);
1081 HRESULT
Activate() {
1082 if (activated_handler_
) {
1083 auto ae
= mswr::Make
<ActivatedEvent
>(
1084 winapp::Activation::ActivationKind_File
);
1085 return activated_handler_
->Invoke(this, ae
.Get());
1092 return core_window_
->Close();
1095 // ICoreApplicationView implementation:
1096 virtual HRESULT STDMETHODCALLTYPE
get_CoreWindow(
1097 winui::Core::ICoreWindow
** value
) {
1100 return core_window_
.CopyTo(value
);
1103 virtual HRESULT STDMETHODCALLTYPE
add_Activated(
1104 ActivatedHandler
* handler
,
1105 EventRegistrationToken
* token
) {
1106 // The real component supports multiple handles but we don't yet.
1107 if (activated_handler_
)
1109 activated_handler_
= handler
;
1113 virtual HRESULT STDMETHODCALLTYPE
remove_Activated(
1114 EventRegistrationToken token
) {
1115 // Chrome never unregisters handlers, so we don't care about it.
1119 virtual HRESULT STDMETHODCALLTYPE
get_IsMain(
1124 virtual HRESULT STDMETHODCALLTYPE
get_IsHosted(
1130 mswr::ComPtr
<CoreWindowEmulation
> core_window_
;
1131 mswr::ComPtr
<ActivatedHandler
> activated_handler_
;
1134 class CoreApplicationWin7Emulation
1135 : public mswr::RuntimeClass
<winapp::Core::ICoreApplication
,
1136 winapp::Core::ICoreApplicationExit
> {
1138 // ICoreApplication implementation:
1140 virtual HRESULT STDMETHODCALLTYPE
get_Id(
1145 virtual HRESULT STDMETHODCALLTYPE
add_Suspending(
1146 winfoundtn::IEventHandler
<winapp::SuspendingEventArgs
*>* handler
,
1147 EventRegistrationToken
* token
) {
1151 virtual HRESULT STDMETHODCALLTYPE
remove_Suspending(
1152 EventRegistrationToken token
) {
1156 virtual HRESULT STDMETHODCALLTYPE
add_Resuming(
1157 winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1158 EventRegistrationToken
* token
) {
1162 virtual HRESULT STDMETHODCALLTYPE
remove_Resuming(
1163 EventRegistrationToken token
) {
1167 virtual HRESULT STDMETHODCALLTYPE
get_Properties(
1168 winfoundtn::Collections::IPropertySet
** value
) {
1172 virtual HRESULT STDMETHODCALLTYPE
GetCurrentView(
1173 winapp::Core::ICoreApplicationView
** value
) {
1177 virtual HRESULT STDMETHODCALLTYPE
Run(
1178 winapp::Core::IFrameworkViewSource
* viewSource
) {
1179 HRESULT hr
= viewSource
->CreateView(app_view_
.GetAddressOf());
1182 view_emulation_
= mswr::Make
<CoreApplicationViewEmulation
>(
1184 hr
= app_view_
->Initialize(view_emulation_
.Get());
1187 mswr::ComPtr
<winui::Core::ICoreWindow
> core_window
;
1188 hr
= view_emulation_
->get_CoreWindow(core_window
.GetAddressOf());
1191 hr
= app_view_
->SetWindow(core_window
.Get());
1194 hr
= app_view_
->Load(NULL
);
1197 hr
= view_emulation_
->Activate();
1200 return app_view_
->Run();
1203 virtual HRESULT STDMETHODCALLTYPE
RunWithActivationFactories(
1204 winfoundtn::IGetActivationFactory
* activationFactoryCallback
) {
1208 // ICoreApplicationExit implementation:
1210 virtual HRESULT STDMETHODCALLTYPE
Exit(void) {
1211 return view_emulation_
->Close();
1214 virtual HRESULT STDMETHODCALLTYPE
add_Exiting(
1215 winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1216 EventRegistrationToken
* token
) {
1220 virtual HRESULT STDMETHODCALLTYPE
remove_Exiting(
1221 EventRegistrationToken token
) {
1226 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
1227 mswr::ComPtr
<CoreApplicationViewEmulation
> view_emulation_
;
1231 mswr::ComPtr
<winapp::Core::ICoreApplication
> InitWindows7() {
1232 HRESULT hr
= ::CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
1235 return mswr::Make
<CoreApplicationWin7Emulation
>();