- 記事一覧 >
- ブログ記事
C++,C# WebBrowserコントロールでIE11のActiveXを延命
はじめに
2022 年 6 月 15 日に IE11 がサポート終了になります。ActiveX が使えなくなり、今まで「IE11 を使ってください。」と言っていた機能が使えなくなり、Edge,Chrome,Firefox,Safari...用に同等機能の開発が必要になると思います。
対応が難しい場合、Edge の IE11 モード、あるいは、WebBrowser コントロールを使用したアプリを使うことになると思います。これにより、ActiveX は今まで通り使用できます。
今回、WebBrowser コントロールを使用したアプリを Visual Studio 2019 で実装、ビルドするところまで紹介したいと思います。
C++版、C#版両方紹介しますが、ほぼ同等機能で、関連していません。どちらかをビルドすればOKです。
Edge の IE11 モードでも、本記事の WebBrowser コントロールでも、例えば、IE11 のウィンドウ名を取得していたりした場合、ActiveX が使えなくなるか、一部機能が失われるかもしれません。
Edge の IE11 モードは、2029年1月9日に終了という情報がありますので、その頃には、この記事の内容も使えなくなると思います。
概要
WebBrowser コントロールとは、下記の図のように、IE のガワ以外のブラウザ機能を利用するものです。
今回実装する内容は、本ブログ別記事「カスタム URL スキームでエクスプローラーを起動してフォルダを開く msi ビルド全手順」のように、カスタム URL をクリックして、IE11 画面が表示されて、ActiveX が起動するところまでがゴールです。
↑
「Hello world.」表示部分が ActiveX です。
ActiveX
ただ単に 「Hello world.」 と表示する ActiveX を独自に作成しました。
(赤枠内が ActiveX です。)
以下の HTML で表示します。
<HTML>
<HEAD>
</HEAD>
<BODY>
<OBJECT CLASSID="CLSID:de1a48df-a483-4876-b4dc-04421671f3f3" WIDTH="200" HEIGHT="100">
<PARAM NAME="Caption" VALUE="Hello world.">
<EMBED TYPE="application/x-test-activex" WIDTH="200" HEIGHT="100" Caption="Hello world.">
</OBJECT>
</BODY>
</HTML>
IE11モードではない Edge の場合は、以下のように起動しません。
ソースコード(C++)
ウィザードで生成されたソースコードを少し変更するのみです。IEView.htm
以外は、差分のみ表示です。
変更するのは、IEView.htm
IEView.cpp
IEViewDlg.cpp
IEViewDlg.h
の4つです。
主に以下の事を行っています。
・OK、キャンセルボタンの削除
・引数の受け渡し
・引数の URL へ遷移
BOOL CIEViewDlg::PreTranslateMessage(MSG* pMsg)
{
if (WM_KEYDOWN == pMsg->message) {
switch (pMsg->wParam) {
case VK_RETURN:
case VK_ESCAPE:
return FALSE;
}
}
return CDHtmlDialog::PreTranslateMessage(pMsg);
}
は ダイアログベース の MFC アプリを Esc, Enter で閉じないようにしています。
<html>
<head>
<style>
body {
background-color: #c0c0c0;
}
</style>
</head>
<body>
</body>
</html>
@@ -42,39 +42,22 @@
|
|
42
42
|
|
43
43
|
// ダイアログにシェル ツリー ビューまたはシェル リスト ビュー コントロールが
|
44
44
|
// 含まれている場合にシェル マネージャーを作成します。
|
45
|
-
CShellManager
|
45
|
+
CShellManager* pShellManager = nullptr;
|
46
|
+
//CShellManager* pShellManager = new CShellManager;
|
46
47
|
|
47
48
|
// MFC コントロールでテーマを有効にするために、"Windows ネイティブ" のビジュアル マネージャーをアクティブ化
|
48
49
|
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
|
49
50
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
// この文字列を変更してください。
|
57
|
-
SetRegistryKey(_T("アプリケーション ウィザードで生成されたローカル アプリケーション"));
|
51
|
+
int dwArgc;
|
52
|
+
LPTSTR* lpszArgv = CommandLineToArgvW(GetCommandLineW(), &dwArgc);
|
53
|
+
CString url = lpszArgv[1];
|
54
|
+
if (url.Find(_T(':'), 0) >= 0) {
|
55
|
+
url = url.Mid(url.Find(_T(':'), 0) + 1);
|
56
|
+
}
|
58
57
|
|
59
|
-
CIEViewDlg dlg;
|
58
|
+
CIEViewDlg dlg(url);
|
60
59
|
m_pMainWnd = &dlg;
|
61
60
|
INT_PTR nResponse = dlg.DoModal();
|
62
|
-
if (nResponse == IDOK)
|
63
|
-
{
|
64
|
-
// TODO: ダイアログが <OK> で消された時のコードを
|
65
|
-
// 記述してください。
|
66
|
-
}
|
67
|
-
else if (nResponse == IDCANCEL)
|
68
|
-
{
|
69
|
-
// TODO: ダイアログが <キャンセル> で消された時のコードを
|
70
|
-
// 記述してください。
|
71
|
-
}
|
72
|
-
else if (nResponse == -1)
|
73
|
-
{
|
74
|
-
TRACE(traceAppMsg, 0, "警告: ダイアログの作成に失敗しました。アプリケーションは予期せずに終了します。\n");
|
75
|
-
TRACE(traceAppMsg, 0, "警告: ダイアログで MFC コントロールを使用している場合、#define _AFX_NO_MFC_CONTROLS_IN_DIALOGS を指定できません。\n");
|
76
|
-
}
|
77
|
-
|
78
61
|
// 上で作成されたシェル マネージャーを削除します。
|
79
62
|
if (pShellManager != nullptr)
|
80
63
|
{
|
@@ -16,15 +16,14 @@
|
|
16
16
|
// CIEViewDlg ダイアログ
|
17
17
|
|
18
18
|
BEGIN_DHTML_EVENT_MAP(CIEViewDlg)
|
19
|
-
DHTML_EVENT_ONCLICK(_T("ButtonOK"), OnButtonOK)
|
20
|
-
DHTML_EVENT_ONCLICK(_T("ButtonCancel"), OnButtonCancel)
|
21
19
|
END_DHTML_EVENT_MAP()
|
22
20
|
|
23
21
|
|
24
|
-
CIEViewDlg::CIEViewDlg(CWnd* pParent /*=nullptr*/)
|
22
|
+
CIEViewDlg::CIEViewDlg(const CString& url, CWnd* pParent /*=nullptr*/)
|
25
23
|
: CDHtmlDialog(IDD_IEVIEW_DIALOG, IDR_HTML_IEVIEW_DIALOG, pParent)
|
26
24
|
{
|
27
25
|
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
26
|
+
m_url = url;
|
28
27
|
}
|
29
28
|
|
30
29
|
void CIEViewDlg::DoDataExchange(CDataExchange* pDX)
|
@@ -48,6 +47,9 @@
|
|
48
47
|
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
|
49
48
|
|
50
49
|
// TODO: 初期化をここに追加します。
|
50
|
+
int pos = m_url.ReverseFind(_T('/'));
|
51
|
+
this->SetWindowTextW(m_url.Mid(pos + 1));
|
52
|
+
this->Navigate(m_url);
|
51
53
|
|
52
54
|
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
|
53
55
|
}
|
@@ -88,14 +90,14 @@
|
|
88
90
|
return static_cast<HCURSOR>(m_hIcon);
|
89
91
|
}
|
90
92
|
|
91
|
-
|
92
|
-
{
|
93
|
-
OnOK();
|
94
|
-
return S_OK;
|
95
|
-
}
|
96
|
-
|
97
|
-
HRESULT CIEViewDlg::OnButtonCancel(IHTMLElement* /*pElement*/)
|
93
|
+
BOOL CIEViewDlg::PreTranslateMessage(MSG* pMsg)
|
98
94
|
{
|
99
|
-
|
100
|
-
|
95
|
+
if (WM_KEYDOWN == pMsg->message) {
|
96
|
+
switch (pMsg->wParam) {
|
97
|
+
case VK_RETURN:
|
98
|
+
case VK_ESCAPE:
|
99
|
+
return FALSE;
|
100
|
+
}
|
101
|
+
}
|
102
|
+
return CDHtmlDialog::PreTranslateMessage(pMsg);
|
101
103
|
}
|
@@ -10,7 +10,7 @@
|
|
10
10
|
{
|
11
11
|
// コンストラクション
|
12
12
|
public:
|
13
|
-
CIEViewDlg(CWnd* pParent = nullptr); // 標準コンストラクター
|
13
|
+
CIEViewDlg(const CString& url, CWnd* pParent = nullptr); // 標準コンストラクター
|
14
14
|
|
15
15
|
// ダイアログ データ
|
16
16
|
|
@@ -20,12 +20,10 @@
|
|
20
20
|
protected:
|
21
21
|
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV サポート
|
22
22
|
|
23
|
-
HRESULT OnButtonOK(IHTMLElement *pElement);
|
24
|
-
HRESULT OnButtonCancel(IHTMLElement *pElement);
|
25
|
-
|
26
23
|
// 実装
|
27
24
|
protected:
|
28
25
|
HICON m_hIcon;
|
26
|
+
CString m_url;
|
29
27
|
|
30
28
|
// 生成された、メッセージ割り当て関数
|
31
29
|
virtual BOOL OnInitDialog();
|
@@ -33,4 +31,6 @@
|
|
33
31
|
afx_msg HCURSOR OnQueryDragIcon();
|
34
32
|
DECLARE_MESSAGE_MAP()
|
35
33
|
DECLARE_DHTML_EVENT_MAP()
|
34
|
+
public:
|
35
|
+
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
36
36
|
};
|
ソースコード(C#)
ウィザードで生成されたソースコードを少し変更するのみです。差分のみ表示です。
変更するのは、Form1.Designer.cs
Form1.cs
Program.cs
の3つです。
主に以下の事を行っています。
・WebBrowser
の初期化
・引数の受け渡し
・引数の URL へ遷移
@@ -29,13 +29,38 @@
|
|
29
29
|
/// </summary>
|
30
30
|
private void InitializeComponent()
|
31
31
|
{
|
32
|
-
this.
|
32
|
+
this.webBrowser1 = new System.Windows.Forms.WebBrowser();
|
33
|
+
this.SuspendLayout();
|
34
|
+
//
|
35
|
+
// webBrowser1
|
36
|
+
//
|
37
|
+
this.webBrowser1.AllowWebBrowserDrop = false;
|
38
|
+
this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
|
39
|
+
this.webBrowser1.IsWebBrowserContextMenuEnabled = false;
|
40
|
+
this.webBrowser1.Location = new System.Drawing.Point(0, 0);
|
41
|
+
this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
|
42
|
+
this.webBrowser1.Name = "webBrowser1";
|
43
|
+
this.webBrowser1.Size = new System.Drawing.Size(1096, 661);
|
44
|
+
this.webBrowser1.TabIndex = 0;
|
45
|
+
this.webBrowser1.Url = new System.Uri("", System.UriKind.Relative);
|
46
|
+
//
|
47
|
+
// Form1
|
48
|
+
//
|
49
|
+
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
|
33
50
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
34
|
-
this.ClientSize = new System.Drawing.Size(
|
51
|
+
this.ClientSize = new System.Drawing.Size(1096, 661);
|
52
|
+
this.Controls.Add(this.webBrowser1);
|
53
|
+
this.Name = "Form1";
|
54
|
+
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
35
55
|
this.Text = "Form1";
|
56
|
+
this.ResumeLayout(false);
|
57
|
+
|
36
58
|
}
|
37
59
|
|
38
60
|
|
61
|
+
|
62
|
+
private System.Windows.Forms.WebBrowser webBrowser1;
|
63
|
+
private string m_url;
|
39
64
|
}
|
40
65
|
}
|
41
66
|
|
@@ -12,9 +12,12 @@
|
|
12
12
|
{
|
13
13
|
public partial class Form1 : Form
|
14
14
|
{
|
15
|
-
public Form1()
|
15
|
+
public Form1( string url )
|
16
16
|
{
|
17
|
+
m_url = url;
|
17
18
|
InitializeComponent();
|
19
|
+
this.webBrowser1.Url = new System.Uri(m_url, System.UriKind.Absolute);
|
20
|
+
this.Text = m_url.Substring(m_url.LastIndexOf("/") + 1);
|
18
21
|
}
|
19
22
|
}
|
20
23
|
}
|
@@ -14,9 +14,13 @@
|
|
14
14
|
[
]
|
15
15
|
static void Main()
|
16
16
|
{
|
17
|
+
string[] args = Environment.GetCommandLineArgs();
|
18
|
+
string url = args[1];
|
19
|
+
url = url.Substring(url.IndexOf(":") + 1);
|
20
|
+
|
17
21
|
Application.EnableVisualStyles();
|
18
22
|
Application.SetCompatibleTextRenderingDefault(false);
|
19
|
-
Application.Run(new Form1());
|
23
|
+
Application.Run(new Form1(url));
|
20
24
|
}
|
21
25
|
}
|
22
26
|
}
|
C++ 版ビルド手順
exe ビルド
Visual Studio 2019 は、インストールしたての状態が前提です。
プロジェクト作成準備
Visual Studio Installer
を起動します。
「変更」をクリックします。
「C++ によるデスクトップ開発」→ 右側の詳細部分の「最新の v142 ビルドツール C++ MFC (x86...」にチェックを入れ、「変更」をクリックします。
プロジェクト作成
Visual Studio Installer
を閉じて、Visual Studio 2019
を起動します。
「新しいプロジェクトの作成」をクリックします。
プロジェクト名:IEView
ソリューション名:IEView
とし、(入力内容は任意です。)「作成」をクリックします。
左側ペインの「アプリケーションの種類のオプション」 「アプリケーションの種類」 : ダイアログベース 「ダイアログベースのオプション」 : HTML ダイアログを使用する とします。
左側ペインの「ユーザーインターフェース機能」をクリックします。 「最小化ボックス」「最大化ボックス」チェックボックスにチェックを入れ、「バージョン情報ボックス」のチェックを外します。(このあたりの選択は任意です。)
左側ペインの「高度な機能」をクリックします。 「高度な機能:」のチェックを全て外します。(このあたりの選択は任意です。) 「完了」をクリックします。
ソースコード編集
この時点で、リポジトリパスにある程度のプログラムが作成されていますので、
(リポジトリパス例:C:\Users\admin\source\repos\IEView\IEView
)
github リポジトリ(itc-lab/IEView)
のIEView.htm
IEView.cpp
IEViewDlg.cpp
IEViewDlg.h
の4つを上書きします。
ビルド実行
いきなり本番ビルドするため、Release x86
に変更します。
C:\Users\admin\source\repos\IEView\Release\IEView.exe
が作成されます。
msi ビルド
本ブログ別記事「カスタム URL スキームでエクスプローラーを起動してフォルダを開く msi ビルド全手順」「拡張機能インストール」の手順とほぼ同じですので、詳細は省略します。
概ね以下の手順になります。
拡張機能の Microsoft Visual Studio Installer Projects
をインストールします。
↓IEView.sln
ソリューションを開きます。
↓
ファイル → 追加 → 新しいプロジェクト → 「Setup Project」選択し、「次へ」をクリックします。
↓
プロジェクト名:IEViewInstaller
とし、「作成」をクリックします。
↓
「Application Folder」をクリックして、DefaultLocation の値を [LocalAppDataFolder]IEView
とします。
↓
「Application Folder」選択状態で、右ペインを右クリック →「Add」→「ファイル」をクリックします。
↓
ビルド済みの IEView.exe
例:C:\Users\admin\source\repos\IEView\Release\IEView.exe
を追加します。
↓
レジストリエディタ―に切り替えます。
↓HKEY_CLASSES_ROOT
のところで、右クリック →「新しいキー」をクリックします。
以降、同要領で、 HKEY_CLASSES_ROOT\ieview\shell\open\command
まで作成します。
↓
command を選択し、右ペインを右クリック →「New」→「文字列の値」をクリックします。
↓
Name を空白にします。※「New Value #1」を空白にすると、「(Default)」になります。
↓
(Default)をクリックして、Value の値を "[TARGETDIR]IEView.exe" "%1"
とします。
↓HKEY_CLASSES_ROOT\ieview
をクリックして、
Name: (Default)
Value: URL: IEView
と
Name: URL Protocol
(Value は何も登録しません。)
を登録します。
↓HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
までキーを作成します。
↓
右ペインを右クリック →「New」→「DWORD の値」をクリックします。
↓
Name: IEView.exe
Value: 11001
を登録します。
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
に
IEView.exe = REG_DWORD 0x00002af9(11001)
を登録する理由は、IE11モードで起動したいからです。デフォルトは、IE7互換表示モードです。
↓
「ビルド」→「IEViewInstaller のビルド」をクリックして、IEViewIntaller.msi
ができます。
(例:C:\Users\admin\source\repos\IEView\IEViewInstaller\Release\IEViewIntaller.msi
)
C# 版ビルド手順
exe ビルド
Visual Studio 2019 は、インストールしたての状態が前提です。
プロジェクト作成準備
Visual Studio Installer
を起動します。
「変更」をクリックします。
「.NET デスクトップ開発」→ 右側の詳細部分はそのままにして、「変更」をクリックします。
プロジェクト作成
Visual Studio Installer
を閉じて、Visual Studio 2019
を起動します。
「新しいプロジェクトの作成」をクリックします。
「Windows フォームアプリケーション (.NET Framework)」を選択して、「次へ」をクリックします。
プロジェクト名:IEViewCS
ソリューション名:IEViewCS
とし、(入力内容は任意です。)「作成」をクリックします。
ソースコード編集
この時点で、リポジトリパスにある程度のプログラムが作成されていますので、
(リポジトリパス例:C:\Users\admin\source\repos\IEViewCS\IEViewCS
)
github リポジトリ(itc-lab/IEViewCS)
のProgram.cs
Form1.Designer.cs
Form1.cs
の3つを上書きします。
ビルド実行
いきなり本番ビルドするため、Release Any CPU
に変更します。
「ビルド」→「IEViewCS のビルド」をクリックします。
C:\Users\admin\source\repos\IEViewCS\Release\IEViewCS.exe
が作成されます。
msi ビルド
本ブログ別記事「カスタム URL スキームでエクスプローラーを起動してフォルダを開く msi ビルド全手順」「拡張機能インストール」の手順とほぼ同じですので、詳細は省略します。
概ね以下の手順になります。
拡張機能の Microsoft Visual Studio Installer Projects
をインストールします。
↓IEViewCS.sln
ソリューションを開きます。
↓
ファイル → 追加 → 新しいプロジェクト → 「Setup Project」選択し、「次へ」をクリックします。
↓
プロジェクト名:IEViewCSInstaller
とし、「作成」をクリックします。
↓
「Application Folder」をクリックして、DefaultLocation の値を [LocalAppDataFolder]IEViewCS
とします。
↓
「Application Folder」選択状態で、右ペインを右クリック →「Add」→「ファイル」をクリックします。
↓
ビルド済みの IEViewCS.exe
例:C:\Users\admin\source\repos\IEViewCS\bin\IEViewCS.exe
を追加します。
↓
レジストリエディタ―に切り替えます。
↓HKEY_CLASSES_ROOT
のところで、右クリック →「新しいキー」をクリックします。
以降、同要領で、 HKEY_CLASSES_ROOT\ieviewcs\shell\open\command
まで作成します。
↓
command を選択し、右ペインを右クリック →「New」→「文字列の値」をクリックします。
↓
Name を空白にします。※「New Value #1」を空白にすると、「(Default)」になります。
↓
(Default)をクリックして、Value の値を "[TARGETDIR]IEViewCS.exe" "%1"
とします。
↓HKEY_CLASSES_ROOT\ieviewcs
をクリックして、
Name: (Default)
Value: URL: IEViewCS
と
Name: URL Protocol
(Value は何も登録しません。)
を登録します。
↓HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
までキーを作成します。
↓
右ペインを右クリック →「New」→「DWORD の値」をクリックします。
↓
Name: IEViewCS.exe
Value: 11001
を登録します。
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION
に
IEView.exe = REG_DWORD 0x00002af9(11001)
を登録する理由は、IE11モードで起動したいからです。デフォルトは、IE7互換表示モードです。
↓
「ビルド」→「IEViewCSInstaller のビルド」をクリックして、IEViewCSIntaller.msi
ができます。
(例:C:\Users\admin\source\repos\IEViewCS\IEViewCSInstaller\Release\IEViewCSIntaller.msi
)
動作例
C++版動作例です。
Edge から IE11 の画面が開き、ActiveX が起動しています。
C#版の方もほとんど同じです。
IE11で開くと、以下のような感じです。
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。