-
Notifications
You must be signed in to change notification settings - Fork 474
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #93 from MicrosoftEdge/publish-wincomp-sample-app1
Publish wincomp sample app
- Loading branch information
Showing
28 changed files
with
1,505 additions
and
223 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Defines the coding style to apply. See: | ||
# <http://clang.llvm.org/docs/ClangFormatStyleOptions.html> | ||
Language: Cpp | ||
BasedOnStyle: LLVM | ||
AccessModifierOffset: -4 | ||
AllowShortCaseLabelsOnASingleLine: false | ||
AllowShortFunctionsOnASingleLine: None | ||
AllowShortIfStatementsOnASingleLine: false | ||
AllowShortLoopsOnASingleLine: false | ||
AlwaysBreakAfterDefinitionReturnType: false | ||
AlignAfterOpenBracket: AlwaysBreak | ||
AlwaysBreakAfterReturnType: None | ||
BreakBeforeBraces: Allman | ||
ColumnLimit: 96 | ||
DerivePointerAlignment: false | ||
IndentWidth: 4 | ||
PointerAlignment: Left | ||
PenaltyReturnTypeOnItsOwnLine: 1000 | ||
TabWidth: 4 | ||
UseTab: Never | ||
... | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Debug/ | ||
Release/ | ||
ipch/ | ||
x64/ | ||
x86/ | ||
ARM64/ | ||
.vs/ | ||
# Created by running event monitor | ||
enc_temp_folder/ | ||
packages/ | ||
|
||
# Override root .gitignore to ensure we pick up changes for the sample app | ||
!*.sln | ||
!*.vcxproj | ||
!*.vcxproj.filters | ||
!*.props | ||
|
||
# Ignore the binary generated version of the resource (.rc) file | ||
*.aps | ||
|
||
# Make sure script debug config is checked in for vendor testing | ||
!.vscode |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright (C) Microsoft Corporation. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "pch.h" | ||
#include "framework.h" | ||
#include "App.h" | ||
#include "Appwindow.h" | ||
#include "CompositionHost.h" | ||
#define MAX_LOADSTRING 100 | ||
#define WM_LBUTTONDOWN 0x0201 | ||
|
||
// Global Variables: | ||
HINSTANCE hInst; // current instance | ||
int nCmdShow; | ||
int RunMessagePump(); | ||
|
||
int APIENTRY wWinMain(_In_ HINSTANCE hInstance, | ||
_In_opt_ HINSTANCE hPrevInstance, | ||
_In_ LPWSTR lpCmdLine, | ||
_In_ int m_nCmdShow) | ||
{ | ||
hInst = hInstance; | ||
UNREFERENCED_PARAMETER(hPrevInstance); | ||
UNREFERENCED_PARAMETER(lpCmdLine); | ||
nCmdShow = m_nCmdShow; | ||
|
||
AppWindow appWindow; | ||
int retVal = RunMessagePump(); | ||
return retVal; | ||
} | ||
|
||
// Run the message pump for one thread. | ||
int RunMessagePump() | ||
{ | ||
HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_WEBVIEW2SAMPLEWINCOMP)); | ||
|
||
MSG msg; | ||
|
||
// Main message loop: | ||
while (GetMessage(&msg, nullptr, 0, 0)) | ||
{ | ||
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) | ||
{ | ||
TranslateMessage(&msg); | ||
DispatchMessage(&msg); | ||
} | ||
} | ||
|
||
return (int) msg.wParam; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (C) Microsoft Corporation. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#pragma once | ||
|
||
#include "resource.h" | ||
extern HINSTANCE hInst; | ||
extern int nCmdShow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
// Copyright (C) Microsoft Corporation. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "pch.h" | ||
|
||
#include "App.h" | ||
#include "AppWindow.h" | ||
#include "CheckFailure.h" | ||
#include "CompositionHost.h" | ||
#include <WinUser.h> | ||
|
||
static constexpr LPCWSTR s_subFolder = nullptr; | ||
static constexpr WCHAR c_samplePath[] = L"WebView2SamplePage.html"; | ||
|
||
AppWindow::AppWindow() : m_winComp(std::make_unique<CompositionHost>()) | ||
{ | ||
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text | ||
CHECK_FAILURE(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)); | ||
LoadStringW(hInst, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); | ||
|
||
// Perform application initialization: | ||
m_mainWindow = CreateWindowW( | ||
GetWindowClass(), szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, | ||
nullptr, nullptr, hInst, nullptr); | ||
SetWindowLongPtr(m_mainWindow, GWLP_USERDATA, (LONG_PTR)this); | ||
ShowWindow(m_mainWindow, nCmdShow); | ||
UpdateWindow(m_mainWindow); | ||
|
||
m_sampleUri = GetLocalUri(c_samplePath); | ||
InitializeWebView(); | ||
} | ||
|
||
// Register the Win32 window class for the app window. | ||
PCWSTR AppWindow::GetWindowClass() | ||
{ | ||
// Only do this once | ||
static PCWSTR windowClass = [] { | ||
static WCHAR windowClass[MAX_LOADSTRING]; | ||
LoadStringW(hInst, IDC_WEBVIEW2SAMPLEWINCOMP, windowClass, MAX_LOADSTRING); | ||
|
||
WNDCLASSEXW wcex; | ||
|
||
wcex.cbSize = sizeof(WNDCLASSEX); | ||
|
||
wcex.style = CS_HREDRAW | CS_VREDRAW; | ||
wcex.lpfnWndProc = WndProcStatic; | ||
wcex.cbClsExtra = 0; | ||
wcex.cbWndExtra = 0; | ||
wcex.hInstance = hInst; | ||
wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_WEBVIEW2SAMPLEWINCOMP)); | ||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); | ||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); | ||
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WEBVIEW2SAMPLEWINCOMP); | ||
wcex.lpszClassName = windowClass; | ||
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); | ||
|
||
RegisterClassExW(&wcex); | ||
return windowClass; | ||
}(); | ||
return windowClass; | ||
} | ||
|
||
LRESULT CALLBACK AppWindow::WndProcStatic(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
|
||
if (auto app = (AppWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA)) | ||
{ | ||
if (app->HandleWindowMessage(hWnd, message, wParam, lParam)) | ||
{ | ||
return 0; | ||
} | ||
} | ||
return DefWindowProc(hWnd, message, wParam, lParam); | ||
} | ||
|
||
bool AppWindow::HandleWindowMessage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
if (message >= WM_MOUSEFIRST && message <= WM_MOUSELAST) | ||
{ | ||
m_winComp->OnMouseMessage(message, wParam, lParam); | ||
return true; | ||
} | ||
|
||
switch (message) | ||
{ | ||
case WM_MOVE: | ||
{ | ||
if (m_controller) | ||
{ | ||
m_controller->NotifyParentWindowPositionChanged(); | ||
} | ||
return true; | ||
} | ||
case WM_SIZE: | ||
{ | ||
RECT availableBounds = {0}; | ||
GetClientRect(m_mainWindow, &availableBounds); | ||
m_winComp->SetBounds(availableBounds); | ||
return true; | ||
} | ||
case WM_COMMAND: | ||
{ | ||
int wmId = LOWORD(wParam); | ||
// Parse the menu selections: | ||
switch (wmId) | ||
{ | ||
case IDM_ABOUT: | ||
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); | ||
return true; | ||
case IDM_EXIT: | ||
CloseAppWindow(); | ||
return true; | ||
} | ||
break; | ||
} | ||
case WM_PAINT: | ||
{ | ||
PAINTSTRUCT ps; | ||
HDC hdc = BeginPaint(hWnd, &ps); | ||
EndPaint(hWnd, &ps); | ||
return true; | ||
} | ||
case WM_DESTROY: | ||
PostQuitMessage(0); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
// Message handler for about box. | ||
INT_PTR CALLBACK AppWindow::About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) | ||
{ | ||
UNREFERENCED_PARAMETER(lParam); | ||
switch (message) | ||
{ | ||
case WM_INITDIALOG: | ||
return (INT_PTR)TRUE; | ||
case WM_COMMAND: | ||
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) | ||
{ | ||
EndDialog(hDlg, LOWORD(wParam)); | ||
return (INT_PTR)TRUE; | ||
} | ||
break; | ||
} | ||
return (INT_PTR)FALSE; | ||
} | ||
|
||
void AppWindow::InitializeWebView() | ||
{ | ||
auto options = Microsoft::WRL::Make<CoreWebView2EnvironmentOptions>(); | ||
HRESULT hr = CreateCoreWebView2EnvironmentWithOptions( | ||
s_subFolder, nullptr, options.Get(), | ||
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>( | ||
[this](HRESULT result, ICoreWebView2Environment* environment) -> HRESULT { | ||
m_webViewEnvironment = environment; | ||
wil::com_ptr<ICoreWebView2Environment3> | ||
webViewEnvironment3 = | ||
m_webViewEnvironment.try_query<ICoreWebView2Environment3>(); | ||
|
||
if (webViewEnvironment3) | ||
{ | ||
CHECK_FAILURE( | ||
webViewEnvironment3->CreateCoreWebView2CompositionController( | ||
m_mainWindow, | ||
Callback< | ||
ICoreWebView2CreateCoreWebView2CompositionControllerCompletedHandler>( | ||
this, &AppWindow::OnCreateCoreWebView2ControllerCompleted) | ||
.Get())); | ||
} | ||
return S_OK; | ||
}) | ||
.Get()); | ||
assert(SUCCEEDED(hr)); | ||
} | ||
|
||
HRESULT AppWindow::OnCreateCoreWebView2ControllerCompleted( | ||
HRESULT result, ICoreWebView2CompositionController* compositionController) | ||
{ | ||
if (result == S_OK) | ||
{ | ||
m_compositionController = compositionController; | ||
CHECK_FAILURE(m_compositionController->QueryInterface(IID_PPV_ARGS(&m_controller))); | ||
CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); | ||
m_controller->put_IsVisible(true); | ||
m_webView->Navigate(m_sampleUri.c_str()); | ||
} | ||
else | ||
{ | ||
ShowFailure(result, L"Failed to create webview"); | ||
} | ||
m_winComp->Initialize(this); | ||
return S_OK; | ||
} | ||
|
||
void AppWindow::CloseWebView() | ||
{ | ||
if (m_controller) | ||
{ | ||
m_controller->Close(); | ||
m_controller = nullptr; | ||
m_webView = nullptr; | ||
} | ||
m_webViewEnvironment = nullptr; | ||
} | ||
|
||
void AppWindow::CloseAppWindow() | ||
{ | ||
CloseWebView(); | ||
DestroyWindow(m_mainWindow); | ||
} | ||
|
||
std::wstring AppWindow::GetLocalUri(std::wstring relativePath) | ||
{ | ||
std::wstring path = GetLocalPath(relativePath, false); | ||
|
||
wil::com_ptr<IUri> uri; | ||
CHECK_FAILURE(CreateUri(path.c_str(), Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME, 0, &uri)); | ||
|
||
wil::unique_bstr uriBstr; | ||
CHECK_FAILURE(uri->GetAbsoluteUri(&uriBstr)); | ||
return std::wstring(uriBstr.get()); | ||
} | ||
|
||
std::wstring AppWindow::GetLocalPath(std::wstring relativePath, bool keep_exe_path) | ||
{ | ||
WCHAR rawPath[MAX_PATH]; | ||
GetModuleFileNameW(hInst, rawPath, MAX_PATH); | ||
std::wstring path(rawPath); | ||
if (keep_exe_path) | ||
{ | ||
path.append(relativePath); | ||
} | ||
else | ||
{ | ||
std::size_t index = path.find_last_of(L"\\") + 1; | ||
path.replace(index, path.length(), relativePath); | ||
} | ||
return path; | ||
} |
Oops, something went wrong.