mirror of
https://github.com/taigrr/wails.git
synced 2026-04-14 10:50:53 -07:00
[windows] Closer to webview2 integration
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
// Some code may be inspired by or directly used from Webview.
|
||||
#include "ffenestri_windows.h"
|
||||
//#include "wv2ComHandler_windows.h"
|
||||
#include "wv2ComHandler_windows.h"
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
#include <Shlwapi.h>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
#include "windows/WebView2.h"
|
||||
|
||||
int debug = 0;
|
||||
DWORD mainThread;
|
||||
@@ -11,40 +16,14 @@ void dispatch(dispatchFunction func) {
|
||||
PostThreadMessage(mainThread, WM_APP, 0, (LPARAM) new dispatchFunction(func));
|
||||
}
|
||||
|
||||
struct Application{
|
||||
// Window specific
|
||||
HWND window;
|
||||
// WebViewControl webview;
|
||||
// ICoreWebView2Controller* controller;
|
||||
|
||||
|
||||
// Application
|
||||
const char *title;
|
||||
int width;
|
||||
int height;
|
||||
int resizable;
|
||||
int devtools;
|
||||
int fullscreen;
|
||||
int startHidden;
|
||||
int logLevel;
|
||||
int hideWindowOnClose;
|
||||
int minSizeSet;
|
||||
LONG minWidth;
|
||||
LONG minHeight;
|
||||
int maxSizeSet;
|
||||
LONG maxWidth;
|
||||
LONG maxHeight;
|
||||
int frame;
|
||||
};
|
||||
|
||||
struct Application *NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel, int hideWindowOnClose) {
|
||||
|
||||
// Create application
|
||||
struct Application *result = (struct Application*)malloc(sizeof(struct Application));
|
||||
|
||||
result->window = nullptr;
|
||||
// result->webview = nullptr;
|
||||
// result->controller = nullptr;
|
||||
result->webview = nullptr;
|
||||
result->webviewController = nullptr;
|
||||
|
||||
result->title = title;
|
||||
result->width = width;
|
||||
@@ -89,8 +68,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
|
||||
case WM_DESTROY: {
|
||||
DestroyApplication(app);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
// case WM_SIZE: {
|
||||
// if( app->webviewController != nullptr) {
|
||||
// RECT bounds;
|
||||
// GetClientRect(app->window, &bounds);
|
||||
// app->webviewController->put_Bounds(bounds);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
case WM_GETMINMAXINFO: {
|
||||
// Exit early if this is called before the window is created.
|
||||
if ( app == NULL ) {
|
||||
@@ -127,29 +114,31 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
default:
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
bool initWebView2(struct Application *app, int debug, messageCallback cb) {
|
||||
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
|
||||
std::atomic_flag flag = ATOMIC_FLAG_INIT;
|
||||
flag.test_and_set();
|
||||
|
||||
//void initWebView2(struct Application *app, int debug, messageCallback cb) {
|
||||
// CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
||||
//
|
||||
// std::atomic_flag flag = ATOMIC_FLAG_INIT;
|
||||
// flag.test_and_set();
|
||||
//
|
||||
// char currentExePath[MAX_PATH];
|
||||
// GetModuleFileNameA(NULL, currentExePath, MAX_PATH);
|
||||
// char *currentExeName = PathFindFileNameA(currentExePath);
|
||||
//
|
||||
// printf("current exe name = %s\n", currentExeName);
|
||||
|
||||
// std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wideCharConverter;
|
||||
// std::wstring userDataFolder = wideCharConverter.from_bytes(std::getenv("APPDATA"));
|
||||
// std::wstring currentExeNameW = wideCharConverter.from_bytes(currentExeName);
|
||||
//
|
||||
// HRESULT res = CreateCoreWebView2EnvironmentWithOptions(
|
||||
// nullptr, (userDataFolder + L"/" + currentExeNameW).c_str(), nullptr,
|
||||
// new wv2ComHandler(app->window, cb,
|
||||
// [&](ICoreWebView2Controller *controller) {
|
||||
// app->controller = controller;
|
||||
// app->controller->get_CoreWebView2(&(app->webview));
|
||||
// new wv2ComHandler(app, cb,
|
||||
// [&](ICoreWebView2Controller *webviewController) {
|
||||
// app->webviewController = webviewController;
|
||||
// app->webviewController->get_CoreWebView2(&(app->webview));
|
||||
// app->webview->AddRef();
|
||||
// flag.clear();
|
||||
// }));
|
||||
@@ -163,9 +152,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
||||
// TranslateMessage(&msg);
|
||||
// DispatchMessage(&msg);
|
||||
// }
|
||||
// init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}");
|
||||
// return true;
|
||||
//}
|
||||
//// init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}");
|
||||
return true;
|
||||
}
|
||||
|
||||
void initialCallback(std::string message) {
|
||||
printf("MESSAGE=%s\n", message);
|
||||
}
|
||||
|
||||
void Run(struct Application* app, int argc, char **argv) {
|
||||
|
||||
@@ -177,6 +170,9 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
wc.lpszClassName = (LPCWSTR)"ffenestri";
|
||||
wc.lpfnWndProc = WndProc;
|
||||
|
||||
// TODO: Menu
|
||||
// wc.lpszMenuName = nullptr;
|
||||
|
||||
|
||||
// Process window resizable
|
||||
DWORD windowStyle = WS_OVERLAPPEDWINDOW;
|
||||
@@ -190,8 +186,8 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
|
||||
RegisterClassEx(&wc);
|
||||
app->window = CreateWindow((LPCWSTR)"ffenestri", (LPCWSTR)"", windowStyle, CW_USEDEFAULT,
|
||||
CW_USEDEFAULT, app->width, app->height, NULL, NULL,
|
||||
GetModuleHandle(NULL), NULL);
|
||||
CW_USEDEFAULT, app->width, app->height, NULL, NULL,
|
||||
hInstance, NULL);
|
||||
|
||||
// Private setTitle as we're on the main thread
|
||||
setTitle(app, app->title);
|
||||
@@ -211,8 +207,8 @@ void Run(struct Application* app, int argc, char **argv) {
|
||||
UpdateWindow(app->window);
|
||||
SetFocus(app->window);
|
||||
|
||||
// TODO: Add webview2
|
||||
// initWebView2(app->window);
|
||||
// Add webview2
|
||||
initWebView2(app, 1, initialCallback);
|
||||
|
||||
// Main event loop
|
||||
MSG msg;
|
||||
|
||||
@@ -2,18 +2,45 @@
|
||||
#ifndef _FFENESTRI_WINDOWS_H
|
||||
#define _FFENESTRI_WINDOWS_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define UNICODE 1
|
||||
|
||||
#include "ffenestri.h"
|
||||
#include <windows.h>
|
||||
#include <wingdi.h>
|
||||
#include <functional>
|
||||
#include "windows/WebView2.h"
|
||||
|
||||
struct Application{
|
||||
// Window specific
|
||||
HWND window;
|
||||
ICoreWebView2 *webview;
|
||||
ICoreWebView2Controller* webviewController;
|
||||
|
||||
// Application
|
||||
const char *title;
|
||||
int width;
|
||||
int height;
|
||||
int resizable;
|
||||
int devtools;
|
||||
int fullscreen;
|
||||
int startHidden;
|
||||
int logLevel;
|
||||
int hideWindowOnClose;
|
||||
int minSizeSet;
|
||||
LONG minWidth;
|
||||
LONG minHeight;
|
||||
int maxSizeSet;
|
||||
LONG maxWidth;
|
||||
LONG maxHeight;
|
||||
int frame;
|
||||
};
|
||||
|
||||
#define ON_MAIN_THREAD(code) dispatch( [=]{ code; } )
|
||||
|
||||
typedef std::function<void()> dispatchFunction;
|
||||
//typedef std::function<void(const std::string)> messageCallback;
|
||||
//typedef std::function<void(ICoreWebView2Controller *)> comHandlerCallback;
|
||||
typedef std::function<void(const std::string)> messageCallback;
|
||||
typedef std::function<void(ICoreWebView2Controller *)> comHandlerCallback;
|
||||
|
||||
void center(struct Application*);
|
||||
void setTitle(struct Application* app, const char *title);
|
||||
|
||||
68
v2/internal/ffenestri/windows/EventToken.h
Normal file
68
v2/internal/ffenestri/windows/EventToken.h
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
|
||||
/* this ALWAYS GENERATED file contains the definitions for the interfaces */
|
||||
|
||||
|
||||
/* File created by MIDL compiler version 8.01.0622 */
|
||||
/* @@MIDL_FILE_HEADING( ) */
|
||||
|
||||
|
||||
|
||||
/* verify that the <rpcndr.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCNDR_H_VERSION__
|
||||
#define __REQUIRED_RPCNDR_H_VERSION__ 500
|
||||
#endif
|
||||
|
||||
/* verify that the <rpcsal.h> version is high enough to compile this file*/
|
||||
#ifndef __REQUIRED_RPCSAL_H_VERSION__
|
||||
#define __REQUIRED_RPCSAL_H_VERSION__ 100
|
||||
#endif
|
||||
|
||||
#include "rpc.h"
|
||||
#include "rpcndr.h"
|
||||
|
||||
#ifndef __RPCNDR_H_VERSION__
|
||||
#error this stub requires an updated version of <rpcndr.h>
|
||||
#endif /* __RPCNDR_H_VERSION__ */
|
||||
|
||||
|
||||
#ifndef __eventtoken_h__
|
||||
#define __eventtoken_h__
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* Forward Declarations */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
|
||||
/* interface __MIDL_itf_eventtoken_0000_0000 */
|
||||
/* [local] */
|
||||
|
||||
// Microsoft Windows
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
#pragma once
|
||||
typedef struct EventRegistrationToken
|
||||
{
|
||||
__int64 value;
|
||||
} EventRegistrationToken;
|
||||
|
||||
|
||||
|
||||
extern RPC_IF_HANDLE __MIDL_itf_eventtoken_0000_0000_v0_0_c_ifspec;
|
||||
extern RPC_IF_HANDLE __MIDL_itf_eventtoken_0000_0000_v0_0_s_ifspec;
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
6499
v2/internal/ffenestri/windows/WebView2.h
Normal file
6499
v2/internal/ffenestri/windows/WebView2.h
Normal file
File diff suppressed because it is too large
Load Diff
75
v2/internal/ffenestri/wv2ComHandler_windows.h
Normal file
75
v2/internal/ffenestri/wv2ComHandler_windows.h
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
#ifndef WV2COMHANDLER_H
|
||||
#define WV2COMHANDLER_H
|
||||
|
||||
#include "ffenestri_windows.h"
|
||||
#include "windows/WebView2.h"
|
||||
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
class wv2ComHandler
|
||||
: public ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler,
|
||||
public ICoreWebView2CreateCoreWebView2ControllerCompletedHandler,
|
||||
public ICoreWebView2WebMessageReceivedEventHandler,
|
||||
public ICoreWebView2PermissionRequestedEventHandler {
|
||||
|
||||
struct Application *app;
|
||||
messageCallback mcb;
|
||||
comHandlerCallback cb;
|
||||
|
||||
public:
|
||||
wv2ComHandler(struct Application *app, messageCallback mcb, comHandlerCallback cb) {
|
||||
this->app = app;
|
||||
this->mcb = mcb;
|
||||
this->cb = cb;
|
||||
}
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return 1; }
|
||||
ULONG STDMETHODCALLTYPE Release() { return 1; }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv) {
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Invoke(HRESULT res,
|
||||
ICoreWebView2Environment *env) {
|
||||
env->CreateCoreWebView2Controller(app->window, this);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Invoke(HRESULT res,
|
||||
ICoreWebView2Controller *controller) {
|
||||
controller->AddRef();
|
||||
|
||||
ICoreWebView2 *webview;
|
||||
::EventRegistrationToken token;
|
||||
controller->get_CoreWebView2(&webview);
|
||||
webview->add_WebMessageReceived(this, &token);
|
||||
webview->add_PermissionRequested(this, &token);
|
||||
|
||||
cb(controller);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE Invoke(
|
||||
ICoreWebView2 *sender, ICoreWebView2WebMessageReceivedEventArgs *args) {
|
||||
LPWSTR message;
|
||||
args->TryGetWebMessageAsString(&message);
|
||||
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wideCharConverter;
|
||||
mcb(wideCharConverter.to_bytes(message));
|
||||
sender->PostWebMessageAsString(message);
|
||||
|
||||
CoTaskMemFree(message);
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
Invoke(ICoreWebView2 *sender,
|
||||
ICoreWebView2PermissionRequestedEventArgs *args) {
|
||||
COREWEBVIEW2_PERMISSION_KIND kind;
|
||||
args->get_PermissionKind(&kind);
|
||||
if (kind == COREWEBVIEW2_PERMISSION_KIND_CLIPBOARD_READ) {
|
||||
args->put_State(COREWEBVIEW2_PERMISSION_STATE_ALLOW);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user