I am new to win32 C++ app . Even you can say I have never done any coding in win32 .Now I am trying to create win32 app , which will use webview2 to launch browser , do some authentication , and fetch token . Here , once I fetched my token in add_WebResourceResponseReceived
, I am closing the browser window from my code . but it crashes in DispatchMessage
.Here is my code ,
void CloseBrowserAndCleanup(HWND _hWnd);
__MIDL_DECLSPEC_DLLEXPORT int getTokenFromWebView2()
{
std::wstring authToken;
WNDCLASSEX wcex;
HINSTANCE hInstance = GetModuleHandle(NULL);
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// Store instance handle in our global variable
hInst = hInstance;
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
1200, 900,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
// nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd,
SW_SHOW);
UpdateWindow(hWnd);
// CreateConsole();
// <-- WebView2 sample code starts here -->
HRESULT hr = CreateCoreWebView2EnvironmentWithOptions(nullptr, L"D:\webview2", nullptr,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
[hWnd, &authToken](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {
// Create a CoreWebView2Controller and get the associated CoreWebView2 whose parent is the main window hWnd
env->CreateCoreWebView2Controller(hWnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
[hWnd, &authToken](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
if (controller != nullptr) {
webviewController = controller;
webviewController->get_CoreWebView2(&webview);
}
wil::com_ptr<ICoreWebView2Settings> settings;
webview->get_Settings(&settings);
settings->put_IsScriptEnabled(TRUE);
settings->put_AreDefaultScriptDialogsEnabled(TRUE);
settings->put_IsWebMessageEnabled(TRUE);
RECT bounds;
GetClientRect(hWnd, &bounds);
webviewController->put_Bounds(bounds);
webview->Navigate(L"my url");
EventRegistrationToken token;
if (auto webView10 = webview.try_query<ICoreWebView2_10>())
{
webView10->add_WebResourceRequested(Callback<ICoreWebView2WebResourceRequestedEventHandler>(
[](ICoreWebView2* sender, ICoreWebView2WebResourceRequestedEventArgs* args) -> HRESULT {
wil::com_ptr<ICoreWebView2WebResourceRequest> request;
args->get_Request(&request);
wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders;
request->get_Headers(&requestHeaders);
RequestHeadersToJsonString(requestHeaders.get());
return S_OK;
}).Get(), nullptr);
webView10->add_WebResourceResponseReceived(Callback<ICoreWebView2WebResourceResponseReceivedEventHandler>(
[hWnd, &authToken](ICoreWebView2* webView , ICoreWebView2WebResourceResponseReceivedEventArgs* args)->HRESULT {
wil::com_ptr<ICoreWebView2WebResourceRequest> request;
CheckFailure(args->get_Request(&request));
wil::unique_cotaskmem_string uri;
CheckFailure(request->get_Uri(&uri));
std::wcout << "response uri : " << uri.get() << std::endl;
if (wcscmp(uri.get(), L"my auth url/"))
{
wil::com_ptr<ICoreWebView2HttpRequestHeaders> requestHeaders;
CheckFailure(request->get_Headers(&requestHeaders));
wil::unique_cotaskmem_string authHeaderValue;
if (requestHeaders->GetHeader(L"Authorization", &authHeaderValue) == S_OK)
{
authToken = authHeaderValue.get();
CloseBrowserAndCleanup(hWnd);
//***once above call is completed it crashing in `DispatchMessage(&msg)` line .
}
}
return S_OK;
}
).Get(), &token);
}
else {
FeatureNotAvailable();
}
return S_OK;
}).Get());
return S_OK;
}).Get());
// <-- WebView2 sample code ends here -->
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg); // it is crashing here after calling `CloseBrowserAndCleanup(hWnd);`
}
//return (int)msg.wParam;
return 1;
}
void CloseBrowserAndCleanup(HWND _hWnd) {
if (!cleanupStarted)
{
cleanupStarted = true;
if (webviewController) {
webviewController->Close();
webviewController = nullptr;
}
if (webview) {
webview = nullptr;
}
if (_hWnd) {
DestroyWindow(_hWnd);
_hWnd = nullptr;
}
PostQuitMessage(0);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
case WM_SIZE:
if (webviewController != nullptr) {
RECT bounds;
GetClientRect(hWnd, &bounds);
webviewController->put_Bounds(bounds);
};
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}