Discuss Autohotkey related topics here. Not a place to share code.
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
Posts: 224
Joined: 01 Mar 2016, 14:52


21 Jun 2019, 11:19

Exciting times:


This extends IUnknown and therefore in theory it's an ActiveX control! I.E. Edge/Chromium GUI's embedded in AHK soon?!
User avatar
Posts: 1169
Joined: 15 Nov 2014, 21:31
GitHub: Flipeador
Location: Argentina

Re: WebView2

22 Jun 2019, 00:34

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 function but I have no idea how to work with the environment_created_handler parameter in AHK.
Microsoft Edge WebView2 (developer preview).
User avatar
Posts: 62
Joined: 20 Jan 2015, 10:31

Re: WebView2

21 Nov 2019, 06:12

Very cool. Would be a very nice feature! :)
Dev for a better world :) > PHP for Web > AHK H for Local > with KISS (Keep it Short and Simple) on Win 10 Pro (Version 1903) x64
User avatar
Posts: 1010
Joined: 06 Oct 2015, 21:39

Re: WebView2

21 Nov 2019, 19:44

Flipeador wrote:
22 Jun 2019, 00:34
Requirements: Microsoft Edge Chromium and WebView2Loader.dll in your System folder.[/spoiler]
Could you be a little more explicit? I'm not sure how that guide you linked ultimately compiles into a dll.

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.
User avatar
Posts: 1010
Joined: 06 Oct 2015, 21:39

Re: WebView2

22 Nov 2019, 08:01

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.
User avatar
Posts: 1010
Joined: 06 Oct 2015, 21:39

Re: WebView2

22 Dec 2019, 13:38

Any other thoughts @Flipeador?
User avatar
Posts: 1010
Joined: 06 Oct 2015, 21:39

Re: WebView2

25 Jan 2020, 21:11

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
#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))

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)
        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
    ; 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) {
    ComCall(3, IWebView2NavigationStartingEventArgs, "Ptr", uri)

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 14 guests