Not work when embed into a win32 window
HIllya51 opened this issue · 2 comments
SteffenL commented
Here's a revised version of the example I posted in #1074.
I've only updated the functions resize_widget
and focus_webview
which depended on PR #1064.
Feel free to let me know any opinions you may have on the ok()
and value()
calls which were introduced not too long ago.
#include "webview.h"
#include <memory>
#include <windows.h>
class window {
public:
window() {
HINSTANCE hInstance = GetModuleHandleW(nullptr);
WNDCLASSEXW wc{};
wc.cbSize = sizeof(WNDCLASSEX);
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
wc.lpszClassName = L"window";
wc.lpfnWndProc = wndproc_wrapper;
RegisterClassExW(&wc);
CreateWindowExW(0, L"window", L"Win32 Example", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, nullptr, nullptr,
hInstance, this);
}
void show() {
// When a future PR stops showing non-owned windows automatially,
// code similar to this will be needed.
ShowWindow(m_native_window, SW_SHOW);
UpdateWindow(m_native_window);
SetFocus(m_native_window);
focus_webview();
}
private:
static LRESULT wndproc_wrapper(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
window *self{};
if (msg == WM_NCCREATE) {
auto *lpcs{reinterpret_cast<LPCREATESTRUCT>(lp)};
self = static_cast<window *>(lpcs->lpCreateParams);
self->m_native_window = hwnd;
SetWindowLongPtrW(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(self));
} else {
self = reinterpret_cast<window *>(GetWindowLongPtrW(hwnd, GWLP_USERDATA));
}
if (!self) {
return DefWindowProcW(hwnd, msg, wp, lp);
}
return self->wndproc(msg, wp, lp);
}
LRESULT wndproc(UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_CREATE:
m_webview = std::make_unique<webview::webview>(false, m_native_window);
m_webview->set_html("Thanks for using webview!");
break;
case WM_SIZE:
resize_widget();
break;
case WM_CLOSE:
DestroyWindow(m_native_window);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_ACTIVATE:
if (LOWORD(wp) != WA_INACTIVE) {
focus_webview();
}
break;
default:
return DefWindowProcW(m_native_window, msg, wp, lp);
}
return 0;
}
void resize_widget() {
if (m_webview) {
auto widget = m_webview->widget();
if (widget.ok()) {
auto widget_handle = static_cast<HWND>(widget.value());
RECT r{};
if (GetClientRect(GetParent(widget_handle), &r)) {
MoveWindow(widget_handle, r.left, r.top, r.right - r.left, r.bottom - r.top,
TRUE);
}
}
}
}
void focus_webview() {
if (m_webview) {
auto controller = m_webview->browser_controller();
if (controller.ok()) {
auto* controller_ptr = static_cast<ICoreWebView2Controller *>(controller.value());
controller_ptr->MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC);
}
}
}
HWND m_native_window{};
std::unique_ptr<webview::webview> m_webview;
};
class application {
public:
application() { CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); }
void run() {
MSG msg;
while (GetMessageW(&msg, nullptr, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
};
int WINAPI WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,
LPSTR /*lpCmdLine*/, int /*nCmdShow*/) {
application app;
window window;
window.show();
app.run();
return 0;
}
This is what it looks like in my Windows 10 environment.
HIllya51 commented
good! it now works fine!