zoukankan      html  css  js  c++  java
  • AutoHotkey 使用UI Automation 获取Chrome的当前网址

    原先的方法是用MSAA,是比较老的技术,获取速度也比较慢。

    最近初步学习了 UIA(AutoHotkey 使用 UI Automation(UIA) 获取相关信息简易教程-20210210),发现很强大,于是更新了调用函数,速度很快。

    需要传入 Chrome_RenderWidgetHostHWND1 控件的 id

    用AutoHotkey V1 试了有问题,待修复

    ;示例 getValue(ControlGetHwnd("Chrome_RenderWidgetHostHWND1", "ahk_class Chrome_WidgetWin_1"))
    getValue(hCtl) {
        uia := ComObjCreate("{ff48dba4-60ef-4201-aa87-54103eef594e}", "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
        ;获取 AutomationElement
        dllcall(numget(numget(uia,0,"ptr") + 6*A_PtrSize, 0, "ptr"), "ptr",uia, "ptr",hCtl, "ptr*",ae)
        ;创建 variant 变量
        VarSetCapacity(var, 8 + 2*A_PtrSize)
        numput(0, var, 0, "short")
        numput(0, var, 8, "ptr")
        ;获取 Value
        dllcall(numget(numget(ae,0,"ptr") + 10*A_PtrSize, 0, "ptr"), "ptr",ae, "int",30045, "ptr",&var)
        return strget(numget(var, 8, "ptr"), "utf-16")
    }

    以下是旧内容,可以忽略,备查。

    网上大部分都是模拟手工操作(激活地址栏并复制)的方式获取,从论坛里找到了纯命令的方式,并已转成AutoHotkey v2版本。

    是通过浏览器的class类来获取的,相信用AutoHotkey的人对此不陌生

    来源:https://www.autohotkey.com/boards/viewtopic.php?f=6&t=3702

    hyf_getUrlFromBrowser(cls:="Chrome_WidgetWin_1")
    {
        reg := "i)^(Chrome_WidgetWin_1|ApplicationFrameWindow|Chrome_WidgetWin_0|Maxthon3Cls_MainFrm|MozillaWindowClass|Slimjet_WidgetWin_1)$"
        if (cls ~= reg)
            return hyf_getUrlByACC(cls)
        else
            return hyf_getUrlByDDE(cls)
        { ;通过Surfingkeys获取网址,通过剪切板传输
            clipboard := ""
            send("{alt down}c{alt up}")
            ClipWait(1)
            u := clipboard
        }
        return u
    }
    
    ; https://www.autohotkey.com/boards/viewtopic.php?f=6&t=3702
    hyf_getUrlByACC(cls:="Chrome_WidgetWin_1")
    {
        accAddressBar := GetAddressBar(Acc_ObjectFromWindow(WinGetID("ahk_class " . cls), 0))
        Try
            sURL := accAddressBar.accValue(0)
        If !strlen(sURL) ;Chrome可能用不到
        {
            arrWin := WinGetList("ahk_class " . cls) ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
            If (arrWin.length() > 1)
            {
                accAddressBar := GetAddressBar(Acc_ObjectFromWindow(arrWin[2], 0))
                Try
                    sURL := accAddressBar.accValue(0)
            }
        }
        If ((sURL != "") && (substr(sURL,1,4) != "http")) ; Modern browsers omit "http://"
            sURL := "http://" . sURL
        Return sURL
        GetAddressBar(accObj)
        {
            if !IsObject(accObj)
                return
            If (accObj.accRole(0) = 42)
            {
                if (accObj.accValue(0).isUrl() || ("http://" . accObj.accValue(0)).isUrl())
                    Return accObj
            }
            else
            {
                Try
                {
                    For _, accChild in Acc_Children(accObj)
                    {
                        accAddressBar := func(A_ThisFunc).call(accChild)
                        If IsObject(accAddressBar)
                            Return accAddressBar
                    }
                }
            }
        }
    }
    
    hyf_getUrlByDDE(cls) {
        sServer := WinGetProcessName("ahk_class " . cls)
        sSearch := substr(sSearch, 1, strlen(sSearch)-4)
        iCodePage := 0x04B0 ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
        dllcall("DdeInitialize", "uptrp",idInst, "uint",0, "uint",0, "uint",0)
        hServer := dllcall("DdeCreateStringHandle", "uptr",idInst, "str",sServer, "int",iCodePage)
        hTopic := dllcall("DdeCreateStringHandle", "uptr",idInst, "str","WWW_GetWindowInfo", "int",iCodePage)
        hItem := dllcall("DdeCreateStringHandle", "uptr",idInst, "str","0xFFFFFFFF", "int",iCodePage)
        hConv := dllcall("DdeConnect", "uptr",idInst, "uptr",hServer, "uptr",hTopic, "uint",0)
        hData := dllcall("DdeClientTransaction", "uint",0, "uint",0, "uptr",hConv, "uptr",hItem, "uint",1, "uint",0x20B0, "uint",10000, "UPtrP",nResult) ; 0x20B0 = XTYP_REQUEST, 10000 = 10s timeout
        sData := dllcall("DdeAccessData", "uint",hData, "uint",0, "str")
        dllcall("DdeFreeStringHandle", "uptr",idInst, "uptr",hServer)
        dllcall("DdeFreeStringHandle", "uptr",idInst, "uptr",hTopic)
        dllcall("DdeFreeStringHandle", "uptr",idInst, "uptr",hItem)
        dllcall("DdeUnaccessData", "uptr",hData)
        dllcall("DdeFreeDataHandle", "uptr",hData)
        dllcall("DdeDisconnect", "uptr",hConv)
        dllcall("DdeUninitialize", "uptr",idInst)
        csvWindowInfo := StrGet(&sData, "CP0")
        return StrSplit(csvWindowInfo, '"')[2]
    }
    

      

  • 相关阅读:
    Java ,python面向对象的继承及其区别
    谈谈我理解的敏捷开发
    Centos7 升级python3,解决升级后不兼容问题
    Django + Uwsgi + Nginx 的生产环境部署
    理解Python协程:从yield/send到yield from再到async/await
    【转】Python 数据库连接池
    为何GET只发一次TCP连接,POST发两次TCP连接
    Python简单密码加密程序,加盐(salt)md5
    spring学习(三) ———— spring事务操作
    spring学习(二) ———— AOP之AspectJ框架的使用
  • 原文地址:https://www.cnblogs.com/hyaray/p/11212846.html
Copyright © 2011-2022 走看看