原先的方法是用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]
}