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