Exciting times:
https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview
This extends IUnknown and therefore in theory it's an ActiveX control! I.E. Edge/Chromium GUI's embedded in AHK soon?!
WebView2
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
Discuss Autohotkey related topics here. Not a place to share code.
Re: WebView2
Cool!. I followed the guide Getting Started with WebView2 (developer preview) and I was able to compile, it seems to work well.
I have tried to use the CreateWebView2Environment functionbut I have no idea how to work with the environment_created_handler parameter in AHK.
Microsoft Edge WebView2 (developer preview).
I have tried to use the CreateWebView2Environment function
Microsoft Edge WebView2 (developer preview).
Spoiler
Re: WebView2
Very cool. Would be a very nice feature!
Re: WebView2
Could you be a little more explicit? I'm not sure how that guide you linked ultimately compiles into a dll.Flipeador wrote: ↑22 Jun 2019, 00:34Requirements: Microsoft Edge Chromium and WebView2Loader.dll in your System folder.[/spoiler]
EDIT: I see now. The DLL gets downloaded when you install the package via NuGet. I am getting error 80070002 when I try to run the script.
EDIT: Installing the DEV channel of the browser removes the error. But as you stated, nothing appears.
Re: WebView2
Well, Edge is definitely starting up with the code provided by @Flipeador. I see four processes kick off in Task Manager however they disappear after a few seconds.
I don't really understand how the iUnknown interfaces work. But it seems like Release is being called immediately after the two calls to AddRef. My understanding is that Release wouldn't be called until it was destroyed or something.
I don't really understand how the iUnknown interfaces work. But it seems like Release is being called immediately after the two calls to AddRef. My understanding is that Release wouldn't be called until it was destroyed or something.
Re: WebView2
Any other thoughts @Flipeador?
Re: WebView2
Some day we'll figure this out . I updated it to use the new ComCall function. Tried inserting a navigation starting event handler to see if the navigation actually does anything but it doesn't get invoked. I also have no clue what I'm doing and largely just am basing my theories on Flipeador's work.
Code: Select all
; AHK v2.0-a103-56441b52
#Warn
#SingleInstance Force
DllCall("User32.dll\SetProcessDpiAwarenessContext", "Ptr", 0xFFFFFFFC)
Gui := GuiCreate()
Gui.OnEvent("Close", "ExitApp")
Gui.Show("w750 h600")
; IWebView2CreateWebView2EnvironmentCompletedHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2createwebview2environmentcompletedhandler#interface_i_web_view2_create_web_view2_environment_completed_handler.
vtbl := BufferAlloc(4*A_PtrSize) ; https://www.autohotkey.com/boards/viewtopic.php?t=37142#p170967
for Each, Method in ["QueryInterface","AddRef","Release","Invoke"]
NumPut("UPtr", CallbackCreate(Method), vtbl, (A_Index-1)*A_PtrSize)
ptr := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl.ptr, ptr)
NumPut("UInt", 1, ptr, A_PtrSize)
; IWebView2CreateWebViewCompletedHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2createwebviewcompletedhandler#invoke.
vtbl2 := BufferAlloc(4*A_PtrSize)
for Each, Method in ["QueryInterface","AddRef","Release","Invoke_2"]
NumPut("UPtr", CallbackCreate(Method), vtbl2, (A_Index-1)*A_PtrSize)
ptr2 := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl2.ptr, ptr2)
NumPut("UInt", 1, ptr2, A_PtrSize)
; IWebView2NavigationCompletedEventHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2navigationcompletedeventhandler
vtbl3 := BufferAlloc(4*A_PtrSize)
for Each, Method in ["QueryInterface","AddRef","Release","Invoke_3"]
NumPut("UPtr", CallbackCreate(Method), vtbl3, (A_Index-1)*A_PtrSize)
ptr3 := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl3.ptr, ptr3)
NumPut("UInt", 1, ptr3, A_PtrSize)
if R := DllCall(A_ScriptDir . "\WebView2Loader.dll\CreateWebView2Environment", "Ptr", ptr, "UInt") {
MsgBox("ERROR " . Format("{:08X}",R))
}
return
QueryInterface(this, riid, ppvObject) {
local IID_IUnknown := BufferAlloc(16)
local IWebView2CreateWebView2EnvironmentCompletedHandler := BufferAlloc(16)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{00000000-0000-0000-C000-000000000046}", "Ptr", IID_IUnknown)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{A8346945-51C2-4CE6-8B4C-6F3C4391828B}", "Ptr", IWebView2CreateWebView2EnvironmentCompletedHandler)
if DllCall("Ole32.dll\IsEqualGUID", "Ptr", riid, "Ptr", IID_IUnknown)
|| DllCall("Ole32.dll\IsEqualGUID", "Ptr", riid, "Ptr", IWebView2CreateWebView2EnvironmentCompletedHandler)
{
NumPut("UPtr", this, ppvObject)
AddRef(this)
return 0 ; S_OK.
}
NumPut("UPtr", 0, ppvObject)
return 0x80004002 ; E_NOINTERFACE.
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-queryinterface%28refiid_void%29
AddRef(this) {
local RefCount := NumGet(this,A_PtrSize,"UInt") + 1
; msgbox("addref")
NumPut("UInt", RefCount, this, A_PtrSize)
return RefCount
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-addref
Release(this) {
local RefCount := NumGet(this,A_PtrSize,"UInt")
if (RefCount > 0)
{
NumPut("UInt", --RefCount, this, A_PtrSize)
if (RefCount == 0)
DllCall("Kernel32.dll\GlobalFree", "Ptr", this)
}
return RefCount
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-release
Invoke(this, HRESULT, IWebView2Environment) {
global Gui, ptr2
; IWebView2Environment::CreateWebView Method.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2environment#createwebview.
ComCall(3, IWebView2Environment, "Ptr", gui.hwnd, "Ptr", ptr2)
return 0 ; S_OK.
} ; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2createwebview2environmentcompletedhandler#invoke
Invoke_2(this, HRESULT, IWebView2WebView) {
global Gui, ptr3
local
; Resize WebView to fit the bounds of the parent window.
; IWebView2WebView::put_Bounds Method.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#put_bounds.
DllCall("User32.dll\GetClientRect", "Ptr", Gui.hWnd, "Ptr", RECT:=BufferAlloc(16))
; MsgBox("x=" NumGet(RECT, 0, "Int") "`ny=" NumGet(RECT, 4, "Int") "`nw=" NumGet(RECT, 8, "Int") "`nh=" NumGet(RECT, 12, "Int"))
; NumPut(-400, RECT, 0, "INT"), NumPut(-100, RECT, 4, "INT")
ComCall(38, IWebView2WebView, "Ptr", RECT)
; ComCall(37, IWebView2WebView, "Ptr", newRECT := BufferAlloc(16))
; MsgBox("x=" NumGet(newRECT, 0, "Int") "`ny=" NumGet(newRECT, 4, "Int") "`nw=" NumGet(newRECT, 8, "Int") "`nh=" NumGet(newRECT, 12, "Int"))
ComCall(42, IWebView2WebView, "Int", 1)
ComCall(8, IWebView2WebView, "Ptr", Ptr3)
; Schedule an async task to navigate to Bing.
; IWebView2WebView::Navigate Method.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2webview#navigate.
; ComCall(7, IWebView2WebView, "Str", "<h1>test</h1>")
ComCall(5, IWebView2WebView, "Str", "https://www.bing.com/")
return 0 ; S_OK.
} ; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2createwebviewcompletedhandler#invoke
Invoke_3(this, IWebView2WebView, IWebView2NavigationStartingEventArgs) {
MsgBox("test")
ComCall(3, IWebView2NavigationStartingEventArgs, "Ptr", uri)
MsgBox(uri)
}
Re: WebView2
:bump: Wondering if anyone has ventured into this again with the updated webview2 api. Still crashes for me when trying to call Navigate.
Re: WebView2
No idea if its correct/proper but TA-DA!!! The key was calling ObjAddRef on the interface pointer to the Controller inside of Invoke_2 because as soon as that event handler finished the ref count on the Controller interface was decrementing. And the documentation for ICoreWebView2Controller states:
Something great about this is that it seems to handle accelerators just fine (copy/cut/paste, F5, navigate forward/back,etc).The CoreWebView2Controller owns the CoreWebView2, and if all references to the CoreWebView2Controller go away, the WebView will be closed.
Code: Select all
; #Requires AutoHotkey v2.0-a112
#Warn
#SingleInstance Force
; DllCall("User32.dll\SetProcessDpiAwarenessContext", "Ptr", 0xFFFFFFFC) ; not sure if this is needed. Works fine without it.
main := gui.new()
main.OnEvent("Close", "ExitApp")
main.Show("w1000 h800")
; IWebView2CreateWebView2EnvironmentCompletedHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler#interface_i_web_view2_create_web_view2_environment_completed_handler.
vtbl := BufferAlloc(4*A_PtrSize) ; https://www.autohotkey.com/boards/viewtopic.php?t=37142#p170967
for Each, Method in ["QueryInterface", "AddRef", "Release", "Invoke"]
NumPut("UPtr", CallbackCreate(Method), vtbl, (A_Index-1)*A_PtrSize)
ptr := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl.ptr, ptr)
NumPut("UInt", 1, ptr, A_PtrSize)
; ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler#invoke.
vtbl2 := BufferAlloc(4*A_PtrSize)
for Each, Method in ["QueryInterface", "AddRef", "Release", "Invoke_2"]
NumPut("UPtr", CallbackCreate(Method), vtbl2, (A_Index-1)*A_PtrSize)
ptr2 := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl2.ptr, ptr2)
NumPut("UInt", 1, ptr2, A_PtrSize)
; IWebView2NavigationCompletedEventHandler.
; https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview2/reference/iwebview2navigationcompletedeventhandler
vtbl3 := BufferAlloc(4*A_PtrSize)
for Each, Method in ["QueryInterface", "AddRef", "Release", "Invoke_3"]
NumPut("UPtr", CallbackCreate(Method), vtbl3, (A_Index-1)*A_PtrSize)
ptr3 := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 0, "Ptr", A_PtrSize+4, "UPtr")
NumPut("UPtr", vtbl3.ptr, ptr3)
NumPut("UInt", 1, ptr3, A_PtrSize)
if R := DllCall(A_ScriptDir . "\WebView2Loader.dll\CreateCoreWebView2Environment", "Ptr", ptr, "UInt") {
MsgBox("ERROR " . Format("{:08X}",R))
}
return
QueryInterface(this, riid, ppvObject) {
local IID_IUnknown := BufferAlloc(16)
local ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler := BufferAlloc(16)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{00000000-0000-0000-C000-000000000046}", "Ptr", IID_IUnknown)
DllCall("Ole32.dll\CLSIDFromString", "Str", "{86EF6808-3C3F-4C6F-975E-8CE0B98F70BA}", "Ptr", ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler)
if DllCall("Ole32.dll\IsEqualGUID", "Ptr", riid, "Ptr", IID_IUnknown)
|| DllCall("Ole32.dll\IsEqualGUID", "Ptr", riid, "Ptr", ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler)
{
NumPut("UPtr", this, ppvObject)
AddRef(this)
return 0 ; S_OK.
}
NumPut("UPtr", 0, ppvObject)
return 0x80004002 ; E_NOINTERFACE.
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-queryinterface%28refiid_void%29
AddRef(this) {
local RefCount := NumGet(this,A_PtrSize,"UInt") + 1
; ToolTip("add count = " . RefCount)
NumPut("UInt", RefCount, this, A_PtrSize)
return RefCount
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-addref
Release(this) {
local RefCount := NumGet(this,A_PtrSize,"UInt")
if (RefCount > 0)
{
NumPut("UInt", --RefCount, this, A_PtrSize)
; ToolTip("released count = " . RefCount)
if (RefCount == 0)
DllCall("Kernel32.dll\GlobalFree", "Ptr", this)
}
return RefCount
} ; https://docs.microsoft.com/en-us/windows/desktop/api/unknwn/nf-unknwn-iunknown-release
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2createcorewebview2environmentcompletedhandler#invoke
Invoke(this, HRESULT, ICoreWebView2Environment) {
global main, ptr2
; ICoreWebView2Environment::CreateCoreWebView2Controller Method.
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2environment#createcorewebview2controller
ComCall(3, ICoreWebView2Environment, "Ptr", main.hwnd, "Ptr", ptr2)
return 0 ; S_OK.
}
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2createcorewebview2controllercompletedhandler#invoke
Invoke_2(this, HRESULT, IWebView2WebViewController) {
global main, webview, ptr3
ObjAddRef(IWebView2WebViewController) ; This was key to retain a reference to the Controller
; Resize WebView to fit the bounds of the parent window.
; IWebView2WebViewController::put_Bounds Method.
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2controller#put_bounds
DllCall("User32.dll\GetClientRect", "Ptr", main.hWnd, "Ptr", RECT := BufferAlloc(16))
ComCall(6, IWebView2WebViewController, "Ptr", RECT)
; IWebView2WebViewController::get_CoreWebView2
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2controller#get_corewebview2
ComCall(25, IWebView2WebViewController, "Ptr", webView := BufferAlloc(8))
webview := NumGet(webView, "Ptr")
; ICoreWebView2::add_navigationstarting
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2#add_navigationstarting
ComCall(7, webview, "Ptr", ptr3, "Ptr", token := BufferAlloc(8))
; ICoreWebView2::Navigate
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2#navigate
ComCall(5, webview, "Str", "https://www.google.com/")
return 0 ; S_OK.
}
; https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/0-9-538/icorewebview2navigationstartingeventhandler#invoke
Invoke_3(this, IWebView2WebView, IWebView2NavigationStartingEventArgs) {
ComCall(4, IWebView2NavigationStartingEventArgs, "Ptr", isUserInitiated := BufferAlloc(4))
if (NumGet(isUserInitiated, "Int")) {
uri := BufferAlloc(8)
ComCall(3, IWebView2NavigationStartingEventArgs, "Ptr", uri)
url := StrGet(NumGet(uri, "Ptr"))
if (MsgBox("You are about to navigate to: " . url . "`n`nDo you want to continue?", "Navigation warning", "YN Icon!") = "No") {
; IWebView2NavigationStartingEventArgs::put_Cancel
ComCall(8, IWebView2NavigationStartingEventArgs, "Int", true)
; ICoreWebView2::NavigateToString
ComCall(6, IWebView2WebView, "Str", "<h1>Navigation Canceled</h1><p>You chose to cancel navigation to the following URL: " . url . "</p>")
}
}
return 0 ; S_OK
}
Re: WebView2
Thanks for keeping this up to date!!!
Re: WebView2
Up to date might be a stretch! This has just always intrigued me, mostly due to my disdain for Internet Explorer. I did some more work to wrap some of this functionality in a few utility classes and then a very basic class called WebView. Eventually, I can see adding to it to wrap most of the functionality of the ICoreWebView2 and ICoreWebView2Controller interfaces.
Re: WebView2
Hi, do you have any update / working example on this?
I tried it, but i get Error 80070002.
By the way, Teamviewer is using WebView2Loader.dll too.
I tried it, but i get Error 80070002.
By the way, Teamviewer is using WebView2Loader.dll too.
Re: WebView2
Re: WebView2
I am using 86.0.622.38 (Offizielles Build) (64-Bit)
Do i have to use anything else?
Do i have to use anything else?
Re: WebView2
You have to have the Beta Channel installed or you can install the Webview2 Runtime.
Are you using the class from the v2 Scripts forum?
Are you using the class from the v2 Scripts forum?
Return to “General Discussion”
Who is online
Users browsing this forum: No registered users and 13 guests