Skip to content

Commit dd3ccca

Browse files
mikehoffmspeiche-ms
authored andcommitted
Restore streamlined Readmes for Win32, WinForms, & WPF (#194)
* Streamline Readme, update screenshot * Restore changes from PR 140 * Restore Readme WinForms & WPF
1 parent b3336b8 commit dd3ccca

File tree

6 files changed

+28
-411
lines changed

6 files changed

+28
-411
lines changed
Lines changed: 14 additions & 337 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
description: "Demonstrate the features and usage patterns of WebView2 in Win32."
2+
description: "Demonstrates the features and usage patterns of WebView2 in a Win32 app."
33
extendedZipContent:
44
-
55
path: SharedContent
@@ -14,346 +14,23 @@ products:
1414
- microsoft-edge
1515
urlFragment: WebView2APISample
1616
---
17-
# WebView2 API Sample
17+
# Win32 sample app
1818

19-
This is a hybrid application built with the [Microsoft Edge WebView2](https://aka.ms/webview2) control.
19+
<!-- only enough info to differentiate this sample vs. the others; what is different about this sample compared to the sibling samples? -->
2020

21-
![Sample App Snapshot](https://raw.githubusercontent.com/MicrosoftEdge/WebView2Samples/master/SampleApps/WebView2APISample/documentation/screenshots/sample-app-screenshot.png)
21+
<!-- distinctive platform: -->
22+
This sample, **WebView2APISample**, embeds a WebView2 control within a Win32 application.
2223

23-
The WebView2APISample is an example of an application that embeds a WebView within a Win32 native application. It is built as a Win32 [Visual Studio 2019](https://visualstudio.microsoft.com/vs/) project and makes use of both C++ and HTML/CSS/JavaScript in the WebView2 environment.
24+
<!-- distinctive project type and language: -->
25+
This sample is built as a Win32 Visual Studio 2019 project. It uses C++ in the native environment together with HTML/CSS/JavaScript in the WebView2 environment. This sample showcases many of WebView2's event handlers and API methods that allow a native Win32 application to directly interact with a WebView, and vice versa.
2426

25-
The API Sample showcases a selection of WebView2's event handlers and API methods that allow a native Win32 application to directly interact with a WebView and vice versa.
27+
<!-- special notes about this particular sample: -->
28+
The solution file for this sample is in the parent directory: `SampleApps/WebView2Samples.sln`. The solution file includes a copy of some of the other, sibling samples for other frameworks or platforms.
2629

27-
If this is your first time using WebView, we recommend first following the [Getting Started](https://learn.microsoft.com/microsoft-edge/webview2/gettingstarted/win32) guide, which goes over how to create a WebView2 and walks through some basic WebView2 functionality.
30+
<!-- link to regular docs: -->
31+
To use this sample, see [Win32 sample app](https://learn.microsoft.com/microsoft-edge/webview2/samples/webview2apissample).
2832

29-
To learn more specifics about events and API Handlers in WebView2, you can refer to the [WebView2 Reference Documentation](https://learn.microsoft.com/microsoft-edge/webview2/webview2-api-reference).
33+
<!-- screenshot of running sample app: -->
34+
This is the main WebView2 sample. The running **WebView2APISample** app window shows the WebView2 SDK version and also the WebView2 Runtime version and path. The **WebView2APISample** app has several menus containing many menuitems that demonstrate a broad range of WebView2 APIs:
3035

31-
## Prerequisites
32-
33-
- [Microsoft Edge (Chromium)](https://www.microsoftedgeinsider.com/download/) installed on a supported OS. Currently we recommend the latest version of the Edge Canary channel.
34-
- [Visual Studio](https://visualstudio.microsoft.com/vs/) with C++ support installed.
35-
- Latest pre-release version of our [WebView2 SDK](https://aka.ms/webviewnuget), which is included in this project.
36-
37-
## Build the WebView2 API Sample
38-
39-
Clone the repository and open the solution in Visual Studio. WebView2 is already included as a NuGet package* in this project.
40-
41-
- Clone this repository
42-
- Open the solution in Visual Studio 2019**
43-
- Set the target you want to build (Debug/Release, x86/x64/ARM64)
44-
- Build the project file: _WebView2APISample.vcxproj_
45-
46-
That's it! Everything should be ready to just launch the app.
47-
48-
*You can get the WebView2 NugetPackage through the Visual Studio NuGet Package Manager.
49-
50-
**You can also use Visual Studio 2017 by changing the project's Platform Toolset in Project Properties/Configuration properties/General/Platform Toolset. You might also need to change the Windows SDK to the latest version available to you.
51-
52-
## Application architecture
53-
54-
The API Sample App is an example of a hybrid application. It has two parts: a Win32 native part and a WebView part. The Win32 part can access native Windows APIs, while the WebView container can utilize standard web technologies (HTML, CSS, JavaScript).
55-
56-
This hybrid approach allows you to create and iterate faster using web technologies, while still being able to take advantage of native functionalities. The Sample App specifically demonstrates how both components can interact with each other.
57-
58-
Both of these parts of the Sample App are displayed in the image below:
59-
60-
![alt text](https://raw.githubusercontent.com/MicrosoftEdge/WebView2Samples/master/SampleApps/WebView2APISample/documentation/screenshots/sample-app-layout-diagram.png)
61-
62-
1. Section One: The top part of the Sample App is a Win32 component written in C++. This part of the application takes in UI inputs from the user and uses them to control the WebView.
63-
64-
2. Section Two: The main part of the Sample App is a WebView that can be repurposed using standard web technologies (HTML/CSS/JavaScript). It can be navigated to websites or local content.
65-
66-
## Project Files
67-
68-
This section briefly explains some key files within the repository. The WebView2APISample is divided vertically into components, instead of horizontally into layers. Each component implements the whole workflow of a category of example features, from listening for menu commands, to calling WebView API methods to implement them.
69-
70-
#### 1. App.cpp
71-
72-
This is the top-level file that runs the Sample App. It reads command line options, sets up the process environment, and handles the app's threading model.
73-
74-
#### 2. AppWindow.cpp
75-
76-
This file implements the application window. In this file, we first set up all the Win32 controls. Second, we initialize the WebView Environment and the WebView. Third, we add some event handlers to the WebView and create all the components that handle various features of the application. The `AppWindow` class itself handles commands from the application's Window menu.
77-
78-
#### 3. FileComponent.cpp
79-
80-
This component handles commands from the File menu (except for Exit), as well as the `DocumentTitleChanged` event.
81-
82-
#### 4. ScriptComponent.cpp
83-
84-
This component handles commands from the Script menu, which involve interacting with the WebView by injecting JavaScript, posting WebMessages, adding native objects to the webpage, or using the DevTools protocol to communicate with the webpage.
85-
86-
#### 5. ProcessComponent.cpp
87-
88-
This component handles commands from the Process menu, which involve interaction with the browser's process. It also handles the ProcessFailed event, in case the browser process or one of its render process crashes or is unresponsive.
89-
90-
#### 6. SettingsComponent.cpp
91-
92-
This component handles commands from the Settings menu, and is also in charge of copying settings from an old WebView when a new one is created. Most code that interacts with the `ICoreWebView2Settings` interface can be found here.
93-
94-
#### 7. ViewComponent.cpp
95-
96-
This component handles commands from the View menu, and any functionality related to sizing and visibility of the WebView. When the app window is resized, minimized, or restored, `ViewComponent` will resize, hide, or show the WebView in response. It also responds to the `ZoomFactorChanged` event.
97-
98-
#### 8. ScenarioWebMessage.cpp and ScenarioWebMessage.html
99-
100-
This component is created when you select the Scenario/Web Messaging menu item. It implements an example application with a C++ part and an HTML+JavaScript part, which communicate with each other by asynchronously posting and receiving messages.
101-
102-
![alt text](https://raw.githubusercontent.com/MicrosoftEdge/WebView2Samples/master/SampleApps/WebView2APISample/documentation/screenshots/sample-app-webmessaging-screenshot.png)
103-
104-
#### 9. ScenarioAddHostObject.cpp and ScenarioAddHostObject.html
105-
106-
This component is created when you select the Scenario/Host Objects menu item. It demonstrates communication between the native app and the HTML webpage by means of host object injection. The interface of the host object is declared in `HostObjectSample.idl`, and the object itself is implemented in `HostObjectSampleImpl.cpp`.
107-
108-
## Key Functions
109-
110-
The section below briefly explains some of the key functions in the Sample App.
111-
112-
### AppWindow.cpp
113-
114-
#### InitializeWebView()
115-
116-
In the AppWindow file, we use the InitializeWebView() function to create the WebView2 environment by using [CreateCoreWebView2EnvironmentWithOptions](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/webview2-idl#createcorewebview2environmentwithoptions).
117-
118-
Once we've created the environment, we create the WebView by using `CreateCoreWebView2Controller`.
119-
120-
To see these API calls in action, refer to the following code snippet from `InitializeWebView()`.
121-
122-
```cpp
123-
HRESULT hr = CreateCoreWebView2EnvironmentWithOptions(
124-
subFolder, nullptr, options.Get(),
125-
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
126-
this, &AppWindow::OnCreateEnvironmentCompleted)
127-
.Get());
128-
if (!SUCCEEDED(hr))
129-
{
130-
if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
131-
{
132-
MessageBox(
133-
m_mainWindow,
134-
L"Couldn't find Edge installation. "
135-
"Do you have a version installed that's compatible with this "
136-
"WebView2 SDK version?",
137-
nullptr, MB_OK);
138-
}
139-
else
140-
{
141-
ShowFailure(hr, L"Failed to create webview environment");
142-
}
143-
}
144-
```
145-
146-
#### OnCreateEnvironmentCompleted()
147-
148-
This callback function is passed to `CreateCoreWebView2EnvironmentWithOptions` in `InitializeWebView()`. It stored the environment pointer and then uses it to create a new WebView.
149-
150-
```cpp
151-
HRESULT AppWindow::OnCreateEnvironmentCompleted(
152-
HRESULT result, ICoreWebView2Environment* environment)
153-
{
154-
CHECK_FAILURE(result);
155-
156-
m_webViewEnvironment = environment;
157-
158-
CHECK_FAILURE(m_webViewEnvironment->CreateCoreWebView2Controller(
159-
m_mainWindow, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
160-
this, &AppWindow::OnCreateCoreWebView2ControllerCompleted)
161-
.Get()));
162-
return S_OK;
163-
}
164-
```
165-
166-
#### OnCreateCoreWebView2ControllerCompleted()
167-
168-
This callback function is passed to `CreateCoreWebView2Controller` in `InitializeWebView()`. Here, we initialize the WebView-related state, register some event handlers, and create the app components.
169-
170-
#### RegisterEventHandlers()
171-
172-
This function is called within `CreateCoreWebView2Controller`. It sets up some of the event handlers used by the application, and adds them to the WebView.
173-
174-
To read more about event handlers in WebView2, you can refer to this [documentation](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2).
175-
176-
Below is a code snippet from `RegisterEventHandlers()`, where we set up an event handler for the `NewWindowRequested` event. This event is fired when JavaScript in the webpage calls `window.open()`, and our handler makes a new `AppWindow` and passes the new window's WebView back to the browser so it can return it from the `window.open()` call. Unlike our calls to `CreateCoreWebView2EnvironmentWithOptions` and `CreateCoreWebView2Controller`, instead of providing a method for the callback, we just provide a C++ lambda right then and there.
177-
178-
```cpp
179-
CHECK_FAILURE(m_webView->add_NewWindowRequested(
180-
Callback<ICoreWebView2NewWindowRequestedEventHandler>(
181-
[this](
182-
ICoreWebView2* sender,
183-
ICoreWebView2NewWindowRequestedEventArgs* args) {
184-
wil::com_ptr<ICoreWebView2Deferral> deferral;
185-
CHECK_FAILURE(args->GetDeferral(&deferral));
186-
187-
auto newAppWindow = new AppWindow(L"");
188-
newAppWindow->m_isPopupWindow = true;
189-
newAppWindow->m_onWebViewFirstInitialized = [args, deferral, newAppWindow]() {
190-
CHECK_FAILURE(args->put_NewWindow(newAppWindow->m_webView.get()));
191-
CHECK_FAILURE(args->put_Handled(TRUE));
192-
CHECK_FAILURE(deferral->Complete());
193-
};
194-
195-
return S_OK;
196-
})
197-
.Get(),
198-
nullptr));
199-
```
200-
201-
### ScenarioWebMessage
202-
203-
The `ScenarioWebMessage` files show how the Win32 Host can modify the WebView, how the WebView can modify the Win32Host, and how the WebView can modify itself by accessing information from the Win32 Host. This is done asynchronously.
204-
205-
The following sections demonstrate how each discrete function works using the Sample App and then explains how to implement this functionality.
206-
207-
First, navigate to the ScenarioWebMessage application within the Sample App, using the following steps:
208-
209-
1. Open the Sample App
210-
2. Click on Scenario
211-
3. Click on Web Messaging
212-
213-
The WebView should display a simple webpage titled: "WebMessage sample page". The code for this page can be found in the `ScenarioWebMessage.html` file.
214-
215-
![alt text](https://raw.githubusercontent.com/MicrosoftEdge/WebView2Samples/master/SampleApps/WebView2APISample/documentation/screenshots/sample-app-webmessaging-screenshot.png)
216-
217-
To better understand ScenarioWebMessage functionality, you can either follow the instructions on the page or the steps detailed below.
218-
219-
#### 1. Posting Messages (Win32 Host to WebView)
220-
221-
The following steps show how the Win32 Host can modify a WebView. In this example, you will turn the text blue:
222-
223-
1. Click on Script in the Toolbar
224-
2. Click on Post Web Message JSON
225-
226-
A dialog box with the pre-written code `{"SetColor":"blue"}` should appear.
227-
228-
3. Click OK
229-
230-
The text under Posting Messages should now be blue.
231-
232-
Here's how it works:
233-
234-
1. In `ScriptComponent.cpp`, we use [PostWebMessageAsJson](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#postwebmessageasjson) to post user input to the `ScenarioMessage.html` web application.
235-
236-
```cpp
237-
// Prompt the user for some JSON and then post it as a web message.
238-
void ScriptComponent::SendJsonWebMessage()
239-
{
240-
TextInputDialog dialog(
241-
m_appWindow->GetMainWindow(),
242-
L"Post Web Message JSON",
243-
L"Web message JSON:",
244-
L"Enter the web message as JSON.",
245-
L"{\"SetColor\":\"blue\"}");
246-
if (dialog.confirmed)
247-
{
248-
m_webView->PostWebMessageAsJson(dialog.input.c_str());
249-
}
250-
}
251-
```
252-
253-
2. Within the web application, event listeners are used to receive and respond to the web message. The code snippet below is from `ScenarioWebMessage.html`. The event listener changes the color of the text if it reads "SetColor".
254-
255-
```js
256-
window.chrome.webview.addEventListener('message', arg => {
257-
if ("SetColor" in arg.data) {
258-
document.getElementById("colorable").style.color = arg.data.SetColor;
259-
}
260-
});
261-
```
262-
263-
#### 2. Receiving Messages (WebView to Win32 Host)
264-
265-
The following steps show how the WebView can modify the Win32 Host App by changing the title of the Win32 App:
266-
267-
1. Locate the Title of the Sample App - the top left of the window next to the icon.
268-
2. Under the Receiving Message section, fill out the form with the new title of your choice.
269-
3. Click Send
270-
271-
Locate the Title of the Sample App, it should have changed to the title you have just inputted.
272-
273-
Here's how it works:
274-
275-
1. Within `ScenarioWebMessage.html`, we call [window.chrome.webview.postMessage()](https://developer.mozilla.org/docs/Web/API/Window/postMessage) to send the user input to the host application. Refer to code snippet below:
276-
277-
```js
278-
function SetTitleText() {
279-
let titleText = document.getElementById("title-text");
280-
window.chrome.webview.postMessage(`SetTitleText ${titleText.value}`);
281-
}
282-
```
283-
284-
2. Within `ScenarioWebMessage.cpp`, we use [add_WebMessageReceived](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived) to register the event handler. When we receive the event, after validating the input, we change the title of the App Window.
285-
286-
```cpp
287-
// Setup the web message received event handler before navigating to
288-
// ensure we don't miss any messages.
289-
CHECK_FAILURE(m_webview->add_WebMessageReceived(
290-
Microsoft::WRL::Callback<ICoreWebView2WebMessageReceivedEventHandler>(
291-
[this](ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args)
292-
{
293-
wil::unique_cotaskmem_string uri;
294-
CHECK_FAILURE(args->get_Source(&uri));
295-
296-
// Always validate that the origin of the message is what you expect.
297-
if (uri.get() != m_sampleUri)
298-
{
299-
return S_OK;
300-
}
301-
wil::unique_cotaskmem_string messageRaw;
302-
CHECK_FAILURE(args->TryGetWebMessageAsString(&messageRaw));
303-
std::wstring message = messageRaw.get();
304-
305-
if (message.compare(0, 13, L"SetTitleText ") == 0)
306-
{
307-
m_appWindow->SetTitleText(message.substr(13).c_str());
308-
}
309-
return S_OK;
310-
}).Get(), &m_webMessageReceivedToken));
311-
```
312-
313-
#### 3. Roundtrip (WebView to WebView)
314-
315-
The following steps show how the WebView can get information from the Win32 Host and modify itself by displaying the size of the Win32 App.
316-
317-
1. Under RoundTrip, click GetWindowBounds
318-
319-
The box underneath the button should display the bounds for the Sample App.
320-
321-
Here's how it works:
322-
323-
1. When the 'Get window bounds' button is clicked, the `GetWindowBounds` function in `ScenarioWebMessage.html` gets called. It uses [window.chrome.webview.postMessage()](https://developer.mozilla.org/docs/Web/API/Window/postMessage) to send a message to the host application.
324-
325-
```js
326-
function GetWindowBounds() {
327-
window.chrome.webview.postMessage("GetWindowBounds");
328-
}
329-
```
330-
331-
2. Within `ScenarioWebMessage.cpp`, we use [add_WebMessageReceived](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#add_webmessagereceived) to register the received event handler. After validating the input, the event handler gets window bounds from the App Window. [PostWebMessageAsJson](https://learn.microsoft.com/microsoft-edge/webview2/reference/win32/icorewebview2#postwebmessageasjson) sends the bounds to the web application.
332-
333-
```cpp
334-
if (message.compare(L"GetWindowBounds") == 0)
335-
{
336-
RECT bounds = m_appWindow->GetWindowBounds();
337-
std::wstring reply =
338-
L"{\"WindowBounds\":\"Left:" + std::to_wstring(bounds.left)
339-
+ L"\\nTop:" + std::to_wstring(bounds.top)
340-
+ L"\\nRight:" + std::to_wstring(bounds.right)
341-
+ L"\\nBottom:" + std::to_wstring(bounds.bottom)
342-
+ L"\"}";
343-
CHECK_FAILURE(sender->PostWebMessageAsJson(reply.c_str()));
344-
}
345-
```
346-
347-
3. Within `ScenarioWebMessage.html`, an event listener responds to the WindowBounds message and displays the bounds of the window.
348-
349-
```js
350-
window.chrome.webview.addEventListener('message', arg => {
351-
if ("WindowBounds" in arg.data) {
352-
document.getElementById("window-bounds").value = arg.data.WindowBounds;
353-
}
354-
});
355-
```
356-
357-
## Code of Conduct
358-
359-
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [email protected] with any additional questions or comments.
36+
![The WebView2APISample sample app running](./documentation/screenshots/sample-app-screenshot.png)
-1.13 MB
Loading

0 commit comments

Comments
 (0)