• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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