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 |
| 7 EXTERN_C IMAGE_DOS_HEADER __ImageBase; |
| 8 |
| 9 struct Globals { |
| 10 LPTHREAD_START_ROUTINE host_main; |
| 11 void* host_context; |
| 12 HWND core_window; |
| 13 HWND host_window; |
| 14 HANDLE host_thread; |
| 15 DWORD main_thread_id; |
| 16 } globals; |
| 17 |
| 18 |
| 19 void ODS(const char* str, LONG_PTR val = 0) { |
| 20 char buf[80]; |
| 21 size_t len = strlen(str); |
| 22 if (len > 50) { |
| 23 ::OutputDebugStringA("ODS: buffer too long"); |
| 24 return; |
| 25 } |
| 26 |
| 27 if (str[0] == '!') { |
| 28 // Fatal error. |
| 29 DWORD gle = ::GetLastError(); |
| 30 if (::IsDebuggerPresent()) |
| 31 __debugbreak(); |
| 32 wsprintfA(buf, "ODS:fatal %s (%p) gle=0x%x", str, val, gle); |
| 33 ::MessageBoxA(NULL, buf, "!!!", MB_OK); |
| 34 ::ExitProcess(gle); |
| 35 } else { |
| 36 // Just information. |
| 37 wsprintfA(buf, "ODS:%s (%p)\n", str, val); |
| 38 ::OutputDebugStringA(buf); |
| 39 } |
| 40 } |
| 41 |
| 42 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, |
| 43 WPARAM wparam, LPARAM lparam) { |
| 44 PAINTSTRUCT ps; |
| 45 HDC hdc; |
| 46 switch (message) { |
| 47 case WM_PAINT: |
| 48 hdc = BeginPaint(hwnd, &ps); |
| 49 EndPaint(hwnd, &ps); |
| 50 break; |
| 51 case WM_DESTROY: |
| 52 PostQuitMessage(0); |
| 53 ODS("Metro WM_DESTROY received"); |
| 54 break; |
| 55 default: |
| 56 return DefWindowProc(hwnd, message, wparam, lparam); |
| 57 } |
| 58 return 0; |
| 59 } |
| 60 |
| 61 HWND CreateMetroTopLevelWindow() { |
| 62 HINSTANCE hInst = reinterpret_cast<HINSTANCE>(&__ImageBase); |
| 63 WNDCLASSEXW wcex; |
| 64 wcex.cbSize = sizeof(wcex); |
| 65 wcex.style = CS_HREDRAW | CS_VREDRAW; |
| 66 wcex.lpfnWndProc = WndProc; |
| 67 wcex.cbClsExtra = 0; |
| 68 wcex.cbWndExtra = 0; |
| 69 wcex.hInstance = hInst; |
| 70 wcex.hIcon = 0; |
| 71 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
| 72 wcex.hbrBackground = (HBRUSH)(COLOR_INACTIVECAPTION+1); |
| 73 wcex.lpszMenuName = 0; |
| 74 wcex.lpszClassName = L"Windows.UI.Core.CoreWindow"; |
| 75 wcex.hIconSm = 0; |
| 76 |
| 77 HWND hwnd = ::CreateWindowExW(0, |
| 78 MAKEINTATOM(::RegisterClassExW(&wcex)), |
| 79 L"metro_metro", |
| 80 WS_POPUP, |
| 81 0, 0, 0, 0, |
| 82 NULL, NULL, hInst, NULL); |
| 83 return hwnd; |
| 84 } |
| 85 |
| 86 DWORD WINAPI HostThread(void*) { |
| 87 // The sleeps simulates the delay we have in the actual metro code |
| 88 // which takes in account the corewindow being created and some other |
| 89 // unknown machinations of metro. |
| 90 ODS("Chrome main thread", ::GetCurrentThreadId()); |
| 91 ::Sleep(30); |
| 92 return globals.host_main(globals.host_context); |
| 93 } |
| 94 |
| 95 extern "C" __declspec(dllexport) |
| 96 int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { |
| 97 ODS("InitMetro [Win7 emulation]"); |
| 98 HWND window = CreateMetroTopLevelWindow(); |
| 99 if (!window) |
| 100 return 1; |
| 101 // This magic incatation tells windows that the window is going fullscreen |
| 102 // so the taskbar gets out of the wait automatically. |
| 103 ::SetWindowPos(window, |
| 104 HWND_TOP, |
| 105 0,0, |
| 106 GetSystemMetrics(SM_CXSCREEN), |
| 107 GetSystemMetrics(SM_CYSCREEN), |
| 108 SWP_SHOWWINDOW); |
| 109 |
| 110 // Ready to start our caller. |
| 111 globals.core_window = window; |
| 112 globals.host_main = thread_proc; |
| 113 globals.host_context = context; |
| 114 HANDLE thread = ::CreateThread(NULL, 0, &HostThread, NULL, 0, NULL); |
| 115 |
| 116 // Main message loop. |
| 117 MSG msg = {0}; |
| 118 while (GetMessage(&msg, NULL, 0, 0)) { |
| 119 TranslateMessage(&msg); |
| 120 DispatchMessage(&msg); |
| 121 } |
| 122 |
| 123 return (int) msg.wParam; |
| 124 } |
| 125 |
| 126 extern "C" _declspec(dllexport) HWND GetRootWindow() { |
| 127 ODS("GetRootWindow", ULONG_PTR(globals.core_window)); |
| 128 return globals.core_window; |
| 129 } |
| 130 |
| 131 extern "C" _declspec(dllexport) void SetFrameWindow(HWND window) { |
| 132 ODS("SetFrameWindow", ULONG_PTR(window)); |
| 133 globals.host_window = window; |
| 134 } |
| 135 |
| 136 extern "C" __declspec(dllexport) const wchar_t* GetInitialUrl() { |
| 137 return L""; |
| 138 } |
| 139 |
OLD | NEW |