機械学習基礎理論独習

誤りがあればご指摘いただけると幸いです。数式が整うまで少し時間かかります。リンクフリーです。

勉強ログです。リンクフリーです
目次へ戻る

【VS2022】WebView2 の導入方法【C++】

WebView2 のインストールの手順

1. Microsoft Edge WebView2 | Microsoft Edge Developer 下側より Evergreen Standalone Installer x86をダウンロードする。

2. ダウンロードした MicrosoftEdgeWebView2RuntimeInstallerX64.exe を管理者権限でない状態でダブルクリックすると、以下のように失敗する。

右クリックから 管理者として実行するとうまくいく。
インストールが始まると以下のようなインストーラーが起動する。

MFC Application(Dialog Based) で WebView2 を動かす

1. MFC Application を Dialog Base で作成する。プロジェクト名はここでは "SampleWebView2" とする。

2. Project > Manage NuGet Packages を開く。

3. NuGet で Microsoft.Web.WebView2 と Microsoft.Windows.ImplementationLibrary をプロジェクトに追加する。

4. C/C++ > Language > C++ Lamguage Standard を ISO C++ Standard (/std:c++17) にする。

5. リソースで Static Text と Button を削除する。

6. pch.h の実装

// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.

#ifndef PCH_H
#define PCH_H

// add headers that you want to pre-compile here
#include <winsock2.h>
#include <wrl.h>
#include <wil/com.h>
#include <WebView2.h>
#include "framework.h"

#endif //PCH_H

7. SampleWebView2Dlg.h の実装
m_webViewController, m_webView, OnSize を定義する。

// SampleWebView2Dlg.h : header file
//

#pragma once

// CSampleWebView2Dlg dialog
class CSampleWebView2Dlg : public CDialogEx
{
// Construction
public:
	CSampleWebView2Dlg(CWnd* pParent = nullptr);	// standard constructor

// Dialog Data
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_SAMPLEWEBVIEW2_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV support


// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

private:
	wil::com_ptr<ICoreWebView2Controller> m_webViewController;
	wil::com_ptr<ICoreWebView2> m_webView;
public:
	afx_msg void OnSize(UINT nType, int cx, int cy);
};

8. SampleWebView2Dlg.cpp の実装
OnInitDialog(), OnSize() に書き足す。

BOOL CSampleWebView2Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here
	// COM初期化(契約明示)
	HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
	if (FAILED(hr)) {
		MessageBox(L"COM initialization failed", L"Error", MB_ICONERROR);
		return FALSE;
	}
	HRESULT hrWebview = CreateCoreWebView2EnvironmentWithOptions(
		nullptr, nullptr, nullptr,
		Microsoft::WRL::Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
			[this](HRESULT result, ICoreWebView2Environment* env) -> HRESULT {
				env->CreateCoreWebView2Controller(this->GetSafeHwnd(),
					Microsoft::WRL::Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
						[this](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT {
							if (controller) {
								m_webViewController = controller;
								m_webViewController->get_CoreWebView2(&m_webView);
							}

							RECT bounds;
							GetClientRect(&bounds);
							m_webViewController->put_Bounds(bounds);

							m_webView->Navigate(L"https://www.google.com");

							return S_OK;
						}).Get());
				return S_OK;
			}).Get());
	if (FAILED(hrWebview)) {
		return FALSE; // 呼び出しが失敗
	}

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CSampleWebView2Dlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here
	// WebView2 コントローラが初期化済みか確認
	if (m_webViewController) {
		RECT bounds;
		GetClientRect(&bounds);
		m_webViewController->put_Bounds(bounds); // ← 描画領域を更新
	}
}

9. 実行すると、以下のように google のページが表示される。

Miscrosoft のサンプルとの違い

Miscrosoft のサンプル と本記事のサンプルが違うのは、
pch.h に winsock2.h をインクルードしたことと、CSampleWebView2Dlg::OnInitDialog() で CoInitializeEx() で COMの初期化をしたことです。
Miscrosoft のサンプル は Win32 であり、本記事のサンプルはMFCであるという違いがあるからか、このようにしないと動きませんでした。

目次へ戻る