#ifndef WINXP #include #include #include #include #include using namespace Microsoft::WRL; #include #define CHECK_FAILURE(x) \ if (FAILED((x))) \ return x; #endif DECLARE_API void set_transparent_background(void *m_host) { #ifndef WINXP COREWEBVIEW2_COLOR color; ZeroMemory(&color, sizeof(color)); wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr coreWebView2 = m_controller.try_query(); if (coreWebView2) { coreWebView2->put_DefaultBackgroundColor(color); } #endif } DECLARE_API void put_PreferredColorScheme(void *m_host, COREWEBVIEW2_PREFERRED_COLOR_SCHEME scheme) { #ifndef WINXP wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr coreWebView2; [&]() { CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2)); auto webView2_13 = coreWebView2.try_query(); if (webView2_13) { wil::com_ptr profile; CHECK_FAILURE(webView2_13->get_Profile(&profile)); CHECK_FAILURE(profile->put_PreferredColorScheme(scheme)); } return S_OK; }(); #endif } DECLARE_API void *add_ZoomFactorChanged(void *m_host, void (*signal)(double)) { #ifndef WINXP EventRegistrationToken *m_zoomFactorChangedToken = new EventRegistrationToken; // Register a handler for the ZoomFactorChanged event. // This handler just announces the new level of zoom on the window's title bar. reinterpret_cast(m_host)->add_ZoomFactorChanged( Callback( [signal](ICoreWebView2Controller *sender, IUnknown *args) -> HRESULT { double zoomFactor; sender->get_ZoomFactor(&zoomFactor); signal(zoomFactor); // std::wstring message = L"WebView2APISample (Zoom: " + // std::to_wstring(int(zoomFactor * 100)) + L"%)"; // SetWindowText(m_appWindow->GetMainWindow(), message.c_str()); return S_OK; }) .Get(), m_zoomFactorChangedToken); return m_zoomFactorChangedToken; #else return NULL; #endif } DECLARE_API void remove_ZoomFactorChanged(void *m_host, void *m_zoomFactorChangedToken) { #ifndef WINXP auto token = reinterpret_cast(m_zoomFactorChangedToken); reinterpret_cast(m_host)->remove_ZoomFactorChanged(*token); delete token; #endif } DECLARE_API double get_ZoomFactor(void *m_host) { #ifndef WINXP double zoomFactor; reinterpret_cast(m_host)->get_ZoomFactor(&zoomFactor); return zoomFactor; #else return 1; #endif } DECLARE_API void put_ZoomFactor(void *m_host, double zoomFactor) { #ifndef WINXP reinterpret_cast(m_host)->put_ZoomFactor(zoomFactor); #endif } // https://github.com/MicrosoftEdge/WebView2Feedback/blob/main/specs/WebMessageObjects.md DECLARE_API void remove_WebMessageReceived(void *m_host, void *m_webMessageReceivedToken) { #ifndef WINXP auto token = reinterpret_cast(m_webMessageReceivedToken); wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr m_webView; [&]() { CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); CHECK_FAILURE(m_webView->remove_WebMessageReceived(*token)); return S_OK; }(); delete token; #endif } DECLARE_API void *add_WebMessageReceived(void *m_host, void (*callback)(const wchar_t *)) { #ifndef WINXP wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr coreWebView4 = m_controller.try_query(); if (coreWebView4) { coreWebView4->put_AllowExternalDrop(true); } wil::com_ptr m_webView; EventRegistrationToken *m_webMessageReceivedToken = new EventRegistrationToken; [&]() { CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); CHECK_FAILURE(m_webView->add_WebMessageReceived( Callback( [=](ICoreWebView2 *sender, ICoreWebView2WebMessageReceivedEventArgs *args) noexcept { wil::unique_cotaskmem_string message; CHECK_FAILURE(args->TryGetWebMessageAsString(&message)); if (std::wstring(L"FilesDropped") == message.get()) { wil::com_ptr args2 = wil::com_ptr(args) .query(); if (args2) { wil::com_ptr objectsCollection; CHECK_FAILURE(args2->get_AdditionalObjects(&objectsCollection)); unsigned int length; CHECK_FAILURE(objectsCollection->get_Count(&length)); std::vector paths; for (unsigned int i = 0; i < length; i++) { wil::com_ptr object; CHECK_FAILURE(objectsCollection->GetValueAtIndex(i, &object)); // Note that objects can be null. if (object) { wil::com_ptr file = object.query(); if (file) { // Add the file to message to be sent back to webview wil::unique_cotaskmem_string path; CHECK_FAILURE(file->get_Path(&path)); paths.push_back(path.get()); } } } // ProcessPaths(paths); if (paths.size()) { callback(paths[0].c_str()); } } } return S_OK; }) .Get(), m_webMessageReceivedToken)); return S_OK; }(); return m_webMessageReceivedToken; #else return NULL; #endif }