WebView2、登場秘話
登場秘話
〜半年前に自分で埋めた種と、たーぼーさんからの一通の報告〜
このツールの誕生秘話の終章でも触れた通り、WebView2対応(v3.0.0)の種は、実は2026年3月――第7章「機械語を書いた春」とほぼ同じ時期――にすでに蒔かれていました。ここでは、その種がなぜ一度は本体と分離し、どうやって半年越しに復活したのかを、もう少し詳しく振り返ります。
きっかけ — Qiitaに落ちていた「ブレイクスルー」
すべては、1本の記事を見つけたことから始まりました。
🔗 Excel VBAだけでWebView2を動かす(Qiita)
「外部DLLの登録も、TLBの参照設定も要らない。純粋なExcel VBAのメモリ空間だけで、本物のWebView2が動く」
第7章でWinHTTPのコールバックを機械語サンクで生き延びさせた直後だったこともあり、この記事の言っていることが、体感としてすんなり信じられました。「vtableを直接叩けば、VBAでもここまでできるのか」と。
一発目の挑戦 — 動いた。けれど、本体とは別の生き物になった
3月15日、さっそく手を動かし始めます。
2026-03-15 WebView2を動かす基盤を作成
2026-03-15 QueryInterface が E_NOINTERFACE を返していた問題を修正
2026-03-15 vtable オフセットが間違っている影響でクラッシュする問題を修正
2026-03-15 UserFormに埋め込むウィンドウを用意しそこに埋め込むように改良数日で、UserFormにWebView2を埋め込んで動かすところまでは辿り着きました。ただし、ここで大きな壁にぶつかります。当時の本体(main)には、まだ RaiseEvent による非同期イベント配信の仕組みがありませんでした。 それが整うのは、第8章で CDPCore.cls に RaiseEvent CDPBrowserEvent 等が生まれる5月末〜6月のことで、この時点ではまだ2ヶ月以上先の話です。
共有できる土台がない以上、やれることは1つでした。
2026-03-17 `CDPBrowser`にあったmethodの一部を移植
2026-03-17 別ツールで分けるため、セル定義の整理
2026-03-21 `CDPBrowser`にあるほとんど機能を一旦そのまま移植
2026-03-21 `CDPBrowser`→`WebView2Browser`へ置き換えCDPBrowser にあった機能を、ほぼそのまま WebView2Browser というクラスにコピーする形で移植しました。動きはします。しかし、結果として生まれたのは、同じ根から生えた、しかし物理的には完全に別の2本のツールでした。
- Chromiumブラウザ制御ツール(本体)
- WebView2専用制御ツール(新顔)
コードは似ているのに、修正は毎回2箇所。片方を直せば、もう片方も直さないと辻褄が合わない。保守が、単純につらい。 この時点の自分には、2本を統合し直す体力も、正しい設計も持ち合わせていませんでした。
一旦、諦めました
4月4日の「リファクタリング」を最後に、WebView2ブランチへのコミットは止まります。ここから約4ヶ月半、このブランチは誰にも触られません。 悔しさより、「今の本体を育てるほうが先だ」という判断が勝ちました。
本体だけが、どんどん育っていく数ヶ月
WebView2を脇に置いている間、Chromium制御ツールの方は劇的に進化していきます。
5月末〜6月、第8章の God クラス解体で CDPBrowser / CDPContext / CDPCore に責務が割れ、RaiseEvent ベースの配信基盤が整いました。これがどれだけ効いたかは、7月の v2.3.0 で証明されます。WinSock を自力実装し、WebSocket という2本目の通信路を、既存クラスにほとんど手を入れずに増設できたのです(第10章)。
皮肉なことに、「複数の通信路を素直に増やせる土台」は、まさにWebView2に一番欲しかったものでした。それが3月には無く、7月には当たり前のようにできていました。
転機 — たーぼーさんからの一通の報告
そろそろプログラミング作業から一区切り置こうかと考えていた、8月のある日。WebView2記事の書き手であるたーぼーさんから、こんな報告をいただきました。
「ページ自動制御の土台ができました」
その一文を読んだ瞬間、こう思いました。
「いまなら、あのWebView2ブランチ、復活できそうじゃね😳😳」
ちょうど新作ゲームスプラトゥーン レイダースにどっぷり浸かり始めていた時期でしたが、そっちのけでWebView2の再配線工事に取りかかることにしました。
再配線工事 — 実質、1からやり直し
いざブランチを掘り起こしてみると、想像以上の作業になりました。3月から半年近く経つ間に、本体側は
CDPBrowser/CDPContext/CDPCoreへの God クラス解体(第8章)BiDiCDPJsonによるJSONゼロコピー化(第9章)- WinSock自力実装(第10章)
Scripting.Dictionaryから自作Dictionary.clsへの移行、src/へのディレクトリ再編(第13章)
と、原型を留めないほど作り変えられていました。3月に書いた WebView2Browser を、その上にそのまま接ぎ木することはできません。コード構成としては、実質1からのやり直しでした。
救いだったのは、この半年でAIを使ったコーディングの精度が上がっていたことです。CDPコマンドの送受信を担う CallDevToolsProtocolMethodForSession まわりの部品調達は、AIに相談しながら比較的スムーズに揃えられました。
もう1つ、WebView2ならではの壁がありました。Pipe や WebSocket は「バイト列の断片が何回かに分かれて届く」前提でバッファを組んでいましたが、WebView2はCOMコールバック経由で 「1つの完成したJSONが一発で丸ごと届く」 という、全く違う配送のされ方をします。
2026-08-25 バインバイン以外の拡張ロジックにも対応させるこのコミットで、CDPCore.cls のバッファ拡張ロジックに、WebView2のこの配送パターンにも対応できる分岐を追加しました。「足りなくなったら倍々に拡張する」という、これまで通用していた前提が、WebView2相手には必ずしも当てはまらなかったということです。
第三のルート、開通
そうして、Pipe・WebSocketに続く3つ目の通信路として、WebView2がこのツールに合流しました。
到達点
あくまでもCDPツールとして作っているため、WebView2固有の高レベルメソッドはほとんど用意していません。ですが正直なところ、CDPだけでほぼ賄えます。 CDPContext.navigate や CDPElement.getElementByQuery など、Pipe / WebSocket でおなじみの操作が、埋め込んだWebView2に対してもそのまま使えます。
唯一CDPの外側にあるのが、ICoreWebView2Settings(コンテキストメニューの有効/無効など)や ICoreWebView2Controller(表示サイズ・位置)のような、「Web領域の外側」の設定です。CDPはあくまでWeb(ページの中身)を制御するプロトコルなので、こういったホスト側の挙動までは届きません。
とはいえ、これも大した負担ではありませんでした。必要になるたびAIに頼んで、数行のプロシージャを1つ足すだけ。Visible / DevToolsEnabled / ContextMenuEnabled といったプロパティは、そうやって都度増設したものです。
結論 — 半年寝かせた種は、腐っていなかった
3月に諦めかけたブランチは、8月にはちゃんと芽を出しました。理由は単純です。本体側が、新しい通信路を受け止められるだけの土台に育っていたから。 蒔いた種そのものより、畑(本体の設計)を耕し続けたことのほうが、結果的にものを言った気がしています。
フィナーレ
ブレイクスルーの記事を教えてくれ、Wv2Thunks.bas という土台まで公開してくれた、たーぼーさんに改めて感謝します。あなたの一言の報告がなければ、このブランチはもうしばらく凍ったままだったはずです。
次に読む
- このツールの誕生秘話 — 終章:半年前に埋めた種を掘り起こす
- WebView2モードの設計思想について — 機械語サンク・vtableの技術詳細
- WebView2モードでできること
- Excel単独で「真のWebView2」を完全制御する

