Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 54 additions & 44 deletions WindowSpy.ahk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;
;
; Window Spy for AHKv2
;

Expand All @@ -15,16 +15,16 @@ 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.SetFont('s9', "Segoe UI")

oGui.Add("Text",,"Window Title, Class and Process:")
oGui.Add("Checkbox","yp xp+200 w120 Right vCtrl_FollowMouse","Follow Mouse").Value := 1
oGui.Add("Edit","xm w320 r5 ReadOnly -Wrap vCtrl_Title")
Expand All @@ -36,34 +36,36 @@ WinSpyGui() {
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("Checkbox","vCtrl_IsSlowTitle","Slow TitleMatchMode")
oGui.Add("Checkbox","yp xp+180 vCtrl_IsSlowWindow","Slow WindowRefresh")
oGui.Add("Text","xm","Visible Text:")
oGui.Add("Edit","w320 r2 ReadOnly vCtrl_VisText")
oGui.Add("Text",,"All Text:")
oGui.Add("Edit","w320 r2 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.wndSpeedLast := 1
oGui.txtNotFrozen := txtNotFrozen ; create properties for futur use
oGui.txtFrozen := "(Updates suspended)"
oGui.txtMouseCtrl := "Control Under Mouse Position"
oGui.txtFocusCtrl := txtFocusCtrl
SetTimer Update, 250

SetTimer Update, oGui["Ctrl_IsSlowWindow"].Value?250:1
}

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

SetTimer Update, (MinMax=0)?oGui["Ctrl_IsSlowWindow"].Value?250:1: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, ","
Expand All @@ -80,15 +82,15 @@ Update() { ; timer, no params

TryUpdate() {
Global oGui

If !oGui.HasProp("txtNotFrozen") ; WinSpyGui() not done yet, return until it is
return

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?
Expand All @@ -98,74 +100,74 @@ TryUpdate() {
}
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()

WinDataText := t1 "`n" ; ZZZ
. "ahk_class " t2 "`n"
. "ahk_exe " t3 "`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")
mClr := SubStr(mClr, 3)

mpText := "Screen:`t" msX ", " msY "`n"
. "Window:`t" mrX ", " mrY "`n"
. "Client:`t" mcX ", " mcY " (default)`n"
. "Color:`t" mClr " (Red=" SubStr(mClr, 1, 2) " Green=" SubStr(mClr, 3, 2) " Blue=" SubStr(mClr, 5) ")"

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
} 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
bSlow := oGui["Ctrl_IsSlowTitle"].Value ; GuiControlGet, bSlow,, Ctrl_IsSlowTitle

if (bSlow) {
DetectHiddenText False
ovVisText := WinGetText() ; WinGetText, ovVisText
Expand All @@ -175,32 +177,40 @@ TryUpdate() {
ovVisText := WinGetTextFast(false)
ovAllText := WinGetTextFast(true)
}

UpdateText("Ctrl_VisText", ovVisText)
UpdateText("Ctrl_AllText", ovAllText)

wSlow := oGui["Ctrl_IsSlowWindow"].Value ; GuiControlGet, wSlow,, Ctrl_IsSlowWindow
if (wSlow != oGui.wndSpeedLast)
{
oGui.wndSpeedLast := wSlow
if (!GetKeyState("Shift") && !GetKeyState("Ctrl"))
SetTimer Update, wSlow?250:1
}
}

; ===========================================================================================
; 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) {
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
Expand All @@ -215,7 +225,7 @@ 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
Expand Down Expand Up @@ -243,4 +253,4 @@ suspend_timer() {
~*Ctrl::suspend_timer()

~*Ctrl up::
~*Shift up::SetTimer Update, 250
~*Shift up::SetTimer Update, oGui["Ctrl_IsSlowWindow"].Value?250:1