If this can help, here is my full script for getting the URL and getting the web page title. Most of the code for getting the URL comes from this thread but code formatting and variables naming were adapted to my own style.
Tested with IE 11, Chrome and Firefox 57 and Edge 40. Alt-Q to test it.
Code: Select all
#SingleInstance force ; Skips the dialog box and replaces the old instance automatically
g_strModernBrowsers := "ApplicationFrameWindow,Chrome_WidgetWin_0,Chrome_WidgetWin_1,Maxthon3Cls_MainFrm,Slimjet_WidgetWin_1,MozillaWindowClass"
g_strLegacyBrowsers := "IEFrame,OperaWindowClass"
;------------------------------------------------------------
!q::
;------------------------------------------------------------
strURL := ""
WinGetClass, strClass, A
if InStr(g_strModernBrowsers, strClass)
strURL := GetCurrentUrlAcc(strClass)
else if InStr(g_strLegacyBrowsers, strClass)
strURL := GetCurrentUrlDDE(strClass) ; empty string if DDE not supported (or not a browser)
if StrLen(strURL)
MsgBox, % "Class: " . strClass
. "`nURL: " . strURL
. "`nTitle: " . GetWebPageTitle(strURL)
else
MsgBox, Current window is not a browser
return
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlDDE(strClass)
; "GetCurrentUrlDDE" adapted from DDE code by Sean, (AHK_L version by maraskan_user) (via Joe Glines)
; Found at http://autohotkey.com/board/topic/17633-/?p=434518
;------------------------------------------------------------
{
WinGet, strServer, ProcessName, % "ahk_class " . strClass
StringTrimRight, strServer, strServer, 4
intCodePage := (A_IsUnicode ? 0x04B0 : 0x03EC) ; 0x04B0 = CP_WINUNICODE, 0x03EC = CP_WINANSI
DllCall("DdeInitialize", "UPtrP", idInst, "Uint", 0, "Uint", 0, "Uint", 0)
hServer := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", strServer, "int", intCodePage)
hTopic := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "WWW_GetWindowInfo", "int", intCodePage)
hItem := DllCall("DdeCreateStringHandle", "UPtr", idInst, "Str", "0xFFFFFFFF", "int", intCodePage)
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")
StringSplit, strWindowInfo, csvWindowInfo, `" ;"; comment to avoid a syntax highlighting issue in autohotkey.com/boards
Return strWindowInfo2
}
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlAcc(strClass)
; Found at https://autohotkey.com/boards/viewtopic.php?f=6&t=3702&start=60
;------------------------------------------------------------
{
; static or global?
global nWindow
global accAddressBar
If (nWindow != WinExist("ahk_class " strClass)) ; reuses accAddressBar if it's the same window
{
nWindow := WinExist("ahk_class " strClass)
accAddressBar := GetAddressBar(GetCurrentUrlAccObjectFromWindow(nWindow))
}
Try sURL := accAddressBar.accValue(0)
If (sURL == "")
{
WinGet, nWindows, List, % "ahk_class " strClass ; In case of a nested browser window as in the old CoolNovo (TO DO: check if still needed)
If (nWindows > 1)
{
accAddressBar := GetAddressBar(GetCurrentUrlAccObjectFromWindow(nWindows2))
Try sURL := accAddressBar.accValue(0)
}
}
If ((sURL != "") and (SubStr(sURL, 1, 4) != "http")) ; Modern browsers omit "http://"
sURL := "http://" . sURL
If (sURL == "")
nWindow := -1 ; Don't remember the window if there is no URL
Return sURL
}
;------------------------------------------------------------
;------------------------------------------------------------
GetAddressBar(accObj, accPath:="")
; "GetAddressBar" based in code by stealzy
; Found at https://autohotkey.com/boards/viewtopic.php?p=109548#p109548
; IsUrl in this functions above replaced by my own code LocationIsHttp
;------------------------------------------------------------
{
n := 0
Try If ((accObj.accRole(0) == 42) and StrLen(accObj.accValue(0)) and LocationIsHttp(accObj.accValue(0)))
Return accObj
Try If ((accObj.accRole(0) == 42) and StrLen(accObj.accValue(0)) and LocationIsHttp("http://" . accObj.accValue(0))) ; Modern browsers omit "http://"
Return accObj
For nChild, accChild in GetCurrentUrlAccChildren(accObj)
{
n++
currentPath := accPath . n . "."
If IsObject(accAddressBar := GetAddressBar(accChild, currentPath))
Return accAddressBar
}
}
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlAccInit()
; Part of the Acc.ahk Standard Library by Sean (updated by jethrow) (via Joe Glines)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
;------------------------------------------------------------
{
static h
If Not h
h := DllCall("LoadLibrary", "Str", "oleacc", "Ptr")
}
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlAccObjectFromWindow(hWnd, idObject = 0)
; Part of the Acc.ahk Standard Library by Sean (updated by jethrow) (via Joe Glines)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
;------------------------------------------------------------
{
GetCurrentUrlAccInit()
If DllCall("oleacc\AccessibleObjectFromWindow", "Ptr", hWnd, "UInt", idObject&=0xFFFFFFFF, "Ptr"
, -VarSetCapacity(IID, 16) + NumPut(idObject == 0xFFFFFFF0 ? 0x46000000000000C0 : 0x719B3800AA000C81
, NumPut(idObject == 0xFFFFFFF0 ? 0x0000000000020400 : 0x11CF3C3D618736E0, IID, "Int64"), "Int64"), "Ptr*", pacc) = 0
Return ComObjEnwrap(9, pacc, 1)
}
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlAccQuery(objAcc)
; Part of the Acc.ahk Standard Library by Sean (updated by jethrow) (via Joe Glines)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
;------------------------------------------------------------
{
Try Return ComObj(9, ComObjQuery(objAcc, "{618736e0-3c3d-11cf-810c-00aa00389b71}"), 1)
}
;------------------------------------------------------------
;------------------------------------------------------------
GetCurrentUrlAccChildren(objAcc)
; Part of the Acc.ahk Standard Library by Sean (updated by jethrow) (via Joe Glines)
; Found at http://autohotkey.com/board/topic/77303-/?p=491516
;------------------------------------------------------------
{
If ComObjType(objAcc,"Name") != "IAccessible"
ErrorLevel := "Invalid IAccessible Object"
Else
{
GetCurrentUrlAccInit()
cChildren := objAcc.accChildCount
Children := []
If DllCall("oleacc\AccessibleChildren", "Ptr", ComObjValue(objAcc), "Int", 0, "Int", cChildren, "Ptr"
, VarSetCapacity(varChildren, cChildren * (8 + 2 * A_PtrSize), 0) * 0 + &varChildren, "Int*", cChildren) = 0
{
Loop, %cChildren%
{
i := (A_Index - 1) * (A_PtrSize * 2 + 8) + 8
child := NumGet(varChildren, i)
Children.Insert(NumGet(varChildren, i - 8) = 9 ? GetCurrentUrlAccQuery(child) : child)
(NumGet(varChildren, i - 8) = 9 ? ObjRelease(child) : "")
}
Return (Children.MaxIndex() ? Children : "")
}
Else
ErrorLevel := "AccessibleChildren DllCall Failed"
}
}
;------------------------------------------------------------
;------------------------------------------------------------
LocationIsHTTP(strLocation)
;------------------------------------------------------------
{
return SubStr(strLocation, 1, 7) = "http://" or SubStr(strLocation, 1, 8) = "https://"
}
;------------------------------------------------------------
;------------------------------------------------------------
GetWebPageTitle(strLocation)
;------------------------------------------------------------
{
ToolTip, %lToolTipRetrievingWebPageTitle%
strHTML := Url2Var(strLocation)
ToolTip
RegExMatch(strHTML, "is)<title>(.*?)</title>", strTitle)
StringReplace, strTitle, strTitle, <title>
StringReplace, strTitle, strTitle, </title>
StringReplace, strTitle, strTitle, `r, , A
StringReplace, strTitle, strTitle, `t, %A_Space%, A
StringReplace, strTitle, strTitle, `n, %A_Space%, A
return NumDecode(Trim(strTitle, Chr(160))) ; Chr(160) to also trim non-breaking spaces
}
;------------------------------------------------------------
;------------------------------------------------------------
Url2Var(strUrl)
;------------------------------------------------------------
{
objWebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
/*
if (A_LastError)
; an error occurred during ComObjCreate (A_LastError probably is E_UNEXPECTED = -2147418113 #0x8000FFFFL)
BUT DO NOT ABORT because the following commands will be executed even if an error occurred in ComObjCreate (!)
*/
objWebRequest.Open("GET", strUrl)
objWebRequest.Send()
return (objWebRequest.StatusText() = "OK" ? objWebRequest.ResponseText() : "")
}
;------------------------------------------------------------
;------------------------------------------------------------
NumDecode(str)
; Extracted from Dec_XML() https://autohotkey.com/board/topic/29866-encoding-and-decoding-functions-v11/
; converts "é" or "é" to "é"
;------------------------------------------------------------
{
Loop
If RegexMatch(str, "S)(&#(\d+);)", dec) ; matches: &#[dec];
StringReplace, str, str, %dec1%, % Chr(dec2), All
Else If RegexMatch(str, "Si)(&#x([\da-f]+);)", hex) ; matches: &#x[hex];
StringReplace, str, str, %hex1%, % Chr("0x" . hex2), All
Else
Break
return str
}
;------------------------------------------------------------