Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: visual_studio/NativeClientVSAddIn/InstallerResources/examples/hello_nacl_cpp/hello_nacl_cpp/hello_nacl_cpp.cpp

Issue 11191009: Add new VS AddIn examples. (Closed) Base URL: http://nativeclient-sdk.googlecode.com/svn/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // 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
3 // plugin (define STEP2 through STEP6), and finally as a Native Client module.
4
5 // 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
7 // previous ones on. Ready, set, port!
8
9 // *** SELECT THE WIN32 PLATFORM AND RUN WITH #define STEP1 ONLY ***
10
11 #define STEP1
12 // Launches the original Windows desktop application, Hello World, which runs
13 // 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
15 // port is finished (STEP6)
16
17 // *** SELECT THE PPAPI PLATFORM ***
18
19 #define STEP2
20
21 // Client Module. STEP2 encloses the Native Client module APIs needed to link
22 // any app to the browser. The module does nothing except report
23 // starting/ending the function Instance_DidCreate. The Windows app does not
24 // run because it is not being called.
25
26 #define STEP3
27 // What changed: Replace WinMain with WndProc, and call it from
28 // Instance_DidCreate, launching hello_nacl_plus in its own window. Since
29 // WndProc spins in its message loop, the call to Instance_DidCreate never
30 // returns. Close the hello_nacl_plus window and the module initialization will
31 // finish.
32
33 #define STEP4
34 // 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.
36
37 #define STEP5
38 // What changed: Instance_DidCreate calls initInstanceInBrowserWindow rather
39 // than initInstanceInPCWindow. The initInstanceInBrowserWindow uses
40 // postMessage to place text (now "Hello, Native Client") in the web page
41 // instead of opening and writing to a window.
42
43 #define STEP6
44 // 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.
46
47 // *** SELECT THE NACL64 PLATFORM AND RUN ***
48
49 // 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
51 // Native Client executable in a NaCl sandbox, with nacl-gdb attached.
52
53 // *** RUN YOUR MODULE IN THE WILD ***
54 // You can run your nexe outside of Visual Studio, directly from Chrome by
55 // following these steps:
56 // - Build STEP6 and verify the file
57 // <project directory>/newlib/hello_nacl_plus/hello_nacl_plus.nexe exists
58 // - Copy the folder <project directory>/hello_nacl_plus into your NaCl SDK's
59 // example directory.
60 // - 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
62 // relaunch Chrome
63 // - Point Chrome at localhost:5103/hello_nacl_plus
64
65 #ifdef STEP6
66 // remove Windows-dependent code.
67 #undef STEP1
68 #undef STEP3
69 #undef STEP4
70 #define NULL 0
71 #else
72 // includes for Windows APIs.
73 #include <windows.h>
74 #include <stdlib.h>
75 #include <tchar.h>
76 #endif
77
78 #ifdef STEP2
79 // includes for PPAPI C++
80 #include "ppapi/cpp/instance.h"
81 #include "ppapi/cpp/module.h"
82 #include "ppapi/cpp/var.h"
83 #include "ppapi/cpp/core.h"
84 #include "ppapi/cpp/completion_callback.h"
85 #include "ppapi/utility/completion_callback_factory.h"
86
87 // This is a known PPAPI platform problem (Issue 81375).
88 // When WinUser.h is included it defines PostMessage, so we undef it here.
89 // There is a work-around:
90 #ifdef PostMessage
91 #undef PostMessage
92 #endif
93
94 class NaClProjectInstance *myInstance;
95 int initInstanceInPCWindow();
96 void initInstanceInBrowserWindow();
97
98 #endif
99
100 #ifdef STEP2
101
102 // **** Native Client Framework ****
103
104 // The Instance class.
105 class NaClProjectInstance : public pp::Instance {
106 public:
107 pp::CompletionCallbackFactory<NaClProjectInstance> factory_;
108
109 explicit NaClProjectInstance(PP_Instance instance)
110 : pp::Instance(instance),
111 // Use this macro to eliminate compiler warning.
112 PP_ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
113 myInstance = this;
114 }
115
116
117 virtual ~NaClProjectInstance() {
118 }
119
120 virtual bool Init(uint32_t /*argc*/, const char* /*argn*/[],
121 const char* /*argv*/[]) {
122 PostMessage(pp::Var("Creating Instance Start"));
123 #ifdef STEP5
124 // Will be included in STEP5 and STEP6
125 // Uses messaging to relay text to the module's view on the web page
126 initInstanceInBrowserWindow();
127 #else
128 #ifdef STEP3
129 // Will be included in STEP3 and STEP4 only
130 // Uses WndProc to place text in a window separate from the browser.
131 initInstanceInPCWindow();
132 #endif
133 #endif
134 PostMessage(pp::Var("Creating Instance End"));
135 return true;
136 }
137
138 #ifdef STEP4
139 // Implements Windows window message loop with a callback function.
140 void NaClProjectInstance::SendCallback(int result) {
141 pp::Core* core = pp::Module::Get()->core();
142 CompletionCallback callback = factory_.NewCallback(&HandleWindowMsg);
143 core->CallOnMainThread(100, callbacl, result);
144 }
145
146 void HandleWindowMsg(int32_t result) {
147 MSG uMsg;
148 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) {
149 TranslateMessage(&uMsg);
150 DispatchMessage(&uMsg);
151 }
152 SendCallback(0);
153 }
154
155 #endif
156 private:
157 virtual void HandleMessage(const pp::Var& var_message) {
158 }
159 };
160
161 // The Module class.
162 class NaClProjectModule : public pp::Module {
163 public:
164 NaClProjectModule() : pp::Module() {}
165 virtual ~NaClProjectModule() {}
166
167 virtual pp::Instance* CreateInstance(PP_Instance instance) {
168 return new NaClProjectInstance(instance);
169 }
170 };
171
172 namespace pp {
173 Module* CreateModule() {
174 return new NaClProjectModule();
175 }
176 }
177
178 #endif
179
180 // **** Application Code ****
181
182 #ifdef STEP1
183 // Desktop Windows Hello World app. Native Client agnostic.
184
185 static TCHAR szWindowClass[] = _T("win32app");
186 static TCHAR szTitle[] = _T("hello_nacl_plus");
187 HINSTANCE hInst;
188 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
189
190 // WinMain
191 int WINAPI WinMain(HINSTANCE hInstance,
192 HINSTANCE hPrevInstance,
193 LPSTR lpCmdLine,
194 int nCmdShow)
195 {
196 WNDCLASSEX wcex;
197
198 wcex.cbSize = sizeof(WNDCLASSEX);
199 wcex.style = CS_HREDRAW | CS_VREDRAW;
200 wcex.lpfnWndProc = WndProc;
201 wcex.cbClsExtra = 0;
202 wcex.cbWndExtra = 0;
203 wcex.hInstance = hInstance;
204 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
205 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
206 wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
207 wcex.lpszMenuName = NULL;
208 wcex.lpszClassName = szWindowClass;
209 wcex.hIconSm = LoadIcon(wcex.hInstance,
210 MAKEINTRESOURCE(IDI_APPLICATION));
211
212 if (!RegisterClassEx(&wcex)) {
213 MessageBox(NULL,
214 _T("Call to RegisterClassEx failed!"),
215 _T("hello_nacl_plus"),
216 NULL);
217
218 return 1;
219 }
220
221 hInst = hInstance;
222
223 HWND hWnd = CreateWindow(
224 szWindowClass,
225 szTitle,
226 WS_OVERLAPPEDWINDOW,
227 CW_USEDEFAULT, CW_USEDEFAULT,
228 500, 100,
229 NULL,
230 NULL,
231 hInstance,
232 NULL);
233
234 if (!hWnd) {
235 MessageBox(NULL,
236 _T("Call to CreateWindow failed!"),
237 _T("hello_nacl_plus"),
238 NULL);
239
240 return 1;
241 }
242
243 ShowWindow(hWnd,
244 nCmdShow);
245 UpdateWindow(hWnd);
246
247 // Main message loop:
248 MSG msg;
249 while (GetMessage(&msg, NULL, 0, 0)) {
250 TranslateMessage(&msg);
251 DispatchMessage(&msg);
252 }
253
254 return (int) msg.wParam;
255 }
256
257 // WndProc
258 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
259 {
260 PAINTSTRUCT ps;
261 HDC hdc;
262 TCHAR greeting[] = _T("Hello, World!");
263
264 switch (message)
265 {
266 case WM_PAINT:
267 hdc = BeginPaint(hWnd, &ps);
268
269 // Here your application is laid out.
270 // For this introduction, we just print out "Hello, World!"
271 // in the top left corner.
272 TextOut(hdc,
273 5, 5,
274 greeting, _tcslen(greeting));
275 // End application-specific layout section.
276
277 EndPaint(hWnd, &ps);
278 break;
279 case WM_DESTROY:
280 PostQuitMessage(0);
281 break;
282 default:
283 return DefWindowProc(hWnd, message, wParam, lParam);
284 break;
285 }
286
287 return 0;
288 }
289 #endif
290
291 #ifdef STEP3
292 // Replace WinMain with initInstanceInPCWindow so the NativeClient Module can
293 // launch the original application.
294 // Note the inclusion of a message-handling loop. STEP4 will replace the loop
295 // with a callback.
296
297 void shutDown(void);
298 HINSTANCE g_hInstance = NULL;
299 HWND g_hWnd = NULL;
300
301 int initInstanceInPCWindow()
302 {
303 WNDCLASSEX winClass;
304 MSG uMsg;
305
306 memset(&uMsg,0,sizeof(uMsg));
307
308 winClass.lpszClassName = _T("MY_WINDOWS_CLASS");
309 winClass.cbSize = sizeof(WNDCLASSEX);
310 winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
311 winClass.lpfnWndProc = WndProc;
312 winClass.hInstance = g_hInstance;
313 winClass.hIcon = NULL;
314 winClass.hIconSm = NULL;
315 winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
316 winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
317 winClass.lpszMenuName = NULL;
318 winClass.cbClsExtra = 0;
319 winClass.cbWndExtra = 0;
320
321 if (!RegisterClassEx(&winClass))
322 return E_FAIL;
323
324 g_hWnd = CreateWindowEx(NULL,_T("MY_WINDOWS_CLASS"),
325 _T("hello_nacl_plus"),
326 WS_OVERLAPPEDWINDOW,
327 0,0, 640, 480, NULL, NULL, g_hInstance, NULL);
328
329 if (g_hWnd == NULL)
330 return E_FAIL;
331
332 ShowWindow(g_hWnd, 1);
333
334 UpdateWindow(g_hWnd);
335
336 #ifdef STEP4
337 // Skip the message loop, schedule a callback instead to periodically check
338 // for messages. Here we schedule at 100ms intervals.
339 myInstance->SendCallback(0);
340 return 0;
341 #else
342 // Main message loop, Windows style.
343 while(uMsg.message != WM_QUIT) {
344 if (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE)) {
345 TranslateMessage(&uMsg);
346 DispatchMessage(&uMsg);
347 }
348 }
349 return uMsg.wParam;
350 #endif
351
352 }
353 #endif
354
355 #ifdef STEP5
356 // Pass the text to the browser page, there is no separate app window anymore.
357 // The text is added as a new element to the page, it does not appear in the
358 // module's embed view.
359 void initInstanceInBrowserWindow() {
360 myInstance->PostMessage(pp::Var("Hello, Native Client!"));
361 }
362 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698