Mercurial > dwindows
comparison win/edge.cpp @ 2042:0d8b898b03e2
Win: Rewrite edge.cpp using C++ classes, EdgeBrowser and EdgeWebView.
This fixes issues with the IWebView2WebView members being out of scope
when I save and reload the pointer.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 24 Nov 2019 21:01:46 +0000 |
parents | 638be5b17715 |
children | 82e5c998df2e |
comparison
equal
deleted
inserted
replaced
2041:638be5b17715 | 2042:0d8b898b03e2 |
---|---|
20 #define _DW_HTML_DATA_RAW "_dw_edge_raw" | 20 #define _DW_HTML_DATA_RAW "_dw_edge_raw" |
21 | 21 |
22 extern "C" { | 22 extern "C" { |
23 | 23 |
24 /* Import the character conversion functions from dw.c */ | 24 /* Import the character conversion functions from dw.c */ |
25 LPWSTR _myUTF8toWide(const char *utf8string, void *outbuf); | 25 LPWSTR _myUTF8toWide(const char* utf8string, void* outbuf); |
26 char *_myWideToUTF8(LPCWSTR widestring, void *outbuf); | 26 char* _myWideToUTF8(LPCWSTR widestring, void* outbuf); |
27 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL) | 27 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL) |
28 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL) | 28 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL) |
29 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); | 29 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); |
30 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam); | 30 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam); |
31 IWebView2Environment *DW_EDGE_ENV = NULL; | 31 } |
32 | 32 |
33 class EdgeBrowser | |
34 { | |
35 public: | |
36 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); | |
37 BOOL Detect(VOID); | |
38 protected: | |
39 Microsoft::WRL::ComPtr<IWebView2Environment> Env; | |
40 }; | |
41 | |
42 class EdgeWebView | |
43 { | |
44 public: | |
45 VOID Action(int action); | |
46 int Raw(const char* string); | |
47 int URL(const char* url); | |
48 int JavascriptRun(const char* script, void* scriptdata); | |
49 VOID DoSize(VOID); | |
50 VOID Setup(HWND hwnd, IWebView2WebView* webview); | |
51 VOID Close(VOID); | |
52 protected: | |
53 HWND hWnd = nullptr; | |
54 Microsoft::WRL::ComPtr<IWebView2WebView> WebView; | |
55 }; | |
56 | |
57 LRESULT CALLBACK EdgeBrowser::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
58 { | |
59 switch (uMsg) | |
60 { | |
61 case WM_SIZE: | |
62 { | |
63 // Resize the browser object to fit the window | |
64 EdgeWebView *webview; | |
65 | |
66 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
67 // we initially attached the browser object to this window. | |
68 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); | |
69 // Resize WebView to fit the bounds of the parent window | |
70 if (webview) | |
71 webview->DoSize(); | |
72 return(0); | |
73 } | |
74 | |
75 case WM_PAINT: | |
76 { | |
77 PAINTSTRUCT ps; | |
78 HDC hdc = BeginPaint(hWnd, &ps); | |
79 EndPaint(hWnd, &ps); | |
80 return(0); | |
81 } | |
82 | |
83 case WM_CREATE: | |
84 { | |
85 // Step 3 - Create a single WebView within the parent window | |
86 // Create a WebView, whose parent is the main window hWnd | |
87 Env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>( | |
88 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT { | |
89 EdgeWebView* WebView = new EdgeWebView; | |
90 | |
91 WebView->Setup(hWnd, webview); | |
92 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(WebView)); | |
93 | |
94 // Add a few settings for the webview | |
95 // this is a redundant demo step as they are the default settings values | |
96 IWebView2Settings* Settings; | |
97 webview->get_Settings(&Settings); | |
98 Settings->put_IsScriptEnabled(TRUE); | |
99 Settings->put_AreDefaultScriptDialogsEnabled(TRUE); | |
100 Settings->put_IsWebMessageEnabled(TRUE); | |
101 | |
102 // Resize WebView to fit the bounds of the parent window | |
103 WebView->DoSize(); | |
104 | |
105 // Save the token, we might need to dw_window_set_data() this value | |
106 // for later use to remove the handlers | |
107 EventRegistrationToken token; | |
108 | |
109 // Register a handler for the NavigationStarting event. | |
110 webview->add_NavigationStarting( | |
111 Callback<IWebView2NavigationStartingEventHandler>( | |
112 [hWnd](IWebView2WebView* sender, | |
113 IWebView2NavigationStartingEventArgs* args) -> HRESULT | |
114 { | |
115 LPWSTR uri; | |
116 sender->get_Source(&uri); | |
117 | |
118 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED), | |
119 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
120 | |
121 return S_OK; | |
122 }).Get(), &token); | |
123 | |
124 // Register a handler for the DocumentStateChanged event. | |
125 webview->add_DocumentStateChanged( | |
126 Callback<IWebView2DocumentStateChangedEventHandler>( | |
127 [hWnd](IWebView2WebView* sender, | |
128 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT | |
129 { | |
130 LPWSTR uri; | |
131 sender->get_Source(&uri); | |
132 | |
133 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING), | |
134 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
135 | |
136 return S_OK; | |
137 }).Get(), &token); | |
138 | |
139 // Register a handler for the NavigationCompleted event. | |
140 webview->add_NavigationCompleted( | |
141 Callback<IWebView2NavigationCompletedEventHandler>( | |
142 [hWnd](IWebView2WebView* sender, | |
143 IWebView2NavigationCompletedEventArgs* args) -> HRESULT | |
144 { | |
145 LPWSTR uri; | |
146 sender->get_Source(&uri); | |
147 | |
148 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE), | |
149 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
150 | |
151 return S_OK; | |
152 }).Get(), &token); | |
153 | |
154 // Handle cached load requests due to delayed | |
155 // loading of the edge webview contexts | |
156 char *url = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION); | |
157 if (url) | |
158 { | |
159 WebView->URL(url); | |
160 free((void*)url); | |
161 } | |
162 char *raw = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW); | |
163 if (raw) | |
164 { | |
165 WebView->Raw(raw); | |
166 free((void*)raw); | |
167 } | |
168 return S_OK; | |
169 }).Get()); | |
170 // Success | |
171 return(0); | |
172 } | |
173 | |
174 case WM_DESTROY: | |
175 { | |
176 // Detach the browser object from this window, and free resources. | |
177 EdgeWebView *webview; | |
178 | |
179 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
180 // we initially attached the browser object to this window. | |
181 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); | |
182 if (webview) | |
183 { | |
184 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL); | |
185 webview->Close(); | |
186 delete webview; | |
187 } | |
188 _free_window_memory(hWnd, 0); | |
189 return(TRUE); | |
190 } | |
191 } | |
192 | |
193 return(DefWindowProc(hWnd, uMsg, wParam, lParam)); | |
194 } | |
195 | |
196 VOID EdgeWebView::DoSize(VOID) | |
197 { | |
198 RECT bounds; | |
199 | |
200 GetClientRect(hWnd, &bounds); | |
201 WebView->put_Bounds(bounds); | |
202 } | |
203 | |
204 BOOL EdgeBrowser::Detect(VOID) | |
205 { | |
206 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr, | |
207 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>( | |
208 [this](HRESULT result, IWebView2Environment* env) -> HRESULT { | |
209 // Successfully created Edge environment, return TRUE | |
210 Env = env; | |
211 return S_OK; | |
212 }).Get()); | |
213 return Env ? TRUE : FALSE; | |
214 } | |
215 | |
216 void EdgeWebView::Action(int action) | |
217 { | |
218 // We want to get the base address (ie, a pointer) to the IWebView2WebView object embedded within the browser | |
219 // object, so we can call some of the functions in the former's table. | |
220 if (WebView) | |
221 { | |
222 // Call the desired function | |
223 switch (action) | |
224 { | |
225 case DW_HTML_GOBACK: | |
226 { | |
227 // Call the IWebView2WebView object's GoBack function. | |
228 WebView->GoBack(); | |
229 break; | |
230 } | |
231 | |
232 case DW_HTML_GOFORWARD: | |
233 { | |
234 // Call the IWebView2WebView object's GoForward function. | |
235 WebView->GoForward(); | |
236 break; | |
237 } | |
238 | |
239 case DW_HTML_GOHOME: | |
240 { | |
241 // Call the IWebView2WebView object's GoHome function. | |
242 dw_html_url(hWnd, (char*)DW_HOME_URL); | |
243 break; | |
244 } | |
245 | |
246 case DW_HTML_SEARCH: | |
247 { | |
248 // Call the IWebView2WebView object's GoSearch function. | |
249 //WebView->GoSearch(); | |
250 break; | |
251 } | |
252 | |
253 case DW_HTML_RELOAD: | |
254 { | |
255 // Call the IWebView2WebView object's Refresh function. | |
256 WebView->Reload(); | |
257 } | |
258 | |
259 case DW_HTML_STOP: | |
260 { | |
261 // Call the IWebView2WebView object's Stop function. | |
262 //WebView->Stop(); | |
263 } | |
264 } | |
265 } | |
266 } | |
267 | |
268 int EdgeWebView::Raw(const char* string) | |
269 { | |
270 if (WebView) | |
271 WebView->NavigateToString(UTF8toWide(string)); | |
272 return DW_ERROR_NONE; | |
273 } | |
274 | |
275 int EdgeWebView::URL(const char* url) | |
276 { | |
277 if (WebView) | |
278 WebView->Navigate(UTF8toWide(url)); | |
279 return DW_ERROR_NONE; | |
280 } | |
281 | |
282 int EdgeWebView::JavascriptRun(const char* script, void* scriptdata) | |
283 { | |
284 HWND thishwnd = hWnd; | |
285 | |
286 if (WebView) | |
287 WebView->ExecuteScript(UTF8toWide(script), | |
288 Callback<IWebView2ExecuteScriptCompletedHandler>( | |
289 [thishwnd, scriptdata](HRESULT error, PCWSTR result) -> HRESULT | |
290 { | |
291 _wndproc(thishwnd, WM_USER + 100, (error == S_OK ? (WPARAM)WideToUTF8((LPWSTR)result) : NULL), (LPARAM)scriptdata); | |
292 return S_OK; | |
293 }).Get()); | |
294 return DW_ERROR_NONE; | |
295 } | |
296 | |
297 VOID EdgeWebView::Setup(HWND hwnd, IWebView2WebView* webview) | |
298 { | |
299 hWnd = hwnd; | |
300 WebView = webview; | |
301 } | |
302 | |
303 VOID EdgeWebView::Close(VOID) | |
304 { | |
305 if (WebView) | |
306 WebView->Close(); | |
307 } | |
308 | |
309 EdgeBrowser *DW_EDGE = NULL; | |
310 | |
311 extern "C" { | |
33 /******************************* dw_edge_detect() ************************** | 312 /******************************* dw_edge_detect() ************************** |
34 * Attempts to create a temporary Edge (Chromium) browser context... | 313 * Attempts to create a temporary Edge (Chromium) browser context... |
35 * If we succeed return TRUE and use Edge for HTML windows. | 314 * If we succeed return TRUE and use Edge for HTML windows. |
36 * If it fails return FALSE and fall back to using embedded IE. | 315 * If it fails return FALSE and fall back to using embedded IE. |
37 */ | 316 */ |
38 BOOL _dw_edge_detect(VOID) | 317 BOOL _dw_edge_detect(VOID) |
39 { | 318 { |
40 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr, | 319 DW_EDGE = new EdgeBrowser; |
41 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>( | 320 if (DW_EDGE) |
42 [](HRESULT result, IWebView2Environment* env) -> HRESULT { | 321 { |
43 // Successfully created Edge environment, return TRUE | 322 BOOL result = DW_EDGE->Detect(); |
44 DW_EDGE_ENV = env; | 323 if (!result) |
45 return S_OK; | 324 { |
46 }).Get()); | 325 delete DW_EDGE; |
47 return DW_EDGE_ENV ? TRUE : FALSE; | 326 DW_EDGE = NULL; |
327 } | |
328 return result; | |
329 } | |
330 return FALSE; | |
48 } | 331 } |
49 | 332 |
50 /******************************* dw_edge_action() ************************** | 333 /******************************* dw_edge_action() ************************** |
51 * Implements the functionality of a "Back". "Forward", "Home", "Search", | 334 * Implements the functionality of a "Back". "Forward", "Home", "Search", |
52 * "Refresh", or "Stop" button. | 335 * "Refresh", or "Stop" button. |
61 * 5 = Stop the currently loading page. | 344 * 5 = Stop the currently loading page. |
62 */ | 345 */ |
63 | 346 |
64 void _dw_edge_action(HWND hwnd, int action) | 347 void _dw_edge_action(HWND hwnd, int action) |
65 { | 348 { |
66 IWebView2WebView* webview; | 349 EdgeWebView* webview = (EdgeWebView *)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); |
67 | 350 if (webview) |
68 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | 351 webview->Action(action); |
69 // we initially attached the browser object to this window. | |
70 webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); | |
71 | |
72 // We want to get the base address (ie, a pointer) to the IWebView2WebView object embedded within the browser | |
73 // object, so we can call some of the functions in the former's table. | |
74 if (webview) | |
75 { | |
76 // Call the desired function | |
77 switch (action) | |
78 { | |
79 case DW_HTML_GOBACK: | |
80 { | |
81 // Call the IWebView2WebView object's GoBack function. | |
82 webview->GoBack(); | |
83 break; | |
84 } | |
85 | |
86 case DW_HTML_GOFORWARD: | |
87 { | |
88 // Call the IWebView2WebView object's GoForward function. | |
89 webview->GoForward(); | |
90 break; | |
91 } | |
92 | |
93 case DW_HTML_GOHOME: | |
94 { | |
95 // Call the IWebView2WebView object's GoHome function. | |
96 dw_html_url(hwnd, (char *)DW_HOME_URL); | |
97 break; | |
98 } | |
99 | |
100 case DW_HTML_SEARCH: | |
101 { | |
102 // Call the IWebView2WebView object's GoSearch function. | |
103 //webview->GoSearch(); | |
104 break; | |
105 } | |
106 | |
107 case DW_HTML_RELOAD: | |
108 { | |
109 // Call the IWebView2WebView object's Refresh function. | |
110 webview->Reload(); | |
111 } | |
112 | |
113 case DW_HTML_STOP: | |
114 { | |
115 // Call the IWebView2WebView object's Stop function. | |
116 //webview->Stop(); | |
117 } | |
118 } | |
119 } | |
120 } | 352 } |
121 | 353 |
122 /******************************* dw_edge_raw() **************************** | 354 /******************************* dw_edge_raw() **************************** |
123 * Takes a string containing some HTML BODY, and displays it in the specified | 355 * Takes a string containing some HTML BODY, and displays it in the specified |
124 * window. For example, perhaps you want to display the HTML text of... | 356 * window. For example, perhaps you want to display the HTML text of... |
130 * (NOTE: No <BODY></BODY> tags are required in the string). | 362 * (NOTE: No <BODY></BODY> tags are required in the string). |
131 * | 363 * |
132 * RETURNS: 0 if success, or non-zero if an error. | 364 * RETURNS: 0 if success, or non-zero if an error. |
133 */ | 365 */ |
134 | 366 |
135 int _dw_edge_raw(HWND hwnd, const char *string) | 367 int _dw_edge_raw(HWND hwnd, const char* string) |
136 { | 368 { |
137 IWebView2WebView* webview; | 369 EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); |
138 | 370 if (webview) |
139 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | 371 return webview->Raw(string); |
140 // we initially attached the browser object to this window. | |
141 webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); | |
142 | |
143 if (webview) | |
144 webview->NavigateToString(UTF8toWide(string)); | |
145 else | 372 else |
146 dw_window_set_data(hwnd, _DW_HTML_DATA_RAW, _wcsdup(UTF8toWide(string))); | 373 dw_window_set_data(hwnd, _DW_HTML_DATA_RAW, strdup(string)); |
147 return DW_ERROR_NONE; | 374 return DW_ERROR_NONE; |
148 } | 375 } |
149 | 376 |
150 /******************************* dw_edge_url() **************************** | 377 /******************************* dw_edge_url() **************************** |
151 * Displays a URL, or HTML file on disk. | 378 * Displays a URL, or HTML file on disk. |
154 * url = Pointer to nul-terminated name of the URL/file. | 381 * url = Pointer to nul-terminated name of the URL/file. |
155 * | 382 * |
156 * RETURNS: 0 if success, or non-zero if an error. | 383 * RETURNS: 0 if success, or non-zero if an error. |
157 */ | 384 */ |
158 | 385 |
159 int _dw_edge_url(HWND hwnd, const char *url) | 386 int _dw_edge_url(HWND hwnd, const char* url) |
160 { | 387 { |
161 IWebView2WebView* webview; | 388 EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); |
162 | 389 if (webview) |
163 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | 390 return webview->URL(url); |
164 // we initially attached the browser object to this window. | |
165 webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); | |
166 | |
167 if (webview) | |
168 webview->Navigate(UTF8toWide(url)); | |
169 else | 391 else |
170 dw_window_set_data(hwnd, _DW_HTML_DATA_LOCATION, _wcsdup(UTF8toWide(url))); | 392 dw_window_set_data(hwnd, _DW_HTML_DATA_LOCATION, strdup(url)); |
171 return DW_ERROR_NONE; | 393 return DW_ERROR_NONE; |
172 } | 394 } |
173 | 395 |
174 /******************************* dw_edge_javascript_run() **************************** | 396 /******************************* dw_edge_javascript_run() **************************** |
175 * Runs a javascript in the specified browser context. | 397 * Runs a javascript in the specified browser context. |
179 * scriptdata = Pointer to user data to be passed to the callback. | 401 * scriptdata = Pointer to user data to be passed to the callback. |
180 * | 402 * |
181 * RETURNS: 0 if success, or non-zero if an error. | 403 * RETURNS: 0 if success, or non-zero if an error. |
182 */ | 404 */ |
183 | 405 |
184 int _dw_edge_javascript_run(HWND hwnd, const char *script, void *scriptdata) | 406 int _dw_edge_javascript_run(HWND hwnd, const char* script, void* scriptdata) |
185 { | 407 { |
186 IWebView2WebView* webview; | 408 EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); |
187 | 409 if (webview) |
188 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | 410 return webview->JavascriptRun(script, scriptdata); |
189 // we initially attached the browser object to this window. | 411 return DW_ERROR_UNKNOWN; |
190 webview = (IWebView2WebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); | |
191 | |
192 if (webview) | |
193 webview->ExecuteScript(UTF8toWide(script), | |
194 Callback<IWebView2ExecuteScriptCompletedHandler>( | |
195 [hwnd, scriptdata](HRESULT error, PCWSTR result) -> HRESULT | |
196 { | |
197 _wndproc(hwnd, WM_USER + 100, (error == S_OK ? (WPARAM)WideToUTF8((LPWSTR)result) : NULL), (LPARAM)scriptdata); | |
198 return S_OK; | |
199 }).Get()); | |
200 return DW_ERROR_NONE; | |
201 } | 412 } |
202 | 413 |
203 /************************** edgeWindowProc() ************************* | 414 /************************** edgeWindowProc() ************************* |
204 * Our message handler for our window to host the browser. | 415 * Our message handler for our window to host the browser. |
205 */ | 416 */ |
206 | 417 |
207 LRESULT CALLBACK _edgeWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | 418 LRESULT CALLBACK _edgeWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
208 { | 419 { |
209 switch (uMsg) | 420 if (DW_EDGE) |
210 { | 421 return DW_EDGE->WndProc(hWnd, uMsg, wParam, lParam); |
211 case WM_SIZE: | 422 return DefWindowProc(hWnd, uMsg, wParam, lParam); |
212 { | 423 } |
213 // Resize the browser object to fit the window | 424 } |
214 IWebView2WebView* webview; | |
215 | |
216 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
217 // we initially attached the browser object to this window. | |
218 webview = (IWebView2WebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); | |
219 // Resize WebView to fit the bounds of the parent window | |
220 if (webview) | |
221 { | |
222 RECT bounds; | |
223 | |
224 GetClientRect(hWnd, &bounds); | |
225 webview->put_Bounds(bounds); | |
226 } | |
227 return(0); | |
228 } | |
229 | |
230 case WM_PAINT: | |
231 { | |
232 PAINTSTRUCT ps; | |
233 HDC hdc = BeginPaint(hWnd, &ps); | |
234 EndPaint(hWnd, &ps); | |
235 return(0); | |
236 } | |
237 | |
238 case WM_CREATE: | |
239 { | |
240 // Step 3 - Create a single WebView within the parent window | |
241 // Create a WebView, whose parent is the main window hWnd | |
242 DW_EDGE_ENV->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>( | |
243 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT { | |
244 if (webview != nullptr) { | |
245 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(webview)); | |
246 } | |
247 | |
248 // Add a few settings for the webview | |
249 // this is a redundant demo step as they are the default settings values | |
250 IWebView2Settings* Settings; | |
251 webview->get_Settings(&Settings); | |
252 Settings->put_IsScriptEnabled(TRUE); | |
253 Settings->put_AreDefaultScriptDialogsEnabled(TRUE); | |
254 Settings->put_IsWebMessageEnabled(TRUE); | |
255 | |
256 // Resize WebView to fit the bounds of the parent window | |
257 RECT bounds; | |
258 GetClientRect(hWnd, &bounds); | |
259 webview->put_Bounds(bounds); | |
260 | |
261 // Save the token, we might need to dw_window_set_data() this value | |
262 // for later use to remove the handlers | |
263 EventRegistrationToken token; | |
264 | |
265 // Register a handler for the NavigationStarting event. | |
266 webview->add_NavigationStarting( | |
267 Callback<IWebView2NavigationStartingEventHandler>( | |
268 [hWnd](IWebView2WebView* sender, | |
269 IWebView2NavigationStartingEventArgs* args) -> HRESULT | |
270 { | |
271 LPWSTR uri; | |
272 sender->get_Source(&uri); | |
273 | |
274 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED), | |
275 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
276 | |
277 return S_OK; | |
278 }).Get(), &token); | |
279 | |
280 // Register a handler for the DocumentStateChanged event. | |
281 webview->add_DocumentStateChanged( | |
282 Callback<IWebView2DocumentStateChangedEventHandler>( | |
283 [hWnd](IWebView2WebView* sender, | |
284 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT | |
285 { | |
286 LPWSTR uri; | |
287 sender->get_Source(&uri); | |
288 | |
289 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING), | |
290 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
291 | |
292 return S_OK; | |
293 }).Get(), &token); | |
294 | |
295 // Register a handler for the NavigationCompleted event. | |
296 webview->add_NavigationCompleted( | |
297 Callback<IWebView2NavigationCompletedEventHandler>( | |
298 [hWnd](IWebView2WebView* sender, | |
299 IWebView2NavigationCompletedEventArgs* args) -> HRESULT | |
300 { | |
301 LPWSTR uri; | |
302 sender->get_Source(&uri); | |
303 | |
304 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE), | |
305 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); | |
306 | |
307 return S_OK; | |
308 }).Get(), &token); | |
309 | |
310 // Handle cached load requests due to delayed | |
311 // loading of the edge webview contexts | |
312 LPCWSTR url = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION); | |
313 if(url) | |
314 { | |
315 webview->Navigate(url); | |
316 free((void *)url); | |
317 } | |
318 LPCWSTR raw = (LPCWSTR)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW); | |
319 if (raw) | |
320 { | |
321 webview->NavigateToString(raw); | |
322 free((void *)raw); | |
323 } | |
324 return S_OK; | |
325 }).Get()); | |
326 // Success | |
327 return(0); | |
328 } | |
329 | |
330 case WM_DESTROY: | |
331 { | |
332 // Detach the browser object from this window, and free resources. | |
333 IWebView2WebView* webview; | |
334 | |
335 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
336 // we initially attached the browser object to this window. | |
337 webview = (IWebView2WebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); | |
338 if (webview) | |
339 { | |
340 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL); | |
341 webview->Close(); | |
342 } | |
343 _free_window_memory(hWnd, 0); | |
344 return(TRUE); | |
345 } | |
346 } | |
347 | |
348 return(DefWindowProc(hWnd, uMsg, wParam, lParam)); | |
349 } | |
350 } |