Line |
Branch |
Exec |
Source |
1 |
|
|
/* GATE PROJECT LICENSE: |
2 |
|
|
+----------------------------------------------------------------------------+ |
3 |
|
|
| Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | |
4 |
|
|
| All rights reserved. | |
5 |
|
|
| | |
6 |
|
|
| Redistribution and use in source and binary forms, with or without | |
7 |
|
|
| modification, are permitted provided that the following conditions are met:| |
8 |
|
|
| | |
9 |
|
|
| 1. Redistributions of source code must retain the above copyright notice, | |
10 |
|
|
| this list of conditions and the following disclaimer. | |
11 |
|
|
| 2. Redistributions in binary form must reproduce the above copyright | |
12 |
|
|
| notice, this list of conditions and the following disclaimer in the | |
13 |
|
|
| documentation and/or other materials provided with the distribution. | |
14 |
|
|
| | |
15 |
|
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| |
16 |
|
|
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
17 |
|
|
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
18 |
|
|
| ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
19 |
|
|
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
20 |
|
|
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
21 |
|
|
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
22 |
|
|
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
23 |
|
|
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
24 |
|
|
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
25 |
|
|
| THE POSSIBILITY OF SUCH DAMAGE. | |
26 |
|
|
+----------------------------------------------------------------------------+ |
27 |
|
|
*/ |
28 |
|
|
|
29 |
|
|
#include "gate/ui/webviews.h" |
30 |
|
|
#include "gate/results.h" |
31 |
|
|
|
32 |
|
|
#if defined(GATE_UI_WINAPI) && !defined(GATE_SYS_WIN16) |
33 |
|
|
|
34 |
|
|
#include "gate/platform/windows/win32com.h" |
35 |
|
|
#include "gate/ui/gateui_winapi.h" |
36 |
|
|
#include "gate/platforms.h" |
37 |
|
|
|
38 |
|
|
#define GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL 1 |
39 |
|
|
|
40 |
|
|
#if defined(GATE_WIN32_UNICODE) && !defined(GATE_SYS_WINCE) |
41 |
|
|
/* edge webview2 support is only available on WinNT unicode-platforms */ |
42 |
|
|
# define GATE_UI_WEBVIEW_EDGEWV2_IMPL 1 |
43 |
|
|
#endif |
44 |
|
|
|
45 |
|
|
|
46 |
|
|
#include "gate/libraries.h" |
47 |
|
|
|
48 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
49 |
|
|
# include "gate/ui/webviews_win32.h" |
50 |
|
|
#endif |
51 |
|
|
|
52 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
53 |
|
|
# include "gate/ui/webviews_msedgewv2.h" |
54 |
|
|
#endif |
55 |
|
|
|
56 |
|
|
typedef struct gate_ui_webview_impl_class |
57 |
|
|
{ |
58 |
|
|
gate_ui_webview_t* webview; |
59 |
|
|
HWND hwnd; |
60 |
|
|
|
61 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
62 |
|
|
/* atl/webbrowser stuff: */ |
63 |
|
|
IWebBrowser* webbrowser; |
64 |
|
|
IWebBrowser2* webbrowser2; |
65 |
|
|
IDispatch* webbrowser_events; |
66 |
|
|
#endif |
67 |
|
|
|
68 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
69 |
|
|
/* webview2 stuff: */ |
70 |
|
|
ICoreWebView2Controller* wv2_controller; |
71 |
|
|
ICoreWebView2* wv2; |
72 |
|
|
IUnknown* wv2_event_handlers; |
73 |
|
|
#endif |
74 |
|
|
|
75 |
|
|
} gate_ui_webview_impl_t; |
76 |
|
|
|
77 |
|
|
static IID const gate_IID_IUnknown = { 0x00000000, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; |
78 |
|
|
static IID const gate_IID_IDispatch = { 0x00020400, 0x0000, 0x0000, { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }; |
79 |
|
|
|
80 |
|
|
static gate_bool_t webview_windowproc_events(void* hwnd, gate_ui_ctrl_t* ctrl, gate_uint32_t msg, gate_uintptr_t wParam, gate_intptr_t lParam, gate_intptr_t* lresult); |
81 |
|
|
|
82 |
|
|
static gate_result_t webview_destroy_impl(gate_ui_ctrl_t* ctrl); |
83 |
|
|
|
84 |
|
|
static gate_ui_winapi_dispatchers_t global_webview_dispatchers = |
85 |
|
|
{ |
86 |
|
|
&webview_destroy_impl, |
87 |
|
|
&gate_ui_winapi_is_enabled, |
88 |
|
|
&gate_ui_winapi_is_visible, |
89 |
|
|
&gate_ui_winapi_is_focused, |
90 |
|
|
&gate_ui_winapi_get_position, |
91 |
|
|
&gate_ui_winapi_get_size, |
92 |
|
|
&gate_ui_winapi_get_children, |
93 |
|
|
&gate_ui_winapi_get_text_length, |
94 |
|
|
&gate_ui_winapi_get_text, |
95 |
|
|
&gate_ui_winapi_get_state, |
96 |
|
|
&gate_ui_winapi_set_enabled, |
97 |
|
|
&gate_ui_winapi_set_visible, |
98 |
|
|
&gate_ui_winapi_set_focus, |
99 |
|
|
&gate_ui_winapi_set_position, |
100 |
|
|
&gate_ui_winapi_set_text, |
101 |
|
|
&gate_ui_winapi_set_state, |
102 |
|
|
&gate_ui_winapi_refresh |
103 |
|
|
}; |
104 |
|
|
|
105 |
|
|
|
106 |
|
|
|
107 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
108 |
|
|
/****************************/ |
109 |
|
|
/* */ |
110 |
|
|
/* ATL / webbrowser code: */ |
111 |
|
|
/* */ |
112 |
|
|
/****************************/ |
113 |
|
|
|
114 |
|
|
typedef struct gate_ui_winapi_atl_code |
115 |
|
|
{ |
116 |
|
|
BOOL(__stdcall* WinInit)(); |
117 |
|
|
HRESULT(STDMETHODCALLTYPE* GetControl)(HWND hwnd, IUnknown** ptr); |
118 |
|
|
HRESULT(STDMETHODCALLTYPE* GetHost)(HWND hwnd, IUnknown** ptr); |
119 |
|
|
} gate_ui_winapi_atl_code_t; |
120 |
|
|
|
121 |
|
|
|
122 |
|
|
static gate_library_t atl_lib = NULL; |
123 |
|
|
static gate_bool_t volatile atl_code_loaded = false; |
124 |
|
|
static gate_ui_winapi_atl_code_t atl_code = GATE_INIT_EMPTY; |
125 |
|
|
|
126 |
|
|
static gate_result_t load_atl_code() |
127 |
|
|
{ |
128 |
|
|
#if defined(GATE_SYS_WINCE) |
129 |
|
|
static gate_string_t const atl_lib_name = { "atlce300.dll", 12, NULL }; |
130 |
|
|
#else |
131 |
|
|
static gate_string_t const atl_lib_name = { "atl.dll", 7, NULL }; |
132 |
|
|
#endif |
133 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
134 |
|
|
if (!atl_code_loaded) |
135 |
|
|
{ |
136 |
|
|
gate_win32_com_init(); |
137 |
|
|
do |
138 |
|
|
{ |
139 |
|
|
if (atl_lib == NULL) |
140 |
|
|
{ |
141 |
|
|
ret = gate_library_open(&atl_lib_name, &atl_lib, 0); |
142 |
|
|
GATE_BREAK_IF_FAILED(ret); |
143 |
|
|
} |
144 |
|
|
|
145 |
|
|
ret = gate_library_get_function_name(atl_lib, "AtlAxWinInit", &atl_code.WinInit); |
146 |
|
|
GATE_BREAK_IF_FAILED(ret); |
147 |
|
|
|
148 |
|
|
ret = gate_library_get_function_name(atl_lib, "AtlAxGetControl", &atl_code.GetControl); |
149 |
|
|
GATE_BREAK_IF_FAILED(ret); |
150 |
|
|
|
151 |
|
|
ret = gate_library_get_function_name(atl_lib, "AtlAxGetHost", &atl_code.GetHost); |
152 |
|
|
GATE_BREAK_IF_FAILED(ret); |
153 |
|
|
|
154 |
|
|
if (atl_code.WinInit()) |
155 |
|
|
{ |
156 |
|
|
atl_code_loaded = true; |
157 |
|
|
ret = GATE_RESULT_OK; |
158 |
|
|
} |
159 |
|
|
} while (0); |
160 |
|
|
} |
161 |
|
|
else |
162 |
|
|
{ |
163 |
|
|
ret = GATE_RESULT_OK; |
164 |
|
|
} |
165 |
|
|
return ret; |
166 |
|
|
} |
167 |
|
|
|
168 |
|
|
|
169 |
|
|
static gate_result_t get_control_interface(HWND hwnd, GUID const* interface_id, void** pptr_interface) |
170 |
|
|
{ |
171 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
172 |
|
|
IUnknown* punk = NULL; |
173 |
|
|
IUnknown* ptr_interface = NULL; |
174 |
|
|
HRESULT hr; |
175 |
|
|
do |
176 |
|
|
{ |
177 |
|
|
hr = atl_code.GetControl(hwnd, &punk); |
178 |
|
|
if (FAILED(hr)) |
179 |
|
|
{ |
180 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
181 |
|
|
break; |
182 |
|
|
} |
183 |
|
|
if (!punk) |
184 |
|
|
{ |
185 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
186 |
|
|
break; |
187 |
|
|
} |
188 |
|
|
if (!interface_id) |
189 |
|
|
{ |
190 |
|
|
ptr_interface = punk; |
191 |
|
|
punk->lpVtbl->AddRef(punk); |
192 |
|
|
} |
193 |
|
|
else |
194 |
|
|
{ |
195 |
|
|
hr = punk->lpVtbl->QueryInterface(punk, interface_id, (void**)&ptr_interface); |
196 |
|
|
if (FAILED(hr)) |
197 |
|
|
{ |
198 |
|
|
ret = GATE_RESULT_INCORRECTTYPE; |
199 |
|
|
break; |
200 |
|
|
} |
201 |
|
|
} |
202 |
|
|
if (pptr_interface) |
203 |
|
|
{ |
204 |
|
|
*pptr_interface = (void*)ptr_interface; |
205 |
|
|
} |
206 |
|
|
else |
207 |
|
|
{ |
208 |
|
|
ptr_interface->lpVtbl->Release(ptr_interface); |
209 |
|
|
} |
210 |
|
|
ret = GATE_RESULT_OK; |
211 |
|
|
} while (0); |
212 |
|
|
|
213 |
|
|
if (punk) |
214 |
|
|
{ |
215 |
|
|
punk->lpVtbl->Release(punk); |
216 |
|
|
} |
217 |
|
|
|
218 |
|
|
return ret; |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
static void* get_control_interface_ptr(HWND hwnd, GUID const* interface_id) |
222 |
|
|
{ |
223 |
|
|
void* ptr_interface = NULL; |
224 |
|
|
gate_result_t result = get_control_interface(hwnd, interface_id, &ptr_interface); |
225 |
|
|
if (GATE_FAILED(result)) |
226 |
|
|
{ |
227 |
|
|
ptr_interface = NULL; |
228 |
|
|
} |
229 |
|
|
return ptr_interface; |
230 |
|
|
} |
231 |
|
|
|
232 |
|
|
|
233 |
|
|
|
234 |
|
|
typedef struct webbrowser_events_class |
235 |
|
|
{ |
236 |
|
|
IDispatch dispatch; |
237 |
|
|
|
238 |
|
|
gate_atomic_int_t ref_counter; |
239 |
|
|
gate_ui_webview_t* webview; |
240 |
|
|
} webbrowser_events_t; |
241 |
|
|
|
242 |
|
|
|
243 |
|
|
|
244 |
|
|
static HRESULT STDMETHODCALLTYPE webbrowser_events_QueryInterface(IDispatch* This, REFIID riid, void** ppvObject) |
245 |
|
|
{ |
246 |
|
|
webbrowser_events_t* self = (webbrowser_events_t*)This; |
247 |
|
|
|
248 |
|
|
if (!ppvObject || !riid || !self) |
249 |
|
|
{ |
250 |
|
|
return E_POINTER; |
251 |
|
|
} |
252 |
|
|
|
253 |
|
|
if (IsEqualGUID(riid, &gate_IID_IDispatch) || IsEqualGUID(riid, &gate_IID_IUnknown) |
254 |
|
|
|| IsEqualGUID(riid, &IID_DWebBrowserEvents2) || IsEqualGUID(riid, &IID_DWebBrowserEvents)) |
255 |
|
|
{ |
256 |
|
|
*ppvObject = self; |
257 |
|
|
gate_atomic_int_inc(&self->ref_counter); |
258 |
|
|
return S_OK; |
259 |
|
|
} |
260 |
|
|
return E_NOINTERFACE; |
261 |
|
|
} |
262 |
|
|
static ULONG STDMETHODCALLTYPE webbrowser_events_AddRef(IDispatch* This) |
263 |
|
|
{ |
264 |
|
|
webbrowser_events_t* self = (webbrowser_events_t*)This; |
265 |
|
|
return (ULONG)gate_atomic_int_inc(&self->ref_counter); |
266 |
|
|
} |
267 |
|
|
static ULONG STDMETHODCALLTYPE webbrowser_events_Release(IDispatch* This) |
268 |
|
|
{ |
269 |
|
|
webbrowser_events_t* self = (webbrowser_events_t*)This; |
270 |
|
|
ULONG cnt = (ULONG)gate_atomic_int_dec(&self->ref_counter); |
271 |
|
|
if (cnt == 0) |
272 |
|
|
{ |
273 |
|
|
if (self->webview) |
274 |
|
|
{ |
275 |
|
|
self->webview = NULL; |
276 |
|
|
} |
277 |
|
|
gate_mem_dealloc(self); |
278 |
|
|
} |
279 |
|
|
return cnt; |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
static HRESULT STDMETHODCALLTYPE webbrowser_events_GetTypeInfoCount(IDispatch* This, UINT* pctinfo) |
283 |
|
|
{ |
284 |
|
|
if (pctinfo) |
285 |
|
|
{ |
286 |
|
|
*pctinfo = 0; |
287 |
|
|
} |
288 |
|
|
return S_OK; |
289 |
|
|
} |
290 |
|
|
|
291 |
|
|
static HRESULT STDMETHODCALLTYPE webbrowser_events_GetTypeInfo(IDispatch* This, UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) |
292 |
|
|
{ |
293 |
|
|
return DISP_E_BADINDEX; |
294 |
|
|
} |
295 |
|
|
|
296 |
|
|
static gate_bool_t wstr_equal(wchar_t const* a, wchar_t const* b) |
297 |
|
|
{ |
298 |
|
|
if (!a || !b) |
299 |
|
|
{ |
300 |
|
|
return false; |
301 |
|
|
} |
302 |
|
|
for (; *a == *b; ++a, ++b) |
303 |
|
|
{ |
304 |
|
|
if (*a == 0) |
305 |
|
|
{ |
306 |
|
|
return true; |
307 |
|
|
} |
308 |
|
|
} |
309 |
|
|
return false; |
310 |
|
|
} |
311 |
|
|
|
312 |
|
|
struct dispid_map |
313 |
|
|
{ |
314 |
|
|
DISPID id; |
315 |
|
|
wchar_t const* name; |
316 |
|
|
}; |
317 |
|
|
|
318 |
|
|
static struct dispid_map const dispid_webbrowser_map[] = |
319 |
|
|
{ |
320 |
|
|
{ DISPID_BEFORENAVIGATE, L"" }, |
321 |
|
|
{ DISPID_NAVIGATECOMPLETE, L"" }, |
322 |
|
|
{ DISPID_STATUSTEXTCHANGE, L"" }, |
323 |
|
|
{ DISPID_QUIT, L"" }, |
324 |
|
|
{ DISPID_DOWNLOADCOMPLETE, L"" }, |
325 |
|
|
{ DISPID_COMMANDSTATECHANGE, L"" }, |
326 |
|
|
{ DISPID_DOWNLOADBEGIN, L"" }, |
327 |
|
|
{ DISPID_NEWWINDOW, L"" }, |
328 |
|
|
{ DISPID_PROGRESSCHANGE, L"" }, |
329 |
|
|
{ DISPID_WINDOWMOVE, L"" }, |
330 |
|
|
{ DISPID_WINDOWRESIZE, L"" }, |
331 |
|
|
{ DISPID_WINDOWACTIVATE, L"" }, |
332 |
|
|
{ DISPID_PROPERTYCHANGE, L"" }, |
333 |
|
|
{ DISPID_TITLECHANGE, L"" }, |
334 |
|
|
{ DISPID_TITLEICONCHANGE, L"" } |
335 |
|
|
}; |
336 |
|
|
static gate_size_t const dispid_webbrowser_map_count = sizeof(dispid_webbrowser_map) / sizeof(dispid_webbrowser_map[0]); |
337 |
|
|
|
338 |
|
|
|
339 |
|
|
static void webbrowser_disable_script_errors(gate_ui_webview_impl_t* impl) |
340 |
|
|
{ |
341 |
|
|
if (impl->webbrowser2) |
342 |
|
|
{ |
343 |
|
|
VARIANT vin; |
344 |
|
|
VARIANT vout; |
345 |
|
|
HRESULT hr; |
346 |
|
|
VARIANT_BOOL vb = FALSE; |
347 |
|
|
vin.vt = VT_BOOL; |
348 |
|
|
vin.boolVal = vb; |
349 |
|
|
vout.vt = VT_EMPTY; |
350 |
|
|
hr = impl->webbrowser2->lpVtbl->ExecWB(impl->webbrowser2, OLECMDID_SHOWSCRIPTERROR, OLECMDEXECOPT_DONTPROMPTUSER, &vin, &vout); |
351 |
|
|
impl->webbrowser2->lpVtbl->put_Silent(impl->webbrowser2, TRUE); |
352 |
|
|
Sleep(0); |
353 |
|
|
} |
354 |
|
|
} |
355 |
|
|
|
356 |
|
|
|
357 |
|
|
static HRESULT STDMETHODCALLTYPE webbrowser_events_GetIDsOfNames(IDispatch* This, REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) |
358 |
|
|
{ |
359 |
|
|
UINT ndx; |
360 |
|
|
gate_size_t ndx_map; |
361 |
|
|
|
362 |
|
|
for (ndx = 0; ndx != cNames; ++ndx) |
363 |
|
|
{ |
364 |
|
|
rgDispId[ndx] = 0; |
365 |
|
|
for (ndx_map = 0; ndx_map != dispid_webbrowser_map_count; ++ndx_map) |
366 |
|
|
{ |
367 |
|
|
if (wstr_equal(rgszNames[ndx], dispid_webbrowser_map[ndx_map].name)) |
368 |
|
|
{ |
369 |
|
|
rgDispId[ndx] = dispid_webbrowser_map[ndx_map].id; |
370 |
|
|
break; |
371 |
|
|
} |
372 |
|
|
} |
373 |
|
|
} |
374 |
|
|
return S_OK; |
375 |
|
|
} |
376 |
|
|
|
377 |
|
|
static HRESULT STDMETHODCALLTYPE webbrowser_events_Invoke(IDispatch* This, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, |
378 |
|
|
DISPPARAMS* pDispParams, VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) |
379 |
|
|
{ |
380 |
|
|
webbrowser_events_t* self = (webbrowser_events_t*)This; |
381 |
|
|
gate_string_t text = GATE_STRING_INIT_EMPTY; |
382 |
|
|
gate_bool_t b = false; |
383 |
|
|
gate_int32_t n1 = 0, n2 = 0; |
384 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
385 |
|
|
|
386 |
|
|
do |
387 |
|
|
{ |
388 |
|
|
if (!self || !self->webview) |
389 |
|
|
{ |
390 |
|
|
break; |
391 |
|
|
} |
392 |
|
|
impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(&self->webview->ctrl); |
393 |
|
|
|
394 |
|
|
switch (dispIdMember) |
395 |
|
|
{ |
396 |
|
|
case DISPID_BEFORENAVIGATE: |
397 |
|
|
{ |
398 |
|
|
webbrowser_disable_script_errors(impl); |
399 |
|
|
if (self->webview->on_navigate_start) |
400 |
|
|
{ |
401 |
|
|
VARIANTARG* a0 = &pDispParams->rgvarg[0]; |
402 |
|
|
VARIANTARG* a1 = &pDispParams->rgvarg[1]; |
403 |
|
|
VARIANTARG* a2 = &pDispParams->rgvarg[2]; |
404 |
|
|
VARIANTARG* a3 = &pDispParams->rgvarg[3]; |
405 |
|
|
VARIANTARG* a4 = &pDispParams->rgvarg[4]; |
406 |
|
|
VARIANTARG* a5 = &pDispParams->rgvarg[5]; |
407 |
|
|
self->webview->on_navigate_start(&self->webview->ctrl, &text, &b); |
408 |
|
|
} |
409 |
|
|
break; |
410 |
|
|
} |
411 |
|
|
case DISPID_PROGRESSCHANGE: |
412 |
|
|
{ |
413 |
|
|
if (self->webview->on_navigate_progress) |
414 |
|
|
{ |
415 |
|
|
self->webview->on_navigate_progress(&self->webview->ctrl, n1, n2); |
416 |
|
|
} |
417 |
|
|
break; |
418 |
|
|
} |
419 |
|
|
case DISPID_NAVIGATECOMPLETE: |
420 |
|
|
case DISPID_NAVIGATECOMPLETE2: |
421 |
|
|
{ |
422 |
|
|
webbrowser_disable_script_errors(impl); |
423 |
|
|
if (self->webview->on_navigate_complete) |
424 |
|
|
{ |
425 |
|
|
if (pDispParams->cArgs >= 1) |
426 |
|
|
{ |
427 |
|
|
if (pDispParams->rgvarg[0].vt == VT_BSTR) |
428 |
|
|
{ |
429 |
|
|
gate_win32_bstr_to_string(pDispParams->rgvarg[0].bstrVal, &text); |
430 |
|
|
} |
431 |
|
|
else if ((pDispParams->rgvarg[0].vt == (VT_VARIANT | VT_BYREF)) && (pDispParams->rgvarg[0].pvarVal)) |
432 |
|
|
{ |
433 |
|
|
if (pDispParams->rgvarg[0].pvarVal->vt == VT_BSTR) |
434 |
|
|
{ |
435 |
|
|
gate_win32_bstr_to_string(pDispParams->rgvarg[0].pvarVal->bstrVal, &text); |
436 |
|
|
} |
437 |
|
|
} |
438 |
|
|
} |
439 |
|
|
self->webview->on_navigate_complete(&self->webview->ctrl, &text); |
440 |
|
|
} |
441 |
|
|
break; |
442 |
|
|
} |
443 |
|
|
case DISPID_COMMANDSTATECHANGE: |
444 |
|
|
{ |
445 |
|
|
if (self->webview->on_internal_state_changed) |
446 |
|
|
{ |
447 |
|
|
self->webview->on_internal_state_changed(&self->webview->ctrl, 0); |
448 |
|
|
} |
449 |
|
|
break; |
450 |
|
|
} |
451 |
|
|
case DISPID_TITLECHANGE: |
452 |
|
|
{ |
453 |
|
|
if (self->webview->on_title_text_changed) |
454 |
|
|
{ |
455 |
|
|
if ((pDispParams->cArgs >= 1) && (pDispParams->rgvarg[0].vt == VT_BSTR)) |
456 |
|
|
{ |
457 |
|
|
gate_win32_bstr_to_string(pDispParams->rgvarg[0].bstrVal, &text); |
458 |
|
|
} |
459 |
|
|
self->webview->on_title_text_changed(&self->webview->ctrl, &text); |
460 |
|
|
} |
461 |
|
|
break; |
462 |
|
|
} |
463 |
|
|
case DISPID_STATUSTEXTCHANGE: |
464 |
|
|
{ |
465 |
|
|
if (self->webview->on_status_text_changed) |
466 |
|
|
{ |
467 |
|
|
if ((pDispParams->cArgs >= 1) && (pDispParams->rgvarg[0].vt == VT_BSTR)) |
468 |
|
|
{ |
469 |
|
|
gate_win32_bstr_to_string(pDispParams->rgvarg[0].bstrVal, &text); |
470 |
|
|
} |
471 |
|
|
self->webview->on_status_text_changed(&self->webview->ctrl, &text); |
472 |
|
|
} |
473 |
|
|
break; |
474 |
|
|
} |
475 |
|
|
case DISPID_NAVIGATEERROR: |
476 |
|
|
{ |
477 |
|
|
Sleep(0); |
478 |
|
|
break; |
479 |
|
|
} |
480 |
|
|
case DISPID_NEWWINDOW2: |
481 |
|
|
case DISPID_NEWWINDOW: |
482 |
|
|
{ |
483 |
|
|
if (self->webview->on_new_window) |
484 |
|
|
{ |
485 |
|
|
gate_ui_webview_t* ptr_newview = NULL; |
486 |
|
|
self->webview->on_new_window(&self->webview->ctrl, &ptr_newview); |
487 |
|
|
if (ptr_newview && (pDispParams->cArgs >= 2)) |
488 |
|
|
{ |
489 |
|
|
gate_ui_webview_impl_t* other_impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(&ptr_newview->ctrl); |
490 |
|
|
VARIANTARG* a0 = &pDispParams->rgvarg[0]; |
491 |
|
|
//*a0->pboolVal = TRUE; |
492 |
|
|
VARIANTARG* a1 = &pDispParams->rgvarg[1]; |
493 |
|
|
if (other_impl && other_impl->webbrowser2 && (a1->vt == (VT_DISPATCH | VT_BYREF))) |
494 |
|
|
{ |
495 |
|
|
IDispatch* pdisp = NULL; |
496 |
|
|
other_impl->webbrowser2->lpVtbl->put_RegisterAsBrowser(other_impl->webbrowser2, TRUE); |
497 |
|
|
other_impl->webbrowser2->lpVtbl->QueryInterface(other_impl->webbrowser2, &gate_IID_IDispatch, (void**)&pdisp); |
498 |
|
|
*a1->ppdispVal = pdisp; |
499 |
|
|
} |
500 |
|
|
Sleep(0); |
501 |
|
|
} |
502 |
|
|
} |
503 |
|
|
break; |
504 |
|
|
} |
505 |
|
|
case DISPID_QUIT: |
506 |
|
|
case DISPID_DOWNLOADCOMPLETE: |
507 |
|
|
case DISPID_DOWNLOADBEGIN: |
508 |
|
|
case DISPID_WINDOWMOVE: |
509 |
|
|
case DISPID_WINDOWRESIZE: |
510 |
|
|
case DISPID_WINDOWACTIVATE: |
511 |
|
|
case DISPID_PROPERTYCHANGE: |
512 |
|
|
case DISPID_TITLEICONCHANGE: |
513 |
|
|
break; |
514 |
|
|
} |
515 |
|
|
|
516 |
|
|
} while (0); |
517 |
|
|
|
518 |
|
|
gate_string_release(&text); |
519 |
|
|
|
520 |
|
|
|
521 |
|
|
return S_OK; |
522 |
|
|
} |
523 |
|
|
|
524 |
|
|
|
525 |
|
|
static IDispatchVtbl webview_disp_vtbl = |
526 |
|
|
{ |
527 |
|
|
&webbrowser_events_QueryInterface, |
528 |
|
|
&webbrowser_events_AddRef, |
529 |
|
|
&webbrowser_events_Release, |
530 |
|
|
|
531 |
|
|
&webbrowser_events_GetTypeInfoCount, |
532 |
|
|
&webbrowser_events_GetTypeInfo, |
533 |
|
|
&webbrowser_events_GetIDsOfNames, |
534 |
|
|
&webbrowser_events_Invoke |
535 |
|
|
}; |
536 |
|
|
|
537 |
|
|
|
538 |
|
|
|
539 |
|
|
|
540 |
|
|
static DWORD register_webbrowser_event_dispatcher(IUnknown* target, IID const* event_iid, IDispatch* event_handler) |
541 |
|
|
{ |
542 |
|
|
DWORD ret = 0; |
543 |
|
|
HRESULT hr; |
544 |
|
|
IConnectionPointContainer* ptr_container = NULL; |
545 |
|
|
IConnectionPoint* ptr_point = NULL; |
546 |
|
|
DWORD cookie = 0; |
547 |
|
|
|
548 |
|
|
do |
549 |
|
|
{ |
550 |
|
|
hr = target->lpVtbl->QueryInterface(target, &IID_IConnectionPointContainer, (void**)&ptr_container); |
551 |
|
|
if (FAILED(hr)) |
552 |
|
|
{ |
553 |
|
|
break; |
554 |
|
|
} |
555 |
|
|
hr = ptr_container->lpVtbl->FindConnectionPoint(ptr_container, event_iid, &ptr_point); |
556 |
|
|
if (FAILED(hr)) |
557 |
|
|
{ |
558 |
|
|
break; |
559 |
|
|
} |
560 |
|
|
hr = ptr_point->lpVtbl->Advise(ptr_point, (IUnknown*)event_handler, &cookie); |
561 |
|
|
if (FAILED(hr)) |
562 |
|
|
{ |
563 |
|
|
break; |
564 |
|
|
} |
565 |
|
|
ret = cookie; |
566 |
|
|
} while (0); |
567 |
|
|
|
568 |
|
|
if (ptr_point) |
569 |
|
|
{ |
570 |
|
|
ptr_point->lpVtbl->Release(ptr_point); |
571 |
|
|
} |
572 |
|
|
if (ptr_container) |
573 |
|
|
{ |
574 |
|
|
ptr_container->lpVtbl->Release(ptr_container); |
575 |
|
|
} |
576 |
|
|
return ret; |
577 |
|
|
} |
578 |
|
|
|
579 |
|
|
|
580 |
|
|
static gate_ui_webview_impl_t* create_webbrowser_impl(gate_ui_webview_t* webview) |
581 |
|
|
{ |
582 |
|
|
HWND hwnd_ctrl = NULL; |
583 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
584 |
|
|
gate_ui_host_t* host = NULL; |
585 |
|
|
RECT rect; |
586 |
|
|
DWORD event_cookie = 0; |
587 |
|
|
#if defined(GATE_SYS_WINCE) |
588 |
|
|
static LPCTSTR browser_id = TEXT("Microsoft.PIEDocView"); |
589 |
|
|
#else |
590 |
|
|
static LPCTSTR browser_id = TEXT("SHDocVwCtl.WebBrowser"); |
591 |
|
|
#endif |
592 |
|
|
webbrowser_events_t* webbrowser_events; |
593 |
|
|
|
594 |
|
|
do |
595 |
|
|
{ |
596 |
|
|
hwnd_ctrl = GATE_UI_WINAPI_GET_HWND(&webview->ctrl); |
597 |
|
|
host = GATE_UI_WINAPI_GET_HOST(&webview->ctrl); |
598 |
|
|
impl = (gate_ui_webview_impl_t*)gate_mem_alloc(sizeof(gate_ui_webview_impl_t)); |
599 |
|
|
if (!impl) |
600 |
|
|
{ |
601 |
|
|
break; |
602 |
|
|
} |
603 |
|
|
|
604 |
|
|
gate_mem_clear(impl, sizeof(gate_ui_webview_impl_t)); |
605 |
|
|
impl->webview = webview; |
606 |
|
|
GetClientRect(hwnd_ctrl, &rect); |
607 |
|
|
impl->hwnd = CreateWindow(TEXT("AtlAxWin"), browser_id, |
608 |
|
|
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_HSCROLL | WS_VSCROLL, |
609 |
|
|
0, 0, rect.right, rect.bottom, |
610 |
|
|
hwnd_ctrl, NULL, |
611 |
|
|
(HINSTANCE)GATE_UI_WINAPI_GET_HOST_APPHANDLE(host), NULL); |
612 |
|
|
if (impl->hwnd == NULL) |
613 |
|
|
{ |
614 |
|
|
gate_mem_dealloc(impl); |
615 |
|
|
impl = NULL; |
616 |
|
|
break; |
617 |
|
|
} |
618 |
|
|
|
619 |
|
|
impl->webbrowser = (IWebBrowser*)get_control_interface_ptr(impl->hwnd, &IID_IWebBrowser); |
620 |
|
|
impl->webbrowser2 = (IWebBrowser2*)get_control_interface_ptr(impl->hwnd, &IID_IWebBrowser2); |
621 |
|
|
|
622 |
|
|
webbrowser_events = (webbrowser_events_t*)gate_mem_alloc(sizeof(webbrowser_events_t)); |
623 |
|
|
if (NULL != webbrowser_events) |
624 |
|
|
{ |
625 |
|
|
gate_mem_clear(webbrowser_events, sizeof(webbrowser_events_t)); |
626 |
|
|
webbrowser_events->dispatch.lpVtbl = &webview_disp_vtbl; |
627 |
|
|
gate_atomic_int_init(&webbrowser_events->ref_counter, 1); |
628 |
|
|
webbrowser_events->webview = webview; |
629 |
|
|
|
630 |
|
|
event_cookie = register_webbrowser_event_dispatcher((IUnknown*)impl->webbrowser, &IID_DWebBrowserEvents2, (IDispatch*)webbrowser_events); |
631 |
|
|
if (0 == event_cookie) |
632 |
|
|
{ |
633 |
|
|
event_cookie = register_webbrowser_event_dispatcher((IUnknown*)impl->webbrowser, &IID_DWebBrowserEvents, (IDispatch*)webbrowser_events); |
634 |
|
|
} |
635 |
|
|
impl->webbrowser_events = (IDispatch*)webbrowser_events; |
636 |
|
|
} |
637 |
|
|
} while (0); |
638 |
|
|
|
639 |
|
|
return impl; |
640 |
|
|
} |
641 |
|
|
|
642 |
|
|
static gate_result_t gate_ui_webview_create_activex(gate_ui_webview_t* webview, gate_ui_ctrl_t* parent, |
643 |
|
|
gate_ui_position_t const* position, gate_uint32_t flags, void* userparam) |
644 |
|
|
{ |
645 |
|
|
static gate_string_t active_x_progid = { "SHDocVwCtl.WebBrowser", 21, NULL }; |
646 |
|
|
//static gate_string_t active_x_progid = { "Shell.Explorer.2", 16, NULL }; |
647 |
|
|
//static gate_string_t active_x_progid = { "MsRDP.MsRDP.2", 13, NULL }; |
648 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
649 |
|
|
gate_uint32_t styles, exstyles; |
650 |
|
|
gate_ui_host_t* host; |
651 |
|
|
HWND hwnd_ctrl = NULL; |
652 |
|
|
HWND hwnd_parent = NULL; |
653 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
654 |
|
|
|
655 |
|
|
do |
656 |
|
|
{ |
657 |
|
|
ret = load_atl_code(); |
658 |
|
|
GATE_BREAK_IF_FAILED(ret); |
659 |
|
|
|
660 |
|
|
if (parent == NULL) |
661 |
|
|
{ |
662 |
|
|
ret = GATE_RESULT_NULLPOINTER; |
663 |
|
|
break; |
664 |
|
|
} |
665 |
|
|
host = GATE_UI_WINAPI_GET_HOST(parent); |
666 |
|
|
hwnd_parent = GATE_UI_WINAPI_GET_HWND(parent); |
667 |
|
|
|
668 |
|
|
gate_mem_clear(webview, sizeof(gate_ui_webview_t)); |
669 |
|
|
|
670 |
|
|
exstyles = 0; |
671 |
|
|
#if !defined(GATE_SYS_WINCE) |
672 |
|
|
exstyles |= WS_EX_CONTROLPARENT; |
673 |
|
|
#endif |
674 |
|
|
styles = WS_GROUP | WS_CHILD | WS_TABSTOP | WS_CLIPCHILDREN; |
675 |
|
|
if (!GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_ENABLED)) styles |= WS_DISABLED; |
676 |
|
|
if (GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_VISIBLE)) styles |= WS_VISIBLE; |
677 |
|
|
|
678 |
|
|
ret = gate_ui_winapi_create(&webview->ctrl, host, hwnd_parent, NULL, position, styles, exstyles, NULL, userparam, false); |
679 |
|
|
if (GATE_SUCCEEDED(ret)) |
680 |
|
|
{ |
681 |
|
|
GATE_UI_WINAPI_SET_DISPATCHER(&webview->ctrl, &global_webview_dispatchers); |
682 |
|
|
hwnd_ctrl = GATE_UI_WINAPI_GET_HWND(&webview->ctrl); |
683 |
|
|
impl = create_webbrowser_impl(webview); |
684 |
|
|
if (impl == NULL) |
685 |
|
|
{ |
686 |
|
|
gate_ui_winapi_destroy(&webview->ctrl); |
687 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
688 |
|
|
break; |
689 |
|
|
} |
690 |
|
|
GATE_UI_WINAPI_SET_CTRL_PARAM(&webview->ctrl, impl); |
691 |
|
|
|
692 |
|
|
gate_ui_winapi_register_event(host, (void*)hwnd_ctrl, WM_SIZE, &webview_windowproc_events, &webview->ctrl); |
693 |
|
|
} |
694 |
|
|
} while (0); |
695 |
|
|
return ret; |
696 |
|
|
} |
697 |
|
|
|
698 |
|
|
static gate_result_t webbrowser_navigate_to(gate_ui_webview_impl_t* impl, gate_string_t const* address) |
699 |
|
|
{ |
700 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
701 |
|
|
BSTR bstr_address = NULL; |
702 |
|
|
VARIANT var_addr; |
703 |
|
|
VARIANT var_empty = GATE_INIT_EMPTY; |
704 |
|
|
HRESULT hr; |
705 |
|
|
|
706 |
|
|
do |
707 |
|
|
{ |
708 |
|
|
if (!impl->webbrowser && !impl->webbrowser2) |
709 |
|
|
{ |
710 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
711 |
|
|
break; |
712 |
|
|
} |
713 |
|
|
gate_win32_variant_init(&var_empty); |
714 |
|
|
bstr_address = gate_win32_bstr_create(address); |
715 |
|
|
|
716 |
|
|
if (impl->webbrowser2) |
717 |
|
|
{ |
718 |
|
|
webbrowser_disable_script_errors(impl); |
719 |
|
|
|
720 |
|
|
var_addr.vt = VT_BSTR; |
721 |
|
|
var_addr.bstrVal = bstr_address; |
722 |
|
|
hr = impl->webbrowser2->lpVtbl->Navigate2(impl->webbrowser2, &var_addr, NULL, NULL, NULL, NULL); |
723 |
|
|
} |
724 |
|
|
else |
725 |
|
|
{ |
726 |
|
|
hr = impl->webbrowser->lpVtbl->Navigate(impl->webbrowser, bstr_address, NULL, NULL, NULL, NULL); |
727 |
|
|
} |
728 |
|
|
|
729 |
|
|
if (FAILED(hr)) |
730 |
|
|
{ |
731 |
|
|
ret = GATE_RESULT_FAILED; |
732 |
|
|
break; |
733 |
|
|
} |
734 |
|
|
ret = GATE_RESULT_OK; |
735 |
|
|
} while (0); |
736 |
|
|
|
737 |
|
|
gate_win32_bstr_release(bstr_address); |
738 |
|
|
return ret; |
739 |
|
|
} |
740 |
|
|
|
741 |
|
|
static gate_result_t webbrowser_execute(gate_ui_webview_impl_t* impl, gate_enumint_t command) |
742 |
|
|
{ |
743 |
|
|
HRESULT hr; |
744 |
|
|
|
745 |
|
|
switch (command) |
746 |
|
|
{ |
747 |
|
|
case GATE_UI_WEBVIEW_COMMAND_STOP: |
748 |
|
|
{ |
749 |
|
|
if (impl->webbrowser2) |
750 |
|
|
{ |
751 |
|
|
hr = impl->webbrowser2->lpVtbl->Stop(impl->webbrowser2); |
752 |
|
|
} |
753 |
|
|
else |
754 |
|
|
{ |
755 |
|
|
hr = impl->webbrowser->lpVtbl->Stop(impl->webbrowser); |
756 |
|
|
} |
757 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
758 |
|
|
} |
759 |
|
|
case GATE_UI_WEBVIEW_COMMAND_REFRESH: |
760 |
|
|
{ |
761 |
|
|
if (impl->webbrowser2) |
762 |
|
|
{ |
763 |
|
|
hr = impl->webbrowser2->lpVtbl->Refresh(impl->webbrowser2); |
764 |
|
|
} |
765 |
|
|
else |
766 |
|
|
{ |
767 |
|
|
hr = impl->webbrowser->lpVtbl->Refresh(impl->webbrowser); |
768 |
|
|
} |
769 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
770 |
|
|
} |
771 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GOBACK: |
772 |
|
|
{ |
773 |
|
|
if (impl->webbrowser2) |
774 |
|
|
{ |
775 |
|
|
hr = impl->webbrowser2->lpVtbl->GoBack(impl->webbrowser2); |
776 |
|
|
} |
777 |
|
|
else |
778 |
|
|
{ |
779 |
|
|
hr = impl->webbrowser->lpVtbl->GoBack(impl->webbrowser); |
780 |
|
|
} |
781 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
782 |
|
|
} |
783 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GONEXT: |
784 |
|
|
{ |
785 |
|
|
if (impl->webbrowser2) |
786 |
|
|
{ |
787 |
|
|
hr = impl->webbrowser2->lpVtbl->GoForward(impl->webbrowser2); |
788 |
|
|
} |
789 |
|
|
else |
790 |
|
|
{ |
791 |
|
|
hr = impl->webbrowser->lpVtbl->GoForward(impl->webbrowser); |
792 |
|
|
} |
793 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
794 |
|
|
} |
795 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GOHOME: |
796 |
|
|
{ |
797 |
|
|
if (impl->webbrowser2) |
798 |
|
|
{ |
799 |
|
|
hr = impl->webbrowser2->lpVtbl->GoHome(impl->webbrowser2); |
800 |
|
|
} |
801 |
|
|
else |
802 |
|
|
{ |
803 |
|
|
hr = impl->webbrowser->lpVtbl->GoHome(impl->webbrowser); |
804 |
|
|
} |
805 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
806 |
|
|
} |
807 |
|
|
} |
808 |
|
|
|
809 |
|
|
return GATE_RESULT_NOTSUPPORTED; |
810 |
|
|
} |
811 |
|
|
#endif /* GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL */ |
812 |
|
|
|
813 |
|
|
|
814 |
|
|
|
815 |
|
|
|
816 |
|
|
|
817 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
818 |
|
|
|
819 |
|
|
/**********************************/ |
820 |
|
|
/* */ |
821 |
|
|
/* EDGE WebView2 implementation */ |
822 |
|
|
/* */ |
823 |
|
|
/**********************************/ |
824 |
|
|
|
825 |
|
|
#ifndef PM_QS_SENDMESSAGE |
826 |
|
|
#define PM_QS_SENDMESSAGE (QS_SENDMESSAGE << 16) |
827 |
|
|
#endif |
828 |
|
|
|
829 |
|
|
#ifndef PM_QS_POSTMESSAGE |
830 |
|
|
#define PM_QS_POSTMESSAGE ((QS_POSTMESSAGE | QS_HOTKEY | QS_TIMER) << 16) |
831 |
|
|
#endif |
832 |
|
|
|
833 |
|
|
static gate_result_t await_event_and_process_messages(HANDLE waitable, DWORD timeout_ms) |
834 |
|
|
{ |
835 |
|
|
gate_win32_userapi_t const* const userapi = gate_win32_userapi(); |
836 |
|
|
MSG msg; |
837 |
|
|
BOOL b; |
838 |
|
|
DWORD result; |
839 |
|
|
|
840 |
|
|
result = WaitForSingleObject(waitable, 0); |
841 |
|
|
if (result == WAIT_OBJECT_0) |
842 |
|
|
{ |
843 |
|
|
return GATE_RESULT_OK; |
844 |
|
|
} |
845 |
|
|
|
846 |
|
|
for (;;) |
847 |
|
|
{ |
848 |
|
|
gate_mem_clear(&msg, sizeof(msg)); |
849 |
|
|
b = userapi->UserPeekMessage(&msg, NULL, 0, 0, PM_REMOVE); |
850 |
|
|
if (b == TRUE) |
851 |
|
|
{ |
852 |
|
|
/* handle user message */ |
853 |
|
|
userapi->UserDispatchMessage(&msg); |
854 |
|
|
continue; |
855 |
|
|
} |
856 |
|
|
|
857 |
|
|
/* wait for user message or even completion */ |
858 |
|
|
result = userapi->UserMsgWaitForMultipleObjects(1, &waitable, FALSE, timeout_ms, QS_ALLINPUT); |
859 |
|
|
if (result == WAIT_TIMEOUT) |
860 |
|
|
{ |
861 |
|
|
return GATE_RESULT_TIMEOUT; |
862 |
|
|
} |
863 |
|
|
if (result == WAIT_OBJECT_0) |
864 |
|
|
{ |
865 |
|
|
return GATE_RESULT_OK; |
866 |
|
|
} |
867 |
|
|
if (result != (WAIT_OBJECT_0 + 1)) |
868 |
|
|
{ |
869 |
|
|
/* unknown error/state -> cancel loop */ |
870 |
|
|
break; |
871 |
|
|
} |
872 |
|
|
} |
873 |
|
|
return GATE_RESULT_FAILED; |
874 |
|
|
} |
875 |
|
|
|
876 |
|
|
|
877 |
|
|
|
878 |
|
|
static gate_result_t wv2_event_init(HANDLE* ptr_waitable) |
879 |
|
|
{ |
880 |
|
|
if (*ptr_waitable == NULL) |
881 |
|
|
{ |
882 |
|
|
*ptr_waitable = CreateSemaphore(NULL, 0, 1, NULL); |
883 |
|
|
if (*ptr_waitable == NULL) |
884 |
|
|
{ |
885 |
|
|
return GATE_RESULT_OUTOFRESOURCES; |
886 |
|
|
} |
887 |
|
|
return GATE_RESULT_OK; |
888 |
|
|
} |
889 |
|
|
else |
890 |
|
|
{ |
891 |
|
|
//return await_event_and_process_messages(*ptr_waitable, INFINITE); |
892 |
|
|
return GATE_RESULT_OK; |
893 |
|
|
} |
894 |
|
|
} |
895 |
|
|
static void wv2_event_notify(HANDLE waitable) |
896 |
|
|
{ |
897 |
|
|
ReleaseSemaphore(waitable, 1, NULL); |
898 |
|
|
} |
899 |
|
|
static gate_result_t wv2_event_await(HANDLE waitable) |
900 |
|
|
{ |
901 |
|
|
return await_event_and_process_messages(waitable, INFINITE); |
902 |
|
|
} |
903 |
|
|
|
904 |
|
|
|
905 |
|
|
typedef struct wv2_env_completed_class |
906 |
|
|
{ |
907 |
|
|
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl* lpVtbl; |
908 |
|
|
|
909 |
|
|
ICoreWebView2Environment* env; |
910 |
|
|
HANDLE semaphore; |
911 |
|
|
} wv2_env_completed_t; |
912 |
|
|
|
913 |
|
|
static HRESULT STDMETHODCALLTYPE wv2_env_completed_QueryInterface(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler* This, REFIID riid, void** ppvObject) |
914 |
|
|
{ |
915 |
|
|
wv2_env_completed_t* self = (wv2_env_completed_t*)This; |
916 |
|
|
if (ppvObject) |
917 |
|
|
{ |
918 |
|
|
*ppvObject = self; |
919 |
|
|
} |
920 |
|
|
return S_OK; |
921 |
|
|
} |
922 |
|
|
static ULONG STDMETHODCALLTYPE wv2_env_completed_AddRef(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler* This) |
923 |
|
|
{ |
924 |
|
|
wv2_env_completed_t* self = (wv2_env_completed_t*)This; |
925 |
|
|
return 2; |
926 |
|
|
} |
927 |
|
|
static ULONG STDMETHODCALLTYPE wv2_env_completed_Release(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler* This) |
928 |
|
|
{ |
929 |
|
|
wv2_env_completed_t* self = (wv2_env_completed_t*)This; |
930 |
|
|
return 1; |
931 |
|
|
} |
932 |
|
|
|
933 |
|
|
static HRESULT STDMETHODCALLTYPE wv2_env_completed_Invoke(ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler* This, HRESULT errorCode, ICoreWebView2Environment* createdEnvironment) |
934 |
|
|
{ |
935 |
|
|
wv2_env_completed_t* self = (wv2_env_completed_t*)This; |
936 |
|
|
if (createdEnvironment) |
937 |
|
|
{ |
938 |
|
|
self->env = createdEnvironment; |
939 |
|
|
createdEnvironment->lpVtbl->AddRef(createdEnvironment); |
940 |
|
|
} |
941 |
|
|
wv2_event_notify(self->semaphore); |
942 |
|
|
return S_OK; |
943 |
|
|
} |
944 |
|
|
|
945 |
|
|
static ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl wv2_env_completed_vtbl = { |
946 |
|
|
&wv2_env_completed_QueryInterface, |
947 |
|
|
&wv2_env_completed_AddRef, |
948 |
|
|
&wv2_env_completed_Release, |
949 |
|
|
&wv2_env_completed_Invoke |
950 |
|
|
}; |
951 |
|
|
|
952 |
|
|
static wv2_env_completed_t wv2_env_completed = { |
953 |
|
|
&wv2_env_completed_vtbl, |
954 |
|
|
NULL, |
955 |
|
|
NULL |
956 |
|
|
}; |
957 |
|
|
|
958 |
|
|
|
959 |
|
|
|
960 |
|
|
|
961 |
|
|
typedef struct wv2_ctrl_completed_class |
962 |
|
|
{ |
963 |
|
|
ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl* lpVtbl; |
964 |
|
|
|
965 |
|
|
ICoreWebView2Controller* ctrl; |
966 |
|
|
HANDLE semaphore; |
967 |
|
|
} wv2_ctrl_completed_t; |
968 |
|
|
|
969 |
|
|
static HRESULT STDMETHODCALLTYPE wv2_ctrl_completed_QueryInterface(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* This, REFIID riid, void** ppvObject) |
970 |
|
|
{ |
971 |
|
|
wv2_ctrl_completed_t* self = (wv2_ctrl_completed_t*)This; |
972 |
|
|
if (ppvObject) |
973 |
|
|
{ |
974 |
|
|
*ppvObject = self; |
975 |
|
|
} |
976 |
|
|
return S_OK; |
977 |
|
|
} |
978 |
|
|
static ULONG STDMETHODCALLTYPE wv2_ctrl_completed_AddRef(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* This) |
979 |
|
|
{ |
980 |
|
|
wv2_ctrl_completed_t* self = (wv2_ctrl_completed_t*)This; |
981 |
|
|
return 2; |
982 |
|
|
} |
983 |
|
|
static ULONG STDMETHODCALLTYPE wv2_ctrl_completed_Release(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* This) |
984 |
|
|
{ |
985 |
|
|
wv2_ctrl_completed_t* self = (wv2_ctrl_completed_t*)This; |
986 |
|
|
return 1; |
987 |
|
|
} |
988 |
|
|
|
989 |
|
|
static HRESULT STDMETHODCALLTYPE wv2_ctrl_completed_Invoke(ICoreWebView2CreateCoreWebView2ControllerCompletedHandler* This, HRESULT errorCode, ICoreWebView2Controller* createdController) |
990 |
|
|
{ |
991 |
|
|
wv2_ctrl_completed_t* self = (wv2_ctrl_completed_t*)This; |
992 |
|
|
if (createdController) |
993 |
|
|
{ |
994 |
|
|
self->ctrl = createdController; |
995 |
|
|
createdController->lpVtbl->AddRef(createdController); |
996 |
|
|
} |
997 |
|
|
wv2_event_notify(self->semaphore); |
998 |
|
|
return S_OK; |
999 |
|
|
} |
1000 |
|
|
|
1001 |
|
|
static ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl wv2_ctrl_completed_vtbl = { |
1002 |
|
|
&wv2_ctrl_completed_QueryInterface, |
1003 |
|
|
&wv2_ctrl_completed_AddRef, |
1004 |
|
|
&wv2_ctrl_completed_Release, |
1005 |
|
|
&wv2_ctrl_completed_Invoke |
1006 |
|
|
}; |
1007 |
|
|
|
1008 |
|
|
static wv2_ctrl_completed_t wv2_ctrl_completed = { |
1009 |
|
|
&wv2_ctrl_completed_vtbl, |
1010 |
|
|
NULL |
1011 |
|
|
}; |
1012 |
|
|
|
1013 |
|
|
|
1014 |
|
|
typedef struct wv2_event_handlers_class |
1015 |
|
|
{ |
1016 |
|
|
IUnknownVtbl* vtblUnkown; |
1017 |
|
|
|
1018 |
|
|
ICoreWebView2NewWindowRequestedEventHandler NewWindowRequested; |
1019 |
|
|
EventRegistrationToken tokenNewWindowRequested; |
1020 |
|
|
|
1021 |
|
|
ICoreWebView2NavigationStartingEventHandler NavigationStarting; |
1022 |
|
|
EventRegistrationToken tokenNavigationStarting; |
1023 |
|
|
|
1024 |
|
|
ICoreWebView2NavigationCompletedEventHandler NavigationCompleted; |
1025 |
|
|
EventRegistrationToken tokenNavigationCompleted; |
1026 |
|
|
|
1027 |
|
|
gate_atomic_int_t ref_counter; |
1028 |
|
|
gate_ui_webview_impl_t* impl; |
1029 |
|
|
|
1030 |
|
|
} wv2_event_handlers_t; |
1031 |
|
|
|
1032 |
|
|
|
1033 |
|
|
static void wv2_event_handlers_attach_events(wv2_event_handlers_t* handlers) |
1034 |
|
|
{ |
1035 |
|
|
HRESULT hr; |
1036 |
|
|
ICoreWebView2* wv2 = handlers->impl->wv2; |
1037 |
|
|
|
1038 |
|
|
hr = wv2->lpVtbl->add_NewWindowRequested(wv2, &handlers->NewWindowRequested, &handlers->tokenNewWindowRequested); |
1039 |
|
|
hr = wv2->lpVtbl->add_NavigationStarting(wv2, &handlers->NavigationStarting, &handlers->tokenNavigationStarting); |
1040 |
|
|
hr = wv2->lpVtbl->add_NavigationCompleted(wv2, &handlers->NavigationCompleted, &handlers->tokenNavigationCompleted); |
1041 |
|
|
} |
1042 |
|
|
|
1043 |
|
|
|
1044 |
|
|
static void wv2_event_handlers_detach_events(wv2_event_handlers_t* handlers) |
1045 |
|
|
{ |
1046 |
|
|
ICoreWebView2* wv2 = NULL; |
1047 |
|
|
|
1048 |
|
|
if (!handlers || !handlers->impl || !handlers->impl->wv2) return; |
1049 |
|
|
wv2 = handlers->impl->wv2; |
1050 |
|
|
|
1051 |
|
|
if (handlers->tokenNewWindowRequested.value) |
1052 |
|
|
{ |
1053 |
|
|
wv2->lpVtbl->remove_NewWindowRequested(wv2, handlers->tokenNewWindowRequested); |
1054 |
|
|
handlers->tokenNewWindowRequested.value = 0; |
1055 |
|
|
} |
1056 |
|
|
|
1057 |
|
|
if (handlers->tokenNavigationStarting.value) |
1058 |
|
|
{ |
1059 |
|
|
wv2->lpVtbl->remove_NavigationStarting(wv2, handlers->tokenNavigationStarting); |
1060 |
|
|
handlers->tokenNavigationStarting.value = 0; |
1061 |
|
|
} |
1062 |
|
|
|
1063 |
|
|
if (handlers->tokenNavigationCompleted.value) |
1064 |
|
|
{ |
1065 |
|
|
wv2->lpVtbl->remove_NavigationCompleted(wv2, handlers->tokenNavigationCompleted); |
1066 |
|
|
handlers->tokenNavigationCompleted.value = 0; |
1067 |
|
|
} |
1068 |
|
|
} |
1069 |
|
|
|
1070 |
|
|
|
1071 |
|
|
|
1072 |
|
|
static ULONG STDMETHODCALLTYPE wv2_event_handlers_AddRef(IUnknown* This) |
1073 |
|
|
{ |
1074 |
|
|
wv2_event_handlers_t* handlers = (wv2_event_handlers_t*)This; |
1075 |
|
|
return (ULONG)gate_atomic_int_inc(&handlers->ref_counter); |
1076 |
|
|
} |
1077 |
|
|
|
1078 |
|
|
static ULONG STDMETHODCALLTYPE wv2_event_handlers_Release(IUnknown* This) |
1079 |
|
|
{ |
1080 |
|
|
wv2_event_handlers_t* handlers = (wv2_event_handlers_t*)This; |
1081 |
|
|
ULONG cnt = (ULONG)gate_atomic_int_dec(&handlers->ref_counter); |
1082 |
|
|
if (cnt == 0) |
1083 |
|
|
{ |
1084 |
|
|
wv2_event_handlers_detach_events(handlers); |
1085 |
|
|
gate_mem_dealloc(handlers); |
1086 |
|
|
} |
1087 |
|
|
return cnt; |
1088 |
|
|
} |
1089 |
|
|
static HRESULT STDMETHODCALLTYPE wv2_event_handlers_QueryInterface(IUnknown* This, REFIID riid, void** ppvObject) |
1090 |
|
|
{ |
1091 |
|
|
wv2_event_handlers_t* handlers = (wv2_event_handlers_t*)This; |
1092 |
|
|
if (!ppvObject || !riid || !This) |
1093 |
|
|
{ |
1094 |
|
|
return E_INVALIDARG; |
1095 |
|
|
} |
1096 |
|
|
|
1097 |
|
|
if (IsEqualGUID(riid, &gate_IID_IUnknown)) |
1098 |
|
|
{ |
1099 |
|
|
*ppvObject = This; |
1100 |
|
|
wv2_event_handlers_AddRef(This); |
1101 |
|
|
return S_OK; |
1102 |
|
|
} |
1103 |
|
|
if (IsEqualGUID(riid, &IID_ICoreWebView2NewWindowRequestedEventHandler)) |
1104 |
|
|
{ |
1105 |
|
|
*ppvObject = &handlers->NewWindowRequested; |
1106 |
|
|
wv2_event_handlers_AddRef(This); |
1107 |
|
|
return S_OK; |
1108 |
|
|
} |
1109 |
|
|
if (IsEqualGUID(riid, &IID_ICoreWebView2NavigationStartingEventHandler)) |
1110 |
|
|
{ |
1111 |
|
|
*ppvObject = &handlers->NavigationStarting; |
1112 |
|
|
wv2_event_handlers_AddRef(This); |
1113 |
|
|
return S_OK; |
1114 |
|
|
} |
1115 |
|
|
if (IsEqualGUID(riid, &IID_ICoreWebView2NavigationCompletedEventHandler)) |
1116 |
|
|
{ |
1117 |
|
|
*ppvObject = &handlers->NavigationCompleted; |
1118 |
|
|
wv2_event_handlers_AddRef(This); |
1119 |
|
|
return S_OK; |
1120 |
|
|
} |
1121 |
|
|
|
1122 |
|
|
return E_NOTIMPL; |
1123 |
|
|
} |
1124 |
|
|
|
1125 |
|
|
static IUnknownVtbl IUnknown_wv2_event_handlers_vtbl = { |
1126 |
|
|
&wv2_event_handlers_QueryInterface, |
1127 |
|
|
&wv2_event_handlers_AddRef, |
1128 |
|
|
&wv2_event_handlers_Release |
1129 |
|
|
}; |
1130 |
|
|
|
1131 |
|
|
#define CREATE_WV2_EVENT_HANDLER_VTBL(event_name, iface_type, sender_type, args_type) \ |
1132 |
|
|
static HRESULT STDMETHODCALLTYPE event_name ## _QueryInterface ( iface_type * This, REFIID riid, void** ppvObject) \ |
1133 |
|
|
{ \ |
1134 |
|
|
char* const this_ptr = (char*)This; \ |
1135 |
|
|
static size_t const obj_pos = offsetof(wv2_event_handlers_t, event_name); \ |
1136 |
|
|
IUnknown* unk_ptr = (IUnknown*)(this_ptr - obj_pos); \ |
1137 |
|
|
return wv2_event_handlers_QueryInterface(unk_ptr, riid, ppvObject); \ |
1138 |
|
|
} \ |
1139 |
|
|
static ULONG STDMETHODCALLTYPE event_name ## _AddRef ( iface_type * This) \ |
1140 |
|
|
{ \ |
1141 |
|
|
char* const this_ptr = (char*)This; \ |
1142 |
|
|
static size_t const obj_pos = offsetof(wv2_event_handlers_t, event_name); \ |
1143 |
|
|
IUnknown* unk_ptr = (IUnknown*)(this_ptr - obj_pos); \ |
1144 |
|
|
return wv2_event_handlers_AddRef(unk_ptr); \ |
1145 |
|
|
} \ |
1146 |
|
|
static ULONG STDMETHODCALLTYPE event_name ## _Release( iface_type * This) \ |
1147 |
|
|
{ \ |
1148 |
|
|
char* const this_ptr = (char*)This; \ |
1149 |
|
|
static size_t const obj_pos = offsetof(wv2_event_handlers_t, event_name); \ |
1150 |
|
|
IUnknown* unk_ptr = (IUnknown*)(this_ptr - obj_pos); \ |
1151 |
|
|
return wv2_event_handlers_Release(unk_ptr); \ |
1152 |
|
|
} \ |
1153 |
|
|
static HRESULT STDMETHODCALLTYPE event_name ## _Invoke( iface_type * This, sender_type sender, args_type args) \ |
1154 |
|
|
{ \ |
1155 |
|
|
char* const this_ptr = (char*)This; \ |
1156 |
|
|
static size_t const obj_pos = offsetof(wv2_event_handlers_t, event_name); \ |
1157 |
|
|
wv2_event_handlers_t* evt_handlers_ptr = (wv2_event_handlers_t*)(this_ptr - obj_pos); \ |
1158 |
|
|
return event_name ## _wv2_callback (evt_handlers_ptr, sender, args); \ |
1159 |
|
|
} \ |
1160 |
|
|
static iface_type ## Vtbl event_name ## _wv2_event_handlers_vtbl = { \ |
1161 |
|
|
& event_name ## _QueryInterface, \ |
1162 |
|
|
& event_name ## _AddRef, \ |
1163 |
|
|
& event_name ## _Release, \ |
1164 |
|
|
& event_name ## _Invoke \ |
1165 |
|
|
} |
1166 |
|
|
|
1167 |
|
|
|
1168 |
|
|
|
1169 |
|
|
typedef struct NewWindowRequested_task_class |
1170 |
|
|
{ |
1171 |
|
|
GATE_INTERFACE_VTBL(gate_runnable) const* vtbl; |
1172 |
|
|
|
1173 |
|
|
gate_atomic_int_t ref_counter; |
1174 |
|
|
ICoreWebView2NewWindowRequestedEventArgs* args; |
1175 |
|
|
ICoreWebView2Deferral* deferral; |
1176 |
|
|
gate_ui_webview_t* webview; |
1177 |
|
|
} NewWindowRequested_task_t; |
1178 |
|
|
|
1179 |
|
|
static char const* NewWindowRequested_task_get_interface_name(void* ptr) |
1180 |
|
|
{ |
1181 |
|
|
return GATE_INTERFACE_NAME_RUNNABLE; |
1182 |
|
|
} |
1183 |
|
|
static void NewWindowRequested_task_release(void* ptr) |
1184 |
|
|
{ |
1185 |
|
|
NewWindowRequested_task_t* self = (NewWindowRequested_task_t*)ptr; |
1186 |
|
|
if (0 == gate_atomic_int_dec(&self->ref_counter)) |
1187 |
|
|
{ |
1188 |
|
|
self->deferral->lpVtbl->Release(self->deferral); |
1189 |
|
|
self->args->lpVtbl->Release(self->args); |
1190 |
|
|
} |
1191 |
|
|
} |
1192 |
|
|
static int NewWindowRequested_task_retain(void* ptr) |
1193 |
|
|
{ |
1194 |
|
|
NewWindowRequested_task_t* self = (NewWindowRequested_task_t*)ptr; |
1195 |
|
|
return (int)gate_atomic_int_inc(&self->ref_counter); |
1196 |
|
|
} |
1197 |
|
|
static gate_result_t NewWindowRequested_task_run(void* ptr) |
1198 |
|
|
{ |
1199 |
|
|
NewWindowRequested_task_t* self = (NewWindowRequested_task_t*)ptr; |
1200 |
|
|
gate_ui_webview_t* ptr_new_webview = NULL; |
1201 |
|
|
|
1202 |
|
|
self->webview->on_new_window(&self->webview->ctrl, &ptr_new_webview); |
1203 |
|
|
if (ptr_new_webview) |
1204 |
|
|
{ |
1205 |
|
|
gate_ui_webview_impl_t* impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(&ptr_new_webview->ctrl); |
1206 |
|
|
self->args->lpVtbl->put_Handled(self->args, TRUE); |
1207 |
|
|
self->args->lpVtbl->put_NewWindow(self->args, impl->wv2); |
1208 |
|
|
} |
1209 |
|
|
self->deferral->lpVtbl->Complete(self->deferral); |
1210 |
|
|
return GATE_RESULT_OK; |
1211 |
|
|
} |
1212 |
|
|
GATE_INTERFACE_VTBL(gate_runnable) const NewWindowRequested_task_vtbl = { |
1213 |
|
|
&NewWindowRequested_task_get_interface_name, |
1214 |
|
|
&NewWindowRequested_task_release, |
1215 |
|
|
&NewWindowRequested_task_retain, |
1216 |
|
|
&NewWindowRequested_task_run |
1217 |
|
|
}; |
1218 |
|
|
|
1219 |
|
|
static HRESULT NewWindowRequested_wv2_callback(wv2_event_handlers_t* handlers, ICoreWebView2* sender, ICoreWebView2NewWindowRequestedEventArgs* args) |
1220 |
|
|
{ |
1221 |
|
|
gate_ui_webview_t* ptr_new_webview = NULL; |
1222 |
|
|
ICoreWebView2Deferral* deferral = NULL; |
1223 |
|
|
gate_ui_host_t* host = NULL; |
1224 |
|
|
NewWindowRequested_task_t* task = NULL; |
1225 |
|
|
HRESULT hr; |
1226 |
|
|
|
1227 |
|
|
if (handlers && handlers->impl && handlers->impl->webview && handlers->impl->webview->on_new_window) |
1228 |
|
|
{ |
1229 |
|
|
host = GATE_UI_WINAPI_GET_HOST(&handlers->impl->webview->ctrl); |
1230 |
|
|
// gate_ui_host_execute(host, gate_runnable_create) |
1231 |
|
|
hr = args->lpVtbl->GetDeferral(args, &deferral); |
1232 |
|
|
if (SUCCEEDED(hr)) |
1233 |
|
|
{ |
1234 |
|
|
NewWindowRequested_task_t* task = gate_mem_alloc(sizeof(NewWindowRequested_task_t)); |
1235 |
|
|
if (!task) |
1236 |
|
|
{ |
1237 |
|
|
deferral->lpVtbl->Release(deferral); |
1238 |
|
|
} |
1239 |
|
|
else |
1240 |
|
|
{ |
1241 |
|
|
gate_mem_clear(task, sizeof(NewWindowRequested_task_t)); |
1242 |
|
|
task->vtbl = &NewWindowRequested_task_vtbl; |
1243 |
|
|
gate_atomic_int_init(&task->ref_counter, 1); |
1244 |
|
|
task->args = args; |
1245 |
|
|
task->deferral = deferral; |
1246 |
|
|
task->args->lpVtbl->AddRef(task->args); |
1247 |
|
|
task->deferral->lpVtbl->AddRef(task->deferral); |
1248 |
|
|
task->webview = handlers->impl->webview; |
1249 |
|
|
gate_ui_winapi_host_post_runner(host, (gate_runnable_t*)task, true, false); |
1250 |
|
|
task = NULL; |
1251 |
|
|
} |
1252 |
|
|
} |
1253 |
|
|
} |
1254 |
|
|
if (task) |
1255 |
|
|
{ |
1256 |
|
|
gate_object_release(task); |
1257 |
|
|
} |
1258 |
|
|
return S_OK; |
1259 |
|
|
} |
1260 |
|
|
CREATE_WV2_EVENT_HANDLER_VTBL(NewWindowRequested, ICoreWebView2NewWindowRequestedEventHandler, ICoreWebView2*, ICoreWebView2NewWindowRequestedEventArgs*); |
1261 |
|
|
|
1262 |
|
|
|
1263 |
|
|
static HRESULT NavigationStarting_wv2_callback(wv2_event_handlers_t* handlers, ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args) |
1264 |
|
|
{ |
1265 |
|
|
return S_OK; |
1266 |
|
|
} |
1267 |
|
|
CREATE_WV2_EVENT_HANDLER_VTBL(NavigationStarting, ICoreWebView2NavigationStartingEventHandler, ICoreWebView2*, ICoreWebView2NavigationStartingEventArgs*); |
1268 |
|
|
|
1269 |
|
|
|
1270 |
|
|
static HRESULT NavigationCompleted_wv2_callback(wv2_event_handlers_t* handlers, ICoreWebView2* sender, ICoreWebView2NavigationCompletedEventArgs* args) |
1271 |
|
|
{ |
1272 |
|
|
LPWSTR wstrUrl = NULL; |
1273 |
|
|
HRESULT hr; |
1274 |
|
|
gate_string_t url = GATE_STRING_INIT_EMPTY; |
1275 |
|
|
|
1276 |
|
|
if (handlers && handlers->impl && handlers->impl->webview && handlers->impl->webview->on_navigate_complete) |
1277 |
|
|
{ |
1278 |
|
|
hr = sender->lpVtbl->get_Source(sender, &wstrUrl); |
1279 |
|
|
if (SUCCEEDED(hr)) |
1280 |
|
|
{ |
1281 |
|
|
gate_string_create_utf16(&url, wstrUrl, gate_str16_length(wstrUrl)); |
1282 |
|
|
} |
1283 |
|
|
handlers->impl->webview->on_navigate_complete(&handlers->impl->webview->ctrl, &url); |
1284 |
|
|
} |
1285 |
|
|
gate_string_release(&url); |
1286 |
|
|
if (wstrUrl) |
1287 |
|
|
{ |
1288 |
|
|
// CoTaskMemFree needs to free the URL |
1289 |
|
|
gate_win32_com_dealloc(wstrUrl); |
1290 |
|
|
} |
1291 |
|
|
return S_OK; |
1292 |
|
|
} |
1293 |
|
|
CREATE_WV2_EVENT_HANDLER_VTBL(NavigationCompleted, ICoreWebView2NavigationCompletedEventHandler, ICoreWebView2*, ICoreWebView2NavigationCompletedEventArgs*); |
1294 |
|
|
|
1295 |
|
|
|
1296 |
|
|
|
1297 |
|
|
|
1298 |
|
|
static wv2_event_handlers_t* create_webview2_event_handlers(gate_ui_webview_impl_t* impl) |
1299 |
|
|
{ |
1300 |
|
|
wv2_event_handlers_t* handlers = NULL; |
1301 |
|
|
do |
1302 |
|
|
{ |
1303 |
|
|
handlers = (wv2_event_handlers_t*)gate_mem_alloc(sizeof(wv2_event_handlers_t)); |
1304 |
|
|
if (NULL == handlers) |
1305 |
|
|
{ |
1306 |
|
|
break; |
1307 |
|
|
} |
1308 |
|
|
gate_mem_clear(handlers, sizeof(wv2_event_handlers_t)); |
1309 |
|
|
gate_atomic_int_init(&handlers->ref_counter, 1); |
1310 |
|
|
|
1311 |
|
|
handlers->impl = impl; |
1312 |
|
|
handlers->vtblUnkown = &IUnknown_wv2_event_handlers_vtbl; |
1313 |
|
|
handlers->NewWindowRequested.lpVtbl = &NewWindowRequested_wv2_event_handlers_vtbl; |
1314 |
|
|
handlers->NavigationStarting.lpVtbl = &NavigationStarting_wv2_event_handlers_vtbl; |
1315 |
|
|
handlers->NavigationCompleted.lpVtbl = &NavigationCompleted_wv2_event_handlers_vtbl; |
1316 |
|
|
|
1317 |
|
|
wv2_event_handlers_attach_events(handlers); |
1318 |
|
|
} while (0); |
1319 |
|
|
return handlers; |
1320 |
|
|
|
1321 |
|
|
} |
1322 |
|
|
|
1323 |
|
|
static gate_ui_webview_impl_t* create_webview2_impl(gate_ui_webview_t* webview, ICoreWebView2Controller* controller) |
1324 |
|
|
{ |
1325 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
1326 |
|
|
wv2_event_handlers_t* handlers = NULL; |
1327 |
|
|
HRESULT hr; |
1328 |
|
|
|
1329 |
|
|
do |
1330 |
|
|
{ |
1331 |
|
|
impl = (gate_ui_webview_impl_t*)gate_mem_alloc(sizeof(gate_ui_webview_impl_t)); |
1332 |
|
|
if (!impl) |
1333 |
|
|
{ |
1334 |
|
|
break; |
1335 |
|
|
} |
1336 |
|
|
|
1337 |
|
|
gate_mem_clear(impl, sizeof(gate_ui_webview_impl_t)); |
1338 |
|
|
impl->webview = webview; |
1339 |
|
|
impl->wv2_controller = controller; |
1340 |
|
|
hr = impl->wv2_controller->lpVtbl->get_CoreWebView2(impl->wv2_controller, &impl->wv2); |
1341 |
|
|
if (FAILED(hr)) |
1342 |
|
|
{ |
1343 |
|
|
gate_mem_dealloc(impl); |
1344 |
|
|
impl = NULL; |
1345 |
|
|
break; |
1346 |
|
|
} |
1347 |
|
|
handlers = create_webview2_event_handlers(impl); |
1348 |
|
|
if (!handlers) |
1349 |
|
|
{ |
1350 |
|
|
gate_mem_dealloc(impl); |
1351 |
|
|
impl = NULL; |
1352 |
|
|
break; |
1353 |
|
|
} |
1354 |
|
|
impl->wv2_event_handlers = (IUnknown*)handlers; |
1355 |
|
|
|
1356 |
|
|
hr = impl->wv2_controller->lpVtbl->put_IsVisible(impl->wv2_controller, TRUE); |
1357 |
|
|
|
1358 |
|
|
} while (0); |
1359 |
|
|
|
1360 |
|
|
return impl; |
1361 |
|
|
} |
1362 |
|
|
|
1363 |
|
|
|
1364 |
|
|
static gate_result_t gate_ui_webview_create_wv2(gate_ui_webview_t* webview, gate_ui_ctrl_t* parent, |
1365 |
|
|
gate_ui_position_t const* position, gate_uint32_t flags, void* userparam) |
1366 |
|
|
{ |
1367 |
|
|
gate_result_t ret; |
1368 |
|
|
HRESULT hr; |
1369 |
|
|
HWND hwnd_parent = NULL; |
1370 |
|
|
HWND hwnd_ctrl = NULL; |
1371 |
|
|
gate_ui_host_t* host = NULL; |
1372 |
|
|
gate_uint32_t exstyles = 0; |
1373 |
|
|
gate_uint32_t styles = 0; |
1374 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
1375 |
|
|
ICoreWebView2Controller* controller = NULL; |
1376 |
|
|
static ICoreWebView2Environment* global_wv2_environment = NULL; |
1377 |
|
|
|
1378 |
|
|
host = GATE_UI_WINAPI_GET_HOST(parent); |
1379 |
|
|
hwnd_parent = GATE_UI_WINAPI_GET_HWND(parent); |
1380 |
|
|
|
1381 |
|
|
do |
1382 |
|
|
{ |
1383 |
|
|
ret = gate_win32_com_init(); |
1384 |
|
|
|
1385 |
|
|
ret = load_webview2(); |
1386 |
|
|
GATE_BREAK_IF_FAILED(ret); |
1387 |
|
|
|
1388 |
|
|
if (global_wv2_environment == NULL) |
1389 |
|
|
{ |
1390 |
|
|
ret = wv2_event_init(&wv2_env_completed.semaphore); |
1391 |
|
|
GATE_BREAK_IF_FAILED(ret); |
1392 |
|
|
|
1393 |
|
|
wv2_env_completed.env = NULL; |
1394 |
|
|
hr = webview2_loader.CreateCoreWebView2EnvironmentWithOptions(NULL, NULL, NULL, (ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*)&wv2_env_completed); |
1395 |
|
|
|
1396 |
|
|
wv2_event_await(wv2_env_completed.semaphore); |
1397 |
|
|
if (!wv2_env_completed.env) |
1398 |
|
|
{ |
1399 |
|
|
break; |
1400 |
|
|
} |
1401 |
|
|
global_wv2_environment = wv2_env_completed.env; |
1402 |
|
|
} |
1403 |
|
|
|
1404 |
|
|
exstyles = 0; |
1405 |
|
|
#if !defined(GATE_SYS_WINCE) |
1406 |
|
|
exstyles |= WS_EX_CONTROLPARENT; |
1407 |
|
|
#endif |
1408 |
|
|
styles = WS_GROUP | WS_CHILD | WS_TABSTOP | WS_CLIPCHILDREN; |
1409 |
|
|
if (!GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_ENABLED)) styles |= WS_DISABLED; |
1410 |
|
|
if (GATE_FLAG_ENABLED(flags, GATE_UI_FLAG_VISIBLE)) styles |= WS_VISIBLE; |
1411 |
|
|
|
1412 |
|
|
ret = gate_ui_winapi_create(&webview->ctrl, host, hwnd_parent, NULL, position, styles, exstyles, NULL, userparam, false); |
1413 |
|
|
GATE_BREAK_IF_FAILED(ret); |
1414 |
|
|
|
1415 |
|
|
GATE_UI_WINAPI_SET_DISPATCHER(&webview->ctrl, &global_webview_dispatchers); |
1416 |
|
|
hwnd_ctrl = GATE_UI_WINAPI_GET_HWND(&webview->ctrl); |
1417 |
|
|
|
1418 |
|
|
ret = wv2_event_init(&wv2_ctrl_completed.semaphore); |
1419 |
|
|
GATE_BREAK_IF_FAILED(ret); |
1420 |
|
|
|
1421 |
|
|
wv2_ctrl_completed.ctrl = NULL; |
1422 |
|
|
hr = global_wv2_environment->lpVtbl->CreateCoreWebView2Controller(global_wv2_environment, hwnd_ctrl, (ICoreWebView2CreateCoreWebView2ControllerCompletedHandler*)&wv2_ctrl_completed); |
1423 |
|
|
|
1424 |
|
|
ret = wv2_event_await(wv2_ctrl_completed.semaphore); |
1425 |
|
|
if (!wv2_ctrl_completed.ctrl) |
1426 |
|
|
{ |
1427 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
1428 |
|
|
break; |
1429 |
|
|
} |
1430 |
|
|
controller = wv2_ctrl_completed.ctrl; |
1431 |
|
|
wv2_ctrl_completed.ctrl = NULL; |
1432 |
|
|
|
1433 |
|
|
impl = create_webview2_impl(webview, controller); |
1434 |
|
|
if (impl == NULL) |
1435 |
|
|
{ |
1436 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
1437 |
|
|
break; |
1438 |
|
|
} |
1439 |
|
|
GATE_UI_WINAPI_SET_CTRL_PARAM(&webview->ctrl, impl); |
1440 |
|
|
|
1441 |
|
|
gate_ui_winapi_register_event(host, (void*)hwnd_ctrl, WM_SIZE, &webview_windowproc_events, &webview->ctrl); |
1442 |
|
|
|
1443 |
|
|
ret = GATE_RESULT_OK; |
1444 |
|
|
} while (0); |
1445 |
|
|
|
1446 |
|
|
if (GATE_FAILED(ret)) |
1447 |
|
|
{ |
1448 |
|
|
if (controller) |
1449 |
|
|
{ |
1450 |
|
|
controller->lpVtbl->Release(controller); |
1451 |
|
|
} |
1452 |
|
|
if (hwnd_ctrl) |
1453 |
|
|
{ |
1454 |
|
|
gate_ui_winapi_destroy(&webview->ctrl); |
1455 |
|
|
} |
1456 |
|
|
if (impl != NULL) |
1457 |
|
|
{ |
1458 |
|
|
} |
1459 |
|
|
} |
1460 |
|
|
|
1461 |
|
|
return ret; |
1462 |
|
|
} |
1463 |
|
|
|
1464 |
|
|
static gate_result_t wv2_navigate_to(gate_ui_webview_impl_t* impl, gate_string_t const* address) |
1465 |
|
|
{ |
1466 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1467 |
|
|
gate_cstrbuffer16_t buffer = GATE_INIT_EMPTY; |
1468 |
|
|
HRESULT hr; |
1469 |
|
|
|
1470 |
|
|
do |
1471 |
|
|
{ |
1472 |
|
|
if (NULL == gate_cstrbuffer16_create_string(&buffer, address)) |
1473 |
|
|
{ |
1474 |
|
|
ret = GATE_RESULT_OUTOFMEMORY; |
1475 |
|
|
break; |
1476 |
|
|
} |
1477 |
|
|
hr = impl->wv2->lpVtbl->Navigate(impl->wv2, gate_cstrbuffer16_get(&buffer)); |
1478 |
|
|
if (FAILED(hr)) |
1479 |
|
|
{ |
1480 |
|
|
ret = GATE_RESULT_FAILED; |
1481 |
|
|
break; |
1482 |
|
|
} |
1483 |
|
|
|
1484 |
|
|
ret = GATE_RESULT_OK; |
1485 |
|
|
} while (0); |
1486 |
|
|
|
1487 |
|
|
gate_cstrbuffer16_destroy(&buffer); |
1488 |
|
|
return ret; |
1489 |
|
|
} |
1490 |
|
|
|
1491 |
|
|
static gate_result_t wv2_execute(gate_ui_webview_impl_t* impl, gate_enumint_t command) |
1492 |
|
|
{ |
1493 |
|
|
HRESULT hr; |
1494 |
|
|
|
1495 |
|
|
switch (command) |
1496 |
|
|
{ |
1497 |
|
|
case GATE_UI_WEBVIEW_COMMAND_STOP: |
1498 |
|
|
{ |
1499 |
|
|
hr = impl->wv2->lpVtbl->Stop(impl->wv2); |
1500 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
1501 |
|
|
} |
1502 |
|
|
case GATE_UI_WEBVIEW_COMMAND_REFRESH: |
1503 |
|
|
{ |
1504 |
|
|
hr = impl->wv2->lpVtbl->Reload(impl->wv2); |
1505 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
1506 |
|
|
} |
1507 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GOHOME: |
1508 |
|
|
{ |
1509 |
|
|
break; |
1510 |
|
|
} |
1511 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GOBACK: |
1512 |
|
|
{ |
1513 |
|
|
hr = impl->wv2->lpVtbl->GoBack(impl->wv2); |
1514 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
1515 |
|
|
} |
1516 |
|
|
case GATE_UI_WEBVIEW_COMMAND_GONEXT: |
1517 |
|
|
{ |
1518 |
|
|
hr = impl->wv2->lpVtbl->GoForward(impl->wv2); |
1519 |
|
|
return SUCCEEDED(hr) ? GATE_RESULT_OK : GATE_RESULT_FAILED; |
1520 |
|
|
} |
1521 |
|
|
} |
1522 |
|
|
return GATE_RESULT_NOTSUPPORTED; |
1523 |
|
|
} |
1524 |
|
|
#endif /* GATE_UI_WEBVIEW_EDGEWV2_IMPL */ |
1525 |
|
|
|
1526 |
|
|
|
1527 |
|
|
|
1528 |
|
|
|
1529 |
|
|
|
1530 |
|
|
/*******************************/ |
1531 |
|
|
/* */ |
1532 |
|
|
/* GATE webview control code: */ |
1533 |
|
|
/* */ |
1534 |
|
|
/*******************************/ |
1535 |
|
|
|
1536 |
|
|
|
1537 |
|
|
static gate_result_t webview_destroy_impl(gate_ui_ctrl_t* ctrl) |
1538 |
|
|
{ |
1539 |
|
|
gate_ui_webview_impl_t* impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(ctrl); |
1540 |
|
|
|
1541 |
|
|
GATE_UI_WINAPI_SET_CTRL_PARAM(ctrl, NULL); |
1542 |
|
|
|
1543 |
|
|
if (impl != NULL) |
1544 |
|
|
{ |
1545 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
1546 |
|
|
|
1547 |
|
|
if (impl->wv2_event_handlers) |
1548 |
|
|
{ |
1549 |
|
|
wv2_event_handlers_t* wv2_handlers = (wv2_event_handlers_t*)impl->wv2_event_handlers; |
1550 |
|
|
wv2_event_handlers_detach_events(wv2_handlers); |
1551 |
|
|
impl->wv2_event_handlers->lpVtbl->Release(impl->wv2_event_handlers); |
1552 |
|
|
impl->wv2_event_handlers = NULL; |
1553 |
|
|
} |
1554 |
|
|
if (impl->wv2) |
1555 |
|
|
{ |
1556 |
|
|
impl->wv2->lpVtbl->Release(impl->wv2); |
1557 |
|
|
impl->wv2 = NULL; |
1558 |
|
|
} |
1559 |
|
|
if (impl->wv2_controller) |
1560 |
|
|
{ |
1561 |
|
|
impl->wv2_controller->lpVtbl->Close(impl->wv2_controller); |
1562 |
|
|
impl->wv2_controller->lpVtbl->Release(impl->wv2_controller); |
1563 |
|
|
impl->wv2_controller = NULL; |
1564 |
|
|
} |
1565 |
|
|
#endif |
1566 |
|
|
|
1567 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
1568 |
|
|
if (impl->webbrowser2) |
1569 |
|
|
{ |
1570 |
|
|
impl->webbrowser2->lpVtbl->Release(impl->webbrowser2); |
1571 |
|
|
impl->webbrowser2 = NULL; |
1572 |
|
|
} |
1573 |
|
|
|
1574 |
|
|
if (impl->webbrowser) |
1575 |
|
|
{ |
1576 |
|
|
impl->webbrowser->lpVtbl->Release(impl->webbrowser); |
1577 |
|
|
impl->webbrowser = NULL; |
1578 |
|
|
} |
1579 |
|
|
if (impl->webbrowser_events) |
1580 |
|
|
{ |
1581 |
|
|
impl->webbrowser_events->lpVtbl->Release(impl->webbrowser_events); |
1582 |
|
|
impl->webbrowser_events = NULL; |
1583 |
|
|
} |
1584 |
|
|
#endif |
1585 |
|
|
|
1586 |
|
|
impl->webview = NULL; |
1587 |
|
|
if (impl->hwnd) |
1588 |
|
|
{ |
1589 |
|
|
DestroyWindow(impl->hwnd); |
1590 |
|
|
impl->hwnd = NULL; |
1591 |
|
|
} |
1592 |
|
|
gate_mem_dealloc(impl); |
1593 |
|
|
} |
1594 |
|
|
return gate_ui_winapi_destroy(ctrl); |
1595 |
|
|
} |
1596 |
|
|
|
1597 |
|
|
|
1598 |
|
|
static gate_bool_t webview_windowproc_events(void* hwnd, gate_ui_ctrl_t* ctrl, gate_uint32_t msg, gate_uintptr_t wParam, gate_intptr_t lParam, gate_intptr_t* lresult) |
1599 |
|
|
{ |
1600 |
|
|
HWND hwndctrl; |
1601 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
1602 |
|
|
RECT rect; |
1603 |
|
|
|
1604 |
|
|
if (!ctrl) |
1605 |
|
|
{ |
1606 |
|
|
return false; |
1607 |
|
|
} |
1608 |
|
|
|
1609 |
|
|
hwndctrl = GATE_UI_WINAPI_GET_HWND(ctrl); |
1610 |
|
|
impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(ctrl); |
1611 |
|
|
if (!hwndctrl || !impl || (hwndctrl != hwnd)) |
1612 |
|
|
{ |
1613 |
|
|
return false; |
1614 |
|
|
} |
1615 |
|
|
|
1616 |
|
|
switch (msg) |
1617 |
|
|
{ |
1618 |
|
|
case WM_SIZE: |
1619 |
|
|
{ |
1620 |
|
|
GetClientRect(hwndctrl, &rect); |
1621 |
|
|
|
1622 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
1623 |
|
|
if (impl->wv2_controller) |
1624 |
|
|
{ |
1625 |
|
|
impl->wv2_controller->lpVtbl->put_Bounds(impl->wv2_controller, rect); |
1626 |
|
|
} |
1627 |
|
|
#endif |
1628 |
|
|
|
1629 |
|
|
if (impl->hwnd) |
1630 |
|
|
{ |
1631 |
|
|
SetWindowPos(impl->hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, |
1632 |
|
|
SWP_DRAWFRAME | SWP_FRAMECHANGED | SWP_SHOWWINDOW); |
1633 |
|
|
*lresult = 0; |
1634 |
|
|
return true; |
1635 |
|
|
} |
1636 |
|
|
break; |
1637 |
|
|
} |
1638 |
|
|
} |
1639 |
|
|
return false; |
1640 |
|
|
} |
1641 |
|
|
|
1642 |
|
|
|
1643 |
|
|
|
1644 |
|
|
|
1645 |
|
|
|
1646 |
|
|
|
1647 |
|
|
|
1648 |
|
|
|
1649 |
|
|
|
1650 |
|
|
|
1651 |
|
|
|
1652 |
|
|
gate_result_t gate_ui_webview_create(gate_ui_webview_t* webview, gate_ui_ctrl_t* parent, |
1653 |
|
|
gate_ui_position_t const* position, gate_uint32_t flags, void* userparam) |
1654 |
|
|
{ |
1655 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1656 |
|
|
do |
1657 |
|
|
{ |
1658 |
|
|
|
1659 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
1660 |
|
|
ret = gate_ui_webview_create_wv2(webview, parent, position, flags, userparam); |
1661 |
|
|
if (GATE_SUCCEEDED(ret)) |
1662 |
|
|
{ |
1663 |
|
|
break; |
1664 |
|
|
} |
1665 |
|
|
#endif |
1666 |
|
|
|
1667 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
1668 |
|
|
ret = gate_ui_webview_create_activex(webview, parent, position, flags, userparam); |
1669 |
|
|
if (GATE_SUCCEEDED(ret)) |
1670 |
|
|
{ |
1671 |
|
|
break; |
1672 |
|
|
} |
1673 |
|
|
#endif |
1674 |
|
|
|
1675 |
|
|
} while (0); |
1676 |
|
|
return ret; |
1677 |
|
|
} |
1678 |
|
|
|
1679 |
|
|
|
1680 |
|
|
|
1681 |
|
|
|
1682 |
|
|
gate_result_t gate_ui_webview_navigate_to(gate_ui_webview_t* webview, gate_string_t const* address) |
1683 |
|
|
{ |
1684 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1685 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
1686 |
|
|
|
1687 |
|
|
if (webview) |
1688 |
|
|
{ |
1689 |
|
|
impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(&webview->ctrl); |
1690 |
|
|
} |
1691 |
|
|
|
1692 |
|
|
do |
1693 |
|
|
{ |
1694 |
|
|
if (!impl) |
1695 |
|
|
{ |
1696 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
1697 |
|
|
break; |
1698 |
|
|
} |
1699 |
|
|
|
1700 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
1701 |
|
|
if (impl->wv2) |
1702 |
|
|
{ |
1703 |
|
|
ret = wv2_navigate_to(impl, address); |
1704 |
|
|
break; |
1705 |
|
|
} |
1706 |
|
|
#endif |
1707 |
|
|
|
1708 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
1709 |
|
|
if (impl->webbrowser || impl->webbrowser2) |
1710 |
|
|
{ |
1711 |
|
|
ret = webbrowser_navigate_to(impl, address); |
1712 |
|
|
break; |
1713 |
|
|
} |
1714 |
|
|
#endif |
1715 |
|
|
|
1716 |
|
|
} while (0); |
1717 |
|
|
|
1718 |
|
|
return ret; |
1719 |
|
|
} |
1720 |
|
|
|
1721 |
|
|
|
1722 |
|
|
|
1723 |
|
|
|
1724 |
|
|
gate_result_t gate_ui_webview_execute(gate_ui_webview_t* webview, gate_enumint_t command) |
1725 |
|
|
{ |
1726 |
|
|
gate_result_t ret = GATE_RESULT_FAILED; |
1727 |
|
|
gate_ui_webview_impl_t* impl = NULL; |
1728 |
|
|
|
1729 |
|
|
do |
1730 |
|
|
{ |
1731 |
|
|
if (webview) |
1732 |
|
|
{ |
1733 |
|
|
impl = (gate_ui_webview_impl_t*)GATE_UI_WINAPI_GET_CTRL_PARAM(&webview->ctrl); |
1734 |
|
|
} |
1735 |
|
|
if (!impl) |
1736 |
|
|
{ |
1737 |
|
|
ret = GATE_RESULT_NOTAVAILABLE; |
1738 |
|
|
break; |
1739 |
|
|
} |
1740 |
|
|
|
1741 |
|
|
#ifdef GATE_UI_WEBVIEW_EDGEWV2_IMPL |
1742 |
|
|
if (impl->wv2) |
1743 |
|
|
{ |
1744 |
|
|
ret = wv2_execute(impl, command); |
1745 |
|
|
break; |
1746 |
|
|
} |
1747 |
|
|
#endif |
1748 |
|
|
|
1749 |
|
|
#ifdef GATE_UI_WEBVIEW_ATLWEBBROWSER_IMPL |
1750 |
|
|
if (impl->webbrowser || impl->webbrowser2) |
1751 |
|
|
{ |
1752 |
|
|
ret = webbrowser_execute(impl, command); |
1753 |
|
|
break; |
1754 |
|
|
} |
1755 |
|
|
#endif |
1756 |
|
|
|
1757 |
|
|
} while (0); |
1758 |
|
|
|
1759 |
|
|
return ret; |
1760 |
|
|
} |
1761 |
|
|
|
1762 |
|
|
|
1763 |
|
|
#endif |
1764 |
|
|
|
1765 |
|
|
#if defined(GATE_UI_GTK) |
1766 |
|
|
|
1767 |
|
|
gate_result_t gate_ui_webview_create(gate_ui_webview_t* webview, gate_ui_ctrl_t* parent, |
1768 |
|
|
gate_ui_position_t const* position, gate_uint32_t flags, void* userparam) |
1769 |
|
|
{ |
1770 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1771 |
|
|
} |
1772 |
|
|
|
1773 |
|
|
gate_result_t gate_ui_webview_navigate_to(gate_ui_webview_t* webview, gate_string_t const* address) |
1774 |
|
|
{ |
1775 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1776 |
|
|
} |
1777 |
|
|
|
1778 |
|
|
gate_result_t gate_ui_webview_execute(gate_ui_webview_t* webview, gate_enumint_t command) |
1779 |
|
|
{ |
1780 |
|
|
return GATE_RESULT_NOTIMPLEMENTED; |
1781 |
|
|
} |
1782 |
|
|
|
1783 |
|
|
|
1784 |
|
|
#endif /* GATE_UI_GTK */ |
1785 |
|
|
|
1786 |
|
|
|
1787 |
|
|
|
1788 |
|
|
#if defined(GATE_UI_MOTIF) |
1789 |
|
|
|
1790 |
|
✗ |
gate_result_t gate_ui_webview_create(gate_ui_webview_t* webview, gate_ui_ctrl_t* parent, |
1791 |
|
|
gate_ui_position_t const* position, gate_uint32_t flags, void* userparam) |
1792 |
|
|
{ |
1793 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
1794 |
|
|
} |
1795 |
|
|
|
1796 |
|
✗ |
gate_result_t gate_ui_webview_navigate_to(gate_ui_webview_t* webview, gate_string_t const* address) |
1797 |
|
|
{ |
1798 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
1799 |
|
|
} |
1800 |
|
|
|
1801 |
|
✗ |
gate_result_t gate_ui_webview_execute(gate_ui_webview_t* webview, gate_enumint_t command) |
1802 |
|
|
{ |
1803 |
|
✗ |
return GATE_RESULT_NOTIMPLEMENTED; |
1804 |
|
|
} |
1805 |
|
|
|
1806 |
|
|
#endif /* GATE_UI_MOTIF */ |
1807 |
|
|
|