Mercurial > dwindows
diff win/edge.cpp @ 2981:0058ab32e1bd
Win: Support for dw_html_javascript_add() and DW_SIGNAL_HTML_MESSAGE.
This only works with Microsoft Edge WebView2 currently.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Sun, 26 Mar 2023 22:10:10 +0000 |
parents | f99414164f5b |
children |
line wrap: on
line diff
--- a/win/edge.cpp Sat Mar 25 20:10:05 2023 +0000 +++ b/win/edge.cpp Sun Mar 26 22:10:10 2023 +0000 @@ -9,12 +9,14 @@ #include "dw.h" #include "WebView2.h" #include <wrl.h> +#include <string> using namespace Microsoft::WRL; #define _DW_HTML_DATA_NAME "_dw_edge" #define _DW_HTML_DATA_LOCATION "_dw_edge_location" #define _DW_HTML_DATA_RAW "_dw_edge_raw" +#define _DW_HTML_DATA_ADD "_dw_edge_add" extern "C" { @@ -44,6 +46,7 @@ int Raw(const char* string); int URL(const char* url); int JavascriptRun(const char* script, void* scriptdata); + int JavascriptAdd(const char* name); VOID DoSize(VOID); VOID Setup(HWND hwnd, ICoreWebView2Controller* webview); VOID Close(VOID); @@ -166,6 +169,32 @@ return S_OK; }).Get(), &token); + + // Register a handler for the WebMessageReceived event. + webview->add_WebMessageReceived( + Callback<ICoreWebView2WebMessageReceivedEventHandler>( + [hWnd](ICoreWebView2* sender, + ICoreWebView2WebMessageReceivedEventArgs* args) -> HRESULT + { + LPWSTR message, name = NULL, body = NULL; + args->TryGetWebMessageAsString(&message); + + // Locate the DWindows|<function name>| signature and body + if(message && !wcsncmp(message, L"DWindows|", 9)) { + name = message + 9; + if(*name) { + body = wcschr(name, L'|'); + if(body) { + *body = 0; + body++; + } + } + } + if(name && body) + _dw_wndproc(hWnd, WM_USER + 103, (WPARAM)WideToUTF8(name), (LPARAM)WideToUTF8(body)); + + return S_OK; + }).Get(), &token); } // Resize WebView to fit the bounds of the parent window @@ -187,6 +216,21 @@ dw_window_set_data(hWnd, _DW_HTML_DATA_RAW, NULL); free((void*)raw); } + char *adds = (char *)dw_window_get_data(hWnd, _DW_HTML_DATA_ADD); + if(adds) + { + char *start = adds, *separator; + + while((separator = strchr(start, '|'))) + { + *separator = 0; + WebView->JavascriptAdd(start); + start = separator + 1; + } + WebView->JavascriptAdd(start); + dw_window_set_data(hWnd, _DW_HTML_DATA_ADD, NULL); + free((void *)adds); + } return S_OK; }).Get()); // Success @@ -366,6 +410,21 @@ return DW_ERROR_NONE; } +int EdgeWebView::JavascriptAdd(const char* name) +{ + if (WebView) { + std::wstring wname = std::wstring(UTF8toWide(name)); + std::wstring script = L"function " + wname + L"(body) {window.chrome.webview.postMessage('DWindows|" + wname + L"|' + body);}"; + WebView->AddScriptToExecuteOnDocumentCreated(script.c_str(), + Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>( + [this](HRESULT error, PCWSTR id) -> HRESULT { + return S_OK; + }).Get()); + return DW_ERROR_NONE; + } + return DW_ERROR_UNKNOWN; +} + VOID EdgeWebView::Setup(HWND hwnd, ICoreWebView2Controller* host) { hWnd = hwnd; @@ -506,8 +565,12 @@ EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); if (webview) return webview->Raw(string); - else + else { + char *oldstring = (char *)dw_window_get_data(hwnd, _DW_HTML_DATA_RAW); dw_window_set_data(hwnd, _DW_HTML_DATA_RAW, _strdup(string)); + if(oldstring) + free((void *)oldstring); + } return DW_ERROR_NONE; } @@ -525,8 +588,12 @@ EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); if (webview) return webview->URL(url); - else + else { + char *oldurl = (char *)dw_window_get_data(hwnd, _DW_HTML_DATA_LOCATION); dw_window_set_data(hwnd, _DW_HTML_DATA_LOCATION, _strdup(url)); + if(oldurl) + free((void *)oldurl); + } return DW_ERROR_NONE; } @@ -548,6 +615,38 @@ return DW_ERROR_UNKNOWN; } + /******************************* dw_edge_javascript_add() **************************** + * Adds a javascript function in the specified browser context. + * + * hwnd = Handle to the window hosting the browser object. + * name = Pointer to nul-terminated javascript function name string. + * + * RETURNS: 0 if success, or non-zero if an error. + */ + + int _dw_edge_javascript_add(HWND hwnd, const char* name) + { + if(name) { + EdgeWebView* webview = (EdgeWebView*)dw_window_get_data(hwnd, _DW_HTML_DATA_NAME); + if (webview) + return webview->JavascriptAdd(name); + else { + char *oldadd = (char *)dw_window_get_data(hwnd, _DW_HTML_DATA_ADD); + char *newadd = (char *)calloc(strlen(name) + (oldadd ? strlen(oldadd) : 0) + 2, 1); + if(oldadd) { + strcpy(newadd, oldadd); + strcat(newadd, "|"); + } + strcat(newadd, name); + dw_window_set_data(hwnd, _DW_HTML_DATA_ADD, newadd); + if(oldadd) + free((void *)oldadd); + return DW_ERROR_NONE; + } + } + return DW_ERROR_UNKNOWN; + } + /************************** edgeWindowProc() ************************* * Our message handler for our window to host the browser. */