MD Downloads: show 50 downloads instead of 150
[chromium-blink-merge.git] / win8 / metro_driver / metro_driver_win7.cc
blob3ace04caee0a06327e53b95281b2c12e2be42b5c
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.
5 #include "stdafx.h"
6 #include <corewindow.h>
7 #include <shobjidl.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
19 // the metro viewer.
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,
26 LPARAM lparam);
28 HWND CreateMetroTopLevelWindow(const RECT& work_area) {
29 HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
30 WNDCLASSEXW wcex;
31 wcex.cbSize = sizeof(wcex);
32 wcex.style = CS_HREDRAW | CS_VREDRAW;
33 wcex.lpfnWndProc = WndProc;
34 wcex.cbClsExtra = 0;
35 wcex.cbWndExtra = 0;
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)),
46 L"metro_win7",
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);
51 return hwnd;
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
104 // input.
105 class InputHandler {
106 public:
107 InputHandler() {}
108 virtual ~InputHandler() {}
110 virtual bool HandleKeyboardMessage(const MSG& msg) = 0;
111 virtual bool HandleMouseMessage(const MSG& msg) = 0;
113 private:
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> {
123 public:
124 MouseEvent(const MSG& msg)
125 : 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 {
137 return E_NOTIMPL;
140 HRESULT STDMETHODCALLTYPE GetIntermediatePoints(
141 winfoundtn::Collections::IVector<winui::Input::PointerPoint*>** points)
142 override {
143 return E_NOTIMPL;
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);
158 return S_OK;
161 HRESULT STDMETHODCALLTYPE get_PointerId(uint32* pointer_id) override {
162 // TODO(ananta)
163 // Implement this properly.
164 *pointer_id = 1;
165 return S_OK;
168 HRESULT STDMETHODCALLTYPE get_Timestamp(uint64* timestamp) override {
169 *timestamp = msg_.time;
170 return S_OK;
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 {
181 return E_NOTIMPL;
184 HRESULT STDMETHODCALLTYPE get_FrameId(uint32* frame_id) override {
185 return E_NOTIMPL;
188 HRESULT STDMETHODCALLTYPE get_IsInContact(boolean* in_contact) override {
189 return E_NOTIMPL;
192 // IPointerPointProperties implementation.
193 HRESULT STDMETHODCALLTYPE
194 get_PointerUpdateKind(winui::Input::PointerUpdateKind* update_kind) override {
195 // TODO(ananta)
196 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
197 // equivalents.
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;
211 return S_OK;
214 HRESULT STDMETHODCALLTYPE
215 get_IsLeftButtonPressed(boolean* left_button_pressed) override {
216 *left_button_pressed = msg_.wParam & MK_LBUTTON ? true : false;
217 return S_OK;
220 HRESULT STDMETHODCALLTYPE
221 get_IsRightButtonPressed(boolean* right_button_pressed) override {
222 *right_button_pressed = msg_.wParam & MK_RBUTTON ? true : false;
223 return S_OK;
226 HRESULT STDMETHODCALLTYPE
227 get_IsMiddleButtonPressed(boolean* middle_button_pressed) override {
228 *middle_button_pressed = msg_.wParam & MK_MBUTTON ? true : false;
229 return S_OK;
232 HRESULT STDMETHODCALLTYPE
233 get_IsHorizontalMouseWheel(boolean* is_horizontal_mouse_wheel) override {
234 *is_horizontal_mouse_wheel =
235 (msg_.message == WM_MOUSEHWHEEL) ? true : false;
236 return S_OK;
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);
242 return S_OK;
243 } else {
244 return S_FALSE;
248 HRESULT STDMETHODCALLTYPE get_Pressure(float* pressure) override {
249 return E_NOTIMPL;
252 HRESULT STDMETHODCALLTYPE get_IsInverted(boolean* inverted) override {
253 return E_NOTIMPL;
256 HRESULT STDMETHODCALLTYPE get_IsEraser(boolean* is_eraser) override {
257 return E_NOTIMPL;
260 HRESULT STDMETHODCALLTYPE get_Orientation(float* orientation) override {
261 return E_NOTIMPL;
264 HRESULT STDMETHODCALLTYPE get_XTilt(float* x_tilt) override {
265 return E_NOTIMPL;
268 HRESULT STDMETHODCALLTYPE get_YTilt(float* y_tilt) override {
269 return E_NOTIMPL;
272 HRESULT STDMETHODCALLTYPE get_Twist(float* twist) override {
273 return E_NOTIMPL;
276 HRESULT STDMETHODCALLTYPE get_ContactRect(winfoundtn::Rect* rect) override {
277 return E_NOTIMPL;
280 HRESULT STDMETHODCALLTYPE
281 get_ContactRectRaw(winfoundtn::Rect* rect) override {
282 return E_NOTIMPL;
285 HRESULT STDMETHODCALLTYPE get_TouchConfidence(boolean* confidence) override {
286 return E_NOTIMPL;
289 HRESULT STDMETHODCALLTYPE get_IsPrimary(boolean* is_primary) override {
290 return E_NOTIMPL;
293 HRESULT STDMETHODCALLTYPE get_IsInRange(boolean* is_in_range) override {
294 return E_NOTIMPL;
297 HRESULT STDMETHODCALLTYPE get_IsCanceled(boolean* is_canceled) override {
298 return E_NOTIMPL;
301 HRESULT STDMETHODCALLTYPE
302 get_IsBarrelButtonPressed(boolean* is_barrel_button_pressed) override {
303 return E_NOTIMPL;
306 HRESULT STDMETHODCALLTYPE
307 get_IsXButton1Pressed(boolean* is_xbutton1_pressed) override {
308 return E_NOTIMPL;
311 HRESULT STDMETHODCALLTYPE
312 get_IsXButton2Pressed(boolean* is_xbutton2_pressed) override {
313 return E_NOTIMPL;
316 HRESULT STDMETHODCALLTYPE
317 HasUsage(uint32 usage_page, uint32 usage_id, boolean* has_usage) override {
318 return E_NOTIMPL;
321 HRESULT STDMETHODCALLTYPE GetUsageValue(uint32 usage_page,
322 uint32 usage_id,
323 int32* usage_value) override {
324 return E_NOTIMPL;
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;
332 } else {
333 *device_type = windevs::Input::PointerDeviceType_Mouse;
335 return S_OK;
338 HRESULT STDMETHODCALLTYPE get_IsIntegrated(boolean* is_integrated) override {
339 return E_NOTIMPL;
342 HRESULT STDMETHODCALLTYPE get_MaxContacts(uint32* contacts) override {
343 return E_NOTIMPL;
346 HRESULT STDMETHODCALLTYPE
347 get_PhysicalDeviceRect(winfoundtn::Rect* rect) override {
348 return E_NOTIMPL;
351 HRESULT STDMETHODCALLTYPE get_ScreenRect(winfoundtn::Rect* rect) override {
352 return E_NOTIMPL;
355 HRESULT STDMETHODCALLTYPE get_SupportedUsages(
356 winfoundtn::Collections::IVectorView<windevs::Input::PointerDeviceUsage>**
357 usages) override {
358 return E_NOTIMPL;
361 private:
362 MSG msg_;
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> {
373 public:
374 KeyEvent(const MSG& msg)
375 : 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);
381 return S_OK;
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));
393 return S_OK;
396 // ICharacterReceivedEventArgs implementation.
397 HRESULT STDMETHODCALLTYPE get_KeyCode(uint32* key_code) override {
398 *key_code = msg_.wParam;
399 return S_OK;
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;
412 return S_OK;
415 private:
416 MSG msg_;
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
428 // ^ |
429 // | | metro app
430 // ---------------------------------------------------------------------
431 // | | winRT system
432 // | v
433 // ICoreApplication ICoreApplicationView
434 // |
435 // v
436 // ICoreWindow -----> ICoreWindowInterop
437 // | |
438 // | |
439 // v V
440 // ICoreDispatcher <==> real HWND
442 class CoreDispatcherEmulation :
443 public mswr::RuntimeClass<
444 winui::Core::ICoreDispatcher,
445 winui::Core::ICoreAcceleratorKeys> {
446 public:
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 {
453 return S_OK;
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)
461 return E_FAIL;
463 MSG msg = {0};
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
470 // return here.
471 return S_OK;
474 HRESULT STDMETHODCALLTYPE
475 RunAsync(winui::Core::CoreDispatcherPriority priority,
476 winui::Core::IDispatchedHandler* agileCallback,
477 ABI::Windows::Foundation::IAsyncAction** asyncAction) override {
478 return S_OK;
481 HRESULT STDMETHODCALLTYPE
482 RunIdleAsync(winui::Core::IIdleDispatchedHandler* agileCallback,
483 winfoundtn::IAsyncAction** asyncAction) override {
484 return S_OK;
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();
493 return S_OK;
496 HRESULT STDMETHODCALLTYPE
497 remove_AcceleratorKeyActivated(EventRegistrationToken cookie) override {
498 accelerator_key_event_handler_->Release();
499 accelerator_key_event_handler_ = NULL;
500 return S_OK;
503 private:
504 bool ProcessInputMessage(const MSG& msg) {
505 // Poor man's way of dispatching input events.
506 bool ret = false;
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);
512 } else {
513 ret = input_handler_->HandleKeyboardMessage(msg);
515 } else if ((msg.message >= WM_MOUSEFIRST) &&
516 (msg.message <= WM_MOUSELAST)) {
517 ret = input_handler_->HandleMouseMessage(msg);
520 return ret;
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());
527 return true;
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 {
539 public:
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),
551 core_hwnd_(NULL),
552 app_view_(app_view),
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()) {
563 work_area.top = 0;
564 work_area.left = 0;
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 {
574 if (core_hwnd_) {
575 ::RemoveProp(core_hwnd_, kAshWin7CoreWindowHandler);
576 ::DestroyWindow(core_hwnd_);
580 // ICoreWindow implementation:
581 HRESULT STDMETHODCALLTYPE
582 get_AutomationHostProvider(IInspectable** value) override {
583 return S_OK;
586 HRESULT STDMETHODCALLTYPE get_Bounds(winfoundtn::Rect* value) override {
587 RECT rect;
588 if (!::GetClientRect(core_hwnd_, &rect))
589 return E_FAIL;
590 value->Width = rect.right;
591 value->Height = rect.bottom;
592 return S_OK;
595 HRESULT STDMETHODCALLTYPE
596 get_CustomProperties(winfoundtn::Collections::IPropertySet** value) override {
597 return S_OK;
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 {
607 return S_OK;
610 HRESULT STDMETHODCALLTYPE
611 put_FlowDirection(winui::Core::CoreWindowFlowDirection value) override {
612 return S_OK;
615 HRESULT STDMETHODCALLTYPE get_IsInputEnabled(boolean* value) override {
616 return S_OK;
619 HRESULT STDMETHODCALLTYPE put_IsInputEnabled(boolean value) override {
620 return S_OK;
623 HRESULT STDMETHODCALLTYPE
624 get_PointerCursor(winui::Core::ICoreCursor** value) override {
625 return S_OK;
628 HRESULT STDMETHODCALLTYPE
629 put_PointerCursor(winui::Core::ICoreCursor* value) override {
630 return S_OK;
633 HRESULT STDMETHODCALLTYPE
634 get_PointerPosition(winfoundtn::Point* value) override {
635 return S_OK;
638 HRESULT STDMETHODCALLTYPE get_Visible(boolean* value) override {
639 return S_OK;
642 HRESULT STDMETHODCALLTYPE Activate(void) override {
643 // After we fire OnActivate on the View, Chrome calls us back here.
644 return S_OK;
647 HRESULT STDMETHODCALLTYPE Close(void) override {
648 ::PostMessage(core_hwnd_, WM_CLOSE, 0, 0);
649 core_hwnd_ = NULL;
650 return S_OK;
653 HRESULT STDMETHODCALLTYPE GetAsyncKeyState(
654 ABI::Windows::System::VirtualKey virtualKey,
655 winui::Core::CoreVirtualKeyStates* KeyState) override {
656 return S_OK;
659 HRESULT STDMETHODCALLTYPE GetKeyState(
660 ABI::Windows::System::VirtualKey virtualKey,
661 winui::Core::CoreVirtualKeyStates* KeyState) override {
662 return S_OK;
665 HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) override {
666 return S_OK;
669 HRESULT STDMETHODCALLTYPE SetPointerCapture(void) override {
670 return S_OK;
673 HRESULT STDMETHODCALLTYPE add_Activated(
674 WindowActivatedHandler* handler,
675 EventRegistrationToken* pCookie) override {
676 window_activated_handler_ = handler;
677 handler->AddRef();
678 return S_OK;
681 HRESULT STDMETHODCALLTYPE remove_Activated(
682 EventRegistrationToken cookie) override {
683 window_activated_handler_->Release();
684 window_activated_handler_ = NULL;
685 return S_OK;
688 HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested(
689 AutomationProviderHandler* handler,
690 EventRegistrationToken* cookie) override {
691 return S_OK;
694 HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested(
695 EventRegistrationToken cookie) override {
696 return S_OK;
699 HRESULT STDMETHODCALLTYPE add_CharacterReceived(
700 CharEventHandler* handler,
701 EventRegistrationToken* pCookie) override {
702 character_received_handler_ = handler;
703 character_received_handler_->AddRef();
704 return S_OK;
707 HRESULT STDMETHODCALLTYPE remove_CharacterReceived(
708 EventRegistrationToken cookie) override {
709 character_received_handler_->Release();
710 character_received_handler_ = NULL;
711 return S_OK;
714 HRESULT STDMETHODCALLTYPE add_Closed(
715 CoreWindowEventHandler* handler,
716 EventRegistrationToken* pCookie) override {
717 return S_OK;
720 HRESULT STDMETHODCALLTYPE remove_Closed(
721 EventRegistrationToken cookie) override {
722 return S_OK;
725 HRESULT STDMETHODCALLTYPE add_InputEnabled(
726 InputEnabledEventHandler* handler,
727 EventRegistrationToken* pCookie) override {
728 return S_OK;
731 HRESULT STDMETHODCALLTYPE remove_InputEnabled(
732 EventRegistrationToken cookie) override {
733 return S_OK;
736 HRESULT STDMETHODCALLTYPE add_KeyDown(
737 KeyEventHandler* handler,
738 EventRegistrationToken* pCookie) override {
739 key_down_handler_ = handler;
740 key_down_handler_->AddRef();
741 return S_OK;
744 HRESULT STDMETHODCALLTYPE remove_KeyDown(
745 EventRegistrationToken cookie) override {
746 key_down_handler_->Release();
747 key_down_handler_ = NULL;
748 return S_OK;
751 HRESULT STDMETHODCALLTYPE add_KeyUp(
752 KeyEventHandler* handler,
753 EventRegistrationToken* pCookie) override {
754 key_up_handler_ = handler;
755 key_up_handler_->AddRef();
756 return S_OK;
759 HRESULT STDMETHODCALLTYPE remove_KeyUp(
760 EventRegistrationToken cookie) override {
761 key_up_handler_->Release();
762 key_up_handler_ = NULL;
763 return S_OK;
766 HRESULT STDMETHODCALLTYPE add_PointerCaptureLost(
767 PointerEventHandler* handler,
768 EventRegistrationToken* cookie) override {
769 mouse_capture_lost_handler_ = handler;
770 return S_OK;
773 HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost(
774 EventRegistrationToken cookie) override {
775 mouse_capture_lost_handler_ = NULL;
776 return S_OK;
779 HRESULT STDMETHODCALLTYPE add_PointerEntered(
780 PointerEventHandler* handler,
781 EventRegistrationToken* cookie) override {
782 mouse_entered_handler_ = handler;
783 return S_OK;
786 HRESULT STDMETHODCALLTYPE remove_PointerEntered(
787 EventRegistrationToken cookie) override {
788 mouse_entered_handler_ = NULL;
789 return S_OK;
792 HRESULT STDMETHODCALLTYPE add_PointerExited(
793 PointerEventHandler* handler,
794 EventRegistrationToken* cookie) override {
795 mouse_exited_handler_ = handler;
796 return S_OK;
799 HRESULT STDMETHODCALLTYPE remove_PointerExited(
800 EventRegistrationToken cookie) override {
801 mouse_exited_handler_ = NULL;
802 return S_OK;
805 HRESULT STDMETHODCALLTYPE add_PointerMoved(
806 PointerEventHandler* handler,
807 EventRegistrationToken* cookie) override {
808 mouse_moved_handler_ = handler;
809 mouse_moved_handler_->AddRef();
810 return S_OK;
813 HRESULT STDMETHODCALLTYPE remove_PointerMoved(
814 EventRegistrationToken cookie) override {
815 mouse_moved_handler_->Release();
816 mouse_moved_handler_ = NULL;
817 return S_OK;
820 HRESULT STDMETHODCALLTYPE add_PointerPressed(
821 PointerEventHandler* handler,
822 EventRegistrationToken* cookie) override {
823 mouse_pressed_handler_ = handler;
824 mouse_pressed_handler_->AddRef();
825 return S_OK;
828 HRESULT STDMETHODCALLTYPE remove_PointerPressed(
829 EventRegistrationToken cookie) override {
830 mouse_pressed_handler_->Release();
831 mouse_pressed_handler_ = NULL;
832 return S_OK;
835 HRESULT STDMETHODCALLTYPE add_PointerReleased(
836 PointerEventHandler* handler,
837 EventRegistrationToken* cookie) override {
838 mouse_released_handler_ = handler;
839 mouse_released_handler_->AddRef();
840 return S_OK;
843 HRESULT STDMETHODCALLTYPE remove_PointerReleased(
844 EventRegistrationToken cookie) override {
845 mouse_released_handler_->Release();
846 mouse_released_handler_ = NULL;
847 return S_OK;
850 HRESULT STDMETHODCALLTYPE add_TouchHitTesting(
851 TouchHitTestHandler* handler,
852 EventRegistrationToken* pCookie) override {
853 return S_OK;
856 HRESULT STDMETHODCALLTYPE remove_TouchHitTesting(
857 EventRegistrationToken cookie) override {
858 return S_OK;
861 HRESULT STDMETHODCALLTYPE add_PointerWheelChanged(
862 PointerEventHandler* handler,
863 EventRegistrationToken* cookie) override {
864 mouse_wheel_changed_handler_ = handler;
865 mouse_wheel_changed_handler_->AddRef();
866 return S_OK;
869 HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged(
870 EventRegistrationToken cookie) override {
871 mouse_wheel_changed_handler_->Release();
872 mouse_wheel_changed_handler_ = NULL;
873 return S_OK;
876 HRESULT STDMETHODCALLTYPE add_SizeChanged(
877 SizeChangedHandler* handler,
878 EventRegistrationToken* pCookie) override {
879 // TODO(cpu): implement this.
880 return S_OK;
883 HRESULT STDMETHODCALLTYPE remove_SizeChanged(
884 EventRegistrationToken cookie) override {
885 return S_OK;
888 HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
889 VisibilityChangedHandler* handler,
890 EventRegistrationToken* pCookie) override {
891 return S_OK;
894 HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
895 EventRegistrationToken cookie) override {
896 return S_OK;
899 // ICoreWindowInterop implementation:
900 HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) override {
901 if (!core_hwnd_)
902 return E_FAIL;
903 *hwnd = core_hwnd_;
904 return S_OK;
907 HRESULT STDMETHODCALLTYPE put_MessageHandled(boolean value) override {
908 return S_OK;
911 // InputHandler
912 bool HandleKeyboardMessage(const MSG& msg) override {
913 switch (msg.message) {
914 case WM_KEYDOWN:
915 case WM_KEYUP: {
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_;
921 } else {
922 handler = key_up_handler_;
924 handler->Invoke(this, event_args.Get());
925 break;
928 case WM_CHAR:
929 case WM_DEADCHAR:
930 case WM_UNICHAR: {
931 mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> event_args;
932 event_args = mswr::Make<KeyEvent>(msg);
933 character_received_handler_->Invoke(this, event_args.Get());
934 break;
937 default:
938 return false;
940 return true;
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) {
948 case WM_MOUSEMOVE: {
949 handler = mouse_moved_handler_;
950 break;
952 case WM_LBUTTONDOWN: {
953 case WM_RBUTTONDOWN:
954 case WM_MBUTTONDOWN:
955 handler = mouse_pressed_handler_;
956 break;
959 case WM_LBUTTONUP: {
960 case WM_RBUTTONUP:
961 case WM_MBUTTONUP:
962 handler = mouse_released_handler_;
963 break;
966 case WM_MOUSEWHEEL: {
967 case WM_MOUSEHWHEEL:
968 handler = mouse_wheel_changed_handler_;
969 break;
972 default:
973 return false;
975 DCHECK(handler);
976 handler->Invoke(this, event_args.Get());
977 return true;
980 void OnWindowActivated() {
981 if (window_activated_handler_)
982 window_activated_handler_->Invoke(this, NULL);
985 private:
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_;
996 HWND core_hwnd_;
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) {
1004 PAINTSTRUCT ps;
1005 HDC hdc;
1006 switch (message) {
1007 case WM_ACTIVATE: {
1008 // HIWORD(wparam) is 1 if the window is minimized.
1009 bool active = (LOWORD(wparam) != WA_INACTIVE) && !HIWORD(wparam);
1010 if (active) {
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);
1019 case WM_CREATE:
1020 ++g_window_count;
1021 break;
1022 case WM_PAINT:
1023 hdc = ::BeginPaint(hwnd, &ps);
1024 ::EndPaint(hwnd, &ps);
1025 break;
1026 case WM_CLOSE:
1027 ::DestroyWindow(hwnd);
1028 break;
1029 case WM_DESTROY:
1030 --g_window_count;
1031 if (!g_window_count)
1032 ::PostQuitMessage(0);
1033 break;
1034 // Always allow Chrome to set the cursor.
1035 case WM_SETCURSOR:
1036 return 1;
1037 default:
1038 return ::DefWindowProc(hwnd, message, wparam, lparam);
1040 return 0;
1043 class ActivatedEvent
1044 : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> {
1045 public:
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_;
1053 return S_OK;
1056 HRESULT STDMETHODCALLTYPE get_PreviousExecutionState(
1057 winapp::Activation::ApplicationExecutionState* value) override {
1058 *value = winapp::Activation::ApplicationExecutionState_ClosedByUser;
1059 return S_OK;
1062 HRESULT STDMETHODCALLTYPE
1063 get_SplashScreen(winapp::Activation::ISplashScreen** value) override {
1064 return E_FAIL;
1067 private:
1068 winapp::Activation::ActivationKind activation_kind_;
1071 class CoreApplicationViewEmulation
1072 : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> {
1073 public:
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());
1083 } else {
1084 return S_OK;
1088 HRESULT Close() {
1089 return core_window_->Close();
1092 // ICoreApplicationView implementation:
1093 HRESULT STDMETHODCALLTYPE
1094 get_CoreWindow(winui::Core::ICoreWindow** value) override {
1095 if (!core_window_)
1096 return E_FAIL;
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_)
1105 return E_FAIL;
1106 activated_handler_ = handler;
1107 return S_OK;
1110 HRESULT STDMETHODCALLTYPE
1111 remove_Activated(EventRegistrationToken token) override {
1112 // Chrome never unregisters handlers, so we don't care about it.
1113 return S_OK;
1116 HRESULT STDMETHODCALLTYPE get_IsMain(boolean* value) override { return S_OK; }
1118 HRESULT STDMETHODCALLTYPE get_IsHosted(boolean* value) override {
1119 return S_OK;
1122 private:
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> {
1130 public:
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 {
1138 return S_OK;
1141 HRESULT STDMETHODCALLTYPE
1142 remove_Suspending(EventRegistrationToken token) override {
1143 return S_OK;
1146 HRESULT STDMETHODCALLTYPE
1147 add_Resuming(winfoundtn::IEventHandler<IInspectable*>* handler,
1148 EventRegistrationToken* token) override {
1149 return S_OK;
1152 HRESULT STDMETHODCALLTYPE
1153 remove_Resuming(EventRegistrationToken token) override {
1154 return S_OK;
1157 HRESULT STDMETHODCALLTYPE
1158 get_Properties(winfoundtn::Collections::IPropertySet** value) override {
1159 return S_OK;
1162 HRESULT STDMETHODCALLTYPE
1163 GetCurrentView(winapp::Core::ICoreApplicationView** value) override {
1164 return S_OK;
1167 HRESULT STDMETHODCALLTYPE
1168 Run(winapp::Core::IFrameworkViewSource* viewSource) override {
1169 HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf());
1170 if (FAILED(hr))
1171 return hr;
1172 view_emulation_ = mswr::Make<CoreApplicationViewEmulation>(
1173 app_view_.Get());
1174 hr = app_view_->Initialize(view_emulation_.Get());
1175 if (FAILED(hr))
1176 return hr;
1177 mswr::ComPtr<winui::Core::ICoreWindow> core_window;
1178 hr = view_emulation_->get_CoreWindow(core_window.GetAddressOf());
1179 if (FAILED(hr))
1180 return hr;
1181 hr = app_view_->SetWindow(core_window.Get());
1182 if (FAILED(hr))
1183 return hr;
1184 hr = app_view_->Load(NULL);
1185 if (FAILED(hr))
1186 return hr;
1187 hr = view_emulation_->Activate();
1188 if (FAILED(hr))
1189 return hr;
1190 return app_view_->Run();
1193 HRESULT STDMETHODCALLTYPE RunWithActivationFactories(
1194 winfoundtn::IGetActivationFactory* activationFactoryCallback) override {
1195 return S_OK;
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 {
1207 return S_OK;
1210 HRESULT STDMETHODCALLTYPE
1211 remove_Exiting(EventRegistrationToken token) override {
1212 return S_OK;
1215 private:
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);
1223 if (FAILED(hr))
1224 CHECK(false);
1225 return mswr::Make<CoreApplicationWin7Emulation>();