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.
4
5 #include "stdafx.h"
6 #include <corewindow.h>
7 #include <shobjidl.h>
8
9 #include "base/logging.h"
10 #include "ui/gfx/geometry/safe_integer_conversions.h"
11 #include "ui/gfx/win/msg_util.h"
12
13 #pragma comment(lib, "shell32.lib")
14
15 EXTERN_C IMAGE_DOS_HEADER __ImageBase;
16 // Even though we only create a single window, we need to keep this
17 // count because of the hidden window used by the UI message loop of
18 // the metro viewer.
19 int g_window_count = 0;
20
21 const wchar_t kAshWin7AppId[] = L"Google.Chrome.AshWin7.1";
22 const wchar_t kAshWin7CoreWindowHandler[] = L"CoreWindowHandler";
23 extern float GetModernUIScale();
24 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam,
25 LPARAM lparam);
26
CreateMetroTopLevelWindow(const RECT & work_area)27 HWND CreateMetroTopLevelWindow(const RECT& work_area) {
28 HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase);
29 WNDCLASSEXW wcex;
30 wcex.cbSize = sizeof(wcex);
31 wcex.style = CS_HREDRAW | CS_VREDRAW;
32 wcex.lpfnWndProc = WndProc;
33 wcex.cbClsExtra = 0;
34 wcex.cbWndExtra = 0;
35 wcex.hInstance = hInst;
36 wcex.hIcon = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME");
37 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
38 wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1);
39 wcex.lpszMenuName = 0;
40 wcex.lpszClassName = L"Windows.UI.Core.CoreWindow";
41 wcex.hIconSm = LoadIcon(::GetModuleHandle(NULL), L"IDR_MAINFRAME");
42
43 HWND hwnd = ::CreateWindowExW(0,
44 MAKEINTATOM(::RegisterClassExW(&wcex)),
45 L"metro_win7",
46 WS_POPUP | WS_VISIBLE | WS_MINIMIZEBOX,
47 work_area.top, work_area.left,
48 work_area.right, work_area.bottom,
49 NULL, NULL, hInst, NULL);
50 return hwnd;
51 }
52
53 typedef winfoundtn::ITypedEventHandler<
54 winapp::Core::CoreApplicationView*,
55 winapp::Activation::IActivatedEventArgs*> ActivatedHandler;
56
57 typedef winfoundtn::ITypedEventHandler<
58 winui::Core::CoreWindow*,
59 winui::Core::WindowActivatedEventArgs*> WindowActivatedHandler;
60
61 typedef winfoundtn::ITypedEventHandler<
62 winui::Core::CoreWindow*,
63 winui::Core::AutomationProviderRequestedEventArgs*>
64 AutomationProviderHandler;
65
66 typedef winfoundtn::ITypedEventHandler<
67 winui::Core::CoreWindow*,
68 winui::Core::CharacterReceivedEventArgs*> CharEventHandler;
69
70 typedef winfoundtn::ITypedEventHandler<
71 winui::Core::CoreWindow*,
72 winui::Core::CoreWindowEventArgs*> CoreWindowEventHandler;
73
74 typedef winfoundtn::ITypedEventHandler<
75 winui::Core::CoreWindow*,
76 winui::Core::InputEnabledEventArgs*> InputEnabledEventHandler;
77
78 typedef winfoundtn::ITypedEventHandler<
79 winui::Core::CoreWindow*,
80 winui::Core::KeyEventArgs*> KeyEventHandler;
81
82 typedef winfoundtn::ITypedEventHandler<
83 winui::Core::CoreWindow*,
84 winui::Core::PointerEventArgs*> PointerEventHandler;
85
86 typedef winfoundtn::ITypedEventHandler<
87 winui::Core::CoreWindow*,
88 winui::Core::WindowSizeChangedEventArgs*> SizeChangedHandler;
89
90 typedef winfoundtn::ITypedEventHandler<
91 winui::Core::CoreWindow*,
92 winui::Core::TouchHitTestingEventArgs*> TouchHitTestHandler;
93
94 typedef winfoundtn::ITypedEventHandler<
95 winui::Core::CoreWindow*,
96 winui::Core::VisibilityChangedEventArgs*> VisibilityChangedHandler;
97
98 typedef winfoundtn::ITypedEventHandler<
99 winui::Core::CoreDispatcher*,
100 winui::Core::AcceleratorKeyEventArgs*> AcceleratorKeyEventHandler;
101
102 // This interface is implemented by classes which handle mouse and keyboard
103 // input.
104 class InputHandler {
105 public:
InputHandler()106 InputHandler() {}
~InputHandler()107 virtual ~InputHandler() {}
108
109 virtual bool HandleKeyboardMessage(const MSG& msg) = 0;
110 virtual bool HandleMouseMessage(const MSG& msg) = 0;
111
112 private:
113 DISALLOW_COPY_AND_ASSIGN(InputHandler);
114 };
115
116 // This class implements the winrt interfaces corresponding to mouse input.
117 class MouseEvent : public mswr::RuntimeClass<
118 winui::Core::IPointerEventArgs,
119 winui::Input::IPointerPoint,
120 winui::Input::IPointerPointProperties,
121 windevs::Input::IPointerDevice> {
122 public:
MouseEvent(const MSG & msg)123 MouseEvent(const MSG& msg)
124 : msg_(msg) {
125 }
126
127 // IPointerEventArgs implementation.
get_CurrentPoint(winui::Input::IPointerPoint ** point)128 virtual HRESULT STDMETHODCALLTYPE get_CurrentPoint(
129 winui::Input::IPointerPoint** point) {
130 return QueryInterface(winui::Input::IID_IPointerPoint,
131 reinterpret_cast<void**>(point));
132 }
133
get_KeyModifiers(winsys::VirtualKeyModifiers * modifiers)134 virtual HRESULT STDMETHODCALLTYPE get_KeyModifiers(
135 winsys::VirtualKeyModifiers* modifiers) {
136 return E_NOTIMPL;
137 }
138
GetIntermediatePoints(winfoundtn::Collections::IVector<winui::Input::PointerPoint * > ** points)139 virtual HRESULT STDMETHODCALLTYPE GetIntermediatePoints(
140 winfoundtn::Collections::IVector<winui::Input::PointerPoint*>** points) {
141 return E_NOTIMPL;
142 }
143
144 // IPointerPoint implementation.
get_PointerDevice(windevs::Input::IPointerDevice ** pointer_device)145 virtual HRESULT STDMETHODCALLTYPE get_PointerDevice(
146 windevs::Input::IPointerDevice** pointer_device) {
147 return QueryInterface(windevs::Input::IID_IPointerDevice,
148 reinterpret_cast<void**>(pointer_device));
149 }
150
get_Position(winfoundtn::Point * position)151 virtual HRESULT STDMETHODCALLTYPE get_Position(winfoundtn::Point* position) {
152 static float scale = GetModernUIScale();
153 // Scale down the points here as they are scaled up on the other side.
154 position->X = gfx::ToRoundedInt(CR_GET_X_LPARAM(msg_.lParam) / scale);
155 position->Y = gfx::ToRoundedInt(CR_GET_Y_LPARAM(msg_.lParam) / scale);
156 return S_OK;
157 }
158
get_PointerId(uint32 * pointer_id)159 virtual HRESULT STDMETHODCALLTYPE get_PointerId(uint32* pointer_id) {
160 // TODO(ananta)
161 // Implement this properly.
162 *pointer_id = 1;
163 return S_OK;
164 }
165
get_Timestamp(uint64 * timestamp)166 virtual HRESULT STDMETHODCALLTYPE get_Timestamp(uint64* timestamp) {
167 *timestamp = msg_.time;
168 return S_OK;
169 }
170
get_Properties(winui::Input::IPointerPointProperties ** properties)171 virtual HRESULT STDMETHODCALLTYPE get_Properties(
172 winui::Input::IPointerPointProperties** properties) {
173 return QueryInterface(winui::Input::IID_IPointerPointProperties,
174 reinterpret_cast<void**>(properties));
175 }
176
get_RawPosition(winfoundtn::Point * position)177 virtual HRESULT STDMETHODCALLTYPE get_RawPosition(
178 winfoundtn::Point* position) {
179 return E_NOTIMPL;
180 }
181
get_FrameId(uint32 * frame_id)182 virtual HRESULT STDMETHODCALLTYPE get_FrameId(uint32* frame_id) {
183 return E_NOTIMPL;
184 }
185
get_IsInContact(boolean * in_contact)186 virtual HRESULT STDMETHODCALLTYPE get_IsInContact(boolean* in_contact) {
187 return E_NOTIMPL;
188 }
189
190 // IPointerPointProperties implementation.
get_PointerUpdateKind(winui::Input::PointerUpdateKind * update_kind)191 virtual HRESULT STDMETHODCALLTYPE get_PointerUpdateKind(
192 winui::Input::PointerUpdateKind* update_kind) {
193 // TODO(ananta)
194 // There is no WM_POINTERUPDATE equivalent on Windows 7. Look into
195 // equivalents.
196 if (msg_.message == WM_LBUTTONDOWN) {
197 *update_kind = winui::Input::PointerUpdateKind_LeftButtonPressed;
198 } else if (msg_.message == WM_RBUTTONDOWN) {
199 *update_kind = winui::Input::PointerUpdateKind_RightButtonPressed;
200 } else if (msg_.message == WM_MBUTTONDOWN) {
201 *update_kind = winui::Input::PointerUpdateKind_MiddleButtonPressed;
202 } else if (msg_.message == WM_LBUTTONUP) {
203 *update_kind = winui::Input::PointerUpdateKind_LeftButtonReleased;
204 } else if (msg_.message == WM_RBUTTONUP) {
205 *update_kind = winui::Input::PointerUpdateKind_RightButtonReleased;
206 } else if (msg_.message == WM_MBUTTONUP) {
207 *update_kind = winui::Input::PointerUpdateKind_MiddleButtonReleased;
208 }
209 return S_OK;
210 }
211
get_IsLeftButtonPressed(boolean * left_button_pressed)212 virtual HRESULT STDMETHODCALLTYPE get_IsLeftButtonPressed(
213 boolean* left_button_pressed) {
214 *left_button_pressed = msg_.wParam & MK_LBUTTON ? true : false;
215 return S_OK;
216 }
217
get_IsRightButtonPressed(boolean * right_button_pressed)218 virtual HRESULT STDMETHODCALLTYPE get_IsRightButtonPressed(
219 boolean* right_button_pressed) {
220 *right_button_pressed = msg_.wParam & MK_RBUTTON ? true : false;
221 return S_OK;
222 }
223
get_IsMiddleButtonPressed(boolean * middle_button_pressed)224 virtual HRESULT STDMETHODCALLTYPE get_IsMiddleButtonPressed(
225 boolean* middle_button_pressed) {
226 *middle_button_pressed = msg_.wParam & MK_MBUTTON ? true : false;
227 return S_OK;
228 }
229
get_IsHorizontalMouseWheel(boolean * is_horizontal_mouse_wheel)230 virtual HRESULT STDMETHODCALLTYPE get_IsHorizontalMouseWheel(
231 boolean* is_horizontal_mouse_wheel) {
232 *is_horizontal_mouse_wheel =
233 (msg_.message == WM_MOUSEHWHEEL) ? true : false;
234 return S_OK;
235 }
236
get_MouseWheelDelta(int * delta)237 virtual HRESULT STDMETHODCALLTYPE get_MouseWheelDelta(int* delta) {
238 if (msg_.message == WM_MOUSEWHEEL || msg_.message == WM_MOUSEHWHEEL) {
239 *delta = GET_WHEEL_DELTA_WPARAM(msg_.wParam);
240 return S_OK;
241 } else {
242 return S_FALSE;
243 }
244 }
245
get_Pressure(float * pressure)246 virtual HRESULT STDMETHODCALLTYPE get_Pressure(float* pressure) {
247 return E_NOTIMPL;
248 }
249
get_IsInverted(boolean * inverted)250 virtual HRESULT STDMETHODCALLTYPE get_IsInverted(boolean* inverted) {
251 return E_NOTIMPL;
252 }
253
get_IsEraser(boolean * is_eraser)254 virtual HRESULT STDMETHODCALLTYPE get_IsEraser(boolean* is_eraser) {
255 return E_NOTIMPL;
256 }
257
get_Orientation(float * orientation)258 virtual HRESULT STDMETHODCALLTYPE get_Orientation(float* orientation) {
259 return E_NOTIMPL;
260 }
261
get_XTilt(float * x_tilt)262 virtual HRESULT STDMETHODCALLTYPE get_XTilt(float* x_tilt) {
263 return E_NOTIMPL;
264 }
265
get_YTilt(float * y_tilt)266 virtual HRESULT STDMETHODCALLTYPE get_YTilt(float* y_tilt) {
267 return E_NOTIMPL;
268 }
269
get_Twist(float * twist)270 virtual HRESULT STDMETHODCALLTYPE get_Twist(float* twist) {
271 return E_NOTIMPL;
272 }
273
get_ContactRect(winfoundtn::Rect * rect)274 virtual HRESULT STDMETHODCALLTYPE get_ContactRect(winfoundtn::Rect* rect) {
275 return E_NOTIMPL;
276 }
277
get_ContactRectRaw(winfoundtn::Rect * rect)278 virtual HRESULT STDMETHODCALLTYPE get_ContactRectRaw(winfoundtn::Rect* rect) {
279 return E_NOTIMPL;
280 }
281
get_TouchConfidence(boolean * confidence)282 virtual HRESULT STDMETHODCALLTYPE get_TouchConfidence(boolean* confidence) {
283 return E_NOTIMPL;
284 }
285
get_IsPrimary(boolean * is_primary)286 virtual HRESULT STDMETHODCALLTYPE get_IsPrimary(boolean* is_primary) {
287 return E_NOTIMPL;
288 }
289
get_IsInRange(boolean * is_in_range)290 virtual HRESULT STDMETHODCALLTYPE get_IsInRange(boolean* is_in_range) {
291 return E_NOTIMPL;
292 }
293
get_IsCanceled(boolean * is_canceled)294 virtual HRESULT STDMETHODCALLTYPE get_IsCanceled(boolean* is_canceled) {
295 return E_NOTIMPL;
296 }
297
get_IsBarrelButtonPressed(boolean * is_barrel_button_pressed)298 virtual HRESULT STDMETHODCALLTYPE get_IsBarrelButtonPressed(
299 boolean* is_barrel_button_pressed) {
300 return E_NOTIMPL;
301 }
302
get_IsXButton1Pressed(boolean * is_xbutton1_pressed)303 virtual HRESULT STDMETHODCALLTYPE get_IsXButton1Pressed(
304 boolean* is_xbutton1_pressed) {
305 return E_NOTIMPL;
306 }
307
get_IsXButton2Pressed(boolean * is_xbutton2_pressed)308 virtual HRESULT STDMETHODCALLTYPE get_IsXButton2Pressed(
309 boolean* is_xbutton2_pressed) {
310 return E_NOTIMPL;
311 }
312
HasUsage(uint32 usage_page,uint32 usage_id,boolean * has_usage)313 virtual HRESULT STDMETHODCALLTYPE HasUsage(uint32 usage_page,
314 uint32 usage_id,
315 boolean* has_usage) {
316 return E_NOTIMPL;
317 }
318
GetUsageValue(uint32 usage_page,uint32 usage_id,int32 * usage_value)319 virtual HRESULT STDMETHODCALLTYPE GetUsageValue(uint32 usage_page,
320 uint32 usage_id,
321 int32* usage_value) {
322 return E_NOTIMPL;
323 }
324
325 // IPointerDevice implementation.
get_PointerDeviceType(windevs::Input::PointerDeviceType * device_type)326 virtual HRESULT STDMETHODCALLTYPE get_PointerDeviceType(
327 windevs::Input::PointerDeviceType* device_type) {
328 if (msg_.message == WM_TOUCH) {
329 *device_type = windevs::Input::PointerDeviceType_Touch;
330 } else {
331 *device_type = windevs::Input::PointerDeviceType_Mouse;
332 }
333 return S_OK;
334 }
335
get_IsIntegrated(boolean * is_integrated)336 virtual HRESULT STDMETHODCALLTYPE get_IsIntegrated(boolean* is_integrated) {
337 return E_NOTIMPL;
338 }
339
get_MaxContacts(uint32 * contacts)340 virtual HRESULT STDMETHODCALLTYPE get_MaxContacts(uint32* contacts) {
341 return E_NOTIMPL;
342 }
343
get_PhysicalDeviceRect(winfoundtn::Rect * rect)344 virtual HRESULT STDMETHODCALLTYPE get_PhysicalDeviceRect(
345 winfoundtn::Rect* rect) {
346 return E_NOTIMPL;
347 }
348
get_ScreenRect(winfoundtn::Rect * rect)349 virtual HRESULT STDMETHODCALLTYPE get_ScreenRect(winfoundtn::Rect* rect) {
350 return E_NOTIMPL;
351 }
352
get_SupportedUsages(winfoundtn::Collections::IVectorView<windevs::Input::PointerDeviceUsage> ** usages)353 virtual HRESULT STDMETHODCALLTYPE get_SupportedUsages(
354 winfoundtn::Collections::IVectorView<
355 windevs::Input::PointerDeviceUsage>** usages) {
356 return E_NOTIMPL;
357 }
358
359 private:
360 MSG msg_;
361
362 DISALLOW_COPY_AND_ASSIGN(MouseEvent);
363 };
364
365 // This class implements the winrt interfaces needed to support keyboard
366 // character and system character messages.
367 class KeyEvent : public mswr::RuntimeClass<
368 winui::Core::IKeyEventArgs,
369 winui::Core::ICharacterReceivedEventArgs,
370 winui::Core::IAcceleratorKeyEventArgs> {
371 public:
KeyEvent(const MSG & msg)372 KeyEvent(const MSG& msg)
373 : msg_(msg) {}
374
375 // IKeyEventArgs implementation.
get_VirtualKey(winsys::VirtualKey * virtual_key)376 virtual HRESULT STDMETHODCALLTYPE get_VirtualKey(
377 winsys::VirtualKey* virtual_key) {
378 *virtual_key = static_cast<winsys::VirtualKey>(msg_.wParam);
379 return S_OK;
380 }
381
get_KeyStatus(winui::Core::CorePhysicalKeyStatus * key_status)382 virtual HRESULT STDMETHODCALLTYPE get_KeyStatus(
383 winui::Core::CorePhysicalKeyStatus* key_status) {
384 // As per msdn documentation for the keyboard messages.
385 key_status->RepeatCount = msg_.lParam & 0x0000FFFF;
386 key_status->ScanCode = (msg_.lParam >> 16) & 0x00FF;
387 key_status->IsExtendedKey = (msg_.lParam & (1 << 24));
388 key_status->IsMenuKeyDown = (msg_.lParam & (1 << 29));
389 key_status->WasKeyDown = (msg_.lParam & (1 << 30));
390 key_status->IsKeyReleased = (msg_.lParam & (1 << 31));
391 return S_OK;
392 }
393
394 // ICharacterReceivedEventArgs implementation.
get_KeyCode(uint32 * key_code)395 virtual HRESULT STDMETHODCALLTYPE get_KeyCode(uint32* key_code) {
396 *key_code = msg_.wParam;
397 return S_OK;
398 }
399
400 // IAcceleratorKeyEventArgs implementation.
get_EventType(winui::Core::CoreAcceleratorKeyEventType * event_type)401 virtual HRESULT STDMETHODCALLTYPE get_EventType(
402 winui::Core::CoreAcceleratorKeyEventType* event_type) {
403 if (msg_.message == WM_SYSKEYDOWN) {
404 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyDown;
405 } else if (msg_.message == WM_SYSKEYUP) {
406 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemKeyUp;
407 } else if (msg_.message == WM_SYSCHAR) {
408 *event_type = winui::Core::CoreAcceleratorKeyEventType_SystemCharacter;
409 }
410 return S_OK;
411 }
412
413 private:
414 MSG msg_;
415 };
416
417 // The following classes are the emulation of the WinRT system as exposed
418 // to metro applications. There is one application (ICoreApplication) which
419 // contains a series of Views (ICoreApplicationView) each one of them
420 // containing a CoreWindow which represents a surface that can drawn to
421 // and that receives events.
422 //
423 // Here is the general dependency hierachy in terms of interfaces:
424 //
425 // IFrameworkViewSource --> IFrameworkView
426 // ^ |
427 // | | metro app
428 // ---------------------------------------------------------------------
429 // | | winRT system
430 // | v
431 // ICoreApplication ICoreApplicationView
432 // |
433 // v
434 // ICoreWindow -----> ICoreWindowInterop
435 // | |
436 // | |
437 // v V
438 // ICoreDispatcher <==> real HWND
439 //
440 class CoreDispatcherEmulation :
441 public mswr::RuntimeClass<
442 winui::Core::ICoreDispatcher,
443 winui::Core::ICoreAcceleratorKeys> {
444 public:
CoreDispatcherEmulation(InputHandler * input_handler)445 CoreDispatcherEmulation(InputHandler* input_handler)
446 : input_handler_(input_handler),
447 accelerator_key_event_handler_(NULL) {}
448
449 // ICoreDispatcher implementation:
get_HasThreadAccess(boolean * value)450 virtual HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) {
451 return S_OK;
452 }
453
ProcessEvents(winui::Core::CoreProcessEventsOption options)454 virtual HRESULT STDMETHODCALLTYPE ProcessEvents(
455 winui::Core::CoreProcessEventsOption options) {
456 // We don't support the other message pump modes. So we basically enter a
457 // traditional message loop that we only exit a teardown.
458 if (options != winui::Core::CoreProcessEventsOption_ProcessUntilQuit)
459 return E_FAIL;
460
461 MSG msg = {0};
462 while((::GetMessage(&msg, NULL, 0, 0) != 0) && g_window_count > 0) {
463 ProcessInputMessage(msg);
464 ::TranslateMessage(&msg);
465 ::DispatchMessage(&msg);
466 }
467 // TODO(cpu): figure what to do with msg.WParam which we would normally
468 // return here.
469 return S_OK;
470 }
471
RunAsync(winui::Core::CoreDispatcherPriority priority,winui::Core::IDispatchedHandler * agileCallback,ABI::Windows::Foundation::IAsyncAction ** asyncAction)472 virtual HRESULT STDMETHODCALLTYPE RunAsync(
473 winui::Core::CoreDispatcherPriority priority,
474 winui::Core::IDispatchedHandler *agileCallback,
475 ABI::Windows::Foundation::IAsyncAction** asyncAction) {
476 return S_OK;
477 }
478
RunIdleAsync(winui::Core::IIdleDispatchedHandler * agileCallback,winfoundtn::IAsyncAction ** asyncAction)479 virtual HRESULT STDMETHODCALLTYPE RunIdleAsync(
480 winui::Core::IIdleDispatchedHandler *agileCallback,
481 winfoundtn::IAsyncAction** asyncAction) {
482 return S_OK;
483 }
484
485 // ICoreAcceleratorKeys implementation:
add_AcceleratorKeyActivated(AcceleratorKeyEventHandler * handler,EventRegistrationToken * pCookie)486 virtual HRESULT STDMETHODCALLTYPE add_AcceleratorKeyActivated(
487 AcceleratorKeyEventHandler* handler,
488 EventRegistrationToken *pCookie) {
489 accelerator_key_event_handler_ = handler;
490 accelerator_key_event_handler_->AddRef();
491 return S_OK;
492 }
493
remove_AcceleratorKeyActivated(EventRegistrationToken cookie)494 virtual HRESULT STDMETHODCALLTYPE remove_AcceleratorKeyActivated(
495 EventRegistrationToken cookie) {
496 accelerator_key_event_handler_->Release();
497 accelerator_key_event_handler_ = NULL;
498 return S_OK;
499 }
500
501 private:
ProcessInputMessage(const MSG & msg)502 bool ProcessInputMessage(const MSG& msg) {
503 // Poor man's way of dispatching input events.
504 bool ret = false;
505 if (input_handler_) {
506 if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST)) {
507 if ((msg.message == WM_SYSKEYDOWN) || (msg.message == WM_SYSKEYUP) ||
508 msg.message == WM_SYSCHAR) {
509 ret = HandleSystemKeys(msg);
510 } else {
511 ret = input_handler_->HandleKeyboardMessage(msg);
512 }
513 } else if ((msg.message >= WM_MOUSEFIRST) &&
514 (msg.message <= WM_MOUSELAST)) {
515 ret = input_handler_->HandleMouseMessage(msg);
516 }
517 }
518 return ret;
519 }
520
HandleSystemKeys(const MSG & msg)521 bool HandleSystemKeys(const MSG& msg) {
522 mswr::ComPtr<winui::Core::IAcceleratorKeyEventArgs> event_args;
523 event_args = mswr::Make<KeyEvent>(msg);
524 accelerator_key_event_handler_->Invoke(this, event_args.Get());
525 return true;
526 }
527
528 InputHandler* input_handler_;
529 AcceleratorKeyEventHandler* accelerator_key_event_handler_;
530 };
531
532 class CoreWindowEmulation
533 : public mswr::RuntimeClass<
534 mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>,
535 winui::Core::ICoreWindow, ICoreWindowInterop>,
536 public InputHandler {
537 public:
CoreWindowEmulation(winapp::Core::IFrameworkView * app_view)538 CoreWindowEmulation(winapp::Core::IFrameworkView* app_view)
539 : core_hwnd_(NULL),
540 mouse_moved_handler_(NULL),
541 mouse_capture_lost_handler_(NULL),
542 mouse_pressed_handler_(NULL),
543 mouse_released_handler_(NULL),
544 mouse_entered_handler_(NULL),
545 mouse_exited_handler_(NULL),
546 mouse_wheel_changed_handler_(NULL),
547 key_down_handler_(NULL),
548 key_up_handler_(NULL),
549 character_received_handler_(NULL),
550 app_view_(app_view),
551 window_activated_handler_(NULL) {
552 dispatcher_ = mswr::Make<CoreDispatcherEmulation>(this);
553
554 // Unless we select our own AppUserModelID the shell might confuse us
555 // with the app launcher one and we get the wrong taskbar button and icon.
556 ::SetCurrentProcessExplicitAppUserModelID(kAshWin7AppId);
557
558 RECT work_area = {0};
559 ::SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
560 if (::IsDebuggerPresent()) {
561 work_area.top = 0;
562 work_area.left = 0;
563 work_area.right = 1600;
564 work_area.bottom = 900;
565 }
566
567 core_hwnd_ = CreateMetroTopLevelWindow(work_area);
568 ::SetProp(core_hwnd_, kAshWin7CoreWindowHandler, this);
569 }
570
~CoreWindowEmulation()571 ~CoreWindowEmulation() {
572 if (core_hwnd_) {
573 ::RemoveProp(core_hwnd_, kAshWin7CoreWindowHandler);
574 ::DestroyWindow(core_hwnd_);
575 }
576 }
577
578 // ICoreWindow implementation:
get_AutomationHostProvider(IInspectable ** value)579 virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider(
580 IInspectable** value) {
581 return S_OK;
582 }
583
get_Bounds(winfoundtn::Rect * value)584 virtual HRESULT STDMETHODCALLTYPE get_Bounds(
585 winfoundtn::Rect* value) {
586 RECT rect;
587 if (!::GetClientRect(core_hwnd_, &rect))
588 return E_FAIL;
589 value->Width = rect.right;
590 value->Height = rect.bottom;
591 return S_OK;
592 }
593
get_CustomProperties(winfoundtn::Collections::IPropertySet ** value)594 virtual HRESULT STDMETHODCALLTYPE get_CustomProperties(
595 winfoundtn::Collections::IPropertySet** value) {
596 return S_OK;
597 }
598
get_Dispatcher(winui::Core::ICoreDispatcher ** value)599 virtual HRESULT STDMETHODCALLTYPE get_Dispatcher(
600 winui::Core::ICoreDispatcher** value) {
601 return dispatcher_.CopyTo(value);
602 }
603
get_FlowDirection(winui::Core::CoreWindowFlowDirection * value)604 virtual HRESULT STDMETHODCALLTYPE get_FlowDirection(
605 winui::Core::CoreWindowFlowDirection* value) {
606 return S_OK;
607 }
608
put_FlowDirection(winui::Core::CoreWindowFlowDirection value)609 virtual HRESULT STDMETHODCALLTYPE put_FlowDirection(
610 winui::Core::CoreWindowFlowDirection value) {
611 return S_OK;
612 }
613
get_IsInputEnabled(boolean * value)614 virtual HRESULT STDMETHODCALLTYPE get_IsInputEnabled(
615 boolean* value) {
616 return S_OK;
617 }
618
put_IsInputEnabled(boolean value)619 virtual HRESULT STDMETHODCALLTYPE put_IsInputEnabled(
620 boolean value) {
621 return S_OK;
622 }
623
get_PointerCursor(winui::Core::ICoreCursor ** value)624 virtual HRESULT STDMETHODCALLTYPE get_PointerCursor(
625 winui::Core::ICoreCursor** value) {
626 return S_OK;
627 }
628
put_PointerCursor(winui::Core::ICoreCursor * value)629 virtual HRESULT STDMETHODCALLTYPE put_PointerCursor(
630 winui::Core::ICoreCursor* value) {
631 return S_OK;
632 }
633
get_PointerPosition(winfoundtn::Point * value)634 virtual HRESULT STDMETHODCALLTYPE get_PointerPosition(
635 winfoundtn::Point* value) {
636 return S_OK;
637 }
638
get_Visible(boolean * value)639 virtual HRESULT STDMETHODCALLTYPE get_Visible(
640 boolean* value) {
641 return S_OK;
642 }
643
Activate(void)644 virtual HRESULT STDMETHODCALLTYPE Activate(void) {
645 // After we fire OnActivate on the View, Chrome calls us back here.
646 return S_OK;
647 }
648
Close(void)649 virtual HRESULT STDMETHODCALLTYPE Close(void) {
650 ::PostMessage(core_hwnd_, WM_CLOSE, 0, 0);
651 core_hwnd_ = NULL;
652 return S_OK;
653 }
654
GetAsyncKeyState(ABI::Windows::System::VirtualKey virtualKey,winui::Core::CoreVirtualKeyStates * KeyState)655 virtual HRESULT STDMETHODCALLTYPE GetAsyncKeyState(
656 ABI::Windows::System::VirtualKey virtualKey,
657 winui::Core::CoreVirtualKeyStates* KeyState) {
658 return S_OK;
659 }
660
GetKeyState(ABI::Windows::System::VirtualKey virtualKey,winui::Core::CoreVirtualKeyStates * KeyState)661 virtual HRESULT STDMETHODCALLTYPE GetKeyState(
662 ABI::Windows::System::VirtualKey virtualKey,
663 winui::Core::CoreVirtualKeyStates* KeyState) {
664 return S_OK;
665 }
666
ReleasePointerCapture(void)667 virtual HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) {
668 return S_OK;
669 }
670
SetPointerCapture(void)671 virtual HRESULT STDMETHODCALLTYPE SetPointerCapture(void) {
672 return S_OK;
673 }
674
add_Activated(WindowActivatedHandler * handler,EventRegistrationToken * pCookie)675 virtual HRESULT STDMETHODCALLTYPE add_Activated(
676 WindowActivatedHandler* handler,
677 EventRegistrationToken* pCookie) {
678 window_activated_handler_ = handler;
679 handler->AddRef();
680 return S_OK;
681 }
682
remove_Activated(EventRegistrationToken cookie)683 virtual HRESULT STDMETHODCALLTYPE remove_Activated(
684 EventRegistrationToken cookie) {
685 window_activated_handler_->Release();
686 window_activated_handler_ = NULL;
687 return S_OK;
688 }
689
add_AutomationProviderRequested(AutomationProviderHandler * handler,EventRegistrationToken * cookie)690 virtual HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested(
691 AutomationProviderHandler* handler,
692 EventRegistrationToken* cookie) {
693 return S_OK;
694 }
695
remove_AutomationProviderRequested(EventRegistrationToken cookie)696 virtual HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested(
697 EventRegistrationToken cookie) {
698 return S_OK;
699 }
700
add_CharacterReceived(CharEventHandler * handler,EventRegistrationToken * pCookie)701 virtual HRESULT STDMETHODCALLTYPE add_CharacterReceived(
702 CharEventHandler* handler,
703 EventRegistrationToken* pCookie) {
704 character_received_handler_ = handler;
705 character_received_handler_->AddRef();
706 return S_OK;
707 }
708
remove_CharacterReceived(EventRegistrationToken cookie)709 virtual HRESULT STDMETHODCALLTYPE remove_CharacterReceived(
710 EventRegistrationToken cookie) {
711 character_received_handler_->Release();
712 character_received_handler_ = NULL;
713 return S_OK;
714 }
715
add_Closed(CoreWindowEventHandler * handler,EventRegistrationToken * pCookie)716 virtual HRESULT STDMETHODCALLTYPE add_Closed(
717 CoreWindowEventHandler* handler,
718 EventRegistrationToken* pCookie) {
719 return S_OK;
720 }
721
remove_Closed(EventRegistrationToken cookie)722 virtual HRESULT STDMETHODCALLTYPE remove_Closed(
723 EventRegistrationToken cookie) {
724 return S_OK;
725 }
726
add_InputEnabled(InputEnabledEventHandler * handler,EventRegistrationToken * pCookie)727 virtual HRESULT STDMETHODCALLTYPE add_InputEnabled(
728 InputEnabledEventHandler* handler,
729 EventRegistrationToken* pCookie) {
730 return S_OK;
731 }
732
remove_InputEnabled(EventRegistrationToken cookie)733 virtual HRESULT STDMETHODCALLTYPE remove_InputEnabled(
734 EventRegistrationToken cookie) {
735 return S_OK;
736 }
737
add_KeyDown(KeyEventHandler * handler,EventRegistrationToken * pCookie)738 virtual HRESULT STDMETHODCALLTYPE add_KeyDown(
739 KeyEventHandler* handler,
740 EventRegistrationToken* pCookie) {
741 key_down_handler_ = handler;
742 key_down_handler_->AddRef();
743 return S_OK;
744 }
745
remove_KeyDown(EventRegistrationToken cookie)746 virtual HRESULT STDMETHODCALLTYPE remove_KeyDown(
747 EventRegistrationToken cookie) {
748 key_down_handler_->Release();
749 key_down_handler_ = NULL;
750 return S_OK;
751 }
752
add_KeyUp(KeyEventHandler * handler,EventRegistrationToken * pCookie)753 virtual HRESULT STDMETHODCALLTYPE add_KeyUp(
754 KeyEventHandler* handler,
755 EventRegistrationToken* pCookie) {
756 key_up_handler_ = handler;
757 key_up_handler_->AddRef();
758 return S_OK;
759 }
760
remove_KeyUp(EventRegistrationToken cookie)761 virtual HRESULT STDMETHODCALLTYPE remove_KeyUp(
762 EventRegistrationToken cookie) {
763 key_up_handler_->Release();
764 key_up_handler_ = NULL;
765 return S_OK;
766 }
767
add_PointerCaptureLost(PointerEventHandler * handler,EventRegistrationToken * cookie)768 virtual HRESULT STDMETHODCALLTYPE add_PointerCaptureLost(
769 PointerEventHandler* handler,
770 EventRegistrationToken* cookie) {
771 mouse_capture_lost_handler_ = handler;
772 return S_OK;
773 }
774
remove_PointerCaptureLost(EventRegistrationToken cookie)775 virtual HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost(
776 EventRegistrationToken cookie) {
777 mouse_capture_lost_handler_ = NULL;
778 return S_OK;
779 }
780
add_PointerEntered(PointerEventHandler * handler,EventRegistrationToken * cookie)781 virtual HRESULT STDMETHODCALLTYPE add_PointerEntered(
782 PointerEventHandler* handler,
783 EventRegistrationToken* cookie) {
784 mouse_entered_handler_ = handler;
785 return S_OK;
786 }
787
remove_PointerEntered(EventRegistrationToken cookie)788 virtual HRESULT STDMETHODCALLTYPE remove_PointerEntered(
789 EventRegistrationToken cookie) {
790 mouse_entered_handler_ = NULL;
791 return S_OK;
792 }
793
add_PointerExited(PointerEventHandler * handler,EventRegistrationToken * cookie)794 virtual HRESULT STDMETHODCALLTYPE add_PointerExited(
795 PointerEventHandler* handler,
796 EventRegistrationToken* cookie) {
797 mouse_exited_handler_ = handler;
798 return S_OK;
799 }
800
remove_PointerExited(EventRegistrationToken cookie)801 virtual HRESULT STDMETHODCALLTYPE remove_PointerExited(
802 EventRegistrationToken cookie) {
803 mouse_exited_handler_ = NULL;
804 return S_OK;
805 }
806
add_PointerMoved(PointerEventHandler * handler,EventRegistrationToken * cookie)807 virtual HRESULT STDMETHODCALLTYPE add_PointerMoved(
808 PointerEventHandler* handler,
809 EventRegistrationToken* cookie) {
810 mouse_moved_handler_ = handler;
811 mouse_moved_handler_->AddRef();
812 return S_OK;
813 }
814
remove_PointerMoved(EventRegistrationToken cookie)815 virtual HRESULT STDMETHODCALLTYPE remove_PointerMoved(
816 EventRegistrationToken cookie) {
817 mouse_moved_handler_->Release();
818 mouse_moved_handler_ = NULL;
819 return S_OK;
820 }
821
add_PointerPressed(PointerEventHandler * handler,EventRegistrationToken * cookie)822 virtual HRESULT STDMETHODCALLTYPE add_PointerPressed(
823 PointerEventHandler* handler,
824 EventRegistrationToken* cookie) {
825 mouse_pressed_handler_ = handler;
826 mouse_pressed_handler_->AddRef();
827 return S_OK;
828 }
829
remove_PointerPressed(EventRegistrationToken cookie)830 virtual HRESULT STDMETHODCALLTYPE remove_PointerPressed(
831 EventRegistrationToken cookie) {
832 mouse_pressed_handler_->Release();
833 mouse_pressed_handler_ = NULL;
834 return S_OK;
835 }
836
add_PointerReleased(PointerEventHandler * handler,EventRegistrationToken * cookie)837 virtual HRESULT STDMETHODCALLTYPE add_PointerReleased(
838 PointerEventHandler* handler,
839 EventRegistrationToken* cookie) {
840 mouse_released_handler_ = handler;
841 mouse_released_handler_->AddRef();
842 return S_OK;
843 }
844
remove_PointerReleased(EventRegistrationToken cookie)845 virtual HRESULT STDMETHODCALLTYPE remove_PointerReleased(
846 EventRegistrationToken cookie) {
847 mouse_released_handler_->Release();
848 mouse_released_handler_ = NULL;
849 return S_OK;
850 }
851
add_TouchHitTesting(TouchHitTestHandler * handler,EventRegistrationToken * pCookie)852 virtual HRESULT STDMETHODCALLTYPE add_TouchHitTesting(
853 TouchHitTestHandler* handler,
854 EventRegistrationToken* pCookie) {
855 return S_OK;
856 }
857
remove_TouchHitTesting(EventRegistrationToken cookie)858 virtual HRESULT STDMETHODCALLTYPE remove_TouchHitTesting(
859 EventRegistrationToken cookie) {
860 return S_OK;
861 }
862
add_PointerWheelChanged(PointerEventHandler * handler,EventRegistrationToken * cookie)863 virtual HRESULT STDMETHODCALLTYPE add_PointerWheelChanged(
864 PointerEventHandler* handler,
865 EventRegistrationToken* cookie) {
866 mouse_wheel_changed_handler_ = handler;
867 mouse_wheel_changed_handler_->AddRef();
868 return S_OK;
869 }
870
remove_PointerWheelChanged(EventRegistrationToken cookie)871 virtual HRESULT STDMETHODCALLTYPE remove_PointerWheelChanged(
872 EventRegistrationToken cookie) {
873 mouse_wheel_changed_handler_->Release();
874 mouse_wheel_changed_handler_ = NULL;
875 return S_OK;
876 }
877
add_SizeChanged(SizeChangedHandler * handler,EventRegistrationToken * pCookie)878 virtual HRESULT STDMETHODCALLTYPE add_SizeChanged(
879 SizeChangedHandler* handler,
880 EventRegistrationToken* pCookie) {
881 // TODO(cpu): implement this.
882 return S_OK;
883 }
884
remove_SizeChanged(EventRegistrationToken cookie)885 virtual HRESULT STDMETHODCALLTYPE remove_SizeChanged(
886 EventRegistrationToken cookie) {
887 return S_OK;
888 }
889
add_VisibilityChanged(VisibilityChangedHandler * handler,EventRegistrationToken * pCookie)890 virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
891 VisibilityChangedHandler* handler,
892 EventRegistrationToken* pCookie) {
893 return S_OK;
894 }
895
remove_VisibilityChanged(EventRegistrationToken cookie)896 virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
897 EventRegistrationToken cookie) {
898 return S_OK;
899 }
900
901 // ICoreWindowInterop implementation:
get_WindowHandle(HWND * hwnd)902 virtual HRESULT STDMETHODCALLTYPE get_WindowHandle(HWND* hwnd) {
903 if (!core_hwnd_)
904 return E_FAIL;
905 *hwnd = core_hwnd_;
906 return S_OK;
907 }
908
put_MessageHandled(boolean value)909 virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(
910 boolean value) {
911 return S_OK;
912 }
913
914 // InputHandler
HandleKeyboardMessage(const MSG & msg)915 virtual bool HandleKeyboardMessage(const MSG& msg) OVERRIDE {
916 switch (msg.message) {
917 case WM_KEYDOWN:
918 case WM_KEYUP: {
919 mswr::ComPtr<winui::Core::IKeyEventArgs> event_args;
920 event_args = mswr::Make<KeyEvent>(msg);
921 KeyEventHandler* handler = NULL;
922 if (msg.message == WM_KEYDOWN) {
923 handler = key_down_handler_;
924 } else {
925 handler = key_up_handler_;
926 }
927 handler->Invoke(this, event_args.Get());
928 break;
929 }
930
931 case WM_CHAR:
932 case WM_DEADCHAR:
933 case WM_UNICHAR: {
934 mswr::ComPtr<winui::Core::ICharacterReceivedEventArgs> event_args;
935 event_args = mswr::Make<KeyEvent>(msg);
936 character_received_handler_->Invoke(this, event_args.Get());
937 break;
938 }
939
940 default:
941 return false;
942 }
943 return true;
944 }
945
HandleMouseMessage(const MSG & msg)946 virtual bool HandleMouseMessage(const MSG& msg) OVERRIDE {
947 PointerEventHandler* handler = NULL;
948 mswr::ComPtr<winui::Core::IPointerEventArgs> event_args;
949 event_args = mswr::Make<MouseEvent>(msg);
950 switch (msg.message) {
951 case WM_MOUSEMOVE: {
952 handler = mouse_moved_handler_;
953 break;
954 }
955 case WM_LBUTTONDOWN: {
956 case WM_RBUTTONDOWN:
957 case WM_MBUTTONDOWN:
958 handler = mouse_pressed_handler_;
959 break;
960 }
961
962 case WM_LBUTTONUP: {
963 case WM_RBUTTONUP:
964 case WM_MBUTTONUP:
965 handler = mouse_released_handler_;
966 break;
967 }
968
969 case WM_MOUSEWHEEL: {
970 case WM_MOUSEHWHEEL:
971 handler = mouse_wheel_changed_handler_;
972 break;
973 }
974
975 default:
976 return false;
977 }
978 DCHECK(handler);
979 handler->Invoke(this, event_args.Get());
980 return true;
981 }
982
OnWindowActivated()983 void OnWindowActivated() {
984 if (window_activated_handler_)
985 window_activated_handler_->Invoke(this, NULL);
986 }
987
988 private:
989 PointerEventHandler* mouse_moved_handler_;
990 PointerEventHandler* mouse_capture_lost_handler_;
991 PointerEventHandler* mouse_pressed_handler_;
992 PointerEventHandler* mouse_released_handler_;
993 PointerEventHandler* mouse_entered_handler_;
994 PointerEventHandler* mouse_exited_handler_;
995 PointerEventHandler* mouse_wheel_changed_handler_;
996 KeyEventHandler* key_down_handler_;
997 KeyEventHandler* key_up_handler_;
998 CharEventHandler* character_received_handler_;
999 HWND core_hwnd_;
1000 mswr::ComPtr<winui::Core::ICoreDispatcher> dispatcher_;
1001 mswr::ComPtr<winapp::Core::IFrameworkView> app_view_;
1002 WindowActivatedHandler* window_activated_handler_;
1003 };
1004
WndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)1005 LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
1006 WPARAM wparam, LPARAM lparam) {
1007 PAINTSTRUCT ps;
1008 HDC hdc;
1009 switch (message) {
1010 case WM_ACTIVATE: {
1011 // HIWORD(wparam) is 1 if the window is minimized.
1012 bool active = (LOWORD(wparam) != WA_INACTIVE) && !HIWORD(wparam);
1013 if (active) {
1014 CoreWindowEmulation* core_window_handler =
1015 reinterpret_cast<CoreWindowEmulation*>(
1016 ::GetProp(hwnd, kAshWin7CoreWindowHandler));
1017 if (core_window_handler)
1018 core_window_handler->OnWindowActivated();
1019 }
1020 return ::DefWindowProc(hwnd, message, wparam, lparam);
1021 }
1022 case WM_CREATE:
1023 ++g_window_count;
1024 break;
1025 case WM_PAINT:
1026 hdc = ::BeginPaint(hwnd, &ps);
1027 ::EndPaint(hwnd, &ps);
1028 break;
1029 case WM_CLOSE:
1030 ::DestroyWindow(hwnd);
1031 break;
1032 case WM_DESTROY:
1033 --g_window_count;
1034 if (!g_window_count)
1035 ::PostQuitMessage(0);
1036 break;
1037 // Always allow Chrome to set the cursor.
1038 case WM_SETCURSOR:
1039 return 1;
1040 default:
1041 return ::DefWindowProc(hwnd, message, wparam, lparam);
1042 }
1043 return 0;
1044 }
1045
1046 class ActivatedEvent
1047 : public mswr::RuntimeClass<winapp::Activation::IActivatedEventArgs> {
1048 public:
ActivatedEvent(winapp::Activation::ActivationKind activation_kind)1049 ActivatedEvent(winapp::Activation::ActivationKind activation_kind)
1050 : activation_kind_(activation_kind) {
1051 }
1052
get_Kind(winapp::Activation::ActivationKind * value)1053 virtual HRESULT STDMETHODCALLTYPE get_Kind(
1054 winapp::Activation::ActivationKind *value) {
1055 *value = activation_kind_;
1056 return S_OK;
1057 }
1058
get_PreviousExecutionState(winapp::Activation::ApplicationExecutionState * value)1059 virtual HRESULT STDMETHODCALLTYPE get_PreviousExecutionState(
1060 winapp::Activation::ApplicationExecutionState *value) {
1061 *value = winapp::Activation::ApplicationExecutionState_ClosedByUser;
1062 return S_OK;
1063 }
1064
get_SplashScreen(winapp::Activation::ISplashScreen ** value)1065 virtual HRESULT STDMETHODCALLTYPE get_SplashScreen(
1066 winapp::Activation::ISplashScreen **value) {
1067 return E_FAIL;
1068 }
1069
1070 private:
1071 winapp::Activation::ActivationKind activation_kind_;
1072 };
1073
1074 class CoreApplicationViewEmulation
1075 : public mswr::RuntimeClass<winapp::Core::ICoreApplicationView> {
1076 public:
CoreApplicationViewEmulation(winapp::Core::IFrameworkView * app_view)1077 CoreApplicationViewEmulation(winapp::Core::IFrameworkView* app_view) {
1078 core_window_ = mswr::Make<CoreWindowEmulation>(app_view);
1079 }
1080
Activate()1081 HRESULT Activate() {
1082 if (activated_handler_) {
1083 auto ae = mswr::Make<ActivatedEvent>(
1084 winapp::Activation::ActivationKind_File);
1085 return activated_handler_->Invoke(this, ae.Get());
1086 } else {
1087 return S_OK;
1088 }
1089 }
1090
Close()1091 HRESULT Close() {
1092 return core_window_->Close();
1093 }
1094
1095 // ICoreApplicationView implementation:
get_CoreWindow(winui::Core::ICoreWindow ** value)1096 virtual HRESULT STDMETHODCALLTYPE get_CoreWindow(
1097 winui::Core::ICoreWindow** value) {
1098 if (!core_window_)
1099 return E_FAIL;
1100 return core_window_.CopyTo(value);
1101 }
1102
add_Activated(ActivatedHandler * handler,EventRegistrationToken * token)1103 virtual HRESULT STDMETHODCALLTYPE add_Activated(
1104 ActivatedHandler* handler,
1105 EventRegistrationToken* token) {
1106 // The real component supports multiple handles but we don't yet.
1107 if (activated_handler_)
1108 return E_FAIL;
1109 activated_handler_ = handler;
1110 return S_OK;
1111 }
1112
remove_Activated(EventRegistrationToken token)1113 virtual HRESULT STDMETHODCALLTYPE remove_Activated(
1114 EventRegistrationToken token) {
1115 // Chrome never unregisters handlers, so we don't care about it.
1116 return S_OK;
1117 }
1118
get_IsMain(boolean * value)1119 virtual HRESULT STDMETHODCALLTYPE get_IsMain(
1120 boolean* value) {
1121 return S_OK;
1122 }
1123
get_IsHosted(boolean * value)1124 virtual HRESULT STDMETHODCALLTYPE get_IsHosted(
1125 boolean* value) {
1126 return S_OK;
1127 }
1128
1129 private:
1130 mswr::ComPtr<CoreWindowEmulation> core_window_;
1131 mswr::ComPtr<ActivatedHandler> activated_handler_;
1132 };
1133
1134 class CoreApplicationWin7Emulation
1135 : public mswr::RuntimeClass<winapp::Core::ICoreApplication,
1136 winapp::Core::ICoreApplicationExit> {
1137 public:
1138 // ICoreApplication implementation:
1139
get_Id(HSTRING * value)1140 virtual HRESULT STDMETHODCALLTYPE get_Id(
1141 HSTRING* value) {
1142 return S_OK;
1143 }
1144
add_Suspending(winfoundtn::IEventHandler<winapp::SuspendingEventArgs * > * handler,EventRegistrationToken * token)1145 virtual HRESULT STDMETHODCALLTYPE add_Suspending(
1146 winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler,
1147 EventRegistrationToken* token) {
1148 return S_OK;
1149 }
1150
remove_Suspending(EventRegistrationToken token)1151 virtual HRESULT STDMETHODCALLTYPE remove_Suspending(
1152 EventRegistrationToken token) {
1153 return S_OK;
1154 }
1155
add_Resuming(winfoundtn::IEventHandler<IInspectable * > * handler,EventRegistrationToken * token)1156 virtual HRESULT STDMETHODCALLTYPE add_Resuming(
1157 winfoundtn::IEventHandler<IInspectable*>* handler,
1158 EventRegistrationToken* token) {
1159 return S_OK;
1160 }
1161
remove_Resuming(EventRegistrationToken token)1162 virtual HRESULT STDMETHODCALLTYPE remove_Resuming(
1163 EventRegistrationToken token) {
1164 return S_OK;
1165 }
1166
get_Properties(winfoundtn::Collections::IPropertySet ** value)1167 virtual HRESULT STDMETHODCALLTYPE get_Properties(
1168 winfoundtn::Collections::IPropertySet** value) {
1169 return S_OK;
1170 }
1171
GetCurrentView(winapp::Core::ICoreApplicationView ** value)1172 virtual HRESULT STDMETHODCALLTYPE GetCurrentView(
1173 winapp::Core::ICoreApplicationView** value) {
1174 return S_OK;
1175 }
1176
Run(winapp::Core::IFrameworkViewSource * viewSource)1177 virtual HRESULT STDMETHODCALLTYPE Run(
1178 winapp::Core::IFrameworkViewSource* viewSource) {
1179 HRESULT hr = viewSource->CreateView(app_view_.GetAddressOf());
1180 if (FAILED(hr))
1181 return hr;
1182 view_emulation_ = mswr::Make<CoreApplicationViewEmulation>(
1183 app_view_.Get());
1184 hr = app_view_->Initialize(view_emulation_.Get());
1185 if (FAILED(hr))
1186 return hr;
1187 mswr::ComPtr<winui::Core::ICoreWindow> core_window;
1188 hr = view_emulation_->get_CoreWindow(core_window.GetAddressOf());
1189 if (FAILED(hr))
1190 return hr;
1191 hr = app_view_->SetWindow(core_window.Get());
1192 if (FAILED(hr))
1193 return hr;
1194 hr = app_view_->Load(NULL);
1195 if (FAILED(hr))
1196 return hr;
1197 hr = view_emulation_->Activate();
1198 if (FAILED(hr))
1199 return hr;
1200 return app_view_->Run();
1201 }
1202
RunWithActivationFactories(winfoundtn::IGetActivationFactory * activationFactoryCallback)1203 virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories(
1204 winfoundtn::IGetActivationFactory* activationFactoryCallback) {
1205 return S_OK;
1206 }
1207
1208 // ICoreApplicationExit implementation:
1209
Exit(void)1210 virtual HRESULT STDMETHODCALLTYPE Exit(void) {
1211 return view_emulation_->Close();
1212 }
1213
add_Exiting(winfoundtn::IEventHandler<IInspectable * > * handler,EventRegistrationToken * token)1214 virtual HRESULT STDMETHODCALLTYPE add_Exiting(
1215 winfoundtn::IEventHandler<IInspectable*>* handler,
1216 EventRegistrationToken* token) {
1217 return S_OK;
1218 }
1219
remove_Exiting(EventRegistrationToken token)1220 virtual HRESULT STDMETHODCALLTYPE remove_Exiting(
1221 EventRegistrationToken token) {
1222 return S_OK;
1223 }
1224
1225 private:
1226 mswr::ComPtr<winapp::Core::IFrameworkView> app_view_;
1227 mswr::ComPtr<CoreApplicationViewEmulation> view_emulation_;
1228 };
1229
1230
InitWindows7()1231 mswr::ComPtr<winapp::Core::ICoreApplication> InitWindows7() {
1232 HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
1233 if (FAILED(hr))
1234 CHECK(false);
1235 return mswr::Make<CoreApplicationWin7Emulation>();
1236 }
1237
1238