Hiroさんがサンプルとしてタブブラウザを作ってくださっていますが、同じ要領です。
タブにではなく、HSP3で新しいウィンドウを作成し、そこに新たなWebView2コントロールを設置して、同様の処理を行います。
(自動生成されるウィンドウはHSP3側で制御できないため)
https://hiro239415.hatenablog.com/entry/2022/04/01/192105
[「sample 2」スクリプト の *EVENT_NEWWND, *EVENT_NEWWND2 の部分 ]
WebView2 が NewWindow を作ろうとしているところに割り込んで、処理を制御する必要があります。
1. 元々のWebView2コントロールにNewWindowRequestの割り込みを設定。
2. 割り込みが発生したら、GetDeferralで非同期処理を一時的に遅延。
3. PostMessageで自身のウィンドウにメッセージを投げて、NewWindowRequestの割り込み外で続きの処理をする(必要があるらしい)。
4. HSP3で新たなウィンドウを作って、そこに新たなWebView2コントロールを設置。
5. put_Handledで1、 put_NewWindowで新たなWebView2コントロールを指定。すると、NewWindowが作られない。
6. DeferralにCompleteを送って、非同期処理の遅延を解除。
#include "user32.as" ; PostMessage用
#include "mod_wv2s.hsp"
WV2Env 0, 0
env = stat
winId = 0
gosub *create_window
stop
*create_window
screen winId
ctrl(winId)=0 : view(winId)=0 : alive(winId)=1
if env {
WV2Ctrl env, hwnd
ctrl(winId) = stat
if stat {
WV2SetVisible ctrl(winId), 1
WV2SetSize ctrl(winId), 0, 0, ginfo_winx, ginfo_winy
if winId == 0 { ; 最初のウィンドウ(ID=0)だけ、Navigateする
surl = "https://www.google.co.jp/"
WV2Navigate ctrl(winId), surl
}
// view取得 (Hiroさんのサンプルに出てくるcurViewに相当するもの)
prm = varptr(v)
ComCall ctrl(winId), 25/*"get_CoreWebView2"*/, prm, 1
view(winId) = v
}
}
onexit gosub *ONEXIT_
// 今回は省きます。
;oncmd gosub *EVENT_ExecuteScript, 0x9010 ; WV2HdlNew用の衝突しない番号を指定(0x8000〜0xBFFFまで)
;WV2HdlNew 2/*type:HW*/, hwnd, 0x9010
;resNew_exec(winId) = stat ; ExecuteScriptするときに使用
// NewWindowRequestの割り込みを設定
if view(winId) != 0 {
oncmd gosub *EVENT_NEWWND, 0x9003
oncmd gosub *EVENT_NEWWND2, 0x9004 ; PostMessageで使用
dim token, 2 ; この token は remove_NewWindowRequested するときに必要となる
WV2HdlNew 0/*type:II*/, hwnd, 0x9003
prm = stat, varptr(token)
ComCall view(winId), 44/*"add_NewWindowRequested"*/, prm, 2
}
return
*EVENT_NEWWND
if lparam == 0 : return
pNewWnd = lparam
prm = varptr(pDef)
ComCall pNewWnd, 9/*"GetDeferral"*/, prm, 1
if stat == 0 : PostMessage hwnd, 0x9004, 0, 0
return
*EVENT_NEWWND2
prm = 1
ComCall pNewWnd, 6/*"put_Handled"*/, prm, 1
if stat == 0 {
winId = ginfo_newid
gosub *create_window ; 新たなウィンドウを作る
if view(winId) {
prm = view(winId)
ComCall pNewWnd, 4/*"put_NewWindow"*/, prm, 1
}
}
ComCall pDef, 3/*"Complete"*/, prm, 0
ComDel pDef
return
*ONEXIT_
gsel wparam, -1 ; ウィンドウを非表示
if view(wparam) : ComDel view(wparam) : view(wparam)=0
if ctrl(wparam) : ComDel ctrl(wparam) : ctrl(wparam)=0
alive(wparam) = 0
al = 0
foreach alive
if alive(cnt) : al = 1 : break
loop
if al : return ; まだ生き残りウィンドウがいる
if env : ComDel env
end
「5.」のときに、以下のようなことも可能(っぽい)
・NewWindowを握りつぶすだけ : put_Handledのみ使用。
・現在のWebView2コントロールでリンクを開く : put_NewWindowのview先に現在のWebView2コントロールのviewを指定する。
> ・新しいウィンドウに対しExecuteScriptを適用するには?
今回は ExecuteScript用ウィンドウを省きましたが、目当ての view 宛てに実行してあげてください。
> ・古いウィンドウを閉じると終了判定となってしまうが、
> 古いウィンドウを閉じても終了判定とならないようにするには?
onexit gosub で wparam を見て、必要なら return してください。