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 virtual HRESULT STDMETHODCALLTYPE
get_CurrentPoint(
130 winui::Input::IPointerPoint
** point
) {
131 return QueryInterface(winui::Input::IID_IPointerPoint
,
132 reinterpret_cast<void**>(point
));
135 virtual HRESULT STDMETHODCALLTYPE
get_KeyModifiers(
136 winsys::VirtualKeyModifiers
* modifiers
) {
140 virtual HRESULT STDMETHODCALLTYPE
GetIntermediatePoints(
141 winfoundtn::Collections::IVector
<winui::Input::PointerPoint
*>** points
) {
145 // IPointerPoint implementation.
146 virtual HRESULT STDMETHODCALLTYPE
get_PointerDevice(
147 windevs::Input::IPointerDevice
** pointer_device
) {
148 return QueryInterface(windevs::Input::IID_IPointerDevice
,
149 reinterpret_cast<void**>(pointer_device
));
152 virtual HRESULT STDMETHODCALLTYPE
get_Position(winfoundtn::Point
* position
) {
153 static float scale
= GetModernUIScale();
154 // Scale down the points here as they are scaled up on the other side.
155 position
->X
= gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_
.lParam
) / scale
);
156 position
->Y
= gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_
.lParam
) / scale
);
160 virtual HRESULT STDMETHODCALLTYPE
get_PointerId(uint32
* pointer_id
) {
162 // Implement this properly.
167 virtual HRESULT STDMETHODCALLTYPE
get_Timestamp(uint64
* timestamp
) {
168 *timestamp
= msg_
.time
;
172 virtual HRESULT STDMETHODCALLTYPE
get_Properties(
173 winui::Input::IPointerPointProperties
** properties
) {
174 return QueryInterface(winui::Input::IID_IPointerPointProperties
,
175 reinterpret_cast<void**>(properties
));
178 virtual HRESULT STDMETHODCALLTYPE
get_RawPosition(
179 winfoundtn::Point
* position
) {
183 virtual HRESULT STDMETHODCALLTYPE
get_FrameId(uint32
* frame_id
) {
187 virtual HRESULT STDMETHODCALLTYPE
get_IsInContact(boolean
* in_contact
) {
191 // IPointerPointProperties implementation.
192 virtual HRESULT STDMETHODCALLTYPE
get_PointerUpdateKind(
193 winui::Input::PointerUpdateKind
* update_kind
) {
195 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
197 if (msg_
.message
== WM_LBUTTONDOWN
) {
198 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonPressed
;
199 } else if (msg_
.message
== WM_RBUTTONDOWN
) {
200 *update_kind
= winui::Input::PointerUpdateKind_RightButtonPressed
;
201 } else if (msg_
.message
== WM_MBUTTONDOWN
) {
202 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonPressed
;
203 } else if (msg_
.message
== WM_LBUTTONUP
) {
204 *update_kind
= winui::Input::PointerUpdateKind_LeftButtonReleased
;
205 } else if (msg_
.message
== WM_RBUTTONUP
) {
206 *update_kind
= winui::Input::PointerUpdateKind_RightButtonReleased
;
207 } else if (msg_
.message
== WM_MBUTTONUP
) {
208 *update_kind
= winui::Input::PointerUpdateKind_MiddleButtonReleased
;
213 virtual HRESULT STDMETHODCALLTYPE
get_IsLeftButtonPressed(
214 boolean
* left_button_pressed
) {
215 *left_button_pressed
= msg_
.wParam
& MK_LBUTTON
? true : false;
219 virtual HRESULT STDMETHODCALLTYPE
get_IsRightButtonPressed(
220 boolean
* right_button_pressed
) {
221 *right_button_pressed
= msg_
.wParam
& MK_RBUTTON
? true : false;
225 virtual HRESULT STDMETHODCALLTYPE
get_IsMiddleButtonPressed(
226 boolean
* middle_button_pressed
) {
227 *middle_button_pressed
= msg_
.wParam
& MK_MBUTTON
? true : false;
231 virtual HRESULT STDMETHODCALLTYPE
get_IsHorizontalMouseWheel(
232 boolean
* is_horizontal_mouse_wheel
) {
233 *is_horizontal_mouse_wheel
=
234 (msg_
.message
== WM_MOUSEHWHEEL
) ? true : false;
238 virtual HRESULT STDMETHODCALLTYPE
get_MouseWheelDelta(int* delta
) {
239 if (msg_
.message
== WM_MOUSEWHEEL
|| msg_
.message
== WM_MOUSEHWHEEL
) {
240 *delta
= GET_WHEEL_DELTA_WPARAM(msg_
.wParam
);
247 virtual HRESULT STDMETHODCALLTYPE
get_Pressure(float* pressure
) {
251 virtual HRESULT STDMETHODCALLTYPE
get_IsInverted(boolean
* inverted
) {
255 virtual HRESULT STDMETHODCALLTYPE
get_IsEraser(boolean
* is_eraser
) {
259 virtual HRESULT STDMETHODCALLTYPE
get_Orientation(float* orientation
) {
263 virtual HRESULT STDMETHODCALLTYPE
get_XTilt(float* x_tilt
) {
267 virtual HRESULT STDMETHODCALLTYPE
get_YTilt(float* y_tilt
) {
271 virtual HRESULT STDMETHODCALLTYPE
get_Twist(float* twist
) {
275 virtual HRESULT STDMETHODCALLTYPE
get_ContactRect(winfoundtn::Rect
* rect
) {
279 virtual HRESULT STDMETHODCALLTYPE
get_ContactRectRaw(winfoundtn::Rect
* rect
) {
283 virtual HRESULT STDMETHODCALLTYPE
get_TouchConfidence(boolean
* confidence
) {
287 virtual HRESULT STDMETHODCALLTYPE
get_IsPrimary(boolean
* is_primary
) {
291 virtual HRESULT STDMETHODCALLTYPE
get_IsInRange(boolean
* is_in_range
) {
295 virtual HRESULT STDMETHODCALLTYPE
get_IsCanceled(boolean
* is_canceled
) {
299 virtual HRESULT STDMETHODCALLTYPE
get_IsBarrelButtonPressed(
300 boolean
* is_barrel_button_pressed
) {
304 virtual HRESULT STDMETHODCALLTYPE
get_IsXButton1Pressed(
305 boolean
* is_xbutton1_pressed
) {
309 virtual HRESULT STDMETHODCALLTYPE
get_IsXButton2Pressed(
310 boolean
* is_xbutton2_pressed
) {
314 virtual HRESULT STDMETHODCALLTYPE
HasUsage(uint32 usage_page
,
316 boolean
* has_usage
) {
320 virtual HRESULT STDMETHODCALLTYPE
GetUsageValue(uint32 usage_page
,
322 int32
* usage_value
) {
326 // IPointerDevice implementation.
327 virtual HRESULT STDMETHODCALLTYPE
get_PointerDeviceType(
328 windevs::Input::PointerDeviceType
* device_type
) {
329 if (msg_
.message
== WM_TOUCH
) {
330 *device_type
= windevs::Input::PointerDeviceType_Touch
;
332 *device_type
= windevs::Input::PointerDeviceType_Mouse
;
337 virtual HRESULT STDMETHODCALLTYPE
get_IsIntegrated(boolean
* is_integrated
) {
341 virtual HRESULT STDMETHODCALLTYPE
get_MaxContacts(uint32
* contacts
) {
345 virtual HRESULT STDMETHODCALLTYPE
get_PhysicalDeviceRect(
346 winfoundtn::Rect
* rect
) {
350 virtual HRESULT STDMETHODCALLTYPE
get_ScreenRect(winfoundtn::Rect
* rect
) {
354 virtual HRESULT STDMETHODCALLTYPE
get_SupportedUsages(
355 winfoundtn::Collections::IVectorView
<
356 windevs::Input::PointerDeviceUsage
>** usages
) {
363 DISALLOW_COPY_AND_ASSIGN(MouseEvent
);
366 // This class implements the winrt interfaces needed to support keyboard
367 // character and system character messages.
368 class KeyEvent
: public mswr::RuntimeClass
<
369 winui::Core::IKeyEventArgs
,
370 winui::Core::ICharacterReceivedEventArgs
,
371 winui::Core::IAcceleratorKeyEventArgs
> {
373 KeyEvent(const MSG
& msg
)
376 // IKeyEventArgs implementation.
377 virtual HRESULT STDMETHODCALLTYPE
get_VirtualKey(
378 winsys::VirtualKey
* virtual_key
) {
379 *virtual_key
= static_cast<winsys::VirtualKey
>(msg_
.wParam
);
383 virtual HRESULT STDMETHODCALLTYPE
get_KeyStatus(
384 winui::Core::CorePhysicalKeyStatus
* key_status
) {
385 // As per msdn documentation for the keyboard messages.
386 key_status
->RepeatCount
= msg_
.lParam
& 0x0000FFFF;
387 key_status
->ScanCode
= (msg_
.lParam
>> 16) & 0x00FF;
388 key_status
->IsExtendedKey
= (msg_
.lParam
& (1 << 24));
389 key_status
->IsMenuKeyDown
= (msg_
.lParam
& (1 << 29));
390 key_status
->WasKeyDown
= (msg_
.lParam
& (1 << 30));
391 key_status
->IsKeyReleased
= (msg_
.lParam
& (1 << 31));
395 // ICharacterReceivedEventArgs implementation.
396 virtual HRESULT STDMETHODCALLTYPE
get_KeyCode(uint32
* key_code
) {
397 *key_code
= msg_
.wParam
;
401 // IAcceleratorKeyEventArgs implementation.
402 virtual HRESULT STDMETHODCALLTYPE
get_EventType(
403 winui::Core::CoreAcceleratorKeyEventType
* event_type
) {
404 if (msg_
.message
== WM_SYSKEYDOWN
) {
405 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown
;
406 } else if (msg_
.message
== WM_SYSKEYUP
) {
407 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp
;
408 } else if (msg_
.message
== WM_SYSCHAR
) {
409 *event_type
= winui::Core::CoreAcceleratorKeyEventType_SystemCharacter
;
418 // The following classes are the emulation of the WinRT system as exposed
419 // to metro applications. There is one application (ICoreApplication) which
420 // contains a series of Views (ICoreApplicationView) each one of them
421 // containing a CoreWindow which represents a surface that can drawn to
422 // and that receives events.
424 // Here is the general dependency hierachy in terms of interfaces:
426 // IFrameworkViewSource --> IFrameworkView
429 // ---------------------------------------------------------------------
432 // ICoreApplication ICoreApplicationView
435 // ICoreWindow -----> ICoreWindowInterop
439 // ICoreDispatcher <==> real HWND
441 class CoreDispatcherEmulation
:
442 public mswr::RuntimeClass
<
443 winui::Core::ICoreDispatcher
,
444 winui::Core::ICoreAcceleratorKeys
> {
446 CoreDispatcherEmulation(InputHandler
* input_handler
)
447 : input_handler_(input_handler
),
448 accelerator_key_event_handler_(NULL
) {}
450 // ICoreDispatcher implementation:
451 virtual HRESULT STDMETHODCALLTYPE
get_HasThreadAccess(boolean
* value
) {
455 virtual HRESULT STDMETHODCALLTYPE
ProcessEvents(
456 winui::Core::CoreProcessEventsOption options
) {
457 // We don't support the other message pump modes. So we basically enter a
458 // traditional message loop that we only exit a teardown.
459 if (options
!= winui::Core::CoreProcessEventsOption_ProcessUntilQuit
)
463 while((::GetMessage(&msg
, NULL
, 0, 0) != 0) && g_window_count
> 0) {
464 ProcessInputMessage(msg
);
465 ::TranslateMessage(&msg
);
466 ::DispatchMessage(&msg
);
468 // TODO(cpu): figure what to do with msg.WParam which we would normally
473 virtual HRESULT STDMETHODCALLTYPE
RunAsync(
474 winui::Core::CoreDispatcherPriority priority
,
475 winui::Core::IDispatchedHandler
*agileCallback
,
476 ABI::Windows::Foundation::IAsyncAction
** asyncAction
) {
480 virtual HRESULT STDMETHODCALLTYPE
RunIdleAsync(
481 winui::Core::IIdleDispatchedHandler
*agileCallback
,
482 winfoundtn::IAsyncAction
** asyncAction
) {
486 // ICoreAcceleratorKeys implementation:
487 virtual HRESULT STDMETHODCALLTYPE
add_AcceleratorKeyActivated(
488 AcceleratorKeyEventHandler
* handler
,
489 EventRegistrationToken
*pCookie
) {
490 accelerator_key_event_handler_
= handler
;
491 accelerator_key_event_handler_
->AddRef();
495 virtual HRESULT STDMETHODCALLTYPE
remove_AcceleratorKeyActivated(
496 EventRegistrationToken cookie
) {
497 accelerator_key_event_handler_
->Release();
498 accelerator_key_event_handler_
= NULL
;
503 bool ProcessInputMessage(const MSG
& msg
) {
504 // Poor man's way of dispatching input events.
506 if (input_handler_
) {
507 if ((msg
.message
>= WM_KEYFIRST
) && (msg
.message
<= WM_KEYLAST
)) {
508 if ((msg
.message
== WM_SYSKEYDOWN
) || (msg
.message
== WM_SYSKEYUP
) ||
509 msg
.message
== WM_SYSCHAR
) {
510 ret
= HandleSystemKeys(msg
);
512 ret
= input_handler_
->HandleKeyboardMessage(msg
);
514 } else if ((msg
.message
>= WM_MOUSEFIRST
) &&
515 (msg
.message
<= WM_MOUSELAST
)) {
516 ret
= input_handler_
->HandleMouseMessage(msg
);
522 bool HandleSystemKeys(const MSG
& msg
) {
523 mswr::ComPtr
<winui::Core::IAcceleratorKeyEventArgs
> event_args
;
524 event_args
= mswr::Make
<KeyEvent
>(msg
);
525 accelerator_key_event_handler_
->Invoke(this, event_args
.Get());
529 InputHandler
* input_handler_
;
530 AcceleratorKeyEventHandler
* accelerator_key_event_handler_
;
533 class CoreWindowEmulation
534 : public mswr::RuntimeClass
<
535 mswr::RuntimeClassFlags
<mswr::WinRtClassicComMix
>,
536 winui::Core::ICoreWindow
, ICoreWindowInterop
>,
537 public InputHandler
{
539 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
),
552 window_activated_handler_(NULL
) {
553 dispatcher_
= mswr::Make
<CoreDispatcherEmulation
>(this);
555 // Unless we select our own AppUserModelID the shell might confuse us
556 // with the app launcher one and we get the wrong taskbar button and icon.
557 ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId
);
559 RECT work_area
= {0};
560 ::SystemParametersInfo(SPI_GETWORKAREA
, 0, &work_area
, 0);
561 if (::IsDebuggerPresent()) {
564 work_area
.right
= 1600;
565 work_area
.bottom
= 900;
568 core_hwnd_
= CreateMetroTopLevelWindow(work_area
);
569 ::SetProp(core_hwnd_
, kAshWin7CoreWindowHandler
, this);
572 ~CoreWindowEmulation() {
574 ::RemoveProp(core_hwnd_
, kAshWin7CoreWindowHandler
);
575 ::DestroyWindow(core_hwnd_
);
579 // ICoreWindow implementation:
580 virtual HRESULT STDMETHODCALLTYPE
get_AutomationHostProvider(
581 IInspectable
** value
) override
{
585 virtual HRESULT STDMETHODCALLTYPE
get_Bounds(
586 winfoundtn::Rect
* value
) override
{
588 if (!::GetClientRect(core_hwnd_
, &rect
))
590 value
->Width
= rect
.right
;
591 value
->Height
= rect
.bottom
;
595 virtual HRESULT STDMETHODCALLTYPE
get_CustomProperties(
596 winfoundtn::Collections::IPropertySet
** value
) override
{
600 virtual HRESULT STDMETHODCALLTYPE
get_Dispatcher(
601 winui::Core::ICoreDispatcher
** value
) override
{
602 return dispatcher_
.CopyTo(value
);
605 virtual HRESULT STDMETHODCALLTYPE
get_FlowDirection(
606 winui::Core::CoreWindowFlowDirection
* value
) override
{
610 virtual HRESULT STDMETHODCALLTYPE
put_FlowDirection(
611 winui::Core::CoreWindowFlowDirection value
) override
{
615 virtual HRESULT STDMETHODCALLTYPE
get_IsInputEnabled(
616 boolean
* value
) override
{
620 virtual HRESULT STDMETHODCALLTYPE
put_IsInputEnabled(
621 boolean value
) override
{
625 virtual HRESULT STDMETHODCALLTYPE
get_PointerCursor(
626 winui::Core::ICoreCursor
** value
) override
{
630 virtual HRESULT STDMETHODCALLTYPE
put_PointerCursor(
631 winui::Core::ICoreCursor
* value
) override
{
635 virtual HRESULT STDMETHODCALLTYPE
get_PointerPosition(
636 winfoundtn::Point
* value
) override
{
640 virtual HRESULT STDMETHODCALLTYPE
get_Visible(
641 boolean
* value
) override
{
645 virtual HRESULT STDMETHODCALLTYPE
Activate(void) override
{
646 // After we fire OnActivate on the View, Chrome calls us back here.
650 virtual HRESULT STDMETHODCALLTYPE
Close(void) override
{
651 ::PostMessage(core_hwnd_
, WM_CLOSE
, 0, 0);
656 virtual HRESULT STDMETHODCALLTYPE
GetAsyncKeyState(
657 ABI::Windows::System::VirtualKey virtualKey
,
658 winui::Core::CoreVirtualKeyStates
* KeyState
) override
{
662 virtual HRESULT STDMETHODCALLTYPE
GetKeyState(
663 ABI::Windows::System::VirtualKey virtualKey
,
664 winui::Core::CoreVirtualKeyStates
* KeyState
) override
{
668 virtual HRESULT STDMETHODCALLTYPE
ReleasePointerCapture(void) override
{
672 virtual HRESULT STDMETHODCALLTYPE
SetPointerCapture(void) override
{
676 virtual HRESULT STDMETHODCALLTYPE
add_Activated(
677 WindowActivatedHandler
* handler
,
678 EventRegistrationToken
* pCookie
) override
{
679 window_activated_handler_
= handler
;
684 virtual HRESULT STDMETHODCALLTYPE
remove_Activated(
685 EventRegistrationToken cookie
) override
{
686 window_activated_handler_
->Release();
687 window_activated_handler_
= NULL
;
691 virtual HRESULT STDMETHODCALLTYPE
add_AutomationProviderRequested(
692 AutomationProviderHandler
* handler
,
693 EventRegistrationToken
* cookie
) override
{
697 virtual HRESULT STDMETHODCALLTYPE
remove_AutomationProviderRequested(
698 EventRegistrationToken cookie
) override
{
702 virtual HRESULT STDMETHODCALLTYPE
add_CharacterReceived(
703 CharEventHandler
* handler
,
704 EventRegistrationToken
* pCookie
) override
{
705 character_received_handler_
= handler
;
706 character_received_handler_
->AddRef();
710 virtual HRESULT STDMETHODCALLTYPE
remove_CharacterReceived(
711 EventRegistrationToken cookie
) override
{
712 character_received_handler_
->Release();
713 character_received_handler_
= NULL
;
717 virtual HRESULT STDMETHODCALLTYPE
add_Closed(
718 CoreWindowEventHandler
* handler
,
719 EventRegistrationToken
* pCookie
) override
{
723 virtual HRESULT STDMETHODCALLTYPE
remove_Closed(
724 EventRegistrationToken cookie
) override
{
728 virtual HRESULT STDMETHODCALLTYPE
add_InputEnabled(
729 InputEnabledEventHandler
* handler
,
730 EventRegistrationToken
* pCookie
) override
{
734 virtual HRESULT STDMETHODCALLTYPE
remove_InputEnabled(
735 EventRegistrationToken cookie
) override
{
739 virtual HRESULT STDMETHODCALLTYPE
add_KeyDown(
740 KeyEventHandler
* handler
,
741 EventRegistrationToken
* pCookie
) override
{
742 key_down_handler_
= handler
;
743 key_down_handler_
->AddRef();
747 virtual HRESULT STDMETHODCALLTYPE
remove_KeyDown(
748 EventRegistrationToken cookie
) override
{
749 key_down_handler_
->Release();
750 key_down_handler_
= NULL
;
754 virtual HRESULT STDMETHODCALLTYPE
add_KeyUp(
755 KeyEventHandler
* handler
,
756 EventRegistrationToken
* pCookie
) override
{
757 key_up_handler_
= handler
;
758 key_up_handler_
->AddRef();
762 virtual HRESULT STDMETHODCALLTYPE
remove_KeyUp(
763 EventRegistrationToken cookie
) override
{
764 key_up_handler_
->Release();
765 key_up_handler_
= NULL
;
769 virtual HRESULT STDMETHODCALLTYPE
add_PointerCaptureLost(
770 PointerEventHandler
* handler
,
771 EventRegistrationToken
* cookie
) override
{
772 mouse_capture_lost_handler_
= handler
;
776 virtual HRESULT STDMETHODCALLTYPE
remove_PointerCaptureLost(
777 EventRegistrationToken cookie
) override
{
778 mouse_capture_lost_handler_
= NULL
;
782 virtual HRESULT STDMETHODCALLTYPE
add_PointerEntered(
783 PointerEventHandler
* handler
,
784 EventRegistrationToken
* cookie
) override
{
785 mouse_entered_handler_
= handler
;
789 virtual HRESULT STDMETHODCALLTYPE
remove_PointerEntered(
790 EventRegistrationToken cookie
) override
{
791 mouse_entered_handler_
= NULL
;
795 virtual HRESULT STDMETHODCALLTYPE
add_PointerExited(
796 PointerEventHandler
* handler
,
797 EventRegistrationToken
* cookie
) override
{
798 mouse_exited_handler_
= handler
;
802 virtual HRESULT STDMETHODCALLTYPE
remove_PointerExited(
803 EventRegistrationToken cookie
) override
{
804 mouse_exited_handler_
= NULL
;
808 virtual HRESULT STDMETHODCALLTYPE
add_PointerMoved(
809 PointerEventHandler
* handler
,
810 EventRegistrationToken
* cookie
) override
{
811 mouse_moved_handler_
= handler
;
812 mouse_moved_handler_
->AddRef();
816 virtual HRESULT STDMETHODCALLTYPE
remove_PointerMoved(
817 EventRegistrationToken cookie
) override
{
818 mouse_moved_handler_
->Release();
819 mouse_moved_handler_
= NULL
;
823 virtual HRESULT STDMETHODCALLTYPE
add_PointerPressed(
824 PointerEventHandler
* handler
,
825 EventRegistrationToken
* cookie
) override
{
826 mouse_pressed_handler_
= handler
;
827 mouse_pressed_handler_
->AddRef();
831 virtual HRESULT STDMETHODCALLTYPE
remove_PointerPressed(
832 EventRegistrationToken cookie
) override
{
833 mouse_pressed_handler_
->Release();
834 mouse_pressed_handler_
= NULL
;
838 virtual HRESULT STDMETHODCALLTYPE
add_PointerReleased(
839 PointerEventHandler
* handler
,
840 EventRegistrationToken
* cookie
) override
{
841 mouse_released_handler_
= handler
;
842 mouse_released_handler_
->AddRef();
846 virtual HRESULT STDMETHODCALLTYPE
remove_PointerReleased(
847 EventRegistrationToken cookie
) override
{
848 mouse_released_handler_
->Release();
849 mouse_released_handler_
= NULL
;
853 virtual HRESULT STDMETHODCALLTYPE
add_TouchHitTesting(
854 TouchHitTestHandler
* handler
,
855 EventRegistrationToken
* pCookie
) override
{
859 virtual HRESULT STDMETHODCALLTYPE
remove_TouchHitTesting(
860 EventRegistrationToken cookie
) override
{
864 virtual HRESULT STDMETHODCALLTYPE
add_PointerWheelChanged(
865 PointerEventHandler
* handler
,
866 EventRegistrationToken
* cookie
) override
{
867 mouse_wheel_changed_handler_
= handler
;
868 mouse_wheel_changed_handler_
->AddRef();
872 virtual HRESULT STDMETHODCALLTYPE
remove_PointerWheelChanged(
873 EventRegistrationToken cookie
) override
{
874 mouse_wheel_changed_handler_
->Release();
875 mouse_wheel_changed_handler_
= NULL
;
879 virtual HRESULT STDMETHODCALLTYPE
add_SizeChanged(
880 SizeChangedHandler
* handler
,
881 EventRegistrationToken
* pCookie
) override
{
882 // TODO(cpu): implement this.
886 virtual HRESULT STDMETHODCALLTYPE
remove_SizeChanged(
887 EventRegistrationToken cookie
) override
{
891 virtual HRESULT STDMETHODCALLTYPE
add_VisibilityChanged(
892 VisibilityChangedHandler
* handler
,
893 EventRegistrationToken
* pCookie
) override
{
897 virtual HRESULT STDMETHODCALLTYPE
remove_VisibilityChanged(
898 EventRegistrationToken cookie
) override
{
902 // ICoreWindowInterop implementation:
903 virtual HRESULT STDMETHODCALLTYPE
get_WindowHandle(HWND
* hwnd
) override
{
910 virtual HRESULT STDMETHODCALLTYPE
put_MessageHandled(
911 boolean value
) override
{
916 virtual bool HandleKeyboardMessage(const MSG
& msg
) override
{
917 switch (msg
.message
) {
920 mswr::ComPtr
<winui::Core::IKeyEventArgs
> event_args
;
921 event_args
= mswr::Make
<KeyEvent
>(msg
);
922 KeyEventHandler
* handler
= NULL
;
923 if (msg
.message
== WM_KEYDOWN
) {
924 handler
= key_down_handler_
;
926 handler
= key_up_handler_
;
928 handler
->Invoke(this, event_args
.Get());
935 mswr::ComPtr
<winui::Core::ICharacterReceivedEventArgs
> event_args
;
936 event_args
= mswr::Make
<KeyEvent
>(msg
);
937 character_received_handler_
->Invoke(this, event_args
.Get());
947 virtual bool HandleMouseMessage(const MSG
& msg
) override
{
948 PointerEventHandler
* handler
= NULL
;
949 mswr::ComPtr
<winui::Core::IPointerEventArgs
> event_args
;
950 event_args
= mswr::Make
<MouseEvent
>(msg
);
951 switch (msg
.message
) {
953 handler
= mouse_moved_handler_
;
956 case WM_LBUTTONDOWN
: {
959 handler
= mouse_pressed_handler_
;
966 handler
= mouse_released_handler_
;
970 case WM_MOUSEWHEEL
: {
972 handler
= mouse_wheel_changed_handler_
;
980 handler
->Invoke(this, event_args
.Get());
984 void OnWindowActivated() {
985 if (window_activated_handler_
)
986 window_activated_handler_
->Invoke(this, NULL
);
990 PointerEventHandler
* mouse_moved_handler_
;
991 PointerEventHandler
* mouse_capture_lost_handler_
;
992 PointerEventHandler
* mouse_pressed_handler_
;
993 PointerEventHandler
* mouse_released_handler_
;
994 PointerEventHandler
* mouse_entered_handler_
;
995 PointerEventHandler
* mouse_exited_handler_
;
996 PointerEventHandler
* mouse_wheel_changed_handler_
;
997 KeyEventHandler
* key_down_handler_
;
998 KeyEventHandler
* key_up_handler_
;
999 CharEventHandler
* character_received_handler_
;
1001 mswr::ComPtr
<winui::Core::ICoreDispatcher
> dispatcher_
;
1002 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
1003 WindowActivatedHandler
* window_activated_handler_
;
1006 LRESULT CALLBACK
WndProc(HWND hwnd
, UINT message
,
1007 WPARAM wparam
, LPARAM lparam
) {
1008 // TODO(vadimt): Remove ScopedTracker below once crbug.com/440919 is fixed.
1009 tracked_objects::ScopedTracker
tracking_profile(
1010 FROM_HERE_WITH_EXPLICIT_FUNCTION("440919 MetroDriver WndProc"));
1016 // HIWORD(wparam) is 1 if the window is minimized.
1017 bool active
= (LOWORD(wparam
) != WA_INACTIVE
) && !HIWORD(wparam
);
1019 CoreWindowEmulation
* core_window_handler
=
1020 reinterpret_cast<CoreWindowEmulation
*>(
1021 ::GetProp(hwnd
, kAshWin7CoreWindowHandler
));
1022 if (core_window_handler
)
1023 core_window_handler
->OnWindowActivated();
1025 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1031 hdc
= ::BeginPaint(hwnd
, &ps
);
1032 ::EndPaint(hwnd
, &ps
);
1035 ::DestroyWindow(hwnd
);
1039 if (!g_window_count
)
1040 ::PostQuitMessage(0);
1042 // Always allow Chrome to set the cursor.
1046 return ::DefWindowProc(hwnd
, message
, wparam
, lparam
);
1051 class ActivatedEvent
1052 : public mswr::RuntimeClass
<winapp::Activation::IActivatedEventArgs
> {
1054 ActivatedEvent(winapp::Activation::ActivationKind activation_kind
)
1055 : activation_kind_(activation_kind
) {
1058 virtual HRESULT STDMETHODCALLTYPE
get_Kind(
1059 winapp::Activation::ActivationKind
*value
) {
1060 *value
= activation_kind_
;
1064 virtual HRESULT STDMETHODCALLTYPE
get_PreviousExecutionState(
1065 winapp::Activation::ApplicationExecutionState
*value
) {
1066 *value
= winapp::Activation::ApplicationExecutionState_ClosedByUser
;
1070 virtual HRESULT STDMETHODCALLTYPE
get_SplashScreen(
1071 winapp::Activation::ISplashScreen
**value
) {
1076 winapp::Activation::ActivationKind activation_kind_
;
1079 class CoreApplicationViewEmulation
1080 : public mswr::RuntimeClass
<winapp::Core::ICoreApplicationView
> {
1082 CoreApplicationViewEmulation(winapp::Core::IFrameworkView
* app_view
) {
1083 core_window_
= mswr::Make
<CoreWindowEmulation
>(app_view
);
1086 HRESULT
Activate() {
1087 if (activated_handler_
) {
1088 auto ae
= mswr::Make
<ActivatedEvent
>(
1089 winapp::Activation::ActivationKind_File
);
1090 return activated_handler_
->Invoke(this, ae
.Get());
1097 return core_window_
->Close();
1100 // ICoreApplicationView implementation:
1101 virtual HRESULT STDMETHODCALLTYPE
get_CoreWindow(
1102 winui::Core::ICoreWindow
** value
) {
1105 return core_window_
.CopyTo(value
);
1108 virtual HRESULT STDMETHODCALLTYPE
add_Activated(
1109 ActivatedHandler
* handler
,
1110 EventRegistrationToken
* token
) {
1111 // The real component supports multiple handles but we don't yet.
1112 if (activated_handler_
)
1114 activated_handler_
= handler
;
1118 virtual HRESULT STDMETHODCALLTYPE
remove_Activated(
1119 EventRegistrationToken token
) {
1120 // Chrome never unregisters handlers, so we don't care about it.
1124 virtual HRESULT STDMETHODCALLTYPE
get_IsMain(
1129 virtual HRESULT STDMETHODCALLTYPE
get_IsHosted(
1135 mswr::ComPtr
<CoreWindowEmulation
> core_window_
;
1136 mswr::ComPtr
<ActivatedHandler
> activated_handler_
;
1139 class CoreApplicationWin7Emulation
1140 : public mswr::RuntimeClass
<winapp::Core::ICoreApplication
,
1141 winapp::Core::ICoreApplicationExit
> {
1143 // ICoreApplication implementation:
1145 virtual HRESULT STDMETHODCALLTYPE
get_Id(
1150 virtual HRESULT STDMETHODCALLTYPE
add_Suspending(
1151 winfoundtn::IEventHandler
<winapp::SuspendingEventArgs
*>* handler
,
1152 EventRegistrationToken
* token
) {
1156 virtual HRESULT STDMETHODCALLTYPE
remove_Suspending(
1157 EventRegistrationToken token
) {
1161 virtual HRESULT STDMETHODCALLTYPE
add_Resuming(
1162 winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1163 EventRegistrationToken
* token
) {
1167 virtual HRESULT STDMETHODCALLTYPE
remove_Resuming(
1168 EventRegistrationToken token
) {
1172 virtual HRESULT STDMETHODCALLTYPE
get_Properties(
1173 winfoundtn::Collections::IPropertySet
** value
) {
1177 virtual HRESULT STDMETHODCALLTYPE
GetCurrentView(
1178 winapp::Core::ICoreApplicationView
** value
) {
1182 virtual HRESULT STDMETHODCALLTYPE
Run(
1183 winapp::Core::IFrameworkViewSource
* viewSource
) {
1184 HRESULT hr
= viewSource
->CreateView(app_view_
.GetAddressOf());
1187 view_emulation_
= mswr::Make
<CoreApplicationViewEmulation
>(
1189 hr
= app_view_
->Initialize(view_emulation_
.Get());
1192 mswr::ComPtr
<winui::Core::ICoreWindow
> core_window
;
1193 hr
= view_emulation_
->get_CoreWindow(core_window
.GetAddressOf());
1196 hr
= app_view_
->SetWindow(core_window
.Get());
1199 hr
= app_view_
->Load(NULL
);
1202 hr
= view_emulation_
->Activate();
1205 return app_view_
->Run();
1208 virtual HRESULT STDMETHODCALLTYPE
RunWithActivationFactories(
1209 winfoundtn::IGetActivationFactory
* activationFactoryCallback
) {
1213 // ICoreApplicationExit implementation:
1215 virtual HRESULT STDMETHODCALLTYPE
Exit(void) {
1216 return view_emulation_
->Close();
1219 virtual HRESULT STDMETHODCALLTYPE
add_Exiting(
1220 winfoundtn::IEventHandler
<IInspectable
*>* handler
,
1221 EventRegistrationToken
* token
) {
1225 virtual HRESULT STDMETHODCALLTYPE
remove_Exiting(
1226 EventRegistrationToken token
) {
1231 mswr::ComPtr
<winapp::Core::IFrameworkView
> app_view_
;
1232 mswr::ComPtr
<CoreApplicationViewEmulation
> view_emulation_
;
1236 mswr::ComPtr
<winapp::Core::ICoreApplication
> InitWindows7() {
1237 HRESULT hr
= ::CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
1240 return mswr::Make
<CoreApplicationWin7Emulation
>();