| OLD | NEW |
| 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 |
| 1 // This project demonstrates how to migrate a Windows desktop app to Native | 6 // This project demonstrates how to migrate a Windows desktop app to Native |
| 2 // Client, running first as a Win32 application (define STEP1), then as a PPAPI | 7 // Client, running first as a Win32 application (define STEP1), then as a PPAPI |
| 3 // plugin (define STEP2 through STEP6), and finally as a Native Client module. | 8 // plugin (define STEP2 through STEP6), and finally as a Native Client module. |
| 4 | 9 |
| 5 // Start with STEP1 defined and the defines for STEP2 through STEP6 commented | 10 // Start with STEP1 defined and the defines for STEP2 through STEP6 commented |
| 6 // out. For each step in the process, un-comment the next #define, leaving the | 11 // out. For each step in the process, un-comment the next #define, leaving the |
| 7 // previous ones on. Ready, set, port! | 12 // previous ones on. Ready, set, port! |
| 8 | 13 |
| 9 // *** SELECT THE WIN32 PLATFORM AND RUN WITH #define STEP1 ONLY *** | 14 // *** SELECT THE WIN32 PLATFORM AND RUN WITH #define STEP1 ONLY *** |
| 10 | 15 |
| 11 #define STEP1 | 16 #define STEP1 |
| 12 // Launches the original Windows desktop application, Hello World, which runs | 17 // Launches the original Windows desktop application, Hello World, which runs |
| 13 // as WinMain. STEP1 encloses Windows-specific functions that are used with | 18 // as WinMain. STEP1 encloses Windows-specific functions that are used with |
| 14 // the WIN32 and PPAPI platforms. These will be removed when the full PPAPI | 19 // the WIN32 and PPAPI platforms. These will be removed when the full PPAPI |
| 15 // port is finished (STEP6) | 20 // port is finished (STEP6) |
| 16 | 21 |
| 17 // *** SELECT THE PPAPI PLATFORM *** | 22 // *** SELECT THE PPAPI PLATFORM *** |
| 18 | 23 |
| 19 //#define STEP2 | 24 //#define STEP2 |
| 20 // What Changed: The platform launches Chrome, which will then load a Native | 25 // What Changed: The platform launches Chrome, which will then load a Native |
| 21 // Client Module. STEP2 encloses the Native Client module APIs needed to link | 26 // Client Module. STEP2 encloses the Native Client module APIs needed to link |
| 22 // any app to the browser. The module does nothing except report | 27 // any app to the browser. The module does nothing except report |
| 23 // starting/ending the function Instance_DidCreate. The Windows app does not | 28 // starting/ending the function Instance_DidCreate. The Windows app does not |
| 24 // run because it is not being called. | 29 // run because it is not being called. |
| 25 | 30 |
| 26 //#define STEP3 | 31 //#define STEP3 |
| 27 // What changed: Replace WinMain with WndProc, and call it from | 32 // What changed: Replace WinMain with WndProc, and call it from |
| 28 // Instance_DidCreate, launching HelloNaCl in its own window. | 33 // Instance_DidCreate, launching hello_nacl in its own window. |
| 29 // Since WndProc spins in its message loop, the call to Instance_DidCreate | 34 // Since WndProc spins in its message loop, the call to Instance_DidCreate |
| 30 // never returns. | 35 // never returns. |
| 31 // Close the HelloNaCl window and the module initialization will finish. | 36 // Close the hello_nacl window and the module initialization will finish. |
| 32 | 37 |
| 33 //#define STEP4 | 38 //#define STEP4 |
| 34 // What changed: In WndProc replace the message loop with a callback function. | 39 // What changed: In WndProc replace the message loop with a callback function. |
| 35 // Now the app window and the Native Client module are running concurrently. | 40 // Now the app window and the Native Client module are running concurrently. |
| 36 | 41 |
| 37 //#define STEP5 | 42 //#define STEP5 |
| 38 // What changed: Instance_DidCreate calls initInstanceInBrowserWindow rather | 43 // What changed: Instance_DidCreate calls InitInstanceInBrowserWindow rather |
| 39 // than initInstanceInPCWindow. | 44 // than InitInstanceInPCWindow. |
| 40 // The initInstanceInBrowserWindow uses postMessage to place text (now "Hello, | 45 // The InitInstanceInBrowserWindow uses postMessage to place text (now "Hello, |
| 41 // Native Client") in the web page instead of opening and writing to a window. | 46 // Native Client") in the web page instead of opening and writing to a window. |
| 42 | 47 |
| 43 //#define STEP6 | 48 //#define STEP6 |
| 44 // What changed: All the Windows code is def'd out, to prove we are | 49 // What changed: All the Windows code is def'd out, to prove we are |
| 45 // PPAPI-compliant. The functional code that is running is the same as STEP5. | 50 // PPAPI-compliant. The functional code that is running is the same as STEP5. |
| 46 | 51 |
| 47 // *** SELECT THE NACL64 PLATFORM AND RUN *** | 52 // *** SELECT THE NACL64 PLATFORM AND RUN *** |
| 48 | 53 |
| 49 // What changed: The code is the same as STEP6, but you are using the SDK | 54 // What changed: The code is the same as STEP6, but you are using the SDK |
| 50 // toolchain to compile it into a nexe. The module is now running as a real | 55 // toolchain to compile it into a nexe. The module is now running as a real |
| 51 // Native Client executable in a NaCl sandbox, with nacl-gdb attached. | 56 // Native Client executable in a NaCl sandbox, with nacl-gdb attached. |
| 52 | 57 |
| 53 // *** RUN YOUR MODULE IN THE WILD *** | 58 // *** RUN YOUR MODULE IN THE WILD *** |
| 54 // You can run your nexe outside of Visual Studio, directly from Chrome by | 59 // You can run your nexe outside of Visual Studio, directly from Chrome by |
| 55 // following these steps: | 60 // following these steps: |
| 56 // - Build STEP6 and verify the file <project | 61 // - Build STEP6 and verify the file |
| 57 // directory>/newlib/HelloNaCl/HelloNaCl.nexe exists | 62 // <project directory>/NaCl64/newlib/Debug/hello_nacl_64.nexe exists |
| 58 // - Copy the folder <project directory>/HelloNaCl into your NaCl SDK's example | 63 // - Copy the folder <project directory> into your NaCl SDK's example |
| 59 // directory. | 64 // directory. |
| 60 // - Go to the NaCl SDK directory and launch the httpd.py server. | 65 // - Go to the NaCl SDK directory and launch the httpd.py server. |
| 61 // - Launch Chrome, go to about:flags and enable the Native Client flag and | 66 // - Launch Chrome, go to about:flags and enable the Native Client flag and |
| 62 // relaunch Chrome | 67 // relaunch Chrome |
| 63 // - Point Chrome at localhost:5103/HelloNaCl | 68 // - Point Chrome at localhost:5103/hello_nacl |
| 64 | 69 |
| 65 | 70 |
| 66 #ifdef STEP6 | 71 #ifdef STEP6 |
| 67 // remove Windows-dependent code. | 72 // remove Windows-dependent code. |
| 68 #undef STEP1 | 73 #undef STEP1 |
| 69 #undef STEP3 | 74 #undef STEP3 |
| 70 #undef STEP4 | 75 #undef STEP4 |
| 71 #define NULL 0 | 76 #define NULL 0 |
| 72 #else | 77 #else |
| 73 // includes for Windows APIs. | 78 // includes for Windows APIs. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 91 #include "ppapi/c/ppp_instance.h" | 96 #include "ppapi/c/ppp_instance.h" |
| 92 #include "ppapi/c/ppp_messaging.h" | 97 #include "ppapi/c/ppp_messaging.h" |
| 93 #include <string.h> | 98 #include <string.h> |
| 94 | 99 |
| 95 // Native Client APIs | 100 // Native Client APIs |
| 96 static PPB_Messaging* ppb_messaging_interface = NULL; | 101 static PPB_Messaging* ppb_messaging_interface = NULL; |
| 97 static PPB_Var* ppb_var_interface = NULL; | 102 static PPB_Var* ppb_var_interface = NULL; |
| 98 static PPB_Core* ppb_core_interface = NULL; | 103 static PPB_Core* ppb_core_interface = NULL; |
| 99 PP_Instance myInstance; | 104 PP_Instance myInstance; |
| 100 | 105 |
| 101 int initInstanceInPCWindow(); | 106 int InitInstanceInPCWindow(); |
| 102 void initInstanceInBrowserWindow(); | 107 void InitInstanceInBrowserWindow(); |
| 103 | 108 |
| 104 #endif | 109 #endif |
| 105 | 110 |
| 106 | 111 |
| 107 #ifdef STEP4 | 112 #ifdef STEP4 |
| 108 // Implements message handling in a callback function. | 113 // Implements message handling in a callback function. |
| 109 void HelloWorldCallbackFun(void* user_data, int32_t result); | 114 void HelloWorldCallback(void* user_data, int32_t result) { |
| 110 struct PP_CompletionCallback HelloWorldCallback = { HelloWorldCallbackFun, NULL
}; | |
| 111 | |
| 112 void HelloWorldCallbackFun(void* user_data, int32_t result) { | |
| 113 MSG uMsg; | 115 MSG uMsg; |
| 114 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) { | 116 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) { |
| 115 TranslateMessage(&uMsg); | 117 TranslateMessage(&uMsg); |
| 116 DispatchMessage(&uMsg); | 118 DispatchMessage(&uMsg); |
| 117 } | 119 } |
| 118 ppb_core_interface->CallOnMainThread(100, HelloWorldCallback, 0); | 120 ppb_core_interface->CallOnMainThread(100, HelloWorldCallback, 0); |
| 119 } | 121 } |
| 120 | 122 |
| 123 struct PP_CompletionCallback HelloWorldCallback = { HelloWorldCallback, NULL }; |
| 121 #endif | 124 #endif |
| 122 | 125 |
| 123 #ifdef STEP2 | 126 #ifdef STEP2 |
| 124 // The basic framework needed for all Native Client Modules. Handles creation | 127 // The basic framework needed for all Native Client Modules. Handles creation |
| 125 // of the module instance and initial handshake with the browser. | 128 // of the module instance and initial handshake with the browser. |
| 126 /** | 129 /** |
| 127 * Creates new string PP_Var from C string. Useful utility for | 130 * Creates new string PP_Var from C string. Useful utility for |
| 128 * message-handling. | 131 * message-handling. |
| 129 */ | 132 */ |
| 130 static struct PP_Var CStrToVar(const char* str) { if (ppb_var_interface != | 133 static struct PP_Var CStrToVar(const char* str) { if (ppb_var_interface != |
| 131 NULL) { return ppb_var_interface->VarFromUtf8(str, strlen(str)); } return | 134 NULL) { return ppb_var_interface->VarFromUtf8(str, strlen(str)); } return |
| 132 PP_MakeUndefined(); } | 135 PP_MakeUndefined(); } |
| 133 | 136 |
| 134 | 137 |
| 135 void initInstanceInBrowserWindow() { | 138 void InitInstanceInBrowserWindow() { |
| 136 // Pass the text to the browser page, there is no separate app window | 139 // Pass the text to the browser page, there is no separate app window |
| 137 // anymore. The text is added as a new element to the page, it does not | 140 // anymore. The text is added as a new element to the page, it does not |
| 138 // appear in the module's embed view. | 141 // appear in the module's embed view. |
| 139 ppb_messaging_interface->PostMessage(myInstance, CStrToVar("Hello, Native | 142 ppb_messaging_interface->PostMessage(myInstance, |
| 140 Client!")); } | 143 CStrToVar("Hello, Native Client!")); |
| 144 } |
| 141 | 145 |
| 142 /** | 146 /** |
| 143 * Called when the NaCl module is instantiated on the web page. | 147 * Called when the NaCl module is instantiated on the web page. |
| 144 */ | 148 */ |
| 145 static PP_Bool Instance_DidCreate(PP_Instance instance, | 149 static PP_Bool Instance_DidCreate(PP_Instance instance, |
| 146 uint32_t argc, | 150 uint32_t argc, |
| 147 const char* argn[], | 151 const char* argn[], |
| 148 const char* argv[]) { | 152 const char* argv[]) { |
| 149 myInstance = instance; | 153 myInstance = instance; |
| 150 ppb_messaging_interface->PostMessage(instance, | 154 ppb_messaging_interface->PostMessage(instance, |
| 151 CStrToVar("Start Instance_DidCreate")); | 155 CStrToVar("Start Instance_DidCreate")); |
| 152 #ifdef STEP5 | 156 #ifdef STEP5 |
| 153 // Will be included in STEP5 and STEP6 | 157 // Will be included in STEP5 and STEP6 |
| 154 // Uses messaging to relay text to the module's view on the web page | 158 // Uses messaging to relay text to the module's view on the web page |
| 155 initInstanceInBrowserWindow(); | 159 InitInstanceInBrowserWindow(); |
| 156 #else | 160 #else |
| 157 #ifdef STEP3 | 161 #ifdef STEP3 |
| 158 // Will be included in STEP3 and STEP4 only | 162 // Will be included in STEP3 and STEP4 only |
| 159 // Uses WndProc to place text in a window separate from the browser. | 163 // Uses WndProc to place text in a window separate from the browser. |
| 160 initInstanceInPCWindow(); | 164 InitInstanceInPCWindow(); |
| 161 #endif | 165 #endif |
| 162 #endif | 166 #endif |
| 163 | 167 |
| 164 ppb_messaging_interface->PostMessage(instance, | 168 ppb_messaging_interface->PostMessage(instance, |
| 165 CStrToVar("End Instance_DidCreate")); | 169 CStrToVar("End Instance_DidCreate")); |
| 166 return PP_TRUE; | 170 return PP_TRUE; |
| 167 } | 171 } |
| 168 | 172 |
| 169 /** | 173 /** |
| 170 * Called when the NaCl module is destroyed. | 174 * Called when the NaCl module is destroyed. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 192 * registered MIME types. This function is not called on NaCl modules. This | 196 * registered MIME types. This function is not called on NaCl modules. This |
| 193 * function is essentially a place-holder for the required function pointer in | 197 * function is essentially a place-holder for the required function pointer in |
| 194 * the PPP_Instance structure. | 198 * the PPP_Instance structure. |
| 195 */ | 199 */ |
| 196 static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, | 200 static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, |
| 197 PP_Resource url_loader) { | 201 PP_Resource url_loader) { |
| 198 /* NaCl modules do not need to handle the document load function. */ | 202 /* NaCl modules do not need to handle the document load function. */ |
| 199 return PP_FALSE; | 203 return PP_FALSE; |
| 200 } | 204 } |
| 201 | 205 |
| 202 | |
| 203 | |
| 204 /** | 206 /** |
| 205 * Entry points for the module. | 207 * Entry points for the module. |
| 206 * Initialize needed interfaces: PPB_Core, PPB_Messaging and PPB_Var. | 208 * Initialize needed interfaces: PPB_Core, PPB_Messaging and PPB_Var. |
| 207 */ | 209 */ |
| 208 PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, | 210 PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, |
| 209 PPB_GetInterface get_browser) { | 211 PPB_GetInterface get_browser) { |
| 210 ppb_messaging_interface = (PPB_Messaging*) | 212 ppb_messaging_interface = (PPB_Messaging*) |
| 211 get_browser(PPB_MESSAGING_INTERFACE); | 213 get_browser(PPB_MESSAGING_INTERFACE); |
| 212 ppb_var_interface = (PPB_Var*)get_browser(PPB_VAR_INTERFACE); | 214 ppb_var_interface = (PPB_Var*)get_browser(PPB_VAR_INTERFACE); |
| 213 ppb_core_interface = (PPB_Core*)get_browser(PPB_CORE_INTERFACE); | 215 ppb_core_interface = (PPB_Core*)get_browser(PPB_CORE_INTERFACE); |
| 214 return PP_OK; | 216 return PP_OK; |
| 215 } | 217 } |
| 216 | 218 |
| 217 | |
| 218 /** | 219 /** |
| 219 * Returns an interface pointer for the interface of the given name, or NULL | 220 * Returns an interface pointer for the interface of the given name, or NULL |
| 220 * if the interface is not supported. | 221 * if the interface is not supported. |
| 221 */ | 222 */ |
| 222 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { | 223 PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { |
| 223 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { | 224 if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { |
| 224 static PPP_Instance instance_interface = { | 225 static PPP_Instance instance_interface = { |
| 225 &Instance_DidCreate, | 226 &Instance_DidCreate, |
| 226 &Instance_DidDestroy, | 227 &Instance_DidDestroy, |
| 227 &Instance_DidChangeView, | 228 &Instance_DidChangeView, |
| 228 &Instance_DidChangeFocus, | 229 &Instance_DidChangeFocus, |
| 229 &Instance_HandleDocumentLoad, | 230 &Instance_HandleDocumentLoad, |
| 230 }; | 231 }; |
| 231 return &instance_interface; | 232 return &instance_interface; |
| 232 } | 233 } |
| 233 return NULL; | 234 return NULL; |
| 234 } | 235 } |
| 235 | 236 |
| 236 | |
| 237 /** | 237 /** |
| 238 * Called before the plugin module is unloaded. | 238 * Called before the plugin module is unloaded. |
| 239 */ | 239 */ |
| 240 PP_EXPORT void PPP_ShutdownModule() { | 240 PP_EXPORT void PPP_ShutdownModule() { |
| 241 } | 241 } |
| 242 #endif | 242 #endif |
| 243 | 243 |
| 244 | |
| 245 | |
| 246 // **** Application Code **** | 244 // **** Application Code **** |
| 247 | 245 |
| 248 #ifdef STEP1 | 246 #ifdef STEP1 |
| 249 // Desktop Windows Hello World app. Native Client agnostic. | 247 // Desktop Windows Hello World app. Native Client agnostic. |
| 250 | 248 |
| 251 static TCHAR szWindowClass[] = _T("win32app"); | 249 static TCHAR szWindowClass[] = _T("win32app"); |
| 252 static TCHAR szTitle[] = _T("HelloNaCl"); | 250 static TCHAR szTitle[] = _T("hello_nacl"); |
| 253 HINSTANCE hInst; | 251 HINSTANCE hInst; |
| 254 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); | 252 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); |
| 255 | 253 |
| 256 // WinMain | 254 // WinMain |
| 257 int WINAPI WinMain(HINSTANCE hInstance, | 255 int WINAPI WinMain(HINSTANCE hInstance, |
| 258 HINSTANCE hPrevInstance, | 256 HINSTANCE hPrevInstance, |
| 259 LPSTR lpCmdLine, | 257 LPSTR lpCmdLine, |
| 260 int nCmdShow) { | 258 int nCmdShow) { |
| 261 WNDCLASSEX wcex; | 259 WNDCLASSEX wcex; |
| 262 HWND hWnd; | 260 HWND hWnd; |
| 263 MSG msg; | 261 MSG msg; |
| 264 | 262 |
| 265 wcex.cbSize = sizeof(WNDCLASSEX); | 263 wcex.cbSize = sizeof(WNDCLASSEX); |
| 266 wcex.style = CS_HREDRAW | CS_VREDRAW; | 264 wcex.style = CS_HREDRAW | CS_VREDRAW; |
| 267 wcex.lpfnWndProc = WndProc; | 265 wcex.lpfnWndProc = WndProc; |
| 268 wcex.cbClsExtra = 0; | 266 wcex.cbClsExtra = 0; |
| 269 wcex.cbWndExtra = 0; | 267 wcex.cbWndExtra = 0; |
| 270 wcex.hInstance = hInstance; | 268 wcex.hInstance = hInstance; |
| 271 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); | 269 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); |
| 272 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); | 270 wcex.hCursor = LoadCursor(NULL, IDC_ARROW); |
| 273 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); | 271 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); |
| 274 wcex.lpszMenuName = NULL; | 272 wcex.lpszMenuName = NULL; |
| 275 wcex.lpszClassName = szWindowClass; | 273 wcex.lpszClassName = szWindowClass; |
| 276 wcex.hIconSm = LoadIcon(wcex.hInstance, | 274 wcex.hIconSm = LoadIcon(wcex.hInstance, |
| 277 MAKEINTRESOURCE(IDI_APPLICATION)); | 275 MAKEINTRESOURCE(IDI_APPLICATION)); |
| 278 | 276 |
| 279 if (!RegisterClassEx(&wcex)) { | 277 if (!RegisterClassEx(&wcex)) { |
| 280 MessageBox(NULL, | 278 MessageBox(NULL, |
| 281 _T("Call to RegisterClassEx failed!"), | 279 _T("Call to RegisterClassEx failed!"), |
| 282 _T("HelloNaCl"), | 280 _T("hello_nacl"), |
| 283 0); | 281 0); |
| 284 | 282 |
| 285 return 1; | 283 return 1; |
| 286 } | 284 } |
| 287 | 285 |
| 288 hInst = hInstance; | 286 hInst = hInstance; |
| 289 | 287 |
| 290 hWnd = CreateWindow( | 288 hWnd = CreateWindow( |
| 291 szWindowClass, | 289 szWindowClass, |
| 292 szTitle, | 290 szTitle, |
| 293 WS_OVERLAPPEDWINDOW, | 291 WS_OVERLAPPEDWINDOW, |
| 294 CW_USEDEFAULT, CW_USEDEFAULT, | 292 CW_USEDEFAULT, CW_USEDEFAULT, |
| 295 500, 100, | 293 500, 100, |
| 296 NULL, | 294 NULL, |
| 297 NULL, | 295 NULL, |
| 298 hInstance, | 296 hInstance, |
| 299 NULL | 297 NULL); |
| 300 ); | |
| 301 | 298 |
| 302 if (!hWnd) { | 299 if (!hWnd) { |
| 303 MessageBox(NULL, | 300 MessageBox(NULL, |
| 304 _T("Call to CreateWindow failed!"), | 301 _T("Call to CreateWindow failed!"), |
| 305 _T("HelloNaCl"), | 302 _T("hello_nacl"), |
| 306 0); | 303 0); |
| 307 | 304 |
| 308 return 1; | 305 return 1; |
| 309 } | 306 } |
| 310 | 307 |
| 311 ShowWindow(hWnd, nCmdShow); | 308 ShowWindow(hWnd, nCmdShow); |
| 312 UpdateWindow(hWnd); | 309 UpdateWindow(hWnd); |
| 313 | 310 |
| 314 // Main message loop: | 311 // Main message loop: |
| 315 | 312 |
| 316 while (GetMessage(&msg, NULL, 0, 0)) { | 313 while (GetMessage(&msg, NULL, 0, 0)) { |
| 317 TranslateMessage(&msg); | 314 TranslateMessage(&msg); |
| 318 DispatchMessage(&msg); | 315 DispatchMessage(&msg); |
| 319 } | 316 } |
| 320 | 317 |
| 321 return (int) msg.wParam; | 318 return (int) msg.wParam; |
| 322 } | 319 } |
| 323 | 320 |
| 324 // WndProc | 321 // WndProc |
| 325 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | 322 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, |
| 326 { | 323 WPARAM wParam, LPARAM lParam) { |
| 327 PAINTSTRUCT ps; | 324 PAINTSTRUCT ps; |
| 328 HDC hdc; | 325 HDC hdc; |
| 329 TCHAR greeting[] = _T("Hello, World!"); | 326 TCHAR greeting[] = _T("Hello, World!"); |
| 330 | 327 |
| 331 switch (message) { | 328 switch (message) { |
| 332 case WM_PAINT: | 329 case WM_PAINT: |
| 333 hdc = BeginPaint(hWnd, &ps); | 330 hdc = BeginPaint(hWnd, &ps); |
| 334 TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); | 331 TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); |
| 335 EndPaint(hWnd, &ps); | 332 EndPaint(hWnd, &ps); |
| 336 break; | 333 break; |
| 337 case WM_DESTROY: | 334 case WM_DESTROY: |
| 338 PostQuitMessage(0); | 335 PostQuitMessage(0); |
| 339 break; | 336 break; |
| 340 default: | 337 default: |
| 341 return DefWindowProc(hWnd, message, wParam, lParam); | 338 return DefWindowProc(hWnd, message, wParam, lParam); |
| 342 break; | 339 break; |
| 343 } | 340 } |
| 344 | 341 |
| 345 return 0; | 342 return 0; |
| 346 } | 343 } |
| 347 #endif | 344 #endif |
| 348 | 345 |
| 349 #ifdef STEP3 | 346 #ifdef STEP3 |
| 350 // Replace WinMain with initInstanceInPCWindow so the Native Client Module can | 347 // Replace WinMain with InitInstanceInPCWindow so the Native Client Module can |
| 351 // launch the original application. Note the inclusion of a message-handling | 348 // launch the original application. Note the inclusion of a message-handling |
| 352 // loop. STEP4 will replace the loop with a callback. | 349 // loop. STEP4 will replace the loop with a callback. |
| 353 HINSTANCE g_hInstance = NULL; HWND g_hWnd = NULL; int initInstanceInPCWindow() | 350 HINSTANCE g_hInstance = NULL; |
| 354 { WNDCLASSEX winClass; MSG uMsg; | 351 HWND g_hWnd = NULL; |
| 352 |
| 353 int InitInstanceInPCWindow() { |
| 354 WNDCLASSEX winClass; MSG uMsg; |
| 355 | 355 |
| 356 memset(&uMsg,0,sizeof(uMsg)); | 356 memset(&uMsg,0,sizeof(uMsg)); |
| 357 | 357 |
| 358 winClass.lpszClassName = _T("MY_WINDOWS_CLASS"); | 358 winClass.lpszClassName = _T("MY_WINDOWS_CLASS"); |
| 359 winClass.cbSize = sizeof(WNDCLASSEX); | 359 winClass.cbSize = sizeof(WNDCLASSEX); |
| 360 winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; | 360 winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; |
| 361 winClass.lpfnWndProc = WndProc; | 361 winClass.lpfnWndProc = WndProc; |
| 362 winClass.hInstance = g_hInstance; | 362 winClass.hInstance = g_hInstance; |
| 363 winClass.hIcon = NULL; | 363 winClass.hIcon = NULL; |
| 364 winClass.hIconSm = NULL; | 364 winClass.hIconSm = NULL; |
| 365 winClass.hCursor = LoadCursor(NULL, IDC_ARROW); | 365 winClass.hCursor = LoadCursor(NULL, IDC_ARROW); |
| 366 winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); | 366 winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); |
| 367 winClass.lpszMenuName = NULL; | 367 winClass.lpszMenuName = NULL; |
| 368 winClass.cbClsExtra = 0; | 368 winClass.cbClsExtra = 0; |
| 369 winClass.cbWndExtra = 0; | 369 winClass.cbWndExtra = 0; |
| 370 | 370 |
| 371 if (!RegisterClassEx(&winClass)) | 371 if (!RegisterClassEx(&winClass)) |
| 372 return E_FAIL; | 372 return E_FAIL; |
| 373 | 373 |
| 374 g_hWnd = CreateWindowEx(NULL, _T("MY_WINDOWS_CLASS"), | 374 g_hWnd = CreateWindowEx( |
| 375 _T("HelloNaCl"), | 375 NULL, _T("MY_WINDOWS_CLASS"), |
| 376 WS_OVERLAPPEDWINDOW, | 376 _T("hello_nacl"), WS_OVERLAPPEDWINDOW, |
| 377 0, 0, 640,480, NULL, NULL, g_hInstance, NULL); | 377 0, 0, 640, 480, NULL, NULL, g_hInstance, NULL); |
| 378 | 378 |
| 379 if (g_hWnd == NULL) | 379 if (g_hWnd == NULL) |
| 380 return E_FAIL; | 380 return E_FAIL; |
| 381 | 381 |
| 382 ShowWindow(g_hWnd, 1); | 382 ShowWindow(g_hWnd, 1); |
| 383 | 383 |
| 384 UpdateWindow(g_hWnd); | 384 UpdateWindow(g_hWnd); |
| 385 | 385 |
| 386 #ifdef STEP4 | 386 #ifdef STEP4 |
| 387 // Skip the message loop, schedule a callback instead to periodically check | 387 // Skip the message loop, schedule a callback instead to periodically check |
| 388 // for messages. Here we schedule at 100ms intervals. | 388 // for messages. Here we schedule at 100ms intervals. |
| 389 ppb_core_interface->CallOnMainThread(100, HelloWorldCallback, 0); | 389 ppb_core_interface->CallOnMainThread(100, HelloWorldCallback, 0); |
| 390 return 0; | 390 return 0; |
| 391 #else | 391 #else |
| 392 // Main message loop, Windows style. | 392 // Main message loop, Windows style. |
| 393 while(uMsg.message != WM_QUIT) { | 393 while(uMsg.message != WM_QUIT) { |
| 394 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) { | 394 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) { |
| 395 TranslateMessage( &uMsg ); | 395 TranslateMessage( &uMsg ); |
| 396 DispatchMessage( &uMsg ); | 396 DispatchMessage( &uMsg ); |
| 397 } | 397 } |
| 398 } | 398 } |
| 399 return uMsg.wParam; | 399 return uMsg.wParam; |
| 400 #endif | 400 #endif |
| 401 | 401 |
| 402 } | 402 } |
| 403 #endif | 403 #endif |
| OLD | NEW |