| 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 |