Home | History | Annotate | Download | only in metro_driver
      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 
     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:
    106   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:
    123   MouseEvent(const MSG& msg)
    124       : msg_(msg) {
    125   }
    126 
    127   // IPointerEventArgs implementation.
    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 
    134   virtual HRESULT STDMETHODCALLTYPE get_KeyModifiers(
    135       winsys::VirtualKeyModifiers* modifiers) {
    136     return E_NOTIMPL;
    137   }
    138 
    139   virtual HRESULT STDMETHODCALLTYPE GetIntermediatePoints(
    140       winfoundtn::Collections::IVector<winui::Input::PointerPoint*>** points) {
    141     return E_NOTIMPL;
    142   }
    143 
    144   // IPointerPoint implementation.
    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 
    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 
    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 
    166   virtual HRESULT STDMETHODCALLTYPE get_Timestamp(uint64* timestamp) {
    167     *timestamp = msg_.time;
    168     return S_OK;
    169   }
    170 
    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 
    177   virtual HRESULT STDMETHODCALLTYPE get_RawPosition(
    178       winfoundtn::Point* position) {
    179     return E_NOTIMPL;
    180   }
    181 
    182   virtual HRESULT STDMETHODCALLTYPE get_FrameId(uint32* frame_id) {
    183     return E_NOTIMPL;
    184   }
    185 
    186   virtual HRESULT STDMETHODCALLTYPE get_IsInContact(boolean* in_contact) {
    187     return E_NOTIMPL;
    188   }
    189 
    190   // IPointerPointProperties implementation.
    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 
    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 
    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 
    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 
    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 
    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 
    246   virtual HRESULT STDMETHODCALLTYPE get_Pressure(float* pressure) {
    247     return E_NOTIMPL;
    248   }
    249 
    250   virtual HRESULT STDMETHODCALLTYPE get_IsInverted(boolean* inverted) {
    251     return E_NOTIMPL;
    252   }
    253 
    254   virtual HRESULT STDMETHODCALLTYPE get_IsEraser(boolean* is_eraser) {
    255     return E_NOTIMPL;
    256   }
    257 
    258   virtual HRESULT STDMETHODCALLTYPE get_Orientation(float* orientation) {
    259     return E_NOTIMPL;
    260   }
    261 
    262   virtual HRESULT STDMETHODCALLTYPE get_XTilt(float* x_tilt) {
    263     return E_NOTIMPL;
    264   }
    265 
    266   virtual HRESULT STDMETHODCALLTYPE get_YTilt(float* y_tilt) {
    267     return E_NOTIMPL;
    268   }
    269 
    270   virtual  HRESULT STDMETHODCALLTYPE get_Twist(float* twist) {
    271     return E_NOTIMPL;
    272   }
    273 
    274   virtual HRESULT STDMETHODCALLTYPE get_ContactRect(winfoundtn::Rect* rect) {
    275     return E_NOTIMPL;
    276   }
    277 
    278   virtual HRESULT STDMETHODCALLTYPE get_ContactRectRaw(winfoundtn::Rect* rect) {
    279     return E_NOTIMPL;
    280   }
    281 
    282   virtual HRESULT STDMETHODCALLTYPE get_TouchConfidence(boolean* confidence) {
    283     return E_NOTIMPL;
    284   }
    285 
    286   virtual HRESULT STDMETHODCALLTYPE get_IsPrimary(boolean* is_primary) {
    287     return E_NOTIMPL;
    288   }
    289 
    290   virtual HRESULT STDMETHODCALLTYPE get_IsInRange(boolean* is_in_range) {
    291     return E_NOTIMPL;
    292   }
    293 
    294   virtual HRESULT STDMETHODCALLTYPE get_IsCanceled(boolean* is_canceled) {
    295     return E_NOTIMPL;
    296   }
    297 
    298   virtual HRESULT STDMETHODCALLTYPE get_IsBarrelButtonPressed(
    299       boolean* is_barrel_button_pressed) {
    300     return E_NOTIMPL;
    301   }
    302 
    303   virtual HRESULT STDMETHODCALLTYPE get_IsXButton1Pressed(
    304       boolean* is_xbutton1_pressed) {
    305     return E_NOTIMPL;
    306   }
    307 
    308   virtual HRESULT STDMETHODCALLTYPE get_IsXButton2Pressed(
    309       boolean* is_xbutton2_pressed) {
    310     return E_NOTIMPL;
    311   }
    312 
    313   virtual HRESULT STDMETHODCALLTYPE HasUsage(uint32 usage_page,
    314                                              uint32 usage_id,
    315                                              boolean* has_usage) {
    316     return E_NOTIMPL;
    317   }
    318 
    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.
    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 
    336   virtual HRESULT STDMETHODCALLTYPE get_IsIntegrated(boolean* is_integrated) {
    337     return E_NOTIMPL;
    338   }
    339 
    340   virtual HRESULT STDMETHODCALLTYPE get_MaxContacts(uint32* contacts) {
    341     return E_NOTIMPL;
    342   }
    343 
    344   virtual HRESULT STDMETHODCALLTYPE get_PhysicalDeviceRect(
    345       winfoundtn::Rect* rect) {
    346     return E_NOTIMPL;
    347   }
    348 
    349   virtual HRESULT STDMETHODCALLTYPE get_ScreenRect(winfoundtn::Rect* rect) {
    350     return E_NOTIMPL;
    351   }
    352 
    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:
    372   KeyEvent(const MSG& msg)
    373       : msg_(msg) {}
    374 
    375   // IKeyEventArgs implementation.
    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 
    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.
    395   virtual HRESULT STDMETHODCALLTYPE get_KeyCode(uint32* key_code) {
    396     *key_code = msg_.wParam;
    397     return S_OK;
    398   }
    399 
    400   // IAcceleratorKeyEventArgs implementation.
    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:
    445   CoreDispatcherEmulation(InputHandler* input_handler)
    446       : input_handler_(input_handler),
    447         accelerator_key_event_handler_(NULL) {}
    448 
    449   // ICoreDispatcher implementation:
    450   virtual HRESULT STDMETHODCALLTYPE get_HasThreadAccess(boolean* value) {
    451     return S_OK;
    452   }
    453 
    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 
    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 
    479   virtual HRESULT STDMETHODCALLTYPE RunIdleAsync(
    480       winui::Core::IIdleDispatchedHandler *agileCallback,
    481       winfoundtn::IAsyncAction** asyncAction) {
    482     return S_OK;
    483   }
    484 
    485   // ICoreAcceleratorKeys implementation:
    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 
    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:
    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 
    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:
    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 
    571   ~CoreWindowEmulation() {
    572     if (core_hwnd_) {
    573       ::RemoveProp(core_hwnd_, kAshWin7CoreWindowHandler);
    574       ::DestroyWindow(core_hwnd_);
    575     }
    576   }
    577 
    578   // ICoreWindow implementation:
    579   virtual HRESULT STDMETHODCALLTYPE get_AutomationHostProvider(
    580       IInspectable** value) {
    581     return S_OK;
    582   }
    583 
    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 
    594   virtual HRESULT STDMETHODCALLTYPE get_CustomProperties(
    595       winfoundtn::Collections::IPropertySet** value) {
    596     return S_OK;
    597   }
    598 
    599   virtual HRESULT STDMETHODCALLTYPE get_Dispatcher(
    600       winui::Core::ICoreDispatcher** value) {
    601     return dispatcher_.CopyTo(value);
    602   }
    603 
    604   virtual HRESULT STDMETHODCALLTYPE get_FlowDirection(
    605       winui::Core::CoreWindowFlowDirection* value) {
    606     return S_OK;
    607   }
    608 
    609   virtual HRESULT STDMETHODCALLTYPE put_FlowDirection(
    610       winui::Core::CoreWindowFlowDirection value) {
    611     return S_OK;
    612   }
    613 
    614   virtual HRESULT STDMETHODCALLTYPE get_IsInputEnabled(
    615       boolean* value) {
    616     return S_OK;
    617   }
    618 
    619   virtual HRESULT STDMETHODCALLTYPE put_IsInputEnabled(
    620       boolean value) {
    621     return S_OK;
    622   }
    623 
    624   virtual HRESULT STDMETHODCALLTYPE get_PointerCursor(
    625       winui::Core::ICoreCursor** value) {
    626     return S_OK;
    627   }
    628 
    629   virtual HRESULT STDMETHODCALLTYPE put_PointerCursor(
    630        winui::Core::ICoreCursor* value) {
    631     return S_OK;
    632   }
    633 
    634   virtual HRESULT STDMETHODCALLTYPE get_PointerPosition(
    635       winfoundtn::Point* value) {
    636     return S_OK;
    637   }
    638 
    639   virtual HRESULT STDMETHODCALLTYPE get_Visible(
    640       boolean* value) {
    641     return S_OK;
    642   }
    643 
    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 
    649   virtual HRESULT STDMETHODCALLTYPE Close(void) {
    650     ::PostMessage(core_hwnd_, WM_CLOSE, 0, 0);
    651     core_hwnd_ = NULL;
    652     return S_OK;
    653   }
    654 
    655   virtual HRESULT STDMETHODCALLTYPE GetAsyncKeyState(
    656       ABI::Windows::System::VirtualKey virtualKey,
    657       winui::Core::CoreVirtualKeyStates* KeyState) {
    658     return S_OK;
    659   }
    660 
    661   virtual HRESULT STDMETHODCALLTYPE GetKeyState(
    662       ABI::Windows::System::VirtualKey virtualKey,
    663       winui::Core::CoreVirtualKeyStates* KeyState) {
    664     return S_OK;
    665   }
    666 
    667   virtual HRESULT STDMETHODCALLTYPE ReleasePointerCapture(void) {
    668     return S_OK;
    669   }
    670 
    671   virtual HRESULT STDMETHODCALLTYPE SetPointerCapture(void) {
    672     return S_OK;
    673   }
    674 
    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 
    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 
    690   virtual HRESULT STDMETHODCALLTYPE add_AutomationProviderRequested(
    691       AutomationProviderHandler* handler,
    692       EventRegistrationToken* cookie) {
    693     return S_OK;
    694   }
    695 
    696   virtual HRESULT STDMETHODCALLTYPE remove_AutomationProviderRequested(
    697       EventRegistrationToken cookie) {
    698     return S_OK;
    699   }
    700 
    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 
    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 
    716   virtual HRESULT STDMETHODCALLTYPE add_Closed(
    717       CoreWindowEventHandler* handler,
    718       EventRegistrationToken* pCookie) {
    719     return S_OK;
    720   }
    721 
    722   virtual HRESULT STDMETHODCALLTYPE remove_Closed(
    723       EventRegistrationToken cookie) {
    724     return S_OK;
    725   }
    726 
    727   virtual HRESULT STDMETHODCALLTYPE add_InputEnabled(
    728       InputEnabledEventHandler* handler,
    729       EventRegistrationToken* pCookie) {
    730     return S_OK;
    731   }
    732 
    733   virtual HRESULT STDMETHODCALLTYPE remove_InputEnabled(
    734       EventRegistrationToken cookie) {
    735     return S_OK;
    736   }
    737 
    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 
    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 
    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 
    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 
    768   virtual HRESULT STDMETHODCALLTYPE add_PointerCaptureLost(
    769       PointerEventHandler* handler,
    770       EventRegistrationToken* cookie) {
    771     mouse_capture_lost_handler_ = handler;
    772     return S_OK;
    773   }
    774 
    775   virtual HRESULT STDMETHODCALLTYPE remove_PointerCaptureLost(
    776       EventRegistrationToken cookie) {
    777     mouse_capture_lost_handler_ = NULL;
    778     return S_OK;
    779   }
    780 
    781   virtual HRESULT STDMETHODCALLTYPE add_PointerEntered(
    782       PointerEventHandler* handler,
    783       EventRegistrationToken* cookie) {
    784     mouse_entered_handler_ = handler;
    785     return S_OK;
    786   }
    787 
    788   virtual HRESULT STDMETHODCALLTYPE remove_PointerEntered(
    789       EventRegistrationToken cookie) {
    790     mouse_entered_handler_ = NULL;
    791     return S_OK;
    792   }
    793 
    794   virtual HRESULT STDMETHODCALLTYPE add_PointerExited(
    795       PointerEventHandler* handler,
    796       EventRegistrationToken* cookie) {
    797     mouse_exited_handler_ = handler;
    798     return S_OK;
    799   }
    800 
    801   virtual HRESULT STDMETHODCALLTYPE remove_PointerExited(
    802       EventRegistrationToken cookie) {
    803     mouse_exited_handler_ = NULL;
    804     return S_OK;
    805   }
    806 
    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 
    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 
    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 
    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 
    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 
    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 
    852   virtual HRESULT STDMETHODCALLTYPE add_TouchHitTesting(
    853       TouchHitTestHandler* handler,
    854       EventRegistrationToken* pCookie) {
    855     return S_OK;
    856   }
    857 
    858   virtual HRESULT STDMETHODCALLTYPE remove_TouchHitTesting(
    859       EventRegistrationToken cookie) {
    860     return S_OK;
    861   }
    862 
    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 
    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 
    878   virtual HRESULT STDMETHODCALLTYPE add_SizeChanged(
    879       SizeChangedHandler* handler,
    880       EventRegistrationToken* pCookie) {
    881     // TODO(cpu): implement this.
    882     return S_OK;
    883   }
    884 
    885   virtual HRESULT STDMETHODCALLTYPE remove_SizeChanged(
    886       EventRegistrationToken cookie) {
    887     return S_OK;
    888   }
    889 
    890   virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged(
    891       VisibilityChangedHandler* handler,
    892       EventRegistrationToken* pCookie) {
    893     return S_OK;
    894   }
    895 
    896   virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged(
    897       EventRegistrationToken cookie) {
    898     return S_OK;
    899   }
    900 
    901   // ICoreWindowInterop implementation:
    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 
    909   virtual HRESULT STDMETHODCALLTYPE put_MessageHandled(
    910     boolean value) {
    911     return S_OK;
    912   }
    913 
    914   // InputHandler
    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 
    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 
    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 
   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:
   1049   ActivatedEvent(winapp::Activation::ActivationKind activation_kind)
   1050     : activation_kind_(activation_kind) {
   1051   }
   1052 
   1053   virtual HRESULT STDMETHODCALLTYPE get_Kind(
   1054     winapp::Activation::ActivationKind *value) {
   1055     *value = activation_kind_;
   1056     return S_OK;
   1057   }
   1058 
   1059   virtual HRESULT STDMETHODCALLTYPE get_PreviousExecutionState(
   1060     winapp::Activation::ApplicationExecutionState *value) {
   1061     *value = winapp::Activation::ApplicationExecutionState_ClosedByUser;
   1062     return S_OK;
   1063   }
   1064 
   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:
   1077    CoreApplicationViewEmulation(winapp::Core::IFrameworkView* app_view) {
   1078       core_window_ = mswr::Make<CoreWindowEmulation>(app_view);
   1079    }
   1080 
   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 
   1091   HRESULT Close() {
   1092     return core_window_->Close();
   1093   }
   1094 
   1095   // ICoreApplicationView implementation:
   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 
   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 
   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 
   1119   virtual HRESULT STDMETHODCALLTYPE get_IsMain(
   1120     boolean* value) {
   1121     return S_OK;
   1122   }
   1123 
   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 
   1140   virtual HRESULT STDMETHODCALLTYPE get_Id(
   1141       HSTRING* value) {
   1142     return S_OK;
   1143   }
   1144 
   1145   virtual HRESULT STDMETHODCALLTYPE add_Suspending(
   1146       winfoundtn::IEventHandler<winapp::SuspendingEventArgs*>* handler,
   1147       EventRegistrationToken* token) {
   1148     return S_OK;
   1149   }
   1150 
   1151   virtual HRESULT STDMETHODCALLTYPE remove_Suspending(
   1152       EventRegistrationToken token) {
   1153     return S_OK;
   1154   }
   1155 
   1156   virtual HRESULT STDMETHODCALLTYPE add_Resuming(
   1157        winfoundtn::IEventHandler<IInspectable*>* handler,
   1158       EventRegistrationToken* token) {
   1159     return S_OK;
   1160   }
   1161 
   1162   virtual HRESULT STDMETHODCALLTYPE remove_Resuming(
   1163       EventRegistrationToken token) {
   1164     return S_OK;
   1165   }
   1166 
   1167   virtual HRESULT STDMETHODCALLTYPE get_Properties(
   1168       winfoundtn::Collections::IPropertySet** value) {
   1169     return S_OK;
   1170   }
   1171 
   1172   virtual HRESULT STDMETHODCALLTYPE GetCurrentView(
   1173       winapp::Core::ICoreApplicationView** value) {
   1174     return S_OK;
   1175   }
   1176 
   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 
   1203   virtual HRESULT STDMETHODCALLTYPE RunWithActivationFactories(
   1204       winfoundtn::IGetActivationFactory* activationFactoryCallback) {
   1205     return S_OK;
   1206   }
   1207 
   1208   // ICoreApplicationExit implementation:
   1209 
   1210   virtual HRESULT STDMETHODCALLTYPE Exit(void) {
   1211     return view_emulation_->Close();
   1212   }
   1213 
   1214   virtual HRESULT STDMETHODCALLTYPE add_Exiting(
   1215        winfoundtn::IEventHandler<IInspectable*>* handler,
   1216       EventRegistrationToken* token) {
   1217     return S_OK;
   1218   }
   1219 
   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 
   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