WebView2 Control For Edge

Post your working scripts, libraries and tools.
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

WebView2 Control For Edge

23 Sep 2020, 13:00

From what I read on the forum, could not get the WebView2 examples to work.
Started playing with the WebView2Loader.dll (ver:9.579.0), Win7-Edge ver:85.0.564.51, AHK ver:2.0_122:U64.

In the WebView2Loader I call "CreateCoreWebView2EnvironmentWithOptions" to get started. (see WebView2.ahk for info)
This is set up by the Function Init_WebView2(Gui variable) and make sure your Edge and WebView2Loader path are correct.

Added "IWebView2WebViewController::put_ZoomFactor" to set the ZoomFactor = 125%.

WebView2 Include

Code: Select all

/*  WebView2 for AutoHotkey v2.0-a122
 *
 *  Provides an interfaces to The Microsoft Edge WebView2 control and enables you to host web content in your applications
 *  This is a 64-bit Dll program, use AHK U64.
 *
 *  Use, modify and redistribute without limitation.
 */

winSize(controller,minMax,*){
    ; IWebView2WebViewController::get_IsVisible
    ComCall 3,controller,"int*",isVisible := 0
    If(minMax == -1){
        if(isvisible)
            ; IWebView2WebViewController::put_IsVisible
            ComCall 4,controller,"int",False
    }Else{
        If(!isVisible)
            ; IWebView2WebViewController::put_IsVisible
            ComCall 4,controller,"int",True
        Else{
            DllCall "GetClientRect","ptr",hWnd,"ptr",RECT := BufferAlloc(16)
            ; IWebView2WebViewController::put_Bounds
            ComCall 6,controller,"ptr",RECT
        }
    }
}

QueryInterface(this,riid,ppvObject){
    ; This isn't called at all...
}

AddRef(this){
    NumPut "uint",ObjAddRef(this),this,A_PtrSize
}

Release(this){
    NumPut "uint",ObjRelease(this),this,A_PtrSize
}

Invoke(this,HRESULT,iObject){
    Switch(this){
        Case WebView2Environment:
            ; ICoreWebView2Environment::CreateCoreWebView2Controller Method.
            ComCall(3,iObject,"ptr",hWnd,"ptr",WebView2Controller)
        Case WebView2Controller:
            ObjAddRef iObject
            winParent.OnEvent "Size",Func("winSize").bind(iObject)
            ; Resize WebView to fit the bounds of the parent window.
            ; IWebView2WebViewController::put_Bounds Method.
            DllCall "GetClientRect","ptr",hWnd,"ptr",RECT := BufferAlloc(16)
            ComCall 6,iObject,"ptr",RECT
            ; IWebView2WebViewController::get_CoreWebView2
            ComCall 25,iObject,"ptr*",CoreWebView2
            ; IWebView2WebViewController::put_ZoomFactor
            ComCall 8,iObject,"double",ZoomFactor
            ; ICoreWebView2::add_navigationstarting
            ComCall 7,CoreWebView2,"ptr",WebView2NavigationStartingEventArgs,"uint64",token := 0
            If HtmlSite
                ; ICoreWebView2::Navigate
                ComCall 5,CoreWebView2,"str",HtmlSite
            If HtmlStr
                ; ICoreWebView2::NavigateToString
                ComCall 6,CoreWebView2,"str",HtmlStr
            If WebView2DocumentTitleChangedEventHandler
                ; ICoreWebView2::add_DocumentTitleChanged
                ComCall 46,CoreWebView2,"ptr",WebView2DocumentTitleChangedEventHandler,"uint64",token := 0
        Case WebView2NavigationStartingEventArgs:
            ComCall 4,iObject,"int*",isUserInitiated:=False
            if(isUserInitiated)
                ComCall 3,iObject,"str*",uri := ""
        Case WebView2DocumentTitleChangedEventHandler:
            ; ICoreWebView2::get_DocumentTitle
            ComCall 48,CoreWebView2,"str*",DocTitle := ""
            If(!isfunc("On_Click")){
                MsgBox "Function On_Click Not Created....","Func Error!","iconi"
                ExitApp
            }
            Func("On_Click").Call(DocTitle)
    }
}

WebView2(Invoke){
    vtbl.Push BufferAlloc(4*A_PtrSize)
    For Each,Method In ["QueryInterface","AddRef","Release","Invoke"]
        NumPut "uptr",CallbackCreate(Method),vtbl[Invoke],(A_Index-1)*A_PtrSize
    ptr := DllCall("GlobalAlloc","uint",64,"ptr",A_PtrSize+4,"uptr")
    NumPut "uptr",vtbl[Invoke].ptr,ptr
    NumPut "uint",1,ptr,A_PtrSize
    Return ptr
}

ClickEvents_WebView2(){
    WebView2DocumentTitleChangedEventHandler := WebView2(4)  ; ICoreWebView2DocumentTitleChangedEventHandler.
}

Init_WebView2(parent){
    hWnd                                  := parent.hWnd
    winParent                             := parent
    WebView2Environment                   := WebView2(1)     ; IWebView2CreateWebView2EnvironmentCompletedHandler.
    WebView2Controller                    := WebView2(2)     ; ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.
    WebView2NavigationStartingEventArgs   := WebView2(3)     ; IWebView2NavigationCompletedEventHandler.

    EdgePath := "c:\Program Files (x86)\Microsoft\Edge\Application\85.0.564.63\"
    dllPath  := "WebView2Loader"

    DllCall dllPath "\CreateCoreWebView2EnvironmentWithOptions","str",EdgePath,"str","","ptr",0,"uptr",WebView2Environment

    If(a_lasterror){
        buf := BufferAlloc(8,0)
        DllCall "FormatMessage","uint",256|4096,"ptr",0,"uint",a_lasterror,"uint",0,"ptr",buf.ptr,"uint",0,"ptr",0
        msgbox "Error " a_lasterror " = " StrGet(NumGet(buf,"ptr"))
        exitapp
    }
}

global WebView2Environment                      := 0
global WebView2Controller                       := 0
global WebView2NavigationStartingEventArgs      := 0
global WebView2DocumentTitleChangedEventHandler := 0

global hWnd := 0,winParent := {},vtbl := [],CoreWebView2 := 0,HtmlSite := "",HtmlStr := "",ZoomFactor := 1.25 ; =125%
My example from the forum example, uses index.html,index.js, or the bing web site.

Code: Select all

#include WebView2.ahk

; try a web site (Navigate)
; HtmlSite := "https www.bing.com /"  Broken Link for safety

; try a local html file (Navigate)
HtmlSite := A_ScriptDir "/index.html"

win := Gui.New("+resize","Test WebView2")
win.OnEvent("Close","ExitApp")

Init_WebView2(win)

win.Show "w" A_ScreenWidth//2 " h" A_ScreenHeight//2

Esc::ExitApp
The next example uses "HtmlStr" (NavigateToString) for inline html,CSS,Javascript,whatever.
Edge will put in the basic Html tags for you.(html,head,etc.)

AHK needs to know when an element is Clicked. I created a Function called ClickEvents_WebView2,(see WebView2.ahk)
along with the Function On_Click. (see AHK prg.)

I used "add_DocumentTitleChanged" to trigger the Clicks.

Button Example (all javascript)

Code: Select all

#include WebView2.ahk
#include imagedata.ahk

On_Click(iClick){
    Switch(iClick){
        Case 1,2,3,4: MsgBox "Button " iClick " Clicked","Round Buttons","Iconi t2"
        Case 5,6,7: ExitApp
    }
}

HtmlStr := format("
(
    <body background="{1}" style="overflow:hidden">
    <img src="{2}" style="visibility:hidden">
    <script>
        function On_Click(num){
            document.title = num;
            // Reset Title For Same Click
            document.title = 0;
        }

        for(var i=1;i<6;i++){
            var rButton = document.createElement("button");
            if(i == 5){
                 rButton.textContent = "Over EXIT";
                 rButton.setAttribute("onmouseover","On_Click("+i+")");
            }else{
                rButton.textContent = "Button "+i;
                rButton.setAttribute("onclick","On_Click("+i+")");
                rButton.setAttribute("onmouseover","style.color='cyan';style.border='3px solid red';style.boxShadow='none';style.zIndex=1;style.transform='scale(1.3)';style.transition='all .4s'");
                rButton.setAttribute("onmouseout","style.color='yellow';style.border='none';style.boxShadow='1px 1px 30px white';style.zIndex=0;style.transform='scale(1.0)';style.transition='all .4s'");
            }
            rButton.style.left         = 5;
            rButton.style.top          = 5;
            rButton.style.width        = 60;
            rButton.style.height       = 60;
            rButton.style.position     = "relative";
            rButton.style.font         = "bold 12px arial";
            rButton.style.color        = "yellow";
            rButton.style.cursor       = "pointer";
            rButton.style.background   = "navy";
            rButton.style.border       = "none";
            rButton.style.outline      = "none";
            rButton.style.boxShadow    = "1px 1px 30px white";
            rButton.style.borderRadius = "35px";
            rButton.style.float        = "left";
            rButton.style.transition   = "all .2s";
            document.body.appendChild(rButton);
        }

        rButton = document.createElement("button");
        rButton.setAttribute("onclick","On_Click("+i+++")");
        rButton.setAttribute("onmouseover","style.color='yellow';style.boxShadow='none'");
        rButton.setAttribute("onmouseout","style.color='cyan';style.boxShadow='5px 5px 20px white'");
        rButton.textContent           = "Beam Me Up!";
        rButton.style.left            = 25;
        rButton.style.top             = 125;
        rButton.style.width           = 200;
        rButton.style.height          = 55;
        rButton.style.position        = "absolute";
        rButton.style.textDecoration  = "underline";
        rButton.style.backgroundImage = "linear-gradient(to left,blue,red)";
        rButton.style.font            = "bold 24px times new roman";
        rButton.style.color           = "cyan";
        rButton.style.cursor          = "pointer";
        rButton.style.borderStyle     = "none";
        rButton.style.outline         = "none";
        rButton.style.borderRadius    = "40px";
        rButton.style.boxShadow       = "5px 5px 20px white";
        rButton.style.transition      = "all .2s";
        document.body.appendChild(rButton);

        var img = document.getElementsByTagName("img")[0];
        img.style.visibility = 'visible';
        img.style.float      = "left";
        rButton.appendChild(img);

        rButton = document.createElement("button");
        rButton.setAttribute("onclick","On_Click("+i+")");
        rButton.setAttribute("onmouseover","style.color='yellow';style.boxShadow='1px 1px 30px white';style.border='3px solid red'");
        rButton.setAttribute("onmouseout","style.color='red';style.boxShadow='none';style.border='3px solid yellow'");
        rButton.textContent          = "I Quit!";
        rButton.style.left           = 185;
        rButton.style.top            = 230;
        rButton.style.width          = 100;
        rButton.style.height         = 40;
        rButton.style.position       = "absolute";
        rButton.style.textDecoration = "underline";
        rButton.style.font           = "bold 18px arial";
        rButton.style.color          = "red";
        rButton.style.cursor         = "pointer";
        rButton.style.background     = "blue";
        rButton.style.border         = "3px solid yellow";
        rButton.style.outline        = "none";
        rButton.style.borderRadius   = "10px";
        document.body.appendChild(rButton);
    </script>
)",steel,badge)

win := gui.new(,"WebView2 Button Testing")
win.OnEvent "Close",(*) => ExitApp()

Init_WebView2(win)

ClickEvents_WebView2

win.Show "w400 h400"

Esc::ExitApp
Hope this is helpful for any interested in WebView2 Control for Edge.
webview2.zip
(85.63 KiB) Downloaded 341 times
Last edited by xroot on 26 Sep 2020, 08:58, edited 1 time in total.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: WebView2 Control For Edge

23 Sep 2020, 19:36

You do realize I posted a complete working example of this here, right?
https://www.autohotkey.com/boards/viewtopic.php?f=83&t=79868
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

Re: WebView2 Control For Edge

24 Sep 2020, 08:04

Yes, but it did not work for me, for some reason I do not know.
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: WebView2 Control For Edge

24 Sep 2020, 08:36

I’d be open to work with you to determine why it didn’t work. We’re you getting any errors?
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

Re: WebView2 Control For Edge

25 Sep 2020, 08:23

In your program I changed CreateCoreWebView2Environment to CreateCoreWebView2EnvironmentWithOptions and it works.
With CreateCoreWebView2Environment in your code I get Error 127 = The specified procedure could not be found.
Your codes say ERROR 80070002
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: WebView2 Control For Edge

25 Sep 2020, 09:08

Do you have at least the Beta Channel of Edge installed?
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: WebView2 Control For Edge

25 Sep 2020, 09:42

I was able to get it to work with both CreateCoreWebView2Environment and CreateCoreWebView2EnvironmentWithOptions. Using the WithOptions variation, I was able to pass both the normal Edge install path and the Beta Edge path and it worked for both. I think that you were getting that error with CreateCoreWebView2Environment because you don't have the Beta Channel installed and I think that it won't automatically use the normal channel.
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

Interact With Web Pages in WebView2

29 Sep 2020, 12:11

Added new functionality to WebView2.ahk.

1. WebView2NavigationCompletedEventHandler
2. WebView2ExecuteScriptCompletedHandler
3. jsCode Variable
4. ExecuteScript_WebView2 Fucntion

I wanted to see if I could Fade Out the Google Logo.

Fade Google Logo Example:

Code: Select all

#include WebView2.ahk

HtmlSite := "https www.google.com "  Broken Link for safety

jsCode := "
(
    function Sleep(ms){
        return new Promise(resolve => setTimeout(resolve,ms));
    }
    async function InterAct(){
        // Load jQuery
        var jq = document.createElement("script");
        jq.src = "https ajax.googleapis.com /ajax/libs/jquery/3.5.1/jquery.min.js";  Broken Link for safety
        document.head.appendChild(jq);

        // Load SweetAlert
        var msg = document.createElement("script");
        msg.src = "https unpkg.com /sweetalert/dist/sweetalert.min.js";  Broken Link for safety
        document.head.appendChild(msg);

        // Wait for jQuery & SweetAlert to Load
        await Sleep(500);

        // Show Cool MsgBox SweetAlert
        await swal("Watch Google Logo Fade Out...","jQuery Version = "+$.fn.jquery,"info");

        $("#hplogo").fadeOut(3000);
    }
    InterAct();
)"

win := Gui.new(,"WebView2 Fade Google Logo")
win.OnEvent "Close",(*) => ExitApp()

Init_WebView2(win)

ExecuteScript_WebView2

win.Show "w" A_ScreenWidth//2 " h" A_ScreenHeight//2

Esc::ExitApp
WebView2.zip
(1.94 KiB) Downloaded 262 times
burque505
Posts: 1731
Joined: 22 Jan 2017, 19:37

Re: WebView2 Control For Edge

07 Feb 2021, 10:54

@xroot, thank for your work on this. I am able to run both your examples after I change the Edge folder, in my case

Code: Select all

local EdgePath := "C:\Program Files (x86)\Microsoft\EdgeWebView\Application\88.0.705.63\"
and an acceptable path for the EBWebview folder to be created, in my case

Code: Select all

    ; Call WebView2Loader to setup WebView2 Environment
    DllCall dllPath "\CreateCoreWebView2EnvironmentWithOptions","str",EdgePath,"str","C:\Users\" A_UserName "\Desktop\AHK\V2\WebView2\xroot\","ptr",0,"uptr",WebView2Environment
I am very much looking forward to seeing more work on this. This might be enough to help me break free of v! and start using v2.

Regards,
burque505

Just as an aside, a company called WebKitX (I'm not going to provide a link, as it's an expensive commercial component) apparently has a Chromium embedded framework ActiveX component and a V8 embedded framework ActiveX. Sure would be nice to see something like that open-sourced.
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

Re: WebView2 Control For Edge

08 Feb 2021, 10:54

burque505, Glad you got it working.

I installed Microsoft Edge WebView2 Runtime, now you don't need EdgePath var.
Get it Here
https://developer.microsoft.com/en-us/microsoft-edge/webview2/

Here is the current WebView2 include.

WebView2.ahk

Code: Select all

On_ReSize(controller,*){
    DllCall "GetClientRect","ptr",hWnd,"ptr",RECT
    NumPut "int",wvLeft,RECT
    NumPut "int",wvTop,RECT,4
    NumPut "int",NumGet(RECT,8,"int")-wvLeft,RECT,8
    NumPut "int",NumGet(RECT,12,"int")-wvTop,RECT,12
    ; IWebView2WebViewController::put_Bounds
    ComCall 6,controller,"ptr",RECT
}

QueryInterface(this,riid,ppvObject){
    ; Not used
}

AddRef(this){
    NumPut "uint",ObjAddRef(this),this,A_PtrSize
}

Release(this){
    NumPut "uint",ObjRelease(this),this,A_PtrSize
}

Invoke(this,HRESULT,iObject){
    Switch(this){
        Case WebView2Environment:
            ; iObject = ICoreWebView2Environment
            ; ICoreWebView2Environment::CreateCoreWebView2Controller
            ComCall 3,iObject,"ptr",hWnd,"ptr",WebView2Controller
        Case WebView2Controller:
            ; iObject = IWebView2WebViewController
            ObjAddRef iObject
            winParent.OnEvent "Size",Func("On_ReSize").bind(iObject)
            ; Resize Or Set WebView to fit the bounds of the parent window.
            If(wvLeft+wvTop+wvRight+wvBottom>0)
                DllCall "SetRect","ptr",RECT,"int",wvLeft,"int",wvTop,"int",wvRight,"int",wvBottom
            Else
                DllCall "GetClientRect","ptr",hWnd,"ptr",RECT
            ; IWebView2WebViewController::put_Bounds
            ComCall 6,iObject,"ptr",RECT
            ; IWebView2WebViewController::get_CoreWebView2
            ComCall 25,iObject,"ptr*",CoreWebView2
            ; IWebView2WebViewController::put_ZoomFactor
            ComCall 8,iObject,"double",ZoomFactor
            ; ICoreWebView2::add_NavigationStarting
            ;ComCall 7,CoreWebView2,"ptr",WebView2NavigationStartingEventArgs,"uint64",token := 0
            ; ICoreWebView2::add_NavigationCompleted
            ComCall 15,CoreWebView2,"ptr",WebView2NavigationCompletedEventHandler,"uint64",token := 0
            If NavUri
                ; ICoreWebView2::Navigate
                ComCall 5,CoreWebView2,"str",NavUri
            If NavStr
                ; ICoreWebView2::NavigateToString
                ComCall 6,CoreWebView2,"str",NavStr
            If WebView2DocumentTitleChangedEventHandler
                ; ICoreWebView2::add_DocumentTitleChanged
                ComCall 46,CoreWebView2,"ptr",WebView2DocumentTitleChangedEventHandler,"uint64",token := 0
            If DevTool
                ; ICoreWebView2::OpenDevToolsWindow
                ComCall 51,CoreWebView2
;         Case WebView2NavigationStartingEventArgs:
;             ; iObject = IWebView2NavigationStartingEventArgs
;             ; ICoreWebView2NavigationStartingEventArgs:get_IsUserInitiated
;             ComCall 4,iObject,"int*",isUserInitiated:=False
;             If(isUserInitiated)
;                 ; ICoreWebView2NavigationStartingEventArgs:get_Uri
;                 ComCall 3,iObject,"str*",Uri := ""
        Case WebView2NavigationCompletedEventHandler:
            If(WebView2ExecuteScriptCompletedHandler){
                If(HostName){
                    If(ObjGetCapacity(HostObj)){
                        objBuf      := BufferAlloc(24,0)
                        ahkObject   := ComObject(0x400C,objBuf.ptr)    ;VT_BYREF VT_VARIANT
                        ahkObject[] := HostObj
                        ; ICoreWebView2::AddHostObjectToScript
                        ComCall 49,CoreWebView2,"str",HostName,"ptr",ahkObject
                    }Else{
                        MsgBox "HostObj Not Created...","Variable Error!","iconi"
                        ExitApp
                    }
                }
                If(jsCode)
                    ; ICoreWebView2::ExecuteScript
                    ComCall 29,CoreWebView2,"str",jsCode,"ptr",WebView2ExecuteScriptCompletedHandler
                Else{
                    MsgBox "JavaScript Code Not Created...","jsCode Error!","iconi"
                    ExitApp
                }
            }
        Case WebView2DocumentTitleChangedEventHandler:
            ; ICoreWebView2::get_DocumentTitle
            ComCall 48,CoreWebView2,"str*",DocTitle := ""
            If(!isfunc(Func_Name)){
                MsgBox "Function Name Not Created....","Func Error!","iconi"
                ExitApp
            }
            Func(Func_Name).Call(DocTitle)
;         Case WebView2Settings:
;             ; ICoreWebView2Settings::put_IsStatusBarEnabled
;             ComCall 10,iObject,"int",False
    }
}

WebView2(Invoke){
    vtbl.Push(BufferAlloc(4*A_PtrSize))
    For Each,Method In ["QueryInterface","AddRef","Release","Invoke"]
        NumPut "uptr",CallbackCreate(Method),vtbl[Invoke],(A_Index-1)*A_PtrSize
    ptr := DllCall("GlobalAlloc","uint",64,"ptr",A_PtrSize+4,"uptr")
    NumPut "uptr",vtbl[Invoke].ptr,ptr
    NumPut "uint",1,ptr,A_PtrSize
    Return ptr
}

WebView2_ClickEvents(fName){
    Func_Name := fName
    WebView2DocumentTitleChangedEventHandler := WebView2(vtbl_Count++)  ; ICoreWebView2DocumentTitleChangedEventHandler.
}

WebView2_ExecuteScript(){
    WebView2ExecuteScriptCompletedHandler := WebView2(vtbl_Count++)     ; ICoreWebView2ExecuteScriptCompletedHandler
}

; WebView2_Settings(){
;     WebView2Settings := WebView2(vtbl_Count++)     ; ICoreWebView2Settings
; }

WebView2_Init(iGui){
    hWnd                                    := iGui.hWnd
    winParent                               := iGui
    WebView2Environment                     := WebView2(vtbl_Count++)     ; IWebView2CreateWebView2EnvironmentCompletedHandler.
    WebView2Controller                      := WebView2(vtbl_Count++)     ; ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.
;    WebView2NavigationStartingEventArgs     := WebView2(vtbl_Count++)     ; IWebView2NavigationCompletedEventHandler.
    WebView2NavigationCompletedEventHandler := WebView2(vtbl_Count++)     ; ICoreWebView2NavigationCompletedEventHandler

;     local EdgePath := "c:\Program Files (x86)\Microsoft\Edge Beta\Application\87.0.664.52\"
    local dllPath := "c:\Program Files (x86)\AutoHotKey\JMM\WebView\x64\WebView2Loader"

;    DllCall dllPath "\CreateCoreWebView2EnvironmentWithOptions","str",EdgePath,"str","","ptr",0,"uptr",WebView2Environment
     DllCall dllPath "\CreateCoreWebView2Environment","uptr",WebView2Environment

    If(A_LastError){
        buf := BufferAlloc(8,0)
        DllCall "FormatMessage","uint",256|4096,"ptr",0,"uint",A_LastError,"uint",0,"ptr",buf.ptr,"uint",0,"ptr",0
        msgbox "Error " A_LastError " = " StrGet(NumGet(buf,"ptr"))
        ExitApp
    }
}

global WebView2Environment                      := 0
global WebView2Controller                       := 0
; global WebView2NavigationStartingEventArgs      := 0
global WebView2NavigationCompletedEventHandler  := 0
global WebView2DocumentTitleChangedEventHandler := 0
global WebView2ExecuteScriptCompletedHandler    := 0
; global WebView2Settings                         := 0

global hWnd := 0,winParent := {},vtbl := [],vtbl_Count := 1,CoreWebView2 := 0,ZoomFactor := 1.25
global RECT := BufferAlloc(16,0),wvLeft := 0,wvTop := 0,wvRight := 0,wvBottom := 0,DevTool := False
global NavUri := "",NavStr := "",Func_Name := "",jsCode := "",objBuf := 0,HostName := "",HostObj := {},ahkObject := {}
I have written a lot of different examples.
Let me know what you come up with and if I can help, please ask.
Main thing is having fun.

Here is one with Edge on top and Google on bottom.

Two urls on one page.

Code: Select all

#include webview2.ahk

NavUri := "https www.bing.com "  Broken Link for safety

win           := Gui.New("-caption","WebView2 Testing")
win.BackColor := "Aqua"

wvRight  := A_ScreenWidth
wvBottom := A_ScreenHeight/1.5

WebView2_Init(win)

win.Show "w" A_ScreenWidth " h" A_ScreenHeight

;Give some time to load Gui
sleep 600

NavUri := "https www.google.com "  Broken Link for safety

wvtop    := A_ScreenHeight/1.5
wvBottom := 1090

WebView2_Init(win)

Esc::ExitApp
tqphan
Posts: 26
Joined: 04 Mar 2019, 14:44

Re: WebView2 Control For Edge

04 Mar 2021, 16:41

Hi,
Thank you for sharing this library.

Where does dllPath supposed to point to?

Edit: It's \WebView2Loader, duh! It's working :bravo:
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: WebView2 Control For Edge

05 Aug 2021, 08:22

Hi,

Are you able to help me too?

I use your last code
+ ahk v2-beta1 x86 (last from main ahk page)
+ EmbeddedBrowserWebView.dll x86 v92 2,78MB (last from MS cab > uncompressed + also changed the dllPath in WebView2.ahk ;) )

But i get some code errors:

Var BufferAlloc, isfunc appears to never be assigned a value.

Any ideas? :)
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
swagfag
Posts: 6222
Joined: 11 Jan 2017, 17:59

Re: WebView2 Control For Edge

05 Aug 2021, 08:55

BufferAlloc is a deleted func, use Buffer's constructor instead
IsFunc is a deleted func, use operator is and test against Func

theres probably more errors, best check what changed from a122 -> beta and update accordingly
User avatar
kczx3
Posts: 1640
Joined: 06 Oct 2015, 21:39

Re: WebView2 Control For Edge

05 Aug 2021, 09:57

I need to update my library for the beta as well. Maybe I'll do that this weekend and post an update.
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: WebView2 Control For Edge

06 Aug 2021, 03:29

Would be very great. Thanks for your work! :)
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
xroot
Posts: 40
Joined: 21 Jun 2019, 08:45

Re: WebView2 Control For Edge

06 Aug 2021, 09:12

Here is My Current WebView2 Include for Version 2.0-beta.1

Code: Select all

; Current WebView2 Include
; For Version 2.0-beta.1
On_ReSize(controller,*){
    If(wvLeft+wvTop+wvRight+wvBottom>0)
        DllCall "SetRect","ptr",RECT,"int",wvLeft,"int",wvTop,"int",wvRight,"int",wvBottom
    Else
        DllCall "GetClientRect","ptr",AHKGui.hWnd,"ptr",RECT
    NumPut "int",wvLeft,RECT
    NumPut "int",wvTop,RECT,4
    NumPut "int",NumGet(RECT,8,"int")-wvLeft,RECT,8
    NumPut "int",NumGet(RECT,12,"int")-wvTop,RECT,12
    ; IWebView2WebViewController::put_Bounds
    ComCall 6,controller,"ptr",RECT
}

QueryInterface(this,riid,ppvObject){
    ; Not used
}

AddRef(this){
    NumPut "uint",ObjAddRef(this),this,A_PtrSize
}

Release(this){
    NumPut "uint",ObjRelease(this),this,A_PtrSize
}

Invoke(this,HRESULT,iObject){
    global CoreWebView2
    Switch(this){
        Case WebView2Environment:
            ; iObject = ICoreWebView2Environment
            ; ICoreWebView2Environment::CreateCoreWebView2Controller
            ComCall 3,iObject,"ptr",AHKGui.hWnd,"ptr",WebView2Controller
        Case WebView2Controller:
            ; iObject = IWebView2WebViewController
            ObjAddRef iObject
            AHKGui.OnEvent "Size",On_ReSize.Bind(iObject)
            ; Resize Or Set WebView to fit the bounds of the parent window.
            If(wvLeft+wvTop+wvRight+wvBottom>0)
                DllCall "SetRect","ptr",RECT,"int",wvLeft,"int",wvTop,"int",wvRight,"int",wvBottom
            Else
                DllCall "GetClientRect","ptr",AHKGui.hWnd,"ptr",RECT
            ; IWebView2WebViewController::put_Bounds
            ComCall 6,iObject,"ptr",RECT
            ; IWebView2WebViewController::put_ZoomFactor
            ComCall 8,iObject,"double",ZoomFactor
            ; IWebView2WebViewController::get_CoreWebView2
            ComCall 25,iObject,"ptr*",&iCoreWebView2 := 0
            CoreWebView2 := iCoreWebView2
            ; ICoreWebView2::add_NavigationCompleted
            ComCall 15,CoreWebView2,"ptr",WebView2NavigationCompletedEventHandler,"uint64",token := 0
            ; ICoreWebView2::add_DocumentTitleChanged
            ComCall 46,CoreWebView2,"ptr",WebView2DocumentTitleChangedEventHandler,"uint64",token := 0
            If(NavUri)
                ; ICoreWebView2::Navigate
                ComCall 5,CoreWebView2,"str",NavUri
            Else If(NavStr)
                ; ICoreWebView2::NavigateToString
                ComCall 6,CoreWebView2,"str",NavStr
            If DevTool
                ; ICoreWebView2::OpenDevToolsWindow
                ComCall 51,CoreWebView2
        Case WebView2NavigationCompletedEventHandler:
            If(jsCode)
                ; ICoreWebView2::ExecuteScript
                ComCall 29,CoreWebView2,"str",jsCode,"ptr",WebView2ExecuteScriptCompletedHandler
            If(HostName){
                If(ObjGetCapacity(HostObj)){
                    objBuf      := Buffer(24,0)
                    ahkObject   := ComValue(0x400C,objBuf.ptr)    ;VT_BYREF VT_VARIANT
                    ahkObject[] := HostObj
                    ; ICoreWebView2::AddHostObjectToScript
                    ComCall 49,CoreWebView2,"str",HostName,"ptr",ahkObject
                }Else{
                    MsgBox "HostObj Not Created....","Object Error!","iconi"
                    ExitApp
                }
            }
        Case WebView2DocumentTitleChangedEventHandler:
            If(Type(Event_Name)="Func"){
                ; ICoreWebView2::get_DocumentTitle
                ComCall 48,CoreWebView2,"str*",&DocTitle := 0
                Event_Name.Call(DocTitle)
            }
    }
}

; Run jScript on the fly
Run_JS(Code){
    ; ICoreWebView2::ExecuteScript
    ComCall 29,CoreWebView2,"str",Code,"ptr",WebView2ExecuteScriptCompletedHandler
}

; Main vtable Object Setup
WebView2(){
    Static vtbl := []
    vtbl.Push Buffer(4*A_PtrSize)
    For Method In [QueryInterface,AddRef,Release,Invoke]
        NumPut "uptr",CallbackCreate(Method),vtbl[vtbl.Length],(A_Index-1)*A_PtrSize
    ptr := DllCall("GlobalAlloc","uint",64,"ptr",A_PtrSize+4,"uptr")
    NumPut "uptr",vtbl[vtbl.Length].ptr,ptr
    NumPut "uint",1,ptr,A_PtrSize
    Return ptr
}

; One Main Function For WebView2 Setup
WebView2_Init(iGui){
    global
    AHKGui                                   := iGui
    WebView2Environment                      := WebView2()     ; IWebView2CreateWebView2EnvironmentCompletedHandler.
    WebView2Controller                       := WebView2()     ; ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.
    WebView2NavigationCompletedEventHandler  := WebView2()     ; ICoreWebView2NavigationCompletedEventHandler
    WebView2ExecuteScriptCompletedHandler    := WebView2()     ; ICoreWebView2ExecuteScriptCompletedHandler
    WebView2DocumentTitleChangedEventHandler := WebView2()     ; ICoreWebView2DocumentTitleChangedEventHandler.

    local dllPath := "c:\Program Files (x86)\AutoHotKey\JMM\WebView2\x64\WebView2Loader"
    DllCall dllPath "\CreateCoreWebView2Environment","ptr",WebView2Environment

    If(A_LastError){
        local buf := Buffer(8,0)
        DllCall "FormatMessage","uint",256|4096,"ptr",0,"uint",A_LastError,"uint",0,"ptr",buf.ptr,"uint",0,"ptr",0
        msgbox "Error " A_LastError " = " StrGet(NumGet(buf,"ptr"))
        ExitApp
    }
}

; WebView2 Globals To Make AHK Gui Execute Your Code
NavUri := "",NavStr := "",RECT := Buffer(16,0),Event_Name := "",jsCode := "",HostName := "",HostObj := {}
ZoomFactor := 1.25,wvLeft := 0,wvTop := 0,wvRight := 0,wvBottom := 0,DevTool := False,AHKGui := ""
My Version for WebView2 Runtime is 92.0.902.67, MS Edge is 92.0.902.67, WebView2Loader.dll is 1.0.902.0 all 64 bit.

Try this code, it will fade Googles Logo.

Code: Select all

#include WebView2.ahk

NavUri := "https://www.google.com"

jsCode := Format("
(
    function Sleep(ms){
        return new Promise(resolve => setTimeout(resolve,ms));
    }
    (async function Run_Script(){
        // Load jQuery
        var jq = document.createElement("script");
        jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js";
        document.head.appendChild(jq);

        // Wait for jQuery to Load
        await Sleep(350);

        // Load SweetAlert
        var msg = document.createElement("script");
        msg.src = "https://unpkg.com/sweetalert/dist/sweetalert.min.js";
        document.head.appendChild(msg);

        // Wait for SweetAlert to Load
        await Sleep(350);

        var style = document.createElement("style");
        style.textContent = ".swal-title{color:yellow;}"+
                            ".swal-modal{background-color:navy;border:3px solid cyan}"+
                            ".swal-text{font-size:18px;background-color:navy;border:3px solid cyan;color:yellow;}"
        document.head.appendChild(style);

        // Show Cool MsgBox SweetAlert
        await swal("Watch Google Logo Fade Out...","jQuery Version = "+$.fn.jquery+"\nAHK Version = {}","info");
        // IF GOOGLE LOGO DOES NOT FADE, TRY OTHER FADEOUT
        //$("#hplogo").fadeOut(3000);
        $(".lnXdpd").fadeOut(3000);
    })();
)",A_AhkVersion)

win := Gui("toolwindow","WebView2 Fade Google Logo")
win.OnEvent "Close",ExitApp

WebView2_Init win

win.Show "w" A_ScreenWidth/2 " h" A_ScreenHeight/2

Esc::ExitApp
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: WebView2 Control For Edge

09 Aug 2021, 05:29

Thanks. Code now runs in beta, but i still have problems with the dll.

I changed code to

Code: Select all

local dllPath := "EmbeddedBrowserWebView.dll"
but i get the error 'Call to non existent function - CreateCoreWebView2Environment'.

Am i using the wrong dll? :think:

I downloaded https://developer.microsoft.com/en-us/microsoft-edge/webview2/ + extracted it + found only 'EmbeddedBrowserWebView.dll'. Where do i find the 'WebView2Loader.dll'?
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
User avatar
Taurus
Posts: 94
Joined: 20 Jan 2015, 10:31

Re: WebView2 Control For Edge

09 Aug 2021, 09:12

Ok, downloaded package + extracted runtimes\native\WebView2Loader.dll.

Now i get Error 203 - Missing Environment option. Any idea?
:beard: Full Stack Developer > Dev for a better world | PHP for Web | AHK H for Local | with KISS (Keep IT Short and Simple) on Win 10 Pro (Version 2004) x64
neogna2
Posts: 586
Joined: 15 Sep 2016, 15:44

Re: WebView2 Control For Edge

10 Aug 2021, 06:42

xroot wrote:
06 Aug 2021, 09:12
Here is My Current WebView2 Include for Version 2.0-beta.1
Thank you xroot for the update.

It works also with your previous drag examples if we change the line WebView2_Init to WebView2_Init win

It is worth noting that your WebView2.ahk hardcodes this path
local dllPath := "c:\Program Files (x86)\AutoHotKey\JMM\WebView2\x64\WebView2Loader"
To instead use a copy of the .dll dependency placed in the script's folder we can change the line to
local dllPath := A_ScriptDir "\WebView2Loader"
xroot wrote:
06 Aug 2021, 09:12
Try this code, it will fade Googles Logo.
For me it shows a big consent popup from Google, probably due to some Edge cookie settings? To instead fade Wikipedia's logo I changed
NavUri := "https://www.google.com" to NavUri := "https://www.wikipedia.com" and
$(".lnXdpd").fadeOut(3000); to $(".central-featured-logo").fadeOut(3000);

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: IfThenElse and 21 guests