comparison win/edge.cpp @ 2043:82e5c998df2e

Win: Fix crash on Edge HTML widget destruction. Skip freeing memory from chromium widget windows.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Sun, 24 Nov 2019 22:42:55 +0000
parents 0d8b898b03e2
children b74b9afa31aa
comparison
equal deleted inserted replaced
2042:0d8b898b03e2 2043:82e5c998df2e
25 LPWSTR _myUTF8toWide(const char* utf8string, void* outbuf); 25 LPWSTR _myUTF8toWide(const char* utf8string, void* outbuf);
26 char* _myWideToUTF8(LPCWSTR widestring, void* outbuf); 26 char* _myWideToUTF8(LPCWSTR widestring, void* outbuf);
27 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL) 27 #define UTF8toWide(a) _myUTF8toWide(a, a ? _alloca(MultiByteToWideChar(CP_UTF8, 0, a, -1, NULL, 0) * sizeof(WCHAR)) : NULL)
28 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL) 28 #define WideToUTF8(a) _myWideToUTF8(a, a ? _alloca(WideCharToMultiByte(CP_UTF8, 0, a, -1, NULL, 0, NULL, NULL)) : NULL)
29 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2); 29 LRESULT CALLBACK _wndproc(HWND hWnd, UINT msg, WPARAM mp1, LPARAM mp2);
30 BOOL CALLBACK _free_window_memory(HWND handle, LPARAM lParam);
31 } 30 }
32 31
33 class EdgeBrowser 32 class EdgeBrowser
34 { 33 {
35 public: 34 public:
56 55
57 LRESULT CALLBACK EdgeBrowser::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 56 LRESULT CALLBACK EdgeBrowser::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
58 { 57 {
59 switch (uMsg) 58 switch (uMsg)
60 { 59 {
61 case WM_SIZE: 60 case WM_SIZE:
62 { 61 {
63 // Resize the browser object to fit the window 62 // Resize the browser object to fit the window
64 EdgeWebView *webview; 63 EdgeWebView *webview;
65 64
66 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when 65 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when
67 // we initially attached the browser object to this window. 66 // we initially attached the browser object to this window.
68 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); 67 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
69 // Resize WebView to fit the bounds of the parent window 68 // Resize WebView to fit the bounds of the parent window
70 if (webview) 69 if (webview)
71 webview->DoSize(); 70 webview->DoSize();
72 return(0); 71 return(0);
73 } 72 }
74 73
75 case WM_PAINT: 74 case WM_PAINT:
76 { 75 {
77 PAINTSTRUCT ps; 76 PAINTSTRUCT ps;
78 HDC hdc = BeginPaint(hWnd, &ps); 77 HDC hdc = BeginPaint(hWnd, &ps);
79 EndPaint(hWnd, &ps); 78 EndPaint(hWnd, &ps);
80 return(0); 79 return(0);
81 } 80 }
82 81
83 case WM_CREATE: 82 case WM_CREATE:
84 { 83 {
85 // Step 3 - Create a single WebView within the parent window 84 // Step 3 - Create a single WebView within the parent window
86 // Create a WebView, whose parent is the main window hWnd 85 // Create a WebView, whose parent is the main window hWnd
87 Env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>( 86 Env->CreateWebView(hWnd, Callback<IWebView2CreateWebViewCompletedHandler>(
88 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT { 87 [hWnd](HRESULT result, IWebView2WebView* webview) -> HRESULT {
89 EdgeWebView* WebView = new EdgeWebView; 88 EdgeWebView* WebView = new EdgeWebView;
90 89
91 WebView->Setup(hWnd, webview); 90 WebView->Setup(hWnd, webview);
92 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(WebView)); 91 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, DW_POINTER(WebView));
93 92
94 // Add a few settings for the webview 93 // Add a few settings for the webview
95 // this is a redundant demo step as they are the default settings values 94 // this is a redundant demo step as they are the default settings values
96 IWebView2Settings* Settings; 95 IWebView2Settings* Settings;
97 webview->get_Settings(&Settings); 96 webview->get_Settings(&Settings);
98 Settings->put_IsScriptEnabled(TRUE); 97 Settings->put_IsScriptEnabled(TRUE);
99 Settings->put_AreDefaultScriptDialogsEnabled(TRUE); 98 Settings->put_AreDefaultScriptDialogsEnabled(TRUE);
100 Settings->put_IsWebMessageEnabled(TRUE); 99 Settings->put_IsWebMessageEnabled(TRUE);
101 100
102 // Resize WebView to fit the bounds of the parent window 101 // Resize WebView to fit the bounds of the parent window
103 WebView->DoSize(); 102 WebView->DoSize();
104 103
105 // Save the token, we might need to dw_window_set_data() this value 104 // Save the token, we might need to dw_window_set_data() this value
106 // for later use to remove the handlers 105 // for later use to remove the handlers
107 EventRegistrationToken token; 106 EventRegistrationToken token;
108 107
109 // Register a handler for the NavigationStarting event. 108 // Register a handler for the NavigationStarting event.
110 webview->add_NavigationStarting( 109 webview->add_NavigationStarting(
111 Callback<IWebView2NavigationStartingEventHandler>( 110 Callback<IWebView2NavigationStartingEventHandler>(
112 [hWnd](IWebView2WebView* sender, 111 [hWnd](IWebView2WebView* sender,
113 IWebView2NavigationStartingEventArgs* args) -> HRESULT 112 IWebView2NavigationStartingEventArgs* args) -> HRESULT
114 { 113 {
115 LPWSTR uri; 114 LPWSTR uri;
116 sender->get_Source(&uri); 115 sender->get_Source(&uri);
117 116
118 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED), 117 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_STARTED),
119 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); 118 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
120 119
121 return S_OK; 120 return S_OK;
122 }).Get(), &token); 121 }).Get(), &token);
123 122
124 // Register a handler for the DocumentStateChanged event. 123 // Register a handler for the DocumentStateChanged event.
125 webview->add_DocumentStateChanged( 124 webview->add_DocumentStateChanged(
126 Callback<IWebView2DocumentStateChangedEventHandler>( 125 Callback<IWebView2DocumentStateChangedEventHandler>(
127 [hWnd](IWebView2WebView* sender, 126 [hWnd](IWebView2WebView* sender,
128 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT 127 IWebView2DocumentStateChangedEventArgs* args) -> HRESULT
129 { 128 {
130 LPWSTR uri; 129 LPWSTR uri;
131 sender->get_Source(&uri); 130 sender->get_Source(&uri);
132 131
133 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING), 132 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_LOADING),
134 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); 133 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
135 134
136 return S_OK; 135 return S_OK;
137 }).Get(), &token); 136 }).Get(), &token);
138 137
139 // Register a handler for the NavigationCompleted event. 138 // Register a handler for the NavigationCompleted event.
140 webview->add_NavigationCompleted( 139 webview->add_NavigationCompleted(
141 Callback<IWebView2NavigationCompletedEventHandler>( 140 Callback<IWebView2NavigationCompletedEventHandler>(
142 [hWnd](IWebView2WebView* sender, 141 [hWnd](IWebView2WebView* sender,
143 IWebView2NavigationCompletedEventArgs* args) -> HRESULT 142 IWebView2NavigationCompletedEventArgs* args) -> HRESULT
144 { 143 {
145 LPWSTR uri; 144 LPWSTR uri;
146 sender->get_Source(&uri); 145 sender->get_Source(&uri);
147 146
148 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE), 147 _wndproc(hWnd, WM_USER + 101, (WPARAM)DW_INT_TO_POINTER(DW_HTML_CHANGE_COMPLETE),
149 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri)); 148 !wcscmp(uri, L"about:blank") ? (LPARAM)"" : (LPARAM)WideToUTF8((LPWSTR)uri));
150 149
151 return S_OK; 150 return S_OK;
152 }).Get(), &token); 151 }).Get(), &token);
153 152
154 // Handle cached load requests due to delayed 153 // Handle cached load requests due to delayed
155 // loading of the edge webview contexts 154 // loading of the edge webview contexts
156 char *url = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION); 155 char *url = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_LOCATION);
157 if (url) 156 if (url)
158 { 157 {
159 WebView->URL(url); 158 WebView->URL(url);
160 free((void*)url); 159 free((void*)url);
161 } 160 }
162 char *raw = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW); 161 char *raw = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_RAW);
163 if (raw) 162 if (raw)
164 { 163 {
165 WebView->Raw(raw); 164 WebView->Raw(raw);
166 free((void*)raw); 165 free((void*)raw);
167 } 166 }
168 return S_OK; 167 return S_OK;
169 }).Get()); 168 }).Get());
170 // Success 169 // Success
171 return(0); 170 return(0);
172 } 171 }
173 172
174 case WM_DESTROY: 173 case WM_DESTROY:
175 { 174 {
176 // Detach the browser object from this window, and free resources. 175 // Detach the browser object from this window, and free resources.
177 EdgeWebView *webview; 176 EdgeWebView *webview;
178 177
179 // Retrieve the browser object's pointer we stored in our window's GWL_USERDATA when 178 // 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. 179 // we initially attached the browser object to this window.
181 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME); 180 webview = (EdgeWebView*)dw_window_get_data(hWnd, _DW_HTML_DATA_NAME);
182 if (webview) 181 if (webview)
183 { 182 {
184 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL); 183 dw_window_set_data(hWnd, _DW_HTML_DATA_NAME, NULL);
185 webview->Close(); 184 webview->Close();
186 delete webview; 185 delete webview;
187 } 186 }
188 _free_window_memory(hWnd, 0); 187 return(TRUE);
189 return(TRUE); 188 }
190 }
191 } 189 }
192 190
193 return(DefWindowProc(hWnd, uMsg, wParam, lParam)); 191 return(DefWindowProc(hWnd, uMsg, wParam, lParam));
194 } 192 }
195 193