Mercurial > dwindows
comparison win/edge.cpp @ 1999:4e808c4cadfb
Win: Add initial support for Microsoft Edge (Chromium) embedding.
Only works with Visual Studio currently due to the SDK being a nuget package.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Thu, 31 Oct 2019 07:01:35 +0000 |
parents | |
children | 77e43d71eaa7 |
comparison
equal
deleted
inserted
replaced
1998:a3de27b07a8d | 1999:4e808c4cadfb |
---|---|
1 /* edge.cpp | |
2 * | |
3 * Allows dw_html_new() to embed a Microsoft Edge (Chromium) browser. | |
4 * | |
5 * Requires Windows 10, 8 or 7 with Microsoft Edge (Chromium) installed. | |
6 * | |
7 * Only included when BUILD_EDGE is defined, will fall back to embedded IE. | |
8 * | |
9 * Currently only buildable with Visual Studio since it requires the EDGE | |
10 * SDK which is currently distributed as a nuget package. | |
11 */ | |
12 #include "dw.h" | |
13 #include "webview2.h" | |
14 | |
15 #define _DW_HTML_DATA_NAME (char *)"_dw_edge" | |
16 | |
17 BOOL _dw_edge_detect(VOID) | |
18 { | |
19 return TRUE; | |
20 } | |
21 | |
22 /******************************* dw_html_action() ************************** | |
23 * Implements the functionality of a "Back". "Forward", "Home", "Search", | |
24 * "Refresh", or "Stop" button. | |
25 * | |
26 * hwnd = Handle to the window hosting the browser object. | |
27 * action = One of the following: | |
28 * 0 = Move back to the previously viewed web page. | |
29 * 1 = Move forward to the previously viewed web page. | |
30 * 2 = Move to the home page. | |
31 * 3 = Search. | |
32 * 4 = Refresh the page. | |
33 * 5 = Stop the currently loading page. | |
34 * | |
35 * NOTE: EmbedBrowserObject() must have been successfully called once with the | |
36 * specified window, prior to calling this function. You need call | |
37 * EmbedBrowserObject() once only, and then you can make multiple calls to | |
38 * this function to display numerous pages in the specified window. | |
39 */ | |
40 | |
41 void _dw_edge_action(HWND hwnd, int action) | |
42 { | |
43 IWebView2WebView* webview; | |
44 | |
45 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
46 // we initially attached the browser object to this window. | |
47 | |
48 webview = *((IWebView2WebView**)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME)); | |
49 // We want to get the base address (ie, a pointer) to the IWebBrowser2 object embedded within the browser | |
50 // object, so we can call some of the functions in the former's table. | |
51 if (webview) | |
52 { | |
53 // Ok, now the pointer to our IWebBrowser2 object is in 'webBrowser2', and so its VTable is | |
54 // webBrowser2->lpVtbl. | |
55 | |
56 // Call the desired function | |
57 switch (action) | |
58 { | |
59 case DW_HTML_GOBACK: | |
60 { | |
61 // Call the IWebBrowser2 object's GoBack function. | |
62 webview->GoBack(); | |
63 break; | |
64 } | |
65 | |
66 case DW_HTML_GOFORWARD: | |
67 { | |
68 // Call the IWebBrowser2 object's GoForward function. | |
69 webview->GoForward(); | |
70 break; | |
71 } | |
72 | |
73 case DW_HTML_GOHOME: | |
74 { | |
75 // Call the IWebBrowser2 object's GoHome function. | |
76 //webview->GoHome(); | |
77 break; | |
78 } | |
79 | |
80 case DW_HTML_SEARCH: | |
81 { | |
82 // Call the IWebBrowser2 object's GoSearch function. | |
83 //webview->GoSearch(); | |
84 break; | |
85 } | |
86 | |
87 case DW_HTML_RELOAD: | |
88 { | |
89 // Call the IWebBrowser2 object's Refresh function. | |
90 webview->Reload(); | |
91 } | |
92 | |
93 case DW_HTML_STOP: | |
94 { | |
95 // Call the IWebBrowser2 object's Stop function. | |
96 //webview->Stop(); | |
97 } | |
98 } | |
99 } | |
100 } | |
101 | |
102 /******************************* dw_html_raw() **************************** | |
103 * Takes a string containing some HTML BODY, and displays it in the specified | |
104 * window. For example, perhaps you want to display the HTML text of... | |
105 * | |
106 * <P>This is a picture.<P><IMG src="mypic.jpg"> | |
107 * | |
108 * hwnd = Handle to the window hosting the browser object. | |
109 * string = Pointer to nul-terminated string containing the HTML BODY. | |
110 * (NOTE: No <BODY></BODY> tags are required in the string). | |
111 * | |
112 * RETURNS: 0 if success, or non-zero if an error. | |
113 * | |
114 * NOTE: EmbedBrowserObject() must have been successfully called once with the | |
115 * specified window, prior to calling this function. You need call | |
116 * EmbedBrowserObject() once only, and then you can make multiple calls to | |
117 * this function to display numerous pages in the specified window. | |
118 */ | |
119 | |
120 int _dw_edge_raw(HWND hwnd, LPCWSTR string) | |
121 { | |
122 IWebView2WebView* webview; | |
123 | |
124 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
125 // we initially attached the browser object to this window. | |
126 webview = *((IWebView2WebView**)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME)); | |
127 | |
128 if (webview) | |
129 { | |
130 return DW_ERROR_NONE; | |
131 } | |
132 return DW_ERROR_UNKNOWN; | |
133 } | |
134 | |
135 /******************************* dw_html_url() **************************** | |
136 * Displays a URL, or HTML file on disk. | |
137 * | |
138 * hwnd = Handle to the window hosting the browser object. | |
139 * webPageName = Pointer to nul-terminated name of the URL/file. | |
140 * | |
141 * RETURNS: 0 if success, or non-zero if an error. | |
142 * | |
143 * NOTE: EmbedBrowserObject() must have been successfully called once with the | |
144 * specified window, prior to calling this function. You need call | |
145 * EmbedBrowserObject() once only, and then you can make multiple calls to | |
146 * this function to display numerous pages in the specified window. | |
147 */ | |
148 | |
149 int _dw_edge_url(HWND hwnd, LPCWSTR url) | |
150 { | |
151 IWebView2WebView * webview; | |
152 | |
153 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
154 // we initially attached the browser object to this window. | |
155 webview = *((IWebView2WebView**)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME)); | |
156 | |
157 if (webview) | |
158 { | |
159 webview->Navigate(url); | |
160 return DW_ERROR_NONE; | |
161 } | |
162 return DW_ERROR_UNKNOWN; | |
163 } | |
164 | |
165 /************************** browserWindowProc() ************************* | |
166 * Our message handler for our window to host the browser. | |
167 */ | |
168 | |
169 LRESULT CALLBACK _edgeWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
170 { | |
171 switch (uMsg) | |
172 { | |
173 case WM_SIZE: | |
174 { | |
175 // Resize the browser object to fit the window | |
176 RECT bounds; | |
177 IWebView2WebView* 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 = *((IWebView2WebView**)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME)); | |
182 GetClientRect(hWnd, &bounds); | |
183 // Resize WebView to fit the bounds of the parent window | |
184 if(webview) | |
185 webview->put_Bounds(bounds); | |
186 return(0); | |
187 } | |
188 | |
189 case WM_CREATE: | |
190 { | |
191 // Step 3 - Create a single WebView within the parent window | |
192 // Locate the browser and set up the environment for WebView | |
193 CreateWebView2EnvironmentWithDetails(nullptr, nullptr, nullptr, | |
194 Callback<IWebView2CreateWebView2EnvironmentCompletedHandler>( | |
195 [hWnd](HRESULT result, IWebView2Environment* env) -> HRESULT { | |
196 | |
197 // Create a WebView, whose parent is the main window hWnd | |
198 env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>( | |
199 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT { | |
200 if (webview != nullptr) { | |
201 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(webview)); | |
202 } | |
203 | |
204 // Add a few settings for the webview | |
205 // this is a redundant demo step as they are the default settings values | |
206 IWebView2Settings* Settings; | |
207 webview->get_Settings(&Settings); | |
208 Settings->put_IsScriptEnabled(TRUE); | |
209 Settings->put_AreDefaultScriptDialogsEnabled(TRUE); | |
210 Settings->put_IsWebMessageEnabled(TRUE); | |
211 | |
212 // Resize WebView to fit the bounds of the parent window | |
213 RECT bounds; | |
214 GetClientRect(hWnd, &bounds); | |
215 webview->put_Bounds(bounds); | |
216 return S_OK; | |
217 }).Get()); | |
218 return S_OK; | |
219 }).Get()); | |
220 | |
221 // Success | |
222 return(0); | |
223 } | |
224 | |
225 case WM_DESTROY: | |
226 { | |
227 // Detach the browser object from this window, and free resources. | |
228 IWebView2WebView* webview; | |
229 | |
230 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when | |
231 // we initially attached the browser object to this window. | |
232 webview = *((IWebView2WebView**)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME)); | |
233 if (webview) | |
234 { | |
235 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL); | |
236 webview->Close(); | |
237 | |
238 } | |
239 return(TRUE); | |
240 } | |
241 } | |
242 | |
243 return(DefWindowProc(hWnd, uMsg, wParam, lParam)); | |
244 } | |
245 |