Skip to content

Commit

Permalink
Merge pull request #9 from TheArkive/AutoHotkey-Release
Browse files Browse the repository at this point in the history
  • Loading branch information
Lexikos committed Jun 8, 2022
2 parents 67eafc7 + 286dc98 commit fcc640f
Showing 1 changed file with 239 additions and 0 deletions.
239 changes: 239 additions & 0 deletions installer/source/WindowSpy.v2.ahk
@@ -0,0 +1,239 @@
;
; Window Spy for AHKv2
;

#NoTrayIcon
#SingleInstance Ignore
SetWorkingDir A_ScriptDir
CoordMode "Pixel", "Screen"

Global oGui

WinSpyGui()

WinSpyGui() {
Global oGui

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+200 w120 Right vCtrl_FollowMouse","Follow Mouse").Value := 1
oGui.Add("Edit","xm w320 r5 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 r4 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 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.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_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()

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

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

0 comments on commit fcc640f

Please sign in to comment.