mirror of
https://github.com/taigrr/wails.git
synced 2026-04-02 05:08:54 -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.
|
// Some code may be inspired by or directly used from Webview.
|
||||||
#include "ffenestri_windows.h"
|
#include "ffenestri_windows.h"
|
||||||
//#include "wv2ComHandler_windows.h"
|
#include "wv2ComHandler_windows.h"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <atomic>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <locale>
|
||||||
|
#include <codecvt>
|
||||||
|
#include "windows/WebView2.h"
|
||||||
|
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
DWORD mainThread;
|
DWORD mainThread;
|
||||||
@@ -11,40 +16,14 @@ void dispatch(dispatchFunction func) {
|
|||||||
PostThreadMessage(mainThread, WM_APP, 0, (LPARAM) new 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) {
|
struct Application *NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel, int hideWindowOnClose) {
|
||||||
|
|
||||||
// Create application
|
// Create application
|
||||||
struct Application *result = (struct Application*)malloc(sizeof(struct Application));
|
struct Application *result = (struct Application*)malloc(sizeof(struct Application));
|
||||||
|
|
||||||
result->window = nullptr;
|
result->window = nullptr;
|
||||||
// result->webview = nullptr;
|
result->webview = nullptr;
|
||||||
// result->controller = nullptr;
|
result->webviewController = nullptr;
|
||||||
|
|
||||||
result->title = title;
|
result->title = title;
|
||||||
result->width = width;
|
result->width = width;
|
||||||
@@ -89,8 +68,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
|
|
||||||
case WM_DESTROY: {
|
case WM_DESTROY: {
|
||||||
DestroyApplication(app);
|
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: {
|
case WM_GETMINMAXINFO: {
|
||||||
// Exit early if this is called before the window is created.
|
// Exit early if this is called before the window is created.
|
||||||
if ( app == NULL ) {
|
if ( app == NULL ) {
|
||||||
@@ -127,29 +114,31 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
default:
|
default:
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
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];
|
// char currentExePath[MAX_PATH];
|
||||||
// GetModuleFileNameA(NULL, currentExePath, MAX_PATH);
|
// GetModuleFileNameA(NULL, currentExePath, MAX_PATH);
|
||||||
// char *currentExeName = PathFindFileNameA(currentExePath);
|
// char *currentExeName = PathFindFileNameA(currentExePath);
|
||||||
//
|
//
|
||||||
|
// printf("current exe name = %s\n", currentExeName);
|
||||||
|
|
||||||
// std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wideCharConverter;
|
// std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> wideCharConverter;
|
||||||
// std::wstring userDataFolder = wideCharConverter.from_bytes(std::getenv("APPDATA"));
|
// std::wstring userDataFolder = wideCharConverter.from_bytes(std::getenv("APPDATA"));
|
||||||
// std::wstring currentExeNameW = wideCharConverter.from_bytes(currentExeName);
|
// std::wstring currentExeNameW = wideCharConverter.from_bytes(currentExeName);
|
||||||
//
|
//
|
||||||
// HRESULT res = CreateCoreWebView2EnvironmentWithOptions(
|
// HRESULT res = CreateCoreWebView2EnvironmentWithOptions(
|
||||||
// nullptr, (userDataFolder + L"/" + currentExeNameW).c_str(), nullptr,
|
// nullptr, (userDataFolder + L"/" + currentExeNameW).c_str(), nullptr,
|
||||||
// new wv2ComHandler(app->window, cb,
|
// new wv2ComHandler(app, cb,
|
||||||
// [&](ICoreWebView2Controller *controller) {
|
// [&](ICoreWebView2Controller *webviewController) {
|
||||||
// app->controller = controller;
|
// app->webviewController = webviewController;
|
||||||
// app->controller->get_CoreWebView2(&(app->webview));
|
// app->webviewController->get_CoreWebView2(&(app->webview));
|
||||||
// app->webview->AddRef();
|
// app->webview->AddRef();
|
||||||
// flag.clear();
|
// flag.clear();
|
||||||
// }));
|
// }));
|
||||||
@@ -163,9 +152,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
|
|||||||
// TranslateMessage(&msg);
|
// TranslateMessage(&msg);
|
||||||
// DispatchMessage(&msg);
|
// DispatchMessage(&msg);
|
||||||
// }
|
// }
|
||||||
// init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}");
|
//// init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}");
|
||||||
// return true;
|
return true;
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
void initialCallback(std::string message) {
|
||||||
|
printf("MESSAGE=%s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
void Run(struct Application* app, int argc, char **argv) {
|
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.lpszClassName = (LPCWSTR)"ffenestri";
|
||||||
wc.lpfnWndProc = WndProc;
|
wc.lpfnWndProc = WndProc;
|
||||||
|
|
||||||
|
// TODO: Menu
|
||||||
|
// wc.lpszMenuName = nullptr;
|
||||||
|
|
||||||
|
|
||||||
// Process window resizable
|
// Process window resizable
|
||||||
DWORD windowStyle = WS_OVERLAPPEDWINDOW;
|
DWORD windowStyle = WS_OVERLAPPEDWINDOW;
|
||||||
@@ -190,8 +186,8 @@ void Run(struct Application* app, int argc, char **argv) {
|
|||||||
|
|
||||||
RegisterClassEx(&wc);
|
RegisterClassEx(&wc);
|
||||||
app->window = CreateWindow((LPCWSTR)"ffenestri", (LPCWSTR)"", windowStyle, CW_USEDEFAULT,
|
app->window = CreateWindow((LPCWSTR)"ffenestri", (LPCWSTR)"", windowStyle, CW_USEDEFAULT,
|
||||||
CW_USEDEFAULT, app->width, app->height, NULL, NULL,
|
CW_USEDEFAULT, app->width, app->height, NULL, NULL,
|
||||||
GetModuleHandle(NULL), NULL);
|
hInstance, NULL);
|
||||||
|
|
||||||
// Private setTitle as we're on the main thread
|
// Private setTitle as we're on the main thread
|
||||||
setTitle(app, app->title);
|
setTitle(app, app->title);
|
||||||
@@ -211,8 +207,8 @@ void Run(struct Application* app, int argc, char **argv) {
|
|||||||
UpdateWindow(app->window);
|
UpdateWindow(app->window);
|
||||||
SetFocus(app->window);
|
SetFocus(app->window);
|
||||||
|
|
||||||
// TODO: Add webview2
|
// Add webview2
|
||||||
// initWebView2(app->window);
|
initWebView2(app, 1, initialCallback);
|
||||||
|
|
||||||
// Main event loop
|
// Main event loop
|
||||||
MSG msg;
|
MSG msg;
|
||||||
|
|||||||
@@ -2,18 +2,45 @@
|
|||||||
#ifndef _FFENESTRI_WINDOWS_H
|
#ifndef _FFENESTRI_WINDOWS_H
|
||||||
#define _FFENESTRI_WINDOWS_H
|
#define _FFENESTRI_WINDOWS_H
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#define UNICODE 1
|
#define UNICODE 1
|
||||||
|
|
||||||
#include "ffenestri.h"
|
#include "ffenestri.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wingdi.h>
|
#include <wingdi.h>
|
||||||
#include <functional>
|
#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; } )
|
#define ON_MAIN_THREAD(code) dispatch( [=]{ code; } )
|
||||||
|
|
||||||
typedef std::function<void()> dispatchFunction;
|
typedef std::function<void()> dispatchFunction;
|
||||||
//typedef std::function<void(const std::string)> messageCallback;
|
typedef std::function<void(const std::string)> messageCallback;
|
||||||
//typedef std::function<void(ICoreWebView2Controller *)> comHandlerCallback;
|
typedef std::function<void(ICoreWebView2Controller *)> comHandlerCallback;
|
||||||
|
|
||||||
void center(struct Application*);
|
void center(struct Application*);
|
||||||
void setTitle(struct Application* app, const char *title);
|
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