Created
June 3, 2023 13:54
-
-
Save w-e-w/a7b16879754badc96044d819d9a01adb to your computer and use it in GitHub Desktop.
AutoHotkey V2 WindowSpy.ahk mod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; modify version of https://github.com/AutoHotkey/AutoHotkeyUX/blob/988fc7e6f84635dc0eb8ebee679d6766f4e25e65/WindowSpy.ahk | |
; ahk_exe as Regex escape full path | |
; id of Control Under Mouse | |
; | |
; Window Spy for AHKv2 | |
; | |
#Requires AutoHotkey v2.0 | |
#NoTrayIcon | |
#SingleInstance Ignore | |
SetWorkingDir A_ScriptDir | |
CoordMode "Pixel", "Screen" | |
Global oGui | |
WinSpyGui() | |
WinSpyGui() { | |
Global oGui | |
try TraySetIcon "inc\spy.ico" | |
DllCall("shell32\SetCurrentProcessExplicitAppUserModelID", "wstr", "AutoHotkey.WindowSpy") | |
oGui := Gui("AlwaysOnTop Resize MinSize +DPIScale","Window Spy for AHKv2") | |
oGui.OnEvent("Close",WinSpyClose) | |
oGui.OnEvent("Size",WinSpySize) | |
oGui.Add("Text",,"Window Title, Class and Process:") | |
oGui.Add("Checkbox","yp xp+175 w54 Right vCtrl_DetectHiddenWindows","Hidden").Value := 1 | |
oGui.Add("Checkbox","yp xp+53 w92 Right vCtrl_FollowMouse","Follow Mouse").Value := 1 | |
oGui.Add("Edit","xm w320 r6 ReadOnly -Wrap vCtrl_Title") | |
oGui.Add("Text",,"Mouse Position") | |
oGui.Add("Edit","w320 r4 ReadOnly vCtrl_MousePos") | |
oGui.Add("Text","w320 vCtrl_CtrlLabel",(txtFocusCtrl := "Focused Control") ":") | |
oGui.Add("Edit","w320 r5 ReadOnly vCtrl_Ctrl") | |
oGui.Add("Text",,"Active Window Postition:") | |
oGui.Add("Edit","w320 r2 ReadOnly vCtrl_Pos") | |
oGui.Add("Text",,"Status Bar Text:") | |
oGui.Add("Edit","w320 r2 ReadOnly vCtrl_SBText") | |
oGui.Add("Checkbox","vCtrl_IsSlow","Slow TitleMatchMode") | |
oGui.Add("Text",,"Visible Text:") | |
oGui.Add("Edit","w320 r5 ReadOnly vCtrl_VisText") | |
oGui.Add("Text",,"All Text:") | |
oGui.Add("Edit","w320 r5 ReadOnly vCtrl_AllText") | |
oGui.Add("Text","w320 r1 vCtrl_Freeze",(txtNotFrozen := "(Hold Ctrl or Shift to suspend updates)")) | |
oGui.Show("NoActivate") | |
WinGetClientPos(&x_temp, &y_temp2,,,"ahk_id " oGui.hwnd) | |
; oGui.horzMargin := x_temp*96//A_ScreenDPI - 320 ; now using oGui.MarginX | |
oGui.txtNotFrozen := txtNotFrozen ; create properties for futur use | |
oGui.txtFrozen := "(Updates suspended)" | |
oGui.txtMouseCtrl := "Control Under Mouse Position" | |
oGui.txtFocusCtrl := txtFocusCtrl | |
SetTimer Update, 250 | |
} | |
WinSpySize(GuiObj, MinMax, Width, Height) { | |
Global oGui | |
If !oGui.HasProp("txtNotFrozen") ; WinSpyGui() not done yet, return until it is | |
return | |
SetTimer Update, (MinMax=0)?250:0 ; suspend updates on minimize | |
ctrlW := Width - (oGui.MarginX * 2) ; ctrlW := Width - horzMargin | |
list := "Title,MousePos,Ctrl,Pos,SBText,VisText,AllText,Freeze" | |
Loop Parse list, "," | |
oGui["Ctrl_" A_LoopField].Move(,,ctrlW) | |
} | |
WinSpyClose(GuiObj) { | |
ExitApp | |
} | |
Update() { ; timer, no params | |
Try TryUpdate() ; Try | |
} | |
TryUpdate() { | |
Global oGui | |
If !oGui.HasProp("txtNotFrozen") ; WinSpyGui() not done yet, return until it is | |
return | |
Ctrl_DetectHiddenWindows := oGui["Ctrl_DetectHiddenWindows"].Value | |
If(Ctrl_DetectHiddenWindows) | |
DetectHiddenWindows True | |
Else | |
DetectHiddenWindows False | |
Ctrl_FollowMouse := oGui["Ctrl_FollowMouse"].Value | |
CoordMode "Mouse", "Screen" | |
MouseGetPos &msX, &msY, &msWin, &msCtrl, 2 ; get ClassNN and hWindow | |
actWin := WinExist("A") | |
if (Ctrl_FollowMouse) { | |
curWin := msWin, curCtrl := msCtrl | |
WinExist("ahk_id " curWin) ; updating LastWindowFound? | |
} else { | |
curWin := actWin | |
curCtrl := ControlGetFocus() ; get focused control hwnd from active win | |
} | |
curCtrlClassNN := "" | |
Try curCtrlClassNN := ControlGetClassNN(curCtrl) | |
t1 := WinGetTitle(), t2 := WinGetClass() | |
if (curWin = oGui.hwnd || t2 = "MultitaskingViewFrame") { ; Our Gui || Alt-tab | |
UpdateText("Ctrl_Freeze", oGui.txtFrozen) | |
return | |
} | |
UpdateText("Ctrl_Freeze", oGui.txtNotFrozen) | |
t3 := WinGetProcessName(), t4 := WinGetPID(), t3_1 := WinGetProcessPath() | |
t3_2 := RegExReplace(t3_1, "([\^$.+()[\]{}\\])", "\$1") | |
WinDataText := t1 "`n" ; ZZZ | |
. "ahk_class " t2 "`n" | |
. "ahk_exe " t3 "`n" | |
. "ahk_exe " t3_2 "`n" | |
. "ahk_pid " t4 "`n" | |
. "ahk_id " curWin | |
UpdateText("Ctrl_Title", WinDataText) | |
CoordMode "Mouse", "Window" | |
MouseGetPos &mrX, &mrY | |
CoordMode "Mouse", "Client" | |
MouseGetPos &mcX, &mcY | |
mClr := PixelGetColor(msX,msY,"RGB") | |
mpText := "Screen:`t" msX ", " msY "`n" | |
. "Window:`t" mrX ", " mrY "`n" | |
. "Client:`t" mcX ", " mcY "`t(default)`n" | |
. "Color:`t" Format("0x{:x}", mClr) "`t(r:" SubStr(mClr, 3, 2) " g:" SubStr(mClr, 5, 2) " b:" SubStr(mClr, 7) ")" | |
UpdateText("Ctrl_MousePos", mpText) | |
UpdateText("Ctrl_CtrlLabel", (Ctrl_FollowMouse ? oGui.txtMouseCtrl : oGui.txtFocusCtrl) ":") | |
if (curCtrl) { | |
ctrlTxt := ControlGetText(curCtrl) | |
WinGetClientPos(&sX, &sY, &sW, &sH, curCtrl) | |
ControlGetPos &cX, &cY, &cW, &cH, curCtrl | |
cText := "ClassNN:`t" curCtrlClassNN "`n" | |
. "Text:`t" textMangle(ctrlTxt) "`n" | |
. "Screen:`tx: " sX "`ty: " sY "`tw: " sW "`th: " sH "`n" | |
. "Client`tx: " cX "`ty: " cY "`tw: " cW "`th: " cH "`n" | |
. "id:`t" curCtrl | |
} else | |
cText := "" | |
UpdateText("Ctrl_Ctrl", cText) | |
wX := "", wY := "", wW := "", wH := "" | |
WinGetPos &wX, &wY, &wW, &wH, "ahk_id " curWin | |
WinGetClientPos(&wcX, &wcY, &wcW, &wcH, "ahk_id " curWin) | |
wText := "Screen:`tx: " wX "`ty: " wY "`tw: " wW "`th: " wH "`n" | |
. "Client:`tx: " wcX "`ty: " wcY "`tw: " wcW "`th: " wcH | |
UpdateText("Ctrl_Pos", wText) | |
sbTxt := "" | |
Loop { | |
ovi := "" | |
Try ovi := StatusBarGetText(A_Index) | |
if (ovi = "") | |
break | |
sbTxt .= "(" A_Index "):`t" textMangle(ovi) "`n" | |
} | |
sbTxt := SubStr(sbTxt,1,-1) ; StringTrimRight, sbTxt, sbTxt, 1 | |
UpdateText("Ctrl_SBText", sbTxt) | |
bSlow := oGui["Ctrl_IsSlow"].Value ; GuiControlGet, bSlow,, Ctrl_IsSlow | |
if (bSlow) { | |
DetectHiddenText False | |
ovVisText := WinGetText() ; WinGetText, ovVisText | |
DetectHiddenText True | |
ovAllText := WinGetText() ; WinGetText, ovAllText | |
} else { | |
ovVisText := WinGetTextFast(false) | |
ovAllText := WinGetTextFast(true) | |
} | |
UpdateText("Ctrl_VisText", ovVisText) | |
UpdateText("Ctrl_AllText", ovAllText) | |
} | |
; =========================================================================================== | |
; WinGetText ALWAYS uses the "slow" mode - TitleMatchMode only affects | |
; WinText/ExcludeText parameters. In "fast" mode, GetWindowText() is used | |
; to retrieve the text of each control. | |
; =========================================================================================== | |
WinGetTextFast(detect_hidden) { | |
controls := WinGetControlsHwnd() | |
static WINDOW_TEXT_SIZE := 32767 ; Defined in AutoHotkey source. | |
buf := Buffer(WINDOW_TEXT_SIZE * 2,0) | |
text := "" | |
Loop controls.Length { | |
hCtl := controls[A_Index] | |
if !detect_hidden && !DllCall("IsWindowVisible", "ptr", hCtl) | |
continue | |
if !DllCall("GetWindowText", "ptr", hCtl, "Ptr", buf.ptr, "int", WINDOW_TEXT_SIZE) | |
continue | |
text .= StrGet(buf) "`r`n" ; text .= buf "`r`n" | |
} | |
return text | |
} | |
; =========================================================================================== | |
; Unlike using a pure GuiControl, this function causes the text of the | |
; controls to be updated only when the text has changed, preventing periodic | |
; flickering (especially on older systems). | |
; =========================================================================================== | |
UpdateText(vCtl, NewText) { | |
Global oGui | |
static OldText := {} | |
ctl := oGui[vCtl], hCtl := Integer(ctl.hwnd) | |
if (!oldText.HasProp(hCtl) Or OldText.%hCtl% != NewText) { | |
ctl.Value := NewText | |
OldText.%hCtl% := NewText | |
} | |
} | |
textMangle(x) { | |
elli := false | |
if (pos := InStr(x, "`n")) | |
x := SubStr(x, 1, pos-1), elli := true | |
else if (StrLen(x) > 40) | |
x := SubStr(x,1,40), elli := true | |
if elli | |
x .= " (...)" | |
return x | |
} | |
suspend_timer() { | |
Global oGui | |
SetTimer Update, 0 | |
UpdateText("Ctrl_Freeze", oGui.txtFrozen) | |
} | |
~*Shift:: | |
~*Ctrl::suspend_timer() | |
~*Ctrl up:: | |
~*Shift up::SetTimer Update, 250 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment