#include "../browser_window.h"
#include <wrl.h>
#include <wil/com.h>
#include <WebView2.h>
#include "../win32.h"
#include "../window.h"
#define DEFAULT_EDGE_LOCATION L"C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\84.0.522.52"
#define ASSERT_ON_FAIL( HR_STATEMENT ) \
{ \
HRESULT r = (HR_STATEMENT); \
if ( r != 0 ) { \
BW_WIN32_ASSERT_HRESULT( r ); \
} \
}
#pragma comment(lib, "WebView2Loader.dll.lib")
using namespace Microsoft::WRL;
void _bw_BrowserWindow_doCleanup( bw_BrowserWindow* bw ) {
}
void bw_BrowserWindow_eval_js( bw_BrowserWindow* bw, bw_CStrSlice _js, bw_BrowserWindowJsCallbackFn callback, void* cb_data ) {
WCHAR* js = bw_win32_copyAsNewWstr( _js );
reinterpret_cast<ICoreWebView2*>(bw->inner.webview)->ExecuteScript( js, Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
[bw, cb_data, callback]( HRESULT error_code, LPCWSTR result ) -> HRESULT {
if ( error_code != 0 ) {
bw_Err err = bw_win32_unhandledHresult( error_code );
callback( bw, cb_data, 0, &err );
}
else {
char* cstr = bw_win32_copyWstrAsNewCstr( result );
callback( bw, cb_data, cstr, 0 );
free( cstr );
}
return S_OK;
}).Get()
);
}
bw_Err bw_BrowserWindow_navigate( bw_BrowserWindow* bw, bw_CStrSlice _url ) {
WCHAR* url = bw_win32_copyAsNewWstr( _url );
HRESULT res = reinterpret_cast<ICoreWebView2*>(bw->inner.webview)->Navigate( url );
if ( res != 0 )
return bw_win32_unhandledHresult( res );
SysFreeString( url );
BW_ERR_RETURN_SUCCESS;
}
bw_BrowserWindow* bw_BrowserWindow_new(
const bw_Application* app,
const bw_Window* parent,
bw_BrowserWindowSource source,
bw_CStrSlice title,
int width, int height,
const bw_WindowOptions* window_options,
const bw_BrowserWindowOptions* _options,
bw_BrowserWindowHandlerFn handler,
void* user_data
) {
bw_BrowserWindowOptions options = *_options;
bw_BrowserWindow* browser_window = new bw_BrowserWindow;
browser_window->window = bw_Window_new( app, parent, title, width, height, window_options, browser_window );
browser_window->handler = handler;
browser_window->user_data = user_data;
_bw_BrowserWindow_init_window_callbacks( browser_window );
WCHAR* source_data = bw_win32_copyAsNewWstr( source.data );
HRESULT result = CreateCoreWebView2EnvironmentWithOptions( nullptr, nullptr, nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[browser_window, options, source, source_data](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {
HRESULT r = env->CreateCoreWebView2Controller( browser_window->window->inner.handle, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[browser_window, options, source, source_data](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
if (controller != nullptr) {
browser_window->inner.webview_controller = controller;
ASSERT_ON_FAIL( controller->get_CoreWebView2( reinterpret_cast<ICoreWebView2**>(&browser_window->inner.webview) ) );
auto webview = reinterpret_cast<ICoreWebView2*>( browser_window->inner.webview );
ICoreWebView2Settings* settings;
ASSERT_ON_FAIL( webview->get_Settings(&settings) );
ASSERT_ON_FAIL( settings->put_IsScriptEnabled(true) );
ASSERT_ON_FAIL( settings->put_AreDefaultScriptDialogsEnabled(true) );
ASSERT_ON_FAIL( settings->put_IsWebMessageEnabled(true) );
ASSERT_ON_FAIL( settings->put_AreDevToolsEnabled(options.dev_tools) );
RECT bounds;
GetClientRect(browser_window->window->inner.handle, &bounds);
ASSERT_ON_FAIL( controller->put_Bounds(bounds) );
if ( !source.is_html ) {
ASSERT_ON_FAIL( webview->Navigate( source_data ) );
}
else {
ASSERT_ON_FAIL( webview->NavigateToString( source_data ) );
}
free( source_data );
if ( !UpdateWindow( browser_window->window->inner.handle ) ) {
BW_WIN32_ASSERT_ERROR;
}
fprintf(stderr,"Done!\n");
return S_OK;
}
}
).Get() );
if ( r != 0 ) {
BW_WIN32_ASSERT_HRESULT( r );
}
return S_OK;
}
).Get()
);
if ( result != 0 ) {
if ( result == __HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND ) ) {
fprintf( stderr, "Microsoft Edge (chromium) installation not found!\n" );
assert(0);
}
else {
BW_WIN32_ASSERT_HRESULT( result );
}
}
return browser_window;
}