1313
1414#include " win32_wv2.hpp"
1515#include " WebView2.h"
16- #include < wrl.h>
1716#include < cstdio>
1817
19- using namespace Microsoft ::WRL;
18+ #ifdef _MSC_VER
19+ // MSVC: Use Windows Runtime Library
20+ #include < wrl.h>
21+ using namespace Microsoft ::WRL;
22+ #else
23+ // MinGW: Define our own ComPtr template
24+ template <typename T>
25+ class ComPtr {
26+ T* ptr;
27+ public:
28+ ComPtr () : ptr(nullptr ) {}
29+ ~ComPtr () { Reset (); }
30+ ComPtr (const ComPtr&) = delete ;
31+ ComPtr& operator =(const ComPtr&) = delete ;
32+
33+ void Reset () {
34+ if (ptr) {
35+ ptr->Release ();
36+ ptr = nullptr ;
37+ }
38+ }
39+
40+ T* Get () const { return ptr; }
41+ T** GetAddressOf () { Reset (); return &ptr; }
42+ T* operator ->() const { return ptr; }
43+ operator bool () const { return ptr != nullptr ; }
44+
45+ ComPtr& operator =(T* p) {
46+ Reset ();
47+ ptr = p;
48+ if (ptr) ptr->AddRef ();
49+ return *this ;
50+ }
51+ };
52+ #endif
2053
2154class WebView2Instance {
2255public:
@@ -37,73 +70,219 @@ class WebView2Instance {
3770 }
3871};
3972
40- class TitleChangedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2DocumentTitleChangedEventHandler> {
41- WebView2Instance* instance;
42- public:
43- TitleChangedHandler (WebView2Instance* inst) : instance(inst) {}
44- HRESULT STDMETHODCALLTYPE Invoke (ICoreWebView2* sender, IUnknown* args) override {
45- (void )args;
46- if (sender && instance->hwnd ) {
47- LPWSTR newTitle = nullptr ;
48- sender->get_DocumentTitle (&newTitle);
49- if (newTitle) {
50- SetWindowTextW (instance->hwnd , newTitle);
51- CoTaskMemFree (newTitle);
73+ #ifdef _MSC_VER
74+ // MSVC: Use WRL RuntimeClass
75+ class TitleChangedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2DocumentTitleChangedEventHandler> {
76+ WebView2Instance* instance;
77+ public:
78+ TitleChangedHandler (WebView2Instance* inst) : instance(inst) {}
79+ HRESULT STDMETHODCALLTYPE Invoke (ICoreWebView2* sender, IUnknown* args) override {
80+ (void )args;
81+ if (sender && instance->hwnd ) {
82+ LPWSTR newTitle = nullptr ;
83+ sender->get_DocumentTitle (&newTitle);
84+ if (newTitle) {
85+ SetWindowTextW (instance->hwnd , newTitle);
86+ CoTaskMemFree (newTitle);
87+ }
5288 }
89+ return S_OK;
90+ }
91+ };
92+ #else
93+ // MinGW: Manual COM implementation
94+ class TitleChangedHandler : public ICoreWebView2DocumentTitleChangedEventHandler {
95+ ULONG refCount;
96+ WebView2Instance* instance;
97+ public:
98+ TitleChangedHandler (WebView2Instance* inst) : refCount(1 ), instance(inst) {}
99+
100+ HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppvObject) override {
101+ if (!ppvObject) return E_POINTER;
102+ *ppvObject = nullptr ;
103+ if (riid == IID_IUnknown || riid == __uuidof (ICoreWebView2DocumentTitleChangedEventHandler)) {
104+ *ppvObject = static_cast <ICoreWebView2DocumentTitleChangedEventHandler*>(this );
105+ AddRef ();
106+ return S_OK;
107+ }
108+ return E_NOINTERFACE;
53109 }
54- return S_OK;
55- }
56- };
57110
58- class ControllerCompletedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> {
59- WebView2Instance* instance ;
60- public:
61- ControllerCompletedHandler (WebView2Instance* inst) : instance(inst) {}
62- HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Controller* controller ) override {
63- if ( SUCCEEDED (result) && controller) {
64- instance-> webviewController = controller ;
65- controller-> get_CoreWebView2 (&instance-> webviewWindow ) ;
66-
67- ComPtr<ICoreWebView2Settings> settings;
68- if ( SUCCEEDED (instance-> webviewWindow -> get_Settings (&settings))) {
69- settings-> put_IsScriptEnabled ( TRUE ) ;
70- settings-> put_AreDefaultScriptDialogsEnabled ( TRUE );
71- settings-> put_IsWebMessageEnabled ( TRUE ) ;
72- # ifdef WEBUI_LOG
73- settings-> put_AreDevToolsEnabled ( TRUE );
74- # else
75- settings-> put_AreDevToolsEnabled ( FALSE );
76- # endif
111+ ULONG STDMETHODCALLTYPE AddRef () override {
112+ return ++refCount ;
113+ }
114+
115+ ULONG STDMETHODCALLTYPE Release ( ) override {
116+ ULONG count = --refCount;
117+ if (count == 0 ) delete this ;
118+ return count ;
119+ }
120+
121+ HRESULT STDMETHODCALLTYPE Invoke (ICoreWebView2* sender, IUnknown* args) override {
122+ ( void )args ;
123+ if (sender && instance-> hwnd ) {
124+ LPWSTR newTitle = nullptr ;
125+ sender-> get_DocumentTitle (&newTitle);
126+ if (newTitle) {
127+ SetWindowTextW (instance-> hwnd , newTitle);
128+ CoTaskMemFree (newTitle );
129+ }
77130 }
131+ return S_OK;
132+ }
133+ };
134+ #endif
78135
79- RECT bounds = {0 , 0 , instance->width , instance->height };
80- controller->put_Bounds (bounds);
136+ #ifdef _MSC_VER
137+ class ControllerCompletedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2CreateCoreWebView2ControllerCompletedHandler> {
138+ WebView2Instance* instance;
139+ public:
140+ ControllerCompletedHandler (WebView2Instance* inst) : instance(inst) {}
141+ HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Controller* controller) override {
142+ if (SUCCEEDED (result) && controller) {
143+ instance->webviewController = controller;
144+ controller->get_CoreWebView2 (&instance->webviewWindow );
145+
146+ ComPtr<ICoreWebView2Settings> settings;
147+ if (SUCCEEDED (instance->webviewWindow ->get_Settings (&settings))) {
148+ settings->put_IsScriptEnabled (TRUE );
149+ settings->put_AreDefaultScriptDialogsEnabled (TRUE );
150+ settings->put_IsWebMessageEnabled (TRUE );
151+ #ifdef WEBUI_LOG
152+ settings->put_AreDevToolsEnabled (TRUE );
153+ #else
154+ settings->put_AreDevToolsEnabled (FALSE );
155+ #endif
156+ }
157+
158+ RECT bounds = {0 , 0 , instance->width , instance->height };
159+ controller->put_Bounds (bounds);
160+
161+ auto titleHandler = Make<TitleChangedHandler>(instance);
162+ EventRegistrationToken token;
163+ instance->webviewWindow ->add_DocumentTitleChanged (titleHandler.Get (), &token);
164+
165+ if (instance->url ) {
166+ instance->webviewWindow ->Navigate (instance->url );
167+ }
168+ }
169+ return S_OK;
170+ }
171+ };
172+ #else
173+ class ControllerCompletedHandler : public ICoreWebView2CreateCoreWebView2ControllerCompletedHandler {
174+ ULONG refCount;
175+ WebView2Instance* instance;
176+ public:
177+ ControllerCompletedHandler (WebView2Instance* inst) : refCount(1 ), instance(inst) {}
178+
179+ HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppvObject) override {
180+ if (!ppvObject) return E_POINTER;
181+ *ppvObject = nullptr ;
182+ if (riid == IID_IUnknown || riid == __uuidof (ICoreWebView2CreateCoreWebView2ControllerCompletedHandler)) {
183+ *ppvObject = static_cast <ICoreWebView2CreateCoreWebView2ControllerCompletedHandler*>(this );
184+ AddRef ();
185+ return S_OK;
186+ }
187+ return E_NOINTERFACE;
188+ }
81189
82- auto titleHandler = Make<TitleChangedHandler>(instance);
83- EventRegistrationToken token ;
84- instance-> webviewWindow -> add_DocumentTitleChanged (titleHandler. Get (), &token);
190+ ULONG STDMETHODCALLTYPE AddRef () override {
191+ return ++refCount ;
192+ }
85193
86- if (instance->url ) {
87- instance->webviewWindow ->Navigate (instance->url );
194+ ULONG STDMETHODCALLTYPE Release () override {
195+ ULONG count = --refCount;
196+ if (count == 0 ) delete this ;
197+ return count;
198+ }
199+
200+ HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Controller* controller) override {
201+ if (SUCCEEDED (result) && controller) {
202+ instance->webviewController = controller;
203+ controller->get_CoreWebView2 (instance->webviewWindow .GetAddressOf ());
204+
205+ ICoreWebView2Settings* settings = nullptr ;
206+ if (SUCCEEDED (instance->webviewWindow ->get_Settings (&settings)) && settings) {
207+ settings->put_IsScriptEnabled (TRUE );
208+ settings->put_AreDefaultScriptDialogsEnabled (TRUE );
209+ settings->put_IsWebMessageEnabled (TRUE );
210+ #ifdef WEBUI_LOG
211+ settings->put_AreDevToolsEnabled (TRUE );
212+ #else
213+ settings->put_AreDevToolsEnabled (FALSE );
214+ #endif
215+ settings->Release ();
216+ }
217+
218+ RECT bounds = {0 , 0 , instance->width , instance->height };
219+ controller->put_Bounds (bounds);
220+
221+ TitleChangedHandler* titleHandler = new TitleChangedHandler (instance);
222+ EventRegistrationToken token;
223+ instance->webviewWindow ->add_DocumentTitleChanged (titleHandler, &token);
224+
225+ if (instance->url ) {
226+ instance->webviewWindow ->Navigate (instance->url );
227+ }
88228 }
229+ return S_OK;
89230 }
90- return S_OK;
91- }
92- };
231+ };
232+ #endif
93233
94- class EnvironmentCompletedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler> {
95- WebView2Instance* instance;
96- public:
97- EnvironmentCompletedHandler (WebView2Instance* inst) : instance(inst) {}
98- HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Environment* env) override {
99- if (SUCCEEDED (result) && env) {
100- instance->webviewEnvironment = env;
101- auto controllerHandler = Make<ControllerCompletedHandler>(instance);
102- env->CreateCoreWebView2Controller (instance->hwnd , controllerHandler.Get ());
234+ #ifdef _MSC_VER
235+ class EnvironmentCompletedHandler : public RuntimeClass <RuntimeClassFlags<ClassicCom>, ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler> {
236+ WebView2Instance* instance;
237+ public:
238+ EnvironmentCompletedHandler (WebView2Instance* inst) : instance(inst) {}
239+ HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Environment* env) override {
240+ if (SUCCEEDED (result) && env) {
241+ instance->webviewEnvironment = env;
242+ auto controllerHandler = Make<ControllerCompletedHandler>(instance);
243+ env->CreateCoreWebView2Controller (instance->hwnd , controllerHandler.Get ());
244+ }
245+ return S_OK;
246+ }
247+ };
248+ #else
249+ class EnvironmentCompletedHandler : public ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler {
250+ ULONG refCount;
251+ WebView2Instance* instance;
252+ public:
253+ EnvironmentCompletedHandler (WebView2Instance* inst) : refCount(1 ), instance(inst) {}
254+
255+ HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riid, void ** ppvObject) override {
256+ if (!ppvObject) return E_POINTER;
257+ *ppvObject = nullptr ;
258+ if (riid == IID_IUnknown || riid == __uuidof (ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler)) {
259+ *ppvObject = static_cast <ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler*>(this );
260+ AddRef ();
261+ return S_OK;
262+ }
263+ return E_NOINTERFACE;
264+ }
265+
266+ ULONG STDMETHODCALLTYPE AddRef () override {
267+ return ++refCount;
103268 }
104- return S_OK;
105- }
106- };
269+
270+ ULONG STDMETHODCALLTYPE Release () override {
271+ ULONG count = --refCount;
272+ if (count == 0 ) delete this ;
273+ return count;
274+ }
275+
276+ HRESULT STDMETHODCALLTYPE Invoke (HRESULT result, ICoreWebView2Environment* env) override {
277+ if (SUCCEEDED (result) && env) {
278+ instance->webviewEnvironment = env;
279+ ControllerCompletedHandler* controllerHandler = new ControllerCompletedHandler (instance);
280+ env->CreateCoreWebView2Controller (instance->hwnd , controllerHandler);
281+ }
282+ return S_OK;
283+ }
284+ };
285+ #endif
107286
108287extern " C" {
109288
@@ -248,13 +427,22 @@ bool _webui_win32_wv2_create_environment(_webui_win32_wv2_handle handle, wchar_t
248427 return false ;
249428 }
250429
251- auto environmentHandler = Make<EnvironmentCompletedHandler>(instance);
252- if (!environmentHandler) {
253- FreeLibrary (webviewLib);
254- return false ;
255- }
430+ #ifdef _MSC_VER
431+ auto environmentHandler = Make<EnvironmentCompletedHandler>(instance);
432+ if (!environmentHandler) {
433+ FreeLibrary (webviewLib);
434+ return false ;
435+ }
436+ HRESULT hr = createEnv (NULL , cacheFolder, NULL , environmentHandler.Get ());
437+ #else
438+ EnvironmentCompletedHandler* environmentHandler = new EnvironmentCompletedHandler (instance);
439+ if (!environmentHandler) {
440+ FreeLibrary (webviewLib);
441+ return false ;
442+ }
443+ HRESULT hr = createEnv (NULL , cacheFolder, NULL , environmentHandler);
444+ #endif
256445
257- HRESULT hr = createEnv (NULL , cacheFolder, NULL , environmentHandler.Get ());
258446 return SUCCEEDED (hr);
259447}
260448
0 commit comments