Skip to content

Commit

Permalink
Merge pull request #93 from MicrosoftEdge/publish-wincomp-sample-app1
Browse files Browse the repository at this point in the history
Publish wincomp sample app
  • Loading branch information
tofuandeve authored Jun 8, 2021
2 parents 2449abc + ca7b4cc commit 19cfc87
Show file tree
Hide file tree
Showing 28 changed files with 1,505 additions and 223 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ In the ``GettingStarted`` folder you will find the starter code for its respecti
- [WinUI Getting Started](https://docs.microsoft.com/microsoft-edge/webview2/gettingstarted/winui)

In the ``Sample Apps`` folder you will find:
- [WebView2Samples.sln](SampleApps/WebView2Samples.sln) - a collective solution that includes [WebView2APISample.vcxproj](SampleApps/WebView2APISample/WebView2APISample.vcxproj), [WebView2WpfBrowser.csproj](SampleApps/WebView2WpfBrowser/WebView2WpfBrowser.csproj), [WebView2WindowsFormsBrowser.csproj](SampleApps/WebView2WindowsFormsBrowser/WebView2WindowsFormsBrowser.csproj), [WV2DeploymentWiXCustomActionSample](/SampleApps/WV2DeploymentWiXCustomActionSample/README.md), and [WV2DeploymentWiXBurnBundleSample](/SampleApps/WV2DeploymentWiXBurnBundleSample/README.md).
- [WebView2Samples.sln](SampleApps/WebView2Samples.sln) - a collective solution that includes [WebView2APISample.vcxproj](SampleApps/WebView2APISample/WebView2APISample.vcxproj), [WebView2SampleWinComp.vcxproj](SampleApps/WebView2SampleWinComp/WebView2SampleWinComp.vcxproj), [WebView2WpfBrowser.csproj](SampleApps/WebView2WpfBrowser/WebView2WpfBrowser.csproj), [WebView2WindowsFormsBrowser.csproj](SampleApps/WebView2WindowsFormsBrowser/WebView2WindowsFormsBrowser.csproj), [WV2DeploymentWiXCustomActionSample](/SampleApps/WV2DeploymentWiXCustomActionSample/README.md), and [WV2DeploymentWiXBurnBundleSample](/SampleApps/WV2DeploymentWiXBurnBundleSample/README.md).

Please leave feedback in our [our feedback repo](https://aka.ms/webviewfeedback)!

Expand All @@ -23,7 +23,7 @@ This will require downloading the [Getting Started Guide](https://github.com/Mic

#### Comprehensive API Sample

The **Win32 C++ Sample** can be found in the [WebView2APISample](./SampleApps/WebView2APISample) directory.
The **Win32 C++ Sample** can be found in the [WebView2APISample](./SampleApps/WebView2APISample) directory and [WebView2SampleWinComp](./SampleApps/WebView2SampleWinComp) directory.

#### Multiple WebViews Sample

Expand Down
22 changes: 22 additions & 0 deletions SampleApps/WebView2SampleWinComp/.clang-format
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
...

22 changes: 22 additions & 0 deletions SampleApps/WebView2SampleWinComp/.gitignore
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
51 changes: 51 additions & 0 deletions SampleApps/WebView2SampleWinComp/App.cpp
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;
}
9 changes: 9 additions & 0 deletions SampleApps/WebView2SampleWinComp/App.h
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;
241 changes: 241 additions & 0 deletions SampleApps/WebView2SampleWinComp/AppWindow.cpp
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;
}
Loading

0 comments on commit 19cfc87

Please sign in to comment.