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