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 "base/profiler/scoped_tracker.h"
11 #include "ui/gfx/geometry/safe_integer_conversions.h"
12 #include "ui/gfx/win/msg_util.h"
14 #pragma comment(lib, "shell32.lib")
16 EXTERN_C IMAGE_DOS_HEADER __ImageBase
;
17 // Even though we only create a single window, we need to keep this
18 // count because of the hidden window used by the UI message loop of
20 int g_window_count
= 0;
22 const wchar_t kAshWin7AppId
[] = L
"Google.Chrome.AshWin7.1";
23 const wchar_t kAshWin7CoreWindowHandler
[] = L
"CoreWindowHandler";
24 extern float GetModernUIScale();
25 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
, WPARAM wparam
,
28 HWND
CreateMetroTopLevelWindow(const RECT
& work_area
) {
29 HINSTANCE hInst
= reinterpret_cast<HINSTANCE
>(&__ImageBase
);
31 wcex
.cbSize
= sizeof(wcex
);
32 wcex
.style
= CS_HREDRAW
| CS_VREDRAW
;
33 wcex
.lpfnWndProc
= WndProc
;
36 wcex
.hInstance
= hInst
;
37 wcex
.hIcon
= LoadIcon(::GetModuleHandle(NULL
), L
"IDR_MAINFRAME");
38 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
39 wcex
.hbrBackground
= (HBRUSH
)(COLOR_INACTIVECAPTION
+1);
40 wcex
.lpszMenuName
= 0;
41 wcex
.lpszClassName
= L
"Windows.UI.Core.CoreWindow";
42 wcex
.hIconSm
= LoadIcon(::GetModuleHandle(NULL
), L
"IDR_MAINFRAME");
44 HWND hwnd
= ::CreateWindowExW(0,
45 MAKEINTATOM(::RegisterClassExW(&wcex
)),
47 WS_POPUP
| WS_VISIBLE
| WS_MINIMIZEBOX
,
48 work_area
.top
, work_area
.left
,
49 work_area
.right
, work_area
.bottom
,
50 NULL
, NULL
, hInst
, NULL
);
54 typedef winfoundtn::ITypedEventHandler
<
55 winapp::Core::CoreApplicationView
*,
56 winapp::Activation::IActivatedEventArgs
*> ActivatedHandler
;
58 typedef winfoundtn::ITypedEventHandler
<
59 winui::Core::CoreWindow
*,
60 winui::Core::WindowActivatedEventArgs
*> WindowActivatedHandler
;
62 typedef winfoundtn::ITypedEventHandler
<
63 winui::Core::CoreWindow
*,
64 winui::Core::AutomationProviderRequestedEventArgs
*>
65 AutomationProviderHandler
;
67 typedef winfoundtn::ITypedEventHandler
<
68 winui::Core::CoreWindow
*,
69 winui::Core::CharacterReceivedEventArgs
*> CharEventHandler
;
71 typedef winfoundtn::ITypedEventHandler
<
72 winui::Core::CoreWindow
*,
73 winui::Core::CoreWindowEventArgs
*> CoreWindowEventHandler
;
75 typedef winfoundtn::ITypedEventHandler
<
76 winui::Core::CoreWindow
*,
77 winui::Core::InputEnabledEventArgs
*> InputEnabledEventHandler
;
79 typedef winfoundtn::ITypedEventHandler
<
80 winui::Core::CoreWindow
*,
81 winui::Core::KeyEventArgs
*> KeyEventHandler
;
83 typedef winfoundtn::ITypedEventHandler
<
84 winui::Core::CoreWindow
*,
85 winui::Core::PointerEventArgs
*> PointerEventHandler
;
87 typedef winfoundtn::ITypedEventHandler
<
88 winui::Core::CoreWindow
*,
89 winui::Core::WindowSizeChangedEventArgs
*> SizeChangedHandler
;
91 typedef winfoundtn::ITypedEventHandler
<
92 winui::Core::CoreWindow
*,
93 winui::Core::TouchHitTestingEventArgs
*> TouchHitTestHandler
;
95 typedef winfoundtn::ITypedEventHandler
<
96 winui::Core::CoreWindow
*,
97 winui::Core::VisibilityChangedEventArgs
*> VisibilityChangedHandler
;
99 typedef winfoundtn::ITypedEventHandler
<
100 winui::Core::CoreDispatcher
*,
101 winui::Core::AcceleratorKeyEventArgs
*> AcceleratorKeyEventHandler
;
103 // This interface is implemented by classes which handle mouse and keyboard
108 virtual ~InputHandler() {}
110 virtual bool HandleKeyboardMessage(const MSG
& msg
) = 0;
111 virtual bool HandleMouseMessage(const MSG
& msg
) = 0;
114 DISALLOW_COPY_AND_ASSIGN(InputHandler
);
117 // This class implements the winrt interfaces corresponding to mouse input.
118 class MouseEvent
: public mswr::RuntimeClass
<
119 winui::Core::IPointerEventArgs
,
120 winui::Input::IPointerPoint
,
121 winui::Input::IPointerPointProperties
,
122 windevs::Input::IPointerDevice
> {
124 MouseEvent(const MSG
& msg
)
128 // IPointerEventArgs implementation.
129 HRESULT STDMETHODCALLTYPE
130 get_CurrentPoint(winui::Input::IPointerPoint
** point
) override
{
131 return QueryInterface(winui::Input::IID_IPointerPoint
,
132 reinterpret_cast<void**>(point
));
135 HRESULT STDMETHODCALLTYPE
136 get_KeyModifiers(winsys::VirtualKeyModifiers
* modifiers
) override
{
140 HRESULT STDMETHODCALLTYPE
GetIntermediatePoints(
141 winfoundtn::Collections::IVector
<winui::Input::PointerPoint
*>** points
)
146 // IPointerPoint implementation.
147 HRESULT STDMETHODCALLTYPE
148 get_PointerDevice(windevs::Input::IPointerDevice
** pointer_device
) override
{
149 return QueryInterface(windevs::Input::IID_IPointerDevice
,
150 reinterpret_cast<void**>(pointer_device
));
153 HRESULT STDMETHODCALLTYPE
get_Position(winfoundtn::Point
* position
) override
{
154 static float scale
= GetModernUIScale();
155 // Scale down the points here as they are scaled up on the other side.
156 position
->X
= gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_
.lParam
) / scale
);
157 position
->Y
= gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_
.lParam
) / scale
);
161 HRESULT STDMETHODCALLTYPE
get_PointerId(uint32
* pointer_id
) override
{
163 // Implement this properly.
168 HRESULT STDMETHODCALLTYPE
get_Timestamp(uint64
* timestamp
) override
{
169 *timestamp
= msg_
.time
;
173 HRESULT STDMETHODCALLTYPE
174 get_Properties(winui::Input::IPointerPointProperties
** properties
) override
{
175 return QueryInterface(winui::Input::IID_IPointerPointProperties
,
176 reinterpret_cast<void**>(properties
));
179 HRESULT STDMETHODCALLTYPE
180 get_RawPosition(winfoundtn::Point
* position
) override
{
184 HRESULT STDMETHODCALLTYPE
get_FrameId(uint32
* frame_id
) override
{
188 HRESULT STDMETHODCALLTYPE
get_IsInContact(boolean
* in_contact
) override
{
192 // IPointerPointProperties implementation.
193 HRESULT STDMETHODCALLTYPE
194 get_PointerUpdateKind(winui::Input::PointerUpdateKind
* update_kind
) override
{
196 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
198 if (msg_
.message
== WM_LBUTTONDOWN
) {
199 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonPressed
;
200 } else if (msg_
.message
== WM_RBUTTONDOWN
) {
201 *update_kind
= winui::Input::PointerUpdateKind_RightButtonPressed
;
202 } else if (msg_
.message
== WM_MBUTTONDOWN
) {
203 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonPressed
;
204 } else if (msg_
.message
== WM_LBUTTONUP
) {
205 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonReleased
;
206 } else if (msg_
.message
== WM_RBUTTONUP
) {
207 *update_kind
= winui::Input::PointerUpdateKind_RightButtonReleased
;
208 } else if (msg_
.message
== WM_MBUTTONUP
) {
209 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonReleased
;
214 HRESULT STDMETHODCALLTYPE
215 get_IsLeftButtonPressed(boolean
* left_button_pressed
) override
{
216 *left_button_pressed
= msg_
.wParam
& MK_LBUTTON
? true : false;
220 HRESULT STDMETHODCALLTYPE
221 get_IsRightButtonPressed(boolean
* right_button_pressed
) override
{
222 *right_button_pressed
= msg_
.wParam
& MK_RBUTTON
? true : false;
226 HRESULT STDMETHODCALLTYPE
227 get_IsMiddleButtonPressed(boolean
* middle_button_pressed
) override
{
228 *middle_button_pressed
= msg_
.wParam
& MK_MBUTTON
? true : false;
232 HRESULT STDMETHODCALLTYPE
233 get_IsHorizontalMouseWheel(boolean
* is_horizontal_mouse_wheel
) override
{
234 *is_horizontal_mouse_wheel
=
235 (msg_
.message
== WM_MOUSEHWHEEL
) ? true : false;
239 HRESULT STDMETHODCALLTYPE
get_MouseWheelDelta(int* delta
) override
{
240 if (msg_
.message
== WM_MOUSEWHEEL
|| msg_
.message
== WM_MOUSEHWHEEL
) {
241 *delta
= GET_WHEEL_DELTA_WPARAM(msg_
.wParam
);
248 HRESULT STDMETHODCALLTYPE
get_Pressure(float* pressure
) override
{
252 HRESULT STDMETHODCALLTYPE
get_IsInverted(boolean
* inverted
) override
{
256 HRESULT STDMETHODCALLTYPE
get_IsEraser(boolean
* is_eraser
) override
{
260 HRESULT STDMETHODCALLTYPE
get_Orientation(float* orientation
) override
{
264 HRESULT STDMETHODCALLTYPE
get_XTilt(float* x_tilt
) override
{
268 HRESULT STDMETHODCALLTYPE
get_YTilt(float* y_tilt
) override
{
272 HRESULT STDMETHODCALLTYPE
get_Twist(float* twist
) override
{
276 HRESULT STDMETHODCALLTYPE
get_ContactRect(winfoundtn::Rect
* rect
) override
{
280 HRESULT STDMETHODCALLTYPE
281 get_ContactRectRaw(winfoundtn::Rect
* rect
) override
{
285 HRESULT STDMETHODCALLTYPE
get_TouchConfidence(boolean
* confidence
) override
{
289 HRESULT STDMETHODCALLTYPE
get_IsPrimary(boolean
* is_primary
) override
{
293 HRESULT STDMETHODCALLTYPE
get_IsInRange(boolean
* is_in_range
) override
{
297 HRESULT STDMETHODCALLTYPE
get_IsCanceled(boolean
* is_canceled
) override
{
301 HRESULT STDMETHODCALLTYPE
302 get_IsBarrelButtonPressed(boolean
* is_barrel_button_pressed
) override
{
306 HRESULT STDMETHODCALLTYPE
307 get_IsXButton1Pressed(boolean
* is_xbutton1_pressed
) override
{
311 HRESULT STDMETHODCALLTYPE
312 get_IsXButton2Pressed(boolean
* is_xbutton2_pressed
) override
{
316 HRESULT STDMETHODCALLTYPE
317 HasUsage(uint32 usage_page
, uint32 usage_id
, boolean
* has_usage
) override
{
321 HRESULT STDMETHODCALLTYPE
GetUsageValue(uint32 usage_page
,
323 int32
* usage_value
) override
{
327 // IPointerDevice implementation.
328 HRESULT STDMETHODCALLTYPE
get_PointerDeviceType(
329 windevs::Input::PointerDeviceType
* device_type
) override
{
330 if (msg_
.message
== WM_TOUCH
) {
331 *device_type
= windevs::Input::PointerDeviceType_Touch
;
333 *device_type
= windevs::Input::PointerDeviceType_Mouse
;
338 HRESULT STDMETHODCALLTYPE
get_IsIntegrated(boolean
* is_integrated
) override
{
342 HRESULT STDMETHODCALLTYPE
get_MaxContacts(uint32
* contacts
) override
{
346 HRESULT STDMETHODCALLTYPE
347 get_PhysicalDeviceRect(winfoundtn::Rect
* rect
) override
{
351 HRESULT STDMETHODCALLTYPE
get_ScreenRect(winfoundtn::Rect
* rect
) override
{
355 HRESULT STDMETHODCALLTYPE
get_SupportedUsages(
356 winfoundtn::Collections::IVectorView
<windevs::Input::PointerDeviceUsage
>**
364 DISALLOW_COPY_AND_ASSIGN(MouseEvent
);
367 // This class implements the winrt interfaces needed to support keyboard
368 // character and system character messages.
369 class KeyEvent
: public mswr::RuntimeClass
<
370 winui::Core::IKeyEventArgs
,
371 winui::Core::ICharacterReceivedEventArgs
,
372 winui::Core::IAcceleratorKeyEventArgs
> {
374 KeyEvent(const MSG
& msg
)
377 // IKeyEventArgs implementation.
378 HRESULT STDMETHODCALLTYPE
379 get_VirtualKey(winsys::VirtualKey
* virtual_key
) override
{
380 *virtual_key
= static_cast<winsys::VirtualKey
>(msg_
.wParam
);
384 HRESULT STDMETHODCALLTYPE
385 get_KeyStatus(winui::Core::CorePhysicalKeyStatus
* key_status
) override
{
386 // As per msdn documentation for the keyboard messages.
387 key_status
->RepeatCount
= msg_
.lParam
& 0x0000FFFF;
388 key_status
->ScanCode
= (msg_
.lParam
>> 16) & 0x00FF;
389 key_status
->IsExtendedKey
= (msg_
.lParam
& (1 << 24));
390 key_status
->IsMenuKeyDown
= (msg_
.lParam
& (1 << 29));
391 key_status
->WasKeyDown
= (msg_
.lParam
& (1 << 30));
392 key_status
->IsKeyReleased
= (msg_
.lParam
& (1 << 31));
396 // ICharacterReceivedEventArgs implementation.
397 HRESULT STDMETHODCALLTYPE
get_KeyCode(uint32
* key_code
) override
{
398 *key_code
= msg_
.wParam
;
402 // IAcceleratorKeyEventArgs implementation.
403 HRESULT STDMETHODCALLTYPE
404 get_EventType(winui::Core::CoreAcceleratorKeyEventType
* event_type
) override
{
405 if (msg_
.message
== WM_SYSKEYDOWN
) {
406 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown
;
407 } else if (msg_
.message
== WM_SYSKEYUP
) {
408 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp
;
409 } else if (msg_
.message
== WM_SYSCHAR
) {
410 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemCharacter
;
419 // The following classes are the emulation of the WinRT system as exposed
420 // to metro applications. There is one application (ICoreApplication) which
421 // contains a series of Views (ICoreApplicationView) each one of them
422 // containing a CoreWindow which represents a surface that can drawn to
423 // and that receives events.
425 // Here is the general dependency hierachy in terms of interfaces:
427 // IFrameworkViewSource --> IFrameworkView
430 // ---------------------------------------------------------------------
433 // ICoreApplication ICoreApplicationView
436 // ICoreWindow -----> ICoreWindowInterop
440 // ICoreDispatcher <==> real HWND
442 class CoreDispatcherEmulation
:
443 public mswr::RuntimeClass
<
444 winui::Core::ICoreDispatcher
,
445 winui::Core::ICoreAcceleratorKeys
> {
447 CoreDispatcherEmulation(InputHandler
* input_handler
)
448 : input_handler_(input_handler
),
449 accelerator_key_event_handler_(NULL
) {}
451 // ICoreDispatcher implementation:
452 HRESULT STDMETHODCALLTYPE
get_HasThreadAccess(boolean
* value
) override
{
456 HRESULT STDMETHODCALLTYPE
457 ProcessEvents(winui::Core::CoreProcessEventsOption options
) override
{
458 // We don't support the other message pump modes. So we basically enter a
459 // traditional message loop that we only exit a teardown.
460 if (options
!= winui::Core::CoreProcessEventsOption_ProcessUntilQuit
)
464 while((::GetMessage(&msg
, NULL
, 0, 0) != 0) && g_window_count
> 0) {
465 ProcessInputMessage(msg
);
466 ::TranslateMessage(&msg
);
467 ::DispatchMessage(&msg
);
469 // TODO(cpu): figure what to do with msg.WParam which we would normally
474 HRESULT STDMETHODCALLTYPE
475 RunAsync(winui::Core::CoreDispatcherPriority priority
,
476 winui::Core::IDispatchedHandler
* agileCallback
,
477 ABI::Windows::Foundation::IAsyncAction
** asyncAction
) override
{
481 HRESULT STDMETHODCALLTYPE
482 RunIdleAsync(winui::Core::IIdleDispatchedHandler
* agileCallback
,
483 winfoundtn::IAsyncAction
** asyncAction
) override
{
487 // ICoreAcceleratorKeys implementation:
488 HRESULT STDMETHODCALLTYPE
489 add_AcceleratorKeyActivated(AcceleratorKeyEventHandler
* handler
,
490 EventRegistrationToken
* pCookie
) override
{
491 accelerator_key_event_handler_
= handler
;
492 accelerator_key_event_handler_
->AddRef();
496 HRESULT STDMETHODCALLTYPE
497 remove_AcceleratorKeyActivated(EventRegistrationToken cookie
) override
{
498 accelerator_key_event_handler_
->Release();
499 accelerator_key_event_handler_
= NULL
;
504 bool ProcessInputMessage(const MSG
& msg
) {
505 // Poor man's way of dispatching input events.
507 if (input_handler_
) {
508 if ((msg
.message
>= WM_KEYFIRST
) && (msg
.message
<= WM_KEYLAST
)) {
509 if ((msg
.message
== WM_SYSKEYDOWN
) || (msg
.message
== WM_SYSKEYUP
) ||
510 msg
.message
== WM_SYSCHAR
) {
511 ret
= HandleSystemKeys(msg
);
513 ret
= input_handler_
->HandleKeyboardMessage(msg
);
515 } else if ((msg
.message
>= WM_MOUSEFIRST
) &&
516 (msg
.message
<= WM_MOUSELAST
)) {
517 ret
= input_handler_
->HandleMouseMessage(msg
);
523 bool HandleSystemKeys(const MSG
& msg
) {
524 mswr::ComPtr
<winui::Core::IAcceleratorKeyEventArgs
> event_args
;
525 event_args
= mswr::Make
<KeyEvent
>(msg
);
526 accelerator_key_event_handler_
->Invoke(this, event_args
.Get());
530 InputHandler
* input_handler_
;
531 AcceleratorKeyEventHandler
* accelerator_key_event_handler_
;
534 class CoreWindowEmulation
535 : public mswr::RuntimeClass
<
536 mswr::RuntimeClassFlags
<mswr::WinRtClassicComMix
>,
537 winui::Core::ICoreWindow
, ICoreWindowInterop
>,
538 public InputHandler
{
540 CoreWindowEmulation(winapp::Core::IFrameworkView
* app_view
)
541 : mouse_moved_handler_(NULL
),
542 mouse_capture_lost_handler_(NULL
),
543 mouse_pressed_handler_(NULL
),
544 mouse_released_handler_(NULL
),
545 mouse_entered_handler_(NULL
),
546 mouse_exited_handler_(NULL
),
547 mouse_wheel_changed_handler_(NULL
),
548 key_down_handler_(NULL
),
549 key_up_handler_(NULL
),
550 character_received_handler_(NULL
),
553 window_activated_handler_(NULL
) {
554 dispatcher_
= mswr::Make
<CoreDispatcherEmulation
>(this);
556 // Unless we select our own AppUserModelID the shell might confuse us
557 // with the app launcher one and we get the wrong taskbar button and icon.
558 ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId
);
560 RECT work_area
= {0};
561 ::SystemParametersInfo(SPI_GETWORKAREA
, 0, &work_area
, 0);
562 if (::IsDebuggerPresent()) {
565 work_area
.right
= 1600;
566 work_area
.bottom
= 900;
569 core_hwnd_
= CreateMetroTopLevelWindow(work_area
);
570 ::SetProp(core_hwnd_
, kAshWin7CoreWindowHandler
, this);
573 ~CoreWindowEmulation() override
{
575 ::RemoveProp(core_hwnd_
, kAshWin7CoreWindowHandler
);
576 ::DestroyWindow(core_hwnd_
);
580 // ICoreWindow implementation:
581 HRESULT STDMETHODCALLTYPE
582 get_AutomationHostProvider(IInspectable
** value
) override
{
586 HRESULT STDMETHODCALLTYPE
get_Bounds(winfoundtn::Rect
* value
) override
{
588 if (!::GetClientRect(core_hwnd_
, &rect
))
590 value
->Width
= rect
.right
;
591 value
->Height
= rect
.bottom
;
595 HRESULT STDMETHODCALLTYPE
596 get_CustomProperties(winfoundtn::Collections::IPropertySet
** value
) override
{
600 HRESULT STDMETHODCALLTYPE
601 get_Dispatcher(winui::Core::ICoreDispatcher
** value
) override
{
602 return dispatcher_
.CopyTo(value
);
605 HRESULT STDMETHODCALLTYPE
606 get_FlowDirection(winui::Core::CoreWindowFlowDirection
* value
) override
{
610 HRESULT STDMETHODCALLTYPE
611 put_FlowDirection(winui::Core::CoreWindowFlowDirection value
) override
{
615 HRESULT STDMETHODCALLTYPE
get_IsInputEnabled(boolean
* value
) override
{
619 HRESULT STDMETHODCALLTYPE
put_IsInputEnabled(boolean value
) override
{
623 HRESULT STDMETHODCALLTYPE
624 get_PointerCursor(winui::Core::ICoreCursor
** value
) override
{
628 HRESULT STDMETHODCALLTYPE
629 put_PointerCursor(winui::Core::ICoreCursor
* value
) override
{
633 HRESULT STDMETHODCALLTYPE
634 get_PointerPosition(winfoundtn::Point
* value
) override
{
638 HRESULT STDMETHODCALLTYPE
get_Visible(boolean
* value
) override
{
642 HRESULT STDMETHODCALLTYPE
Activate(void) override
{
643 // After we fire OnActivate on the View, Chrome calls us back here.
647 HRESULT STDMETHODCALLTYPE
Close(void) override
{
648 ::PostMessage(core_hwnd_
, WM_CLOSE
, 0, 0);
653 HRESULT STDMETHODCALLTYPE
GetAsyncKeyState(
654 ABI::Windows::System::VirtualKey virtualKey
,
655 winui::Core::CoreVirtualKeyStates
* KeyState
) override
{
659 HRESULT STDMETHODCALLTYPE
GetKeyState(
660 ABI::Windows::System::VirtualKey virtualKey
,
661 winui::Core::CoreVirtualKeyStates
* KeyState
) override
{
665 HRESULT STDMETHODCALLTYPE
ReleasePointerCapture(void) override
{
669 HRESULT STDMETHODCALLTYPE
SetPointerCapture(void) override
{
673 HRESULT STDMETHODCALLTYPE
add_Activated(
674 WindowActivatedHandler
* handler
,
675 EventRegistrationToken
* pCookie
) override
{
676 window_activated_handler_
= handler
;
681 HRESULT STDMETHODCALLTYPE
remove_Activated(
682 EventRegistrationToken cookie
) override
{
683 window_activated_handler_
->Release();
684 window_activated_handler_
= NULL
;
688 HRESULT STDMETHODCALLTYPE
add_AutomationProviderRequested(
689 AutomationProviderHandler
* handler
,
690 EventRegistrationToken
* cookie
) override
{
694 HRESULT STDMETHODCALLTYPE
remove_AutomationProviderRequested(
695 EventRegistrationToken cookie
) override
{
699 HRESULT STDMETHODCALLTYPE
add_CharacterReceived(
700 CharEventHandler
* handler
,
701 EventRegistrationToken
* pCookie
) override
{
702 character_received_handler_
= handler
;
703 character_received_handler_
->AddRef();
707 HRESULT STDMETHODCALLTYPE
remove_CharacterReceived(
708 EventRegistrationToken cookie
) override
{
709 character_received_handler_
->Release();
710 character_received_handler_
= NULL
;
714 HRESULT STDMETHODCALLTYPE
add_Closed(
715 CoreWindowEventHandler
* handler
,
716 EventRegistrationToken
* pCookie
) override
{
720 HRESULT STDMETHODCALLTYPE
remove_Closed(
721 EventRegistrationToken cookie
) override
{
725 HRESULT STDMETHODCALLTYPE
add_InputEnabled(
726 InputEnabledEventHandler
* handler
,
727 EventRegistrationToken
* pCookie
) override
{
731 HRESULT STDMETHODCALLTYPE
remove_InputEnabled(
732 EventRegistrationToken cookie
) override
{
736 HRESULT STDMETHODCALLTYPE
add_KeyDown(
737 KeyEventHandler
* handler
,
738 EventRegistrationToken
* pCookie
) override
{
739 key_down_handler_
= handler
;
740 key_down_handler_
->AddRef();
744 HRESULT STDMETHODCALLTYPE
remove_KeyDown(
745 EventRegistrationToken cookie
) override
{
746 key_down_handler_
->Release();
747 key_down_handler_
= NULL
;
751 HRESULT STDMETHODCALLTYPE
add_KeyUp(
752 KeyEventHandler
* handler
,
753 EventRegistrationToken
* pCookie
) override
{
754 key_up_handler_
= handler
;
755 key_up_handler_
->AddRef();
759 HRESULT STDMETHODCALLTYPE
remove_KeyUp(
760 EventRegistrationToken cookie
) override
{
761 key_up_handler_
->Release();
762 key_up_handler_
= NULL
;
766 HRESULT STDMETHODCALLTYPE
add_PointerCaptureLost(
767 PointerEventHandler
* handler
,
768 EventRegistrationToken
* cookie
) override
{
769 mouse_capture_lost_handler_
= handler
;
773 HRESULT STDMETHODCALLTYPE
remove_PointerCaptureLost(
774 EventRegistrationToken cookie
) override
{
775 mouse_capture_lost_handler_
= NULL
;
779 HRESULT STDMETHODCALLTYPE
add_PointerEntered(
780 PointerEventHandler
* handler
,
781 EventRegistrationToken
* cookie
) override
{
782 mouse_entered_handler_
= handler
;
786 HRESULT STDMETHODCALLTYPE
remove_PointerEntered(
787 EventRegistrationToken cookie
) override
{
788 mouse_entered_handler_
= NULL
;
792 HRESULT STDMETHODCALLTYPE
add_PointerExited(
793 PointerEventHandler
* handler
,
794 EventRegistrationToken
* cookie
) override
{
795 mouse_exited_handler_
= handler
;
799 HRESULT STDMETHODCALLTYPE
remove_PointerExited(
800 EventRegistrationToken cookie
) override
{
801 mouse_exited_handler_
= NULL
;
805 HRESULT STDMETHODCALLTYPE
add_PointerMoved(
806 PointerEventHandler
* handler
,
807 EventRegistrationToken
* cookie
) override
{
808 mouse_moved_handler_
= handler
;
809 mouse_moved_handler_
->AddRef();
813 HRESULT STDMETHODCALLTYPE
remove_PointerMoved(
814 EventRegistrationToken cookie
) override
{
815 mouse_moved_handler_
->Release();
816 mouse_moved_handler_
= NULL
;
820 HRESULT STDMETHODCALLTYPE
add_PointerPressed(
821 PointerEventHandler
* handler
,
822 EventRegistrationToken
* cookie
) override
{
823 mouse_pressed_handler_
= handler
;
824 mouse_pressed_handler_
->AddRef();
828 HRESULT STDMETHODCALLTYPE
remove_PointerPressed(
829 EventRegistrationToken cookie
) override
{
830 mouse_pressed_handler_
->Release();
831 mouse_pressed_handler_
= NULL
;
835 HRESULT STDMETHODCALLTYPE
add_PointerReleased(
836 PointerEventHandler
* handler
,
837 EventRegistrationToken
* cookie
) override
{
838 mouse_released_handler_
= handler
;
839 mouse_released_handler_
->AddRef();
843 HRESULT STDMETHODCALLTYPE
remove_PointerReleased(
844 EventRegistrationToken cookie
) override
{
845 mouse_released_handler_
->Release();
846 mouse_released_handler_
= NULL
;
850 HRESULT STDMETHODCALLTYPE
add_TouchHitTesting(
851 TouchHitTestHandler
* handler
,
852 EventRegistrationToken
* pCookie
) override
{
856 HRESULT STDMETHODCALLTYPE
remove_TouchHitTesting(
857 EventRegistrationToken cookie
) override
{
861 HRESULT STDMETHODCALLTYPE
add_PointerWheelChanged(
862 PointerEventHandler
* handler
,
863 EventRegistrationToken
* cookie
) override
{
864 mouse_wheel_changed_handler_
= handler
;
865 mouse_wheel_changed_handler_
->AddRef();
869 HRESULT STDMETHODCALLTYPE
remove_PointerWheelChanged(
870 EventRegistrationToken cookie
) override
{
871 mouse_wheel_changed_handler_
->Release();
872 mouse_wheel_changed_handler_
= NULL
;
876 HRESULT STDMETHODCALLTYPE
add_SizeChanged(
877 SizeChangedHandler
* handler
,
878 EventRegistrationToken
* pCookie
) override
{
879 // TODO(cpu): implement this.
883 HRESULT STDMETHODCALLTYPE
remove_SizeChanged(
884 EventRegistrationToken cookie
) override
{
888 HRESULT STDMETHODCALLTYPE
add_VisibilityChanged(
889 VisibilityChangedHandler
* handler
,
890 EventRegistrationToken
* pCookie
) override
{
894 HRESULT STDMETHODCALLTYPE
remove_VisibilityChanged(
895 EventRegistrationToken cookie
) override
{
899 // ICoreWindowInterop implementation:
900 HRESULT STDMETHODCALLTYPE
get_WindowHandle(HWND
* hwnd
) override
{
907 HRESULT STDMETHODCALLTYPE
put_MessageHandled(boolean value
) override
{
912 bool HandleKeyboardMessage(const MSG
& msg
) override
{
913 switch (msg
.message
) {
916 mswr::ComPtr
<winui::Core::IKeyEventArgs
> event_args
;
917 event_args
= mswr::Make
<KeyEvent
>(msg
);
918 KeyEventHandler
* handler
= NULL
;
919 if (msg
.message
== WM_KEYDOWN
) {
920 handler
= key_down_handler_
;
922 handler
= key_up_handler_
;
924 handler
->Invoke(this, event_args
.Get());
931 mswr::ComPtr
<winui::Core::ICharacterReceivedEventArgs
> event_args
;
932 event_args
= mswr::Make
<KeyEvent
>(msg
);
933 character_received_handler_
->Invoke(this, event_args
.Get());
943 bool HandleMouseMessage(const MSG
& msg
) override
{
944 PointerEventHandler
* handler
= NULL
;
945 mswr::ComPtr
<winui::Core::IPointerEventArgs
> event_args
;
946 event_args
= mswr::Make
<MouseEvent
>(msg
);
947 switch (msg
.message
) {
949 handler
= mouse_moved_handler_
;
952 case WM_LBUTTONDOWN
: {
955 handler
= mouse_pressed_handler_
;
962 handler
= mouse_released_handler_
;
966 case WM_MOUSEWHEEL
: {
968 handler
= mouse_wheel_changed_handler_
;
976 handler
->Invoke(this, event_args
.Get());
980 void OnWindowActivated() {
981 if (window_activated_handler_
)
982 window_activated_handler_
->Invoke(this, NULL
);
986 PointerEventHandler
* mouse_moved_handler_
;
987 PointerEventHandler
* mouse_capture_lost_handler_
;
988 PointerEventHandler
* mouse_pressed_handler_
;
989 PointerEventHandler
* mouse_released_handler_
;
990 PointerEventHandler
* mouse_entered_handler_
;
991 PointerEventHandler
* mouse_exited_handler_
;
992 PointerEventHandler
* mouse_wheel_changed_handler_
;
993 KeyEventHandler
* key_down_handler_
;
994 KeyEventHandler
* key_up_handler_
;
995 CharEventHandler
* character_received_handler_
;
997 mswr::ComPtr
<winui::Core::ICoreDispatcher
> dispatcher_
;
998 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
999 WindowActivatedHandler
* window_activated_handler_
;
1002 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
,
1003 WPARAM wparam
, LPARAM lparam
) {
1008 // HIWORD(wparam) is 1 if the window is minimized.
1009 bool active
= (LOWORD(wparam
) != WA_INACTIVE
) && !HIWORD(wparam
);
1011 CoreWindowEmulation
* core_window_handler
=
1012 reinterpret_cast<CoreWindowEmulation
*>(
1013 ::GetProp(hwnd
, kAshWin7CoreWindowHandler
));
1014 if (core_window_handler
)
1015 core_window_handler
->OnWindowActivated();
1017 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1023 hdc
= ::BeginPaint(hwnd
, &ps
);
1024 ::EndPaint(hwnd
, &ps
);
1027 ::DestroyWindow(hwnd
);
1031 if (!g_window_count
)
1032 ::PostQuitMessage(0);
1034 // Always allow Chrome to set the cursor.
1038 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1043 class ActivatedEvent
1044 : public mswr::RuntimeClass
<winapp::Activation::IActivatedEventArgs
> {
1046 ActivatedEvent(winapp::Activation::ActivationKind activation_kind
)
1047 : activation_kind_(activation_kind
) {
1050 HRESULT STDMETHODCALLTYPE
1051 get_Kind(winapp::Activation::ActivationKind
* value
) override
{
1052 *value
= activation_kind_
;
1056 HRESULT STDMETHODCALLTYPE
get_PreviousExecutionState(
1057 winapp::Activation::ApplicationExecutionState
* value
) override
{
1058 *value
= winapp::Activation::ApplicationExecutionState_ClosedByUser
;
1062 HRESULT STDMETHODCALLTYPE
1063 get_SplashScreen(winapp::Activation::ISplashScreen
** value
) override
{
1068 winapp::Activation::ActivationKind activation_kind_
;
1071 class CoreApplicationViewEmulation
1072 : public mswr::RuntimeClass
<winapp::Core::ICoreApplicationView
> {
1074 CoreApplicationViewEmulation(winapp::Core::IFrameworkView
* app_view
) {
1075 core_window_
= mswr::Make
<CoreWindowEmulation
>(app_view
);
1078 HRESULT
Activate() {
1079 if (activated_handler_
) {
1080 auto ae
= mswr::Make
<ActivatedEvent
>(
1081 winapp::Activation::ActivationKind_File
);
1082 return activated_handler_
->Invoke(this, ae
.Get());
1089 return core_window_
->Close();
1092 // ICoreApplicationView implementation:
1093 HRESULT STDMETHODCALLTYPE
1094 get_CoreWindow(winui::Core::ICoreWindow
** value
) override
{
1097 return core_window_
.CopyTo(value
);
1100 HRESULT STDMETHODCALLTYPE
1101 add_Activated(ActivatedHandler
* handler
,
1102 EventRegistrationToken
* token
) override
{
1103 // The real component supports multiple handles but we don't yet.
1104 if (activated_handler_
)
1106 activated_handler_
= handler
;
1110 HRESULT STDMETHODCALLTYPE
1111 remove_Activated(EventRegistrationToken token
) override
{
1112 // Chrome never unregisters handlers, so we don't care about it.
1116 HRESULT STDMETHODCALLTYPE
get_IsMain(boolean
* value
) override
{ return S_OK
; }
1118 HRESULT STDMETHODCALLTYPE
get_IsHosted(boolean
* value
) override
{
1123 mswr::ComPtr
<CoreWindowEmulation
> core_window_
;
1124 mswr::ComPtr
<ActivatedHandler
> activated_handler_
;
1127 class CoreApplicationWin7Emulation
1128 : public mswr::RuntimeClass
<winapp::Core::ICoreApplication
,
1129 winapp::Core::ICoreApplicationExit
> {
1131 // ICoreApplication implementation:
1133 HRESULT STDMETHODCALLTYPE
get_Id(HSTRING
* value
) override
{ return S_OK
; }
1135 HRESULT STDMETHODCALLTYPE
add_Suspending(
1136 winfoundtn::IEventHandler
<winapp::SuspendingEventArgs
*>* handler
,
1137 EventRegistrationToken
* token
) override
{
1141 HRESULT STDMETHODCALLTYPE
1142 remove_Suspending(EventRegistrationToken token
) override
{
1146 HRESULT STDMETHODCALLTYPE
1147 add_Resuming(winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1148 EventRegistrationToken
* token
) override
{
1152 HRESULT STDMETHODCALLTYPE
1153 remove_Resuming(EventRegistrationToken token
) override
{
1157 HRESULT STDMETHODCALLTYPE
1158 get_Properties(winfoundtn::Collections::IPropertySet
** value
) override
{
1162 HRESULT STDMETHODCALLTYPE
1163 GetCurrentView(winapp::Core::ICoreApplicationView
** value
) override
{
1167 HRESULT STDMETHODCALLTYPE
1168 Run(winapp::Core::IFrameworkViewSource
* viewSource
) override
{
1169 HRESULT hr
= viewSource
->CreateView(app_view_
.GetAddressOf());
1172 view_emulation_
= mswr::Make
<CoreApplicationViewEmulation
>(
1174 hr
= app_view_
->Initialize(view_emulation_
.Get());
1177 mswr::ComPtr
<winui::Core::ICoreWindow
> core_window
;
1178 hr
= view_emulation_
->get_CoreWindow(core_window
.GetAddressOf());
1181 hr
= app_view_
->SetWindow(core_window
.Get());
1184 hr
= app_view_
->Load(NULL
);
1187 hr
= view_emulation_
->Activate();
1190 return app_view_
->Run();
1193 HRESULT STDMETHODCALLTYPE
RunWithActivationFactories(
1194 winfoundtn::IGetActivationFactory
* activationFactoryCallback
) override
{
1198 // ICoreApplicationExit implementation:
1200 HRESULT STDMETHODCALLTYPE
Exit(void) override
{
1201 return view_emulation_
->Close();
1204 HRESULT STDMETHODCALLTYPE
1205 add_Exiting(winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1206 EventRegistrationToken
* token
) override
{
1210 HRESULT STDMETHODCALLTYPE
1211 remove_Exiting(EventRegistrationToken token
) override
{
1216 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
1217 mswr::ComPtr
<CoreApplicationViewEmulation
> view_emulation_
;
1221 mswr::ComPtr
<winapp::Core::ICoreApplication
> InitWindows7() {
1222 HRESULT hr
= ::CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1225 return mswr::Make
<CoreApplicationWin7Emulation
>();