Following the 1.1.27.00 update of AHK, there was a script released with the installation of AHK, said file is called WindowSpy.ahk.
This script is already quite useful being taken from the compiled version of AU3 Spy, but I've decided to take the liberty to add on to it and even change a few minor things around.
I shall of course be adding new features into the future as for I am lazy and really like working with AHK
DISCLAIMER
First; Here's my code:
I did NOT write the whole script, credit is where it is due, I do not know the original author. I made this for a bit more of a helper and add on to the already existing script, if you do not know of this script, I suggest to look into it here.
CODE
It's pretty huge, I know. But here's some changes that I put into it:Code: Select all
#NoEnv
#NoTrayIcon
#SingleInstance Ignore
#Persistent
Process, Priority,, H
SetWorkingDir, %A_ScriptDir%
SetBatchLines, -1
CoordMode, Pixel, Screen
txtNotFrozen := "(Hold Ctrl or Shift to suspend updates)"
txtFrozen := "(Updates suspended)"
txtMouseCtrl := "Control Under Mouse Position"
txtFocusCtrl := "Focused Control"
Menu, Options, Add, Change Update Speed`tCtrl+S, UPS
Menu, Options, Add, Push Info to Notepad`tCtrl+Shift+C, Copy
Menu, Options, Add
Menu, Options, Add, Change Transparency, Trans
Menu, Gui, Add, Options, :Options
Menu, Tray, Icon, % "C:\Windows\System32\shell32.dll", 23
Gui, 1:New, hwndhGui +AlwaysOnTop MinSize -MinimizeBox, Window Spy
Gui, 1:Menu, Gui
Gui, 1:Add, Text, x5 y5 w270 h15, Window Title and Process Information:
Gui, 1:Add, Checkbox, x275 y0 w85 h25 vCtrl_FollowMouse gSwitch Right Checked, Follow Mouse
Gui, 1:Add, Edit, x5 y25 w355 h47 vCtrl_Title r3 ReadOnly -Wrap
Gui, 1:Add, Text, x5 y75 w270 h15, Mouse Position:
Gui, 1:Add, Edit, x5 y95 w280 h60 vCtrl_MousePos r4 ReadOnly
Gui, 1:Add, Text, x5 y160 w270 h15 vCtrl_CtrlLabel, % txtFocusCtrl ":"
Gui, 1:Add, Edit, x5 y180 w355 h60 vCtrl_Ctrl r4 ReadOnly
Gui, 1:Add, Progress, x290 y90 w70 h70 vProg +Border, 100
Gui, 1:Add, Text, x5 y245 w270 h15, Active Window Position:
Gui, 1:Add, Edit, x5 y265 w355 h34 vCtrl_Pos r2 ReadOnly
Gui, 1:Add, Text, x5 y305 w270 h15, Status Bar Text:
Gui, 1:Add, Edit, x5 y325 w355 h34 vCtrl_SBText r2 ReadOnly
Gui, 1:Add, Checkbox, x5 y365 w180 h15 vCtrl_IsSlow, Slow TitleMatchMode
Gui, 1:Add, Text, x5 y385 w270 h15, Visible Text:
Gui, 1:Add, Edit, x5 y405 w355 h34 vCtrl_VisText r2 ReadOnly
Gui, 1:Add, Text, x5 y445 w270 h15, All Text:
Gui, 1:Add, Edit, x5 y460 w355 h34 vCtrl_AllText r2 ReadOnly
Gui, 1:Add, Text, x5 y500 w175 h15 vCtrl_Freeze r1, % txtNotFrozen
Gui, 1:Show, x120 y120 w365 h525 NA
HorzMargin := (GetClientSize(hGui).W * 96) // (A_ScreenDPI - 320)
SetTimer("Update", 25)
OnExit, Exit
Return
/*
------------------------------------------------
Gui Actions
------------------------------------------------
*/
GuiSize:
SetTimer("Update", (A_EventInfo == 1) ? "Off" : "On") ; Suspend on minimize
Return
Exit:
GuiClose:
FileObj := FileOpen(A_Desktop "\Log.txt", "w")
Str := Format("{}/{}/{} - {}:{}", A_DD, A_MM, A_YYYY, A_Hour, A_Min)
FileObj.WriteLine("-- [" Str "] ===========================================")
For Each, Item in StrSplit("Ctrl_Title|Ctrl_MousePos|Ctrl_CtrlLabel|Ctrl_Ctrl|Ctrl_Pos|Ctrl_SBText|Ctrl_VisText|Ctrl_AllText", "|")
FileObj.WriteLine(%Item%) ; Put percent signs instead of the variable itself to allow sending the variable's contents instead of the variable's name.
FileObj.Close()
OnExit
ExitApp
/*
------------------------------------------------
Menu Actions
------------------------------------------------
*/
Copy:
Gui, 1:Submit, NoHide
Clipboard := ""
For Each, Item in StrSplit("Ctrl_Title|Ctrl_MousePos|Ctrl_CtrlLabel|Ctrl_Ctrl|Ctrl_Pos|Ctrl_SBText|Ctrl_VisText|Ctrl_AllText", "|")
Clipboard .= StrReplace(StrReplace(%Item% "`n", "`n", "`r`n"), "`r`n`r`n", "`r`n")
Run, notepad.exe
WinWaitActive, Untitled - Notepad ahk_class Notepad ahk_exe notepad.exe
ControlSetText, Edit1, % Clipboard, Untitled - Notepad ahk_class Notepad ahk_exe notepad.exe
WinSetTitle, Untitled - Notepad ahk_class Notepad ahk_exe notepad.exe
,, Log.txt - Notepad
Return
UPS:
CoordMode, Pixel, Screen
WinGetPos, X, Y, Width, Height, % "ahk_id " hGui
Gui, 1:+OwnDialogs
Gui, 2:New, +ToolWindow +Owner1 +HWNDhGui2, Update Speed
Gui, 2:Add, Text, x5 y5 w270 h15, Update Speed:
Gui, 2:Add, Slider, x5 y30 w355 h23 vSpeed gSpeed +Range25-1200 +AltSubmit, 250
Gui, 2:Add, Edit, x275 y5 w85 h21 vSpeed_Edit gSpeed Number +Range25-1200, 250
Gui, 2:Add, UpDown, +Range25-1200 +0x80 +0x100 +0x20, 10
Gui, 2:Add, Button, x285 y60 w75 h23 gClose2, Close
Gui, 2:Show, % "x" X " y" (Y + Height) " w365 h85"
Return
Close2:
Gui, 2:Destroy
Return
Speed:
Gui, Submit, NoHide
If (A_GuiControl != "Speed_Edit") {
GuiControl,, Speed_Edit, % Speed
} Else
GuiControl,, Speed, % Speed_Edit
SetTimer("Update", Speed)
Return
Switch:
GuiControl,, Ctrl_CtrlLabel, % (!Ctrl_FollowMouse ? txtMouseCtrl : txtFocusCtrl) ":"
Return
Trans:
CoordMode, Pixel, Screen
WinGetPos, X, Y, Width, Height, % "ahk_id " hGui
Gui, 3:New, +ToolWindow +Owner1 +HWNDhGui3, Transparency
Gui, 3:Add, Slider, x5 y5 w355 h30 +Range100-255 +AltSubmit gChange_Trans_S vTrans_S, 255
Gui, 3:Add, Edit, x5 y45 w75 h20 +Range100-255 +Number gChange_Trans_E vTrans_E, 255
Gui, 3:Add, UpDown, x65 y45 w16 h20 +Range100-255, 255
Gui, 3:Show, % "x" X " y" (Y + Height) " w365 h75"
Return
Change_Trans_S:
Gui, Submit, NoHide
GuiControl,, Trans_E, % Trans_S
WinSet, Trans, % Trans_S, % "ahk_id " hGui
Return
Change_Trans_E:
Gui, Submit, NoHide
GuiControl,, Trans_S, % Trans_E
WinSet, Trans, % Trans_S, % "ahk_id " hGui
Return
/*
------------------------------------------------
Timer(s)
------------------------------------------------
*/
Update:
Gui %hGui%:Default
GuiControlGet, Ctrl_FollowMouse
CoordMode, Mouse, Screen
MouseGetPos, msX, msY, msWin, msCtrl
actWin := WinExist("A")
If (Ctrl_FollowMouse) {
curWin := msWin
curCtrl := msCtrl
WinExist("ahk_id " curWin)
} Else {
curWin := actWin
ControlGetFocus, curCtrl
}
WinGetTitle, t1
WinGetClass, t2
if (curWin = hGui
|| curWin = hGui2
|| curWin = hGui3
|| t2 = "MultitaskingViewFrame") { ; Our Gui(s) || Alt-tab
GuiControlGet, Ctrl_Freeze
If (Ctrl_Freeze != txtFrozen)
GuiControl,, Ctrl_Freeze, % txtFrozen
Return
}
GuiControlGet, Ctrl_Freeze
If (Ctrl_Freeze != txtNotFrozen)
GuiControl,, Ctrl_Freeze, % txtNotFrozen
WinGet, t3, ProcessName
GuiControl,, Ctrl_Title, % t1 "`nahk_class " t2 "`nahk_exe " t3
CoordMode, Mouse, Relative
MouseGetPos, mrX, mrY
CoordMode, Mouse, Client
MouseGetPos, mcX, mcY
PixelGetColor, mClr, %msX%, %msY%, RGB
mClr := SubStr(mClr, 3)
GuiControl,, Ctrl_MousePos, % "Screen:`t" msX ", " msY " (less often used)`nWindow:`t" mrX ", " mrY " (default)`nClient:`t" mcX ", " mcY " (recommended)"
. "`nColor:`t" mClr " (Red=" SubStr(mClr, 1, 2) " Green=" SubStr(mClr, 3, 2) " Blue=" SubStr(mClr, 5) ")"
GuiControl, +c%mClr%, Prog
GuiControl,, Ctrl_CtrlLabel, % (Ctrl_FollowMouse ? txtMouseCtrl : txtFocusCtrl) ":"
If (curCtrl) {
ControlGetText, ctrlTxt, %curCtrl%
cText := "ClassNN:`t" curCtrl "`nText:`t" textMangle(ctrlTxt)
ControlGetPos cX, cY, cW, cH, %curCtrl%
cText .= "`n`tx: " cX "`ty: " cY "`tw: " cW "`th: " cH
WinToClient(curWin, cX, cY)
ControlGet, curCtrlHwnd, Hwnd,, % curCtrl
GetClientSize(curCtrlHwnd, cW, cH)
cText .= "`nClient:`tx: " cX "`ty: " cY "`tw: " cW "`th: " cH
} Else
cText := ""
GuiControl,, Ctrl_Ctrl, % cText
WinGetPos, wX, wY, wW, wH
GetClientSize(curWin, wcW, wcH)
GuiControl,, Ctrl_Pos, % "`tx: " wX "`ty: " wY "`tw: " wW "`th: " wH "`nClient:`t`t`tw: " wcW "`th: " wcH
sbTxt := ""
Loop, {
StatusBarGetText, ovi, %A_Index%
if ovi =
break
sbTxt .= "(" A_Index "):`t" textMangle(ovi) "`n"
}
StringTrimRight, sbTxt, sbTxt, 1
GuiControl,, Ctrl_SBText, % sbTxt
GuiControlGet, bSlow,, Ctrl_IsSlow
If (bSlow) {
DetectHiddenText, Off
WinGetText, ovVisText
DetectHiddenText, On
WinGetText, ovAllText
} Else {
ovVisText := WinGetTextFast(false)
ovAllText := WinGetTextFast(true)
}
GuiControl,, Ctrl_VisText, % ovVisText
GuiControl,, Ctrl_AllText, % ovAllText
Return
WinGetTextFast(detect_hidden) {
; WinGetText ALWAYS uses the "fast" mode - TitleMatchMode only affects
; WinText/ExcludeText parameters. In Slow mode, GetWindowText() is used
; to retrieve the text of each control.
WinGet controls, ControlListHwnd
static WINDOW_TEXT_SIZE := 32767 ; Defined in AutoHotkey source.
VarSetCapacity(buf, WINDOW_TEXT_SIZE * (A_IsUnicode ? 2 : 1))
text := ""
Loop Parse, controls, `n
{
if !detect_hidden && !DllCall("IsWindowVisible", "ptr", A_LoopField)
continue
if !DllCall("GetWindowText", "ptr", A_LoopField, "str", buf, "int", WINDOW_TEXT_SIZE)
continue
text .= buf "`r`n"
}
Return, text
}
GetClientSize(hWnd, ByRef w := "", ByRef h := "") {
VarSetCapacity(rect, 16)
DllCall("GetClientRect", "ptr", hWnd, "ptr", &rect)
w := NumGet(rect, 8, "int")
h := NumGet(rect, 12, "int")
Return, {w: w, h: h} ; My personal change, nothing major.
}
WinToClient(hWnd, ByRef x, ByRef y) {
WinGetPos wX, wY,,, ahk_id %hWnd%
x += wX, y += wY
VarSetCapacity(pt, 8), NumPut(y, NumPut(x, pt, "int"), "int")
if !DllCall("ScreenToClient", "ptr", hWnd, "ptr", &pt)
return false
x := NumGet(pt, 0, "int"), y := NumGet(pt, 4, "int")
Return, True
}
TextMangle(x, Limit := 40) {
If (Limit == -1)
Limit := 9 * (10 ** 1000)
If (pos := InStr(x, "`n"))
x := SubStr(x, 1, pos-1), elli := true
If (StrLen(x) > Limit) {
StringLeft, x, x, % Limit
elli := true
}
If (elli)
x .= " (...)"
Return, x
}
; Mostly for debug
ToolTip(Str, Speed := "", X := "", Y := "", ByRef WhichToolTip := "") {
ToolTip, % Str, % X, % Y, % WhichToolTip
SetTimer, RemTT, % (0 - Speed)
Return
RemTT:
ToolTip
Return
}
MouseGetPos(Options := 3) {
MouseGetPos, X, Y, Win, Ctrl, % Options
Return, {X: X, Y: Y, Win: Win, Ctrl: Ctrl}
}
; Allows functions and even methods to be set here.
SetTimer(Label, Time := "", Params := "") {
If (Time ~= "i)Off|0|")
SetTimer, % Label, Off
SetTimer, % Label, % Time
Return, True
}
~*Ctrl::
~*Shift::
SetTimer("Update", "Off")
GuiControl, %hGui%:, Ctrl_Freeze, % txtFrozen
Return
~*Ctrl up::
~*Shift up::
SetTimer("Update", "On")
Return
- Hovered color box. Shows the current color in a box on the GUI
- Added a "change update speed" to the script to allow slower computer users to adjust their own speeds.
- Added a transparency dialog to make the background of the window easier to see through (Minimum is 100 for known effects).
- Added "push info to notepad". If notepad is installed in the system (Which it should be), it will open notepad and "paste" in the data currently inside the window. You may close it freely for it does not need to be saved.
- Upon closing the script, there is a "Log.txt" file on the desktop to view your last "save progress" from opening your info in notepad.
TODO
- Fix up the "save to notepad" feature to allow other programs.
- Add more features such as in depth searches.
- Add a window search feature.
- Add a list to show and activate all windows with the choice of hidden or visible windows.
CHANGELOG
- 1.0.0: First release of my edited version of the script.
IMAGES
Since Tidbit asked for some images, here they are:
- 01-03-2018 15.42.png (38.13 KiB) Viewed 4027 times
- 01-03-2018 15.41.png (52.83 KiB) Viewed 5448 times