Skip to content

Commit a596c9f

Browse files
author
Eve Le
committed
Add wincomp sample app to WebView2Samples
1 parent 2449abc commit a596c9f

27 files changed

+1504
-221
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Defines the coding style to apply. See:
2+
# <http://clang.llvm.org/docs/ClangFormatStyleOptions.html>
3+
Language: Cpp
4+
BasedOnStyle: LLVM
5+
AccessModifierOffset: -4
6+
AllowShortCaseLabelsOnASingleLine: false
7+
AllowShortFunctionsOnASingleLine: None
8+
AllowShortIfStatementsOnASingleLine: false
9+
AllowShortLoopsOnASingleLine: false
10+
AlwaysBreakAfterDefinitionReturnType: false
11+
AlignAfterOpenBracket: AlwaysBreak
12+
AlwaysBreakAfterReturnType: None
13+
BreakBeforeBraces: Allman
14+
ColumnLimit: 96
15+
DerivePointerAlignment: false
16+
IndentWidth: 4
17+
PointerAlignment: Left
18+
PenaltyReturnTypeOnItsOwnLine: 1000
19+
TabWidth: 4
20+
UseTab: Never
21+
...
22+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Debug/
2+
Release/
3+
ipch/
4+
x64/
5+
x86/
6+
ARM64/
7+
.vs/
8+
# Created by running event monitor
9+
enc_temp_folder/
10+
packages/
11+
12+
# Override root .gitignore to ensure we pick up changes for the sample app
13+
!*.sln
14+
!*.vcxproj
15+
!*.vcxproj.filters
16+
!*.props
17+
18+
# Ignore the binary generated version of the resource (.rc) file
19+
*.aps
20+
21+
# Make sure script debug config is checked in for vendor testing
22+
!.vscode
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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+
#include "framework.h"
7+
#include "App.h"
8+
#include "Appwindow.h"
9+
#include "CompositionHost.h"
10+
#define MAX_LOADSTRING 100
11+
#define WM_LBUTTONDOWN 0x0201
12+
13+
// Global Variables:
14+
HINSTANCE hInst; // current instance
15+
int nCmdShow;
16+
int RunMessagePump();
17+
18+
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
19+
_In_opt_ HINSTANCE hPrevInstance,
20+
_In_ LPWSTR lpCmdLine,
21+
_In_ int m_nCmdShow)
22+
{
23+
hInst = hInstance;
24+
UNREFERENCED_PARAMETER(hPrevInstance);
25+
UNREFERENCED_PARAMETER(lpCmdLine);
26+
nCmdShow = m_nCmdShow;
27+
28+
AppWindow appWindow;
29+
int retVal = RunMessagePump();
30+
return retVal;
31+
}
32+
33+
// Run the message pump for one thread.
34+
int RunMessagePump()
35+
{
36+
HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_WEBVIEW2SAMPLEWINCOMP));
37+
38+
MSG msg;
39+
40+
// Main message loop:
41+
while (GetMessage(&msg, nullptr, 0, 0))
42+
{
43+
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
44+
{
45+
TranslateMessage(&msg);
46+
DispatchMessage(&msg);
47+
}
48+
}
49+
50+
return (int) msg.wParam;
51+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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+
#pragma once
6+
7+
#include "resource.h"
8+
extern HINSTANCE hInst;
9+
extern int nCmdShow;
Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
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

Comments
 (0)