1
+ // Copyright (C) Microsoft Corporation. All rights reserved.
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ #include " pch.h"
6
+
7
+ #include " App.h"
8
+ #include " AppWindow.h"
9
+ #include " CheckFailure.h"
10
+ #include " CompositionHost.h"
11
+ #include < WinUser.h>
12
+
13
+ static constexpr LPCWSTR s_subFolder = nullptr ;
14
+ static constexpr WCHAR c_samplePath[] = L" WebView2SamplePage.html" ;
15
+
16
+ AppWindow::AppWindow () : m_winComp(std::make_unique<CompositionHost>())
17
+ {
18
+ WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
19
+ CHECK_FAILURE (CoInitializeEx (NULL , COINIT_APARTMENTTHREADED));
20
+ LoadStringW (hInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
21
+
22
+ // Perform application initialization:
23
+ m_mainWindow = CreateWindowW (
24
+ GetWindowClass (), szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0 , CW_USEDEFAULT, 0 ,
25
+ nullptr , nullptr , hInst, nullptr );
26
+ SetWindowLongPtr (m_mainWindow, GWLP_USERDATA, (LONG_PTR)this );
27
+ ShowWindow (m_mainWindow, nCmdShow);
28
+ UpdateWindow (m_mainWindow);
29
+
30
+ m_sampleUri = GetLocalUri (c_samplePath);
31
+ InitializeWebView ();
32
+ }
33
+
34
+ // Register the Win32 window class for the app window.
35
+ PCWSTR AppWindow::GetWindowClass ()
36
+ {
37
+ // Only do this once
38
+ static PCWSTR windowClass = [] {
39
+ static WCHAR windowClass[MAX_LOADSTRING];
40
+ LoadStringW (hInst, IDC_WEBVIEW2SAMPLEWINCOMP, windowClass, MAX_LOADSTRING);
41
+
42
+ WNDCLASSEXW wcex;
43
+
44
+ wcex.cbSize = sizeof (WNDCLASSEX);
45
+
46
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
47
+ wcex.lpfnWndProc = WndProcStatic;
48
+ wcex.cbClsExtra = 0 ;
49
+ wcex.cbWndExtra = 0 ;
50
+ wcex.hInstance = hInst;
51
+ wcex.hIcon = LoadIcon (hInst, MAKEINTRESOURCE (IDI_WEBVIEW2SAMPLEWINCOMP));
52
+ wcex.hCursor = LoadCursor (nullptr , IDC_ARROW);
53
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1 );
54
+ wcex.lpszMenuName = MAKEINTRESOURCEW (IDC_WEBVIEW2SAMPLEWINCOMP);
55
+ wcex.lpszClassName = windowClass;
56
+ wcex.hIconSm = LoadIcon (wcex.hInstance , MAKEINTRESOURCE (IDI_SMALL));
57
+
58
+ RegisterClassExW (&wcex);
59
+ return windowClass;
60
+ }();
61
+ return windowClass;
62
+ }
63
+
64
+ LRESULT CALLBACK AppWindow::WndProcStatic (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
65
+ {
66
+
67
+ if (auto app = (AppWindow*)GetWindowLongPtr (hWnd, GWLP_USERDATA))
68
+ {
69
+ if (app->HandleWindowMessage (hWnd, message, wParam, lParam))
70
+ {
71
+ return 0 ;
72
+ }
73
+ }
74
+ return DefWindowProc (hWnd, message, wParam, lParam);
75
+ }
76
+
77
+ bool AppWindow::HandleWindowMessage (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
78
+ {
79
+ if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST)
80
+ {
81
+ m_winComp->OnMouseMessage (message, wParam, lParam);
82
+ return true ;
83
+ }
84
+
85
+ switch (message)
86
+ {
87
+ case WM_MOVE:
88
+ {
89
+ if (m_controller)
90
+ {
91
+ m_controller->NotifyParentWindowPositionChanged ();
92
+ }
93
+ return true ;
94
+ }
95
+ case WM_SIZE:
96
+ {
97
+ RECT availableBounds = {0 };
98
+ GetClientRect (m_mainWindow, &availableBounds);
99
+ m_winComp->SetBounds (availableBounds);
100
+ return true ;
101
+ }
102
+ case WM_COMMAND:
103
+ {
104
+ int wmId = LOWORD (wParam);
105
+ // Parse the menu selections:
106
+ switch (wmId)
107
+ {
108
+ case IDM_ABOUT:
109
+ DialogBox (hInst, MAKEINTRESOURCE (IDD_ABOUTBOX), hWnd, About);
110
+ return true ;
111
+ case IDM_EXIT:
112
+ CloseAppWindow ();
113
+ return true ;
114
+ }
115
+ break ;
116
+ }
117
+ case WM_PAINT:
118
+ {
119
+ PAINTSTRUCT ps;
120
+ HDC hdc = BeginPaint (hWnd, &ps);
121
+ EndPaint (hWnd, &ps);
122
+ return true ;
123
+ }
124
+ case WM_DESTROY:
125
+ PostQuitMessage (0 );
126
+ return true ;
127
+ }
128
+ return false ;
129
+ }
130
+
131
+ // Message handler for about box.
132
+ INT_PTR CALLBACK AppWindow::About (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
133
+ {
134
+ UNREFERENCED_PARAMETER (lParam);
135
+ switch (message)
136
+ {
137
+ case WM_INITDIALOG:
138
+ return (INT_PTR)TRUE ;
139
+ case WM_COMMAND:
140
+ if (LOWORD (wParam) == IDOK || LOWORD (wParam) == IDCANCEL)
141
+ {
142
+ EndDialog (hDlg, LOWORD (wParam));
143
+ return (INT_PTR)TRUE ;
144
+ }
145
+ break ;
146
+ }
147
+ return (INT_PTR)FALSE ;
148
+ }
149
+
150
+ void AppWindow::InitializeWebView ()
151
+ {
152
+ auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>();
153
+ HRESULT hr = CreateCoreWebView2EnvironmentWithOptions (
154
+ s_subFolder, nullptr , options.Get (),
155
+ Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
156
+ [this ](HRESULT result, ICoreWebView2Environment* environment) -> HRESULT {
157
+ m_webViewEnvironment = environment;
158
+ wil::com_ptr<ICoreWebView2Environment3>
159
+ webViewEnvironment3 =
160
+ m_webViewEnvironment.try_query <ICoreWebView2Environment3>();
161
+
162
+ if (webViewEnvironment3)
163
+ {
164
+ CHECK_FAILURE (
165
+ webViewEnvironment3->CreateCoreWebView2CompositionController (
166
+ m_mainWindow,
167
+ Callback<
168
+ ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>(
169
+ this , &AppWindow::OnCreateCoreWebView2ControllerCompleted)
170
+ .Get ()));
171
+ }
172
+ return S_OK;
173
+ })
174
+ .Get ());
175
+ assert (SUCCEEDED (hr));
176
+ }
177
+
178
+ HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted (
179
+ HRESULT result, ICoreWebView2CompositionController* compositionController)
180
+ {
181
+ if (result == S_OK)
182
+ {
183
+ m_compositionController = compositionController;
184
+ CHECK_FAILURE (m_compositionController->QueryInterface (IID_PPV_ARGS (&m_controller)));
185
+ CHECK_FAILURE (m_controller->get_CoreWebView2 (&m_webView));
186
+ m_controller->put_IsVisible (true );
187
+ m_webView->Navigate (m_sampleUri.c_str ());
188
+ }
189
+ else
190
+ {
191
+ ShowFailure (result, L" Failed to create webview" );
192
+ }
193
+ m_winComp->Initialize (this );
194
+ return S_OK;
195
+ }
196
+
197
+ void AppWindow::CloseWebView ()
198
+ {
199
+ if (m_controller)
200
+ {
201
+ m_controller->Close ();
202
+ m_controller = nullptr ;
203
+ m_webView = nullptr ;
204
+ }
205
+ m_webViewEnvironment = nullptr ;
206
+ }
207
+
208
+ void AppWindow::CloseAppWindow ()
209
+ {
210
+ CloseWebView ();
211
+ DestroyWindow (m_mainWindow);
212
+ }
213
+
214
+ std::wstring AppWindow::GetLocalUri (std::wstring relativePath)
215
+ {
216
+ std::wstring path = GetLocalPath (relativePath, false );
217
+
218
+ wil::com_ptr<IUri> uri;
219
+ CHECK_FAILURE (CreateUri (path.c_str (), Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0 , &uri));
220
+
221
+ wil::unique_bstr uriBstr;
222
+ CHECK_FAILURE (uri->GetAbsoluteUri (&uriBstr));
223
+ return std::wstring (uriBstr.get ());
224
+ }
225
+
226
+ std::wstring AppWindow::GetLocalPath (std::wstring relativePath, bool keep_exe_path)
227
+ {
228
+ WCHAR rawPath[MAX_PATH];
229
+ GetModuleFileNameW (hInst, rawPath, MAX_PATH);
230
+ std::wstring path (rawPath);
231
+ if (keep_exe_path)
232
+ {
233
+ path.append (relativePath);
234
+ }
235
+ else
236
+ {
237
+ std::size_t index = path.find_last_of (L" \\ " ) + 1 ;
238
+ path.replace (index, path.length (), relativePath);
239
+ }
240
+ return path;
241
+ }
0 commit comments