sometimes matches some kind of empty-titled window which gives an incorrect UIAutomation element. After changing all instances of
I've also written a method for AHK v2 using the UIA-v2 library if anyone is interested. Also gets the Chrome URL if Chrome window isn't active or is behind other windows.
Code: Select all
#include UIA.ahk
global HotstringAllSelected := 0
~^a::global HotstringAllSelected := 1
~Left::
~Right::
~Up::
~Down::
~Tab::
~LButton::global HotstringAllSelected := 0
~Backspace::
{
if (HotstringAllSelected)
Hotstring("Reset")
}
~^v::Hotstring("Reset")
#HotIf IsPageActive("chat.openai.com")
::rew::Rewrite this in the style of
#HotIf IsPageActive("instagram.com")
::sth::Something else
IsPageActive(url, WinTitle:="Google Chrome ahk_exe chrome.exe") {
static lastTitle := "", lastUrl := ""
if !WinActive(WinTitle)
return 0
currentTitle := WinGetTitle(WinTitle)
if (!lastTitle || currentTitle != lastTitle) {
lastUrl := ChromeGetURL(WinTitle), lastTitle := currentTitle
}
if (lastUrl == "")
return 0
return InStr(lastUrl, url)
}
ChromeGetURL(WinTitle := "Google Chrome ahk_exe chrome.exe") {
static cache := Map()
if !(hWnd := WinExist(WinTitle))
throw TargetError("No matching Chrome window found", -1)
if !(chWnd := ActivateChromiumAccessibility(WinTitle))
throw TargetError("Unable to find Chrome content element!", -1)
if !cache.Has(chWnd) {
try cache[chWnd] := UIA.ElementFromHandle(chWnd)
catch
throw TargetError("Failed to get the document element", -1)
for k in [cache*]
if !WinExist(k)
cache.Delete(k)
}
try return cache[chWnd].Value
}
ActivateChromiumAccessibility(WinTitle := "Google Chrome ahk_exe chrome.exe") {
static SWP_NOREDRAW := 0x0008, SWP_NOSIZE := 0x0001, SWP_NOMOVE := 0x0002, SWP_NOACTIVATE := 0x0010
hWnd := IsInteger(WinTitle) ? WinTitle : WinExist(WinTitle)
if !IsWindowVisible() || !(cHwnd := TryGetChromiumHwnd()) {
list := WinGetList(), index := 0
for i, win in list
if win = hWnd {
index := i
break
}
active := WinExist("A")
tp := WinGetTransparent(hWnd)
prevDelay := A_WinDelay
SetWinDelay -1
WinSetTransparent(0, hWnd)
; Bring to front
DllCall("SetWindowPos", "ptr", hWnd, "ptr", 0, "int", 0, "int", 0, "int", 0, "int", 0, "int", SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW)
WinActivate(hWnd)
WinActivate(active)
end := A_TickCount + 100
while (A_TickCount < end && !(cHwnd := TryGetChromiumHwnd()))
Sleep -1
if index > 1
DllCall("SetWindowPos", "ptr", hWnd, "ptr", list[index-1], "int", 0, "int", 0, "int", 0, "int", 0, "int", SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW | SWP_NOACTIVATE)
WinSetTransparent(tp, hWnd)
SetWinDelay prevDelay
}
return chWnd
TryGetChromiumHwnd() {
try return ControlGetHwnd("Chrome_RenderWidgetHostHWND1", hWnd)
return 0
}
IsWindowVisible() {
WinGetPosEx(hWnd, &x, &y, &w, &h)
l := Max(0, x), t := Max(0, y), r := Min(x+w-1, A_ScreenWidth), b := Min(y+h-1, A_ScreenHeight)
if !(hWnd = UIA.WindowFromPoint(l, t) || hWnd = UIA.WindowFromPoint(r, t) || hWnd = UIA.WindowFromPoint(l, b) || hWnd = UIA.WindowFromPoint(r, b))
return 0
return 1
}
; https://www.autohotkey.com/boards/viewtopic.php?t=114183&p=508461
WinGetPosEx(hWindow, &X := "", &Y := "", &W := "", &H := "") {
static S_OK := 0x0, DWMWA_EXTENDED_FRAME_BOUNDS := 9
RECTPlus := Buffer(24,0)
try {
DWMRC := DllCall("dwmapi\DwmGetWindowAttribute",
"Ptr", hWindow, ;-- hwnd
"UInt", DWMWA_EXTENDED_FRAME_BOUNDS, ;-- dwAttribute
"Ptr", RECTPlus, ;-- pvAttribute
"UInt", 16, ;-- cbAttribute
"UInt")
} catch
return False
X := NumGet(RECTPlus, 0, "Int"), Y := NumGet(RECTPlus, 4, "Int")
, R := NumGet(RECTPlus, 8, "Int"), B := NumGet(RECTPlus, 12, "Int")
, W := R - X, H := B - Y
}
}