Dear Alguimist,
WinSpy ist great und very useful. I use it a lot and that's why I always wanted a resizable Gui. Your code is wonderful and I hardly dare to post my changes.
What have i changed?
1. Main Window size is increased a little bit to show full informations. You can add own size additions by changing two variables inside this script: 'plusW' & 'plusH'.
2. Messages Tab:
The result will be displayed in decimal and hexadecimal.
Added a message description area for brief information. I have added the extended Messages.ini.
3. at script start WinSpy will be moved to center of primary screen in case it's outside of the visible area. This may happen if you use different screen resolutions for example in different rdp-sessions.
4. AlwaysOnTop can be set from main window (checkbox right from 'Compact Mode' checkbox).
And if the main window was AlwaysOnTop when closing, the setting is restored after the script has started. I missed this feature.
5. added a 'Reload' Button to reload WinSpy script (coding purposes)
I marked changes with *new* or *changed*.
Thanks for your great piece of software!
Code: Select all
; WinSpyM - Window Information Tool [modified] from Alguimist original version
; this is a modified version of WinSpy V1.0.3
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* Description of modifications:
1. Main Window size is increased a little bit to show full informations. You can add own size additions by changing
two variables inside this script: 'plusW' & 'plusH'.
2. Messages Tab:
The result will be displayed in decimal and hexadecimal.
Added a message description area for brief information.
3. at script start WinSpy will be moved to center of primary screen in case it's outside of the visible area. This may happen
if you use different screen resolutions for example in different rdp-sessions.
4. AlwaysOnTop can be set from main window (checkbox right from 'Compact Mode' checkbox).
And if the main window was AlwaysOnTop when closing, the setting is restored after the script has started.
I missed this feature.
5. added a 'Reload' Button to reload WinSpy script (coding purposes)
*/
;----------------------------------------------------------------------------------------------------------------------------------------------
; Script options
;----------------------------------------------------------------------------------------------------------------------------------------------;{
#SingleInstance Off
#NoEnv
#MaxMem 640
#KeyHistory 0
SetWorkingDir %A_ScriptDir%
DetectHiddenWindows On
CoordMode Mouse, Screen
SetControlDelay -1
SetWinDelay -1
SetBatchLines -1
ListLines Off
;}
;----------------------------------------------------------------------------------------------------------------------------------------------
; Variables
;----------------------------------------------------------------------------------------------------------------------------------------------;{
Global AppName := "WinSpyM"
, Version := "1.0.3"
, IniFile := AppName . ".ini"
, ResDir := A_ScriptDir . "\Resources"
, hFindTool
, Descriptions := Object() ; *new*
, Bitmap1 := ResDir . "\FindTool1.bmp"
, Bitmap2 := ResDir . "\FindTool2.bmp"
, hCrossHair := DllCall("LoadImage", "Int", 0, "Str", ResDir . "\CrossHair.cur", "Int", 2, "Int", 32, "Int", 32, "UInt", 0x10, "Ptr") ; LR_LOADFROMFILE
, hOldCursor
, Dragging := False
, g_Borders := []
, g_hWnd
, hSpyWnd
, hTab
, hStylesTab
, hWindowsTab
, g_Style
, g_ExStyle
, g_ExtraStyle
, g_WinMsgs := ""
, hCbxMsg
, Cursors := {}
, oStyles := {}
, Workaround := True
, FindDlgExist := False
, MenuViewerExist := False
, hTreeWnd := 0
, TreeIcons := ResDir . "\TreeIcons.icl"
, ImageList
, g_TreeShowAll := False
, g_Minimized
, g_MouseCoordMode := "Screen"
, g_DetectHidden
, g_Minimize
, g_AlwaysOnTop
IniRead g_DetectHidden , %IniFile%, Settings , DetectHidden , 0
IniRead g_Minimize , %IniFile%, Settings , CompactMode, 0
IniRead g_AlwaysOnTop, %IniFile%, Settings , AlwaysOnTop , 0
IniRead g_ShowBorder , %IniFile%, Screenshot , ShowBorder , 1
IniRead g_BorderColor , %IniFile%, Screenshot , BorderColor , 0xFF0000
IniRead g_BorderWidth , %IniFile%, Screenshot , BorderWidth , 4
IniRead px , %IniFile%, Settings , x , Center
IniRead py , %IniFile%, Settings , y , Center
; gui sizes are added with this values
plusW := 100
plusH := 60
g_BorderColorTemp := g_BorderColor
;}
;----------------------------------------------------------------------------------------------------------------------------------------------
; Main Window
;----------------------------------------------------------------------------------------------------------------------------------------------;{
; Scite RegEx (\s*Gui.*\,.*\,)\s*(.*)w(\d+)(\sh)(\d+)(.*)
; Scite Replace: \1 % "\2 w" (\3+plusW) "\4" (\5+plusH) "\6"
Menu Tray, Icon, %ResDir%\WinSpy.ico
Gui Spy: New, LabelSpy hWndhSpyWnd
SetWindowIcon(hSpyWnd, ResDir . "\WinSpy.ico", 1)
Gui Font, s9, Segoe UI
Gui Add, Picture, hWndhFindTool gFindToolHandler x10 y12 w31 h28, %Bitmap1%
Gui Add, Text, x48 y10 w198, Drag the Finder Tool over a window`nto select it, then release the mouse
Gui Add, CheckBox, gSetDHW x247 y8 Checked%g_DetectHidden%, &Detect Hidden Windows
Gui Add, CheckBox, vg_Minimize gSetMinimize x247 y28 Checked%g_Minimize%, Compact &Mode
GuiControlGet, cpos, Pos, g_Minimize
Gui Add, CheckBox, % "vg_AlwaysOnTop gToggleAlwaysOnTop x" (cposX + cposW +5) " y28 Checked" g_AlwaysOnTop, AlwaysOnTop
Gui Add, Tab3, % "hWndhTab vTab gTabHandler x10 y50 w" (382+plusW) " h" (373+plusH) " AltSubmit -Wrap", General|Styles|Details|Messages|Extra|Windows|Process
; General ;{
Gui Tab, 1
Gui Add, Text , x28 y88 w62 h23 +0x200, Handle:
Gui Add, Edit , % "vEdtHandle gSetHandle x109 y90 w" (180+plusW) " h21"
Gui Add, Button, % "hWndhBtnCommands gShowCommandsMenu x" (297+plusW) " y88 w83 h23", Commands
Gui Add, Text , vTxtText x28 y119 w62 h21 +0x200, Text:
Gui Add, Edit , % "vEdtText x109 y120 w" (180+plusW) " h21"
Gui Add, Button, % "vBtnSetText gSetText x" (297+plusW) " y118 w83 h23", Set Text
Gui Add, Text , x28 y146 w62 h21 +0x200, Class:
Gui Add, Edit , % "vEdtClass x109 y150 w" (270+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Text , x28 y176 w62 h21 +0x200, ClassNN:
Gui Add, Edit , % "vEdtClassNN x109 y180 w" (270+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Text , % "x23 y209 w" (357+plusW) " 0x10"
Gui Add, Text , x28 y220 w62 h21 +0x200, Style:
Gui Add, Edit , % "vEdtStyle x109 y224 w" (270+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Text , x28 y250 w62 h21 +0x200, Extended:
Gui Add, Edit , % "vEdtExStyle x109 y254 w" (270+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Text , % "x23 y283 w" (357+plusW) " 0x10"
Gui Add, Text , x28 y294 w62 h21 +0x200, Position:
Gui Add, Edit , % "vEdtPosition x109 y298 w" (180+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Button, % "gShowXYWHDlg x" (297+plusW) " y294 w83 h23", Change...
Gui Add, Text , x28 y324 w62 h21 +0x200, Size:
Gui Add, Edit , % "vEdtSize x109 y328 w" (180+plusW) " h21 -E0x200 ReadOnly"
Gui Add, Text , % "x23 y357 w" (357+plusW) " 0x10"
Gui Add, Text , x28 y368 w80 h21 +0x200, Cursor:
Gui Add, Edit , % "vEdtCursor x109 y372 w" (180+plusW) " h21 -E0x200 ReadOnly"
Gui Add, DDL , % "vMouseCoordMode gSetMouseCoordMode x" (297+plusW) " y368 w83", Client|Window|Screen||
;}
; Styles ;{
Gui Tab, 2
Gui Add, Custom, % "ClassSysTabControl32 hWndhStylesTab gStylesTabHandler x21 y85 w" (360+plusW) " h230"
Tab_AddItem(hStylesTab, "Styles")
Tab_AddItem(hStylesTab, "Extended Styles")
; ListBox style +0x108: no integral height and simplified multiple selection
Gui Add, ListBox
, hWndhLbxStyles vLbxStyles gLbxStylesHandler x28 y116 w444 h190 +0x108 -E0x200 T133
Gui Add, ListBox
, hWndhLbxExStyles vLbxExStyles gLbxStylesHandler x28 y116 w444 h190 +0x108 -E0x200 T133 Hidden
Gui Add, ListBox
, hWndhLbxExtraStyles vLbxExtraStyles gLbxStylesHandler x28 y116 w444 h190 +0x108 -E0x200 T133 Hidden
Gui Add, GroupBox, % "vGrpDesc x21 y319 w" (268+plusW) " h" (91+plusH+5) , Description
Gui Add, Edit , % "vTxtDesc gShowDescription x32 y338 w" (245+plusW) " h" (64+plusH+5) " +0x80 +Wrap", Left/Right-click an item to see its description.
Gui Add, Edit , % "vEdtStyleSum x" (297+plusW) " y326 w83 h23", 0x00000000
Gui Add, Edit , % "vEdtExStyleSum x" (297+plusW) " y326 w83 h23 Hidden", 0x00000000
Gui Add, Edit , % "vEdtExtraStyleSum x" (297+plusW) " y326 w83 h23 Hidden", 0x00000000
Gui Add, Button , % "gApplyStyle x" (297+plusW) " y355 w83 h24", Apply
Gui Add, Button , % "gResetStyle x" (297+plusW) " y386 w83 h24", Reset
;}
; Details ;{
Gui Tab, 3
Gui Add, ListView , % "hWndhClassInfo x21 y84 w" (360+plusW) " h" (200+Floor(plusH/2)) " +LV0x14000", Property|Value
LV_ModifyCol(1, 138)
LV_ModifyCol(2, 201)
Gui Add, Text , % "x21 y" (288+Floor(plusH/2)) " w360 h20", Window Properties:
Gui Add, ListView , % "hWndhPropInfo x21 y" (306+Floor(plusH/2)) " w" (360+plusW) " h" (104+Floor(plusH/2)) " +LV0x14000", Property|Data
LV_ModifyCol(1, 238)
LV_ModifyCol(2, 100)
;}
; Messages ;{
Gui Tab, 4
Gui Add, Text , x30 y94 w63 h23 +0x200, Message:
Gui Add, ComboBox , % "hWndhCbxMsg vCbxMessages gMessageInfo x105 y94 w" (182+plusW)
SendMessage 0x1701, 20, 0,, ahk_id %hCbxMsg% ; CB_SETMINVISIBLE
Gui Add, Link , % "gGoogleSearch x" (299+plusW) " y97 w78 h23", <a>Google Search</a>
Gui Add, Text , x30 y127 w63 h23 +0x200, wParam:
Gui Add, Edit , % "vwParam x105 y127 w" (182+plusW) " h" 23
Gui Add, DDL , % "vwParamType x" (297+plusW) " y126 w78", Number||String
Gui Add, Text , x30 y161 w63 h23 +0x200, lParam:
Gui Add, Edit , % "vlParam x105 y161 w" (182+plusW) " h" 23
Gui Add, DDL , % "vlParamType x" (297+plusW) " y160 w78", Number||String
Gui Add, Picture , % "x" (58+Floor(plusW/2)) " y200 w16 h16 +Icon2", user32.dll
Gui Add, Text , % "x" (80+Floor(plusW/2)) " y200 w290 h23", Some messages may crash the target application.
Gui Add, Button , % "gSendMsg x" (97+Floor(plusW/2)) " y223 w99 h24", SendMessage
Gui Add, Button , % "gPostMsg x" (203+Floor(plusW/2)) " y223 w99 h24", PostMessage
Gui Add, GroupBox , % "vGBResult x" (84) " y259 w" (232+plusW) " h51 Center", Result
Gui Add, Edit , % "vResult x" (103) " y281 w" (195+plusW) " h21 Center -E0x200 ReadOnly"
; *new* info control for brief message descriptions
GuiControlGet, cpos, Pos, GBResult
Gui Add, GroupBox , % "x20 y" (cposY+cposH+10) " w" (360+plusW) " h" (385+plusH-cposY-cposH+20) " Center", Message Description
Gui Add, Edit , % "vMsgDescription x" (26) " y" (cposY+cposH+30) " w" (360+plusW-12) " h" (385+plusH-cposY-cposH-6) " -E0x200 +Wrap ReadOnly"
;}
; Extra ;{
Gui Tab, 5
Gui Add, ListView , % "hWndhExtraInfo x21 y84 w" (360+plusW) " h" (261+plusH) " +LV0x14000", Property|Value
Gui Add, Button , % "hWndhBtnMenu gShowMenuViewer x21 y" (355+plusH) " w83 h23", Menu...
Gui Add, Button , % "gShowScrollBarInfo x21 y" (387+plusH) " w83 h23", Scroll Bars...
;}
; Windows ;{
Gui Tab, 6
Gui Add, Custom, % "ClassSysTabControl32 hWndhWindowsTab gWindowsTabHandler x21 y85 w" (360+plusW) " h" (255+plusH) ""
Tab_AddItem(hWindowsTab, "Child Windows")
Tab_AddItem(hWindowsTab, "Sibling Windows")
Gui Add, ListView, % "hWndhChildList gChildListHandler x28 y116 w" (344+plusW) " h" (214+plusH) " -E0x200 +LV0x14000"
, Handle|Class Name|Window Text
LV_ModifyCol(1, 76)
LV_ModifyCol(2, 113)
LV_ModifyCol(3, 136)
Gui Add, ListView, % "hWndhSiblingList gSiblingListHandler x28 y116 w" (344+plusW) " h" (214+plusH) " -E0x200 +LV0x14000 Hidden"
, Handle|Class Name|Window Text
LV_ModifyCol(1, 76)
LV_ModifyCol(2, 113)
LV_ModifyCol(3, 136)
Gui Add, Text, % "x33 y" (352+plusH) " w48 h23 +0x200", Parent:
Gui Add, Link, % "vParentLink gLinkToHandle x87 y" (357+plusH) " w300 h20", <a>0x00000000</a>
Gui Add, Text, % "x33 y" (380+plusH) " w48 h23 +0x200", Owner:
Gui Add, Link, % "vOwnerLink gLinkToHandle x87 y" (385+plusH) " w300 h20", <a>0x00000000</a>
;}
; Process ;{
Gui Tab, 7
Gui Add, Picture , vProgIcon x21 y82 w32 h32 Icon3, shell32.dll
Gui Add, Text , vProgName x60 y82 w180 h20, N/A
Gui Add, Text , % "vProgVer x60 y96 w" (180+plusW) " h20 +0x200"
Gui Add, ListView , % "hWndhProcInfo x21 y120 w" (360+plusW) " h" (257+plusH) " +LV0x14000", Property|Value
Gui Add, Button , % "gEndProcess x21 y" (386+plusH) " w83 h23", End Process
Gui Add, Button , % "gOpenFolder x110 y" (386+plusH) " w83 h23", Open Folder
LV_ModifyCol(1, 100)
LV_ModifyCol(2, 256)
Gui Tab
;}
; Buttons ;{
Gui Add, Button, % "hWndhBtnOpts gShowSettingsDlg x10 y" (432+plusH) " w24 h24"
Gui Add, Button, % "gShowFindDlg x39 y" (432+plusH) " w84 h24", &Find...
Gui Add, Button, % "gShowTree x128 y" (432+plusH) " w84 h24", &Tree...
Gui Add, Button, % "gCopyToClipboard x217 y" (432+plusH) " w84 h24", &Copy
Gui Add, Button, % "gScreenshot x306 y" (432+plusH) " w84 h24", &Screenshot
Gui Add, Button, % "gWSReload x395 y" (432+plusH) " w84 h24", &Reload
SetButtonIcon(hBtnOpts, ResDir . "\Settings.ico")
;}
; Show main window ;{
Gui Show, % "x" px " y" py " w" (402+plusW) " h" (465+plusH) " Hide", % AppName ; Show main window
If (g_Minimize) {
WinMove ahk_id %hSpyWnd%,,,,, 78
g_Minimized := True
}
Gui Show
SetExplorerTheme(hClassInfo)
SetExplorerTheme(hPropInfo)
SetExplorerTheme(hExtraInfo)
SetExplorerTheme(hChildList)
SetExplorerTheme(hSiblingList)
SetExplorerTheme(hProcInfo)
; *new*: moves WinSpy to center of primary screen in case it's outside of the visible area.
; This may happen if you use different screen resolutions for example in different rdp-sessions.
MoveWinToCenterScreen(hSpyWnd)
; *new*: AlwaysOnTop at script start. I missed that.
WinSet AlwaysOnTop, % g_AlwaysOnTop ? "On" : "Off", ahk_id %hSpyWnd%
;}
; Commands menu ;{
Menu CommandsMenu, Add, Visible, MenuHandler
Menu CommandsMenu, Add, Enabled, MenuHandler
Menu CommandsMenu, Add, Always on Top, MenuHandler
Menu CommandsMenu, Add
Menu CommandsMenu, Add, Redraw Window, MenuHandler
Menu CommandsMenu, Add
Menu CommandsMenu, Add, Close Window, MenuHandler
Global hCommandsMenu := MenuGetHandle("CommandsMenu")
RegRead Sep, HKEY_CURRENT_USER\Control Panel\International, sThousand
If (Sep == "") {
Sep := "."
}
;}
OnMessage(0x100, "OnWM_KEYDOWN")
OnMessage(0x112, "OnWM_SYSCOMMAND")
OnMessage(0x200, "OnWM_MOUSEMOVE")
OnMessage(0x202, "OnWM_LBUTTONUP")
OnMessage(0x204, "OnWM_RBUTTONDOWN")
LoadCursors()
hSysMenu := DllCall("GetSystemMenu", "Ptr", hSpyWnd, "Int", False, "Ptr")
DllCall("InsertMenu", "Ptr", hSysMenu, "UInt", 5, "UInt", 0x400, "UPtr", 0xC0DE, "Str", "About...")
DllCall("InsertMenu", "Ptr", hSysMenu, "UInt", 5, "UInt", 0xC00, "UPtr", 0, "Str", "") ; Separator
Return ;}
;----------------------------------------------------------------------------------------------------------------------------------------------
; Main Window - Labels & Functions
;----------------------------------------------------------------------------------------------------------------------------------------------;{
SpyEscape: ;{
SpyClose:
Gui, Submit, NoHide
p := GetWindowPlacement(hSpyWnd)
If (!FileExist(IniFile)) {
FileAppend % "[Settings]`n`n[Screenshot]", %IniFile%, UTF-16
}
IniWrite % p.x, %IniFile%, Settings, x
IniWrite % p.y, %IniFile%, Settings, y
IniWrite %g_DetectHidden%, %IniFile%, Settings, DetectHidden
IniWrite %g_Minimize%, %IniFile%, Settings, CompactMode
IniWrite %g_AlwaysOnTop%, %IniFile%, Settings, AlwaysOnTop
IniWrite %g_ShowBorder%, %IniFile%, Screenshot, ShowBorder
IniWrite %g_BorderColor%, %IniFile%, Screenshot, BorderColor
IniWrite %g_BorderWidth%, %IniFile%, Screenshot, BorderWidth
If g_reload
Reload
ExitApp ;}
WSReload: ;{ *new*
g_reload := true
gosub SpyClose
return ;}
ToggleAlwaysOnTop: ;{ *new*
Gui, Submit, NoHide
WinSet AlwaysOnTop, % g_AlwaysOnTop ? "On" : "Off", ahk_id %hSpyWnd%
return ;}
TabHandler: ;{
Gui Spy: Submit, NoHide
TabHandler(Tab)
Return ;}
TabHandler(Tab) {
If (Tab == 7) { ; Process
GoSub LoadProcessProperties
} Else If (Tab == 4) { ; Messages
GoSub LoadMessages
WinSet Redraw,, ahk_id %hCbxMsg%
}
}
ShowWindowInfo(ClassNN := "") {
GuiControl -g, EdtHandle
If (IsChild(g_hWnd)) {
LoadControlInfo(ClassNN)
} Else {
LoadWindowInfo()
}
GuiControl +gSetHandle, EdtHandle
GoSub LoadStyles
GoSub LoadClassInfo
GoSub LoadProperties
GoSub LoadExtraInfo
GoSub LoadWindowsTab
GuiControlGet Tab,, Tab, %hTab%
TabHandler(Tab)
GoSub UpdateTitleBar
}
LoadWindowInfo() {
Gui Spy: Default
; Handle
GuiControl,, EdtHandle, % Format("0x{:X}", g_hWnd)
; Title
WinGetTitle Title, ahk_id %g_hWnd%
GuiControl,, EdtText, %Title%
GuiControl,, TxtText, Title:
GuiControl,, BtnSetText, Set Title
; Class
WinGetClass Class, ahk_id %g_hWnd%
GuiControl,, EdtClass, %Class%
GuiControl,, EdtClassNN, N/A
; Style
WinGet g_Style, Style, ahk_id %g_hWnd%
If ((g_Style & 0x00FF0000) == 0xCF0000) {
StyleInfo := " (overlapped window)"
} Else If (g_Style & 0x80880000) {
StyleInfo := " (popup window)"
} Else {
StyleInfo := ""
}
GuiControl,, EdtStyle, % Format("0x{:08X}", g_Style) . StyleInfo
; Extended style
WinGet g_ExStyle, ExStyle, ahk_id %g_hWnd%
GuiControl,, EdtExStyle, % Format("0x{:08X}", g_ExStyle)
; Position/size
SetFormat Integer, D
WinGetPos X, Y, W, H, ahk_id %g_hWnd%
wi := GetWindowInfo(g_hWnd)
GuiControl,, EdtPosition, % X . ", " . Y . " (" . wi.ClientX . ", " . wi.ClientY . ")"
GuiControl,, EdtSize, % W . " x " . H . " (" . wi.ClientW . " x " . wi.ClientH . ")"
}
LoadControlInfo(ClassNN) {
If (ClassNN == "") {
ClassNN := GetClassNNEx(g_hWnd)
}
Gui Spy: Default
SetFormat Integer, Hex
; Handle
GuiControl,, EdtHandle, % Format("0x{:X}", g_hWnd)
; Class
WinGetClass, Class, ahk_id %g_hWnd%
GuiControl,, EdtClass, %Class%
; Control text
ControlGetText Text,, ahk_id %g_hWnd%
GuiControl,, EdtText, %Text%
GuiControl,, TxtText, Text:
GuiControl,, BtnSetText, Set Text
; ClassNN
GuiControl,, EdtClassNN, %ClassNN%
; Style
ControlGet g_Style, Style,,, ahk_id %g_hWnd%
GuiControl,, EdtStyle, %g_Style%
; Extended style
ControlGet g_ExStyle, ExStyle,,, ahk_id %g_hWnd%
GuiControl,, EdtExStyle, %g_ExStyle%
; Position/Size
SetFormat Integer, D
GetWindowPos(g_hWnd, X, Y, W, H)
wi := GetWindowInfo(g_hWnd)
Pos := X . ", " . Y ; Relative to parent
hParent := GetParent(g_hWnd)
hAncestor := GetAncestor(g_hWnd)
If (hParent != hAncestor) {
VarSetCapacity(RECT, 16, 0)
DllCall("GetWindowRect", "Ptr", g_hWnd, "Ptr", &RECT)
DllCall("MapWindowPoints", "Ptr", 0, "Ptr", GetAncestor(g_hWnd), "Ptr", &RECT, "UInt", 1)
AX := NumGet(RECT, 0, "Int")
AY := NumGet(RECT, 4, "Int")
Pos .= " (" . AX ", " . AY . ")" ; Relative to ancestor
}
GuiControl,, EdtPosition, %Pos%
If (W != wi.ClientW || H != wi.ClientH) {
GuiControl,, EdtSize, % W . " x " . H . " (" . wi.ClientW . " x " . wi.ClientH . ")"
} Else {
GuiControl,, EdtSize, %W% x %H%
}
g_ExtraStyle := GetExtraStyle(g_hWnd)
}
SetHandle: ;{
Gui Spy: Submit, NoHide
If (!Dragging && WinExist("ahk_id " . EdtHandle)) {
g_hWnd := EdtHandle
ShowWindowInfo()
}
Return ;}
MenuHandler: ;{
If (A_ThisMenuItem == "Visible") {
ShowWindow(g_hWnd, !IsWindowVisible(g_hWnd))
} Else If (A_ThisMenuItem == "Enabled") {
DllCall("EnableWindow", "Ptr", g_hWnd, "UInt", !IsWindowEnabled(g_hWnd))
} Else If (A_ThisMenuItem == "Always on Top") {
WinSet AlwaysOnTop, Toggle, ahk_id %g_hWnd%
} Else If (A_ThisMenuItem == "Close Window") {
WinClose ahk_id %g_hWnd%
} Else If (A_ThisMenuItem == "Redraw Window") {
WinSet Redraw,, ahk_id %g_hWnd%
}
Return ;}
UpdateCommandsMenu() {
Visible := IsWindowVisible(g_hWnd)
Enabled := IsWindowEnabled(g_hWnd)
WinGet ExStyle, ExStyle, ahk_id %g_hWnd%
Menu CommandsMenu, % (Visible) ? "Check" : "Uncheck", Visible
Menu CommandsMenu, % (Enabled) ? "Check" : "Uncheck", Enabled
Menu CommandsMenu, % (ExStyle & 0x8) ? "Check" : "Uncheck", Always on Top ; WS_EX_TOPMOST
Menu CommandsMenu, % (IsChild(g_hWnd)) ? "Disable" : "Enable", Always on Top
}
ShowCommandsMenu: ;{
UpdateCommandsMenu()
Flags:= 0x8 ; TPM_TOPALIGN | TPM_RIGHTALIGN
WingetPos wx, wy, ww, wh, ahk_id %hSpyWnd%
ControlGetPos cx, cy, cw, ch,, ahk_id %hBtnCommands%
x := wx + cx + cw
y := wy + cy + ch
DllCall("TrackPopupMenu", "Ptr", hCommandsMenu, "UInt", 0x8, "Int", x, "Int", y, "Int", 0, "Ptr", hSpyWnd, "Ptr", 0)
Return ;}
SetText: ;{
Gui Spy: Submit, NoHide
If (IsChild(g_hWnd)) {
ControlSetText,, %EdtText%, ahk_id %g_hWnd%
} Else {
WinSetTitle ahk_id %g_hWnd%,, %EdtText%
}
Return ;}
MoveWinToCenterScreen(hWin) { ; moves a window to center of screen if its position is outside the visible screen area
; dependencies: GetWindowSpot(), GetMonitorIndexFromWindow(), screenDims()
w:= GetWindowPlacement(hWin)
If !IsInsideVisibleArea(w.x, w.y, w.w, w.h) {
mon := GetMonitorIndexFromWindow(hWin)
scr := screenDims(mon)
SetWindowPos(hWin, (scr.W//2) - (w.X//2), (scr.H//2) - (w.Y//2), w.W, w.H)
}
return
}
IsInsideVisibleArea(x,y,w,h) {
isVis:=0
SysGet, MonitorCount, MonitorCount
Loop, % MonitorCount
{
SysGet, Monitor%A_Index%, MonitorWorkArea, %A_Index%
if (x+w-10>Monitor%A_Index%Left) and (x+10<Monitor%A_Index%Right) and (y+20>Monitor%A_Index%Top) and (y+20<Monitor%A_Index%Bottom)
isVis:=1
}
return, IsVis
}
MessageInfo: ;{ *new*
Gui, Submit, NoHide
GuiControl,, MsgDescription, % CbxMessages ": " StrReplace(Descriptions[CbxMessages], "``n", "`n")
return ;}
;}
GetMonitorIndexFromWindow(windowHandle) { ; *new*
; Starts with 1.
; https://autohotkey.com/board/topic/69464-how-to-determine-a-window-is-in-which-monitor/
monitorIndex := 1
VarSetCapacity(monitorInfo, 40)
NumPut(40, monitorInfo)
if (monitorHandle := DllCall("MonitorFromWindow", "uint", windowHandle, "uint", 0x2))
&& DllCall("GetMonitorInfo", "uint", monitorHandle, "uint", &monitorInfo)
{
monitorLeft := NumGet(monitorInfo, 4, "Int")
monitorTop := NumGet(monitorInfo, 8, "Int")
monitorRight := NumGet(monitorInfo, 12, "Int")
monitorBottom := NumGet(monitorInfo, 16, "Int")
workLeft := NumGet(monitorInfo, 20, "Int")
workTop := NumGet(monitorInfo, 24, "Int")
workRight := NumGet(monitorInfo, 28, "Int")
workBottom := NumGet(monitorInfo, 32, "Int")
isPrimary := NumGet(monitorInfo, 36, "Int") & 1
SysGet, monitorCount, MonitorCount
Loop, % monitorCount
{
SysGet, tempMon, Monitor, %A_Index%
; Compare location to determine the monitor index.
if ((monitorLeft = tempMonLeft) and (monitorTop = tempMonTop)
and (monitorRight = tempMonRight) and (monitorBottom = tempMonBottom))
{
monitorIndex := A_Index
break
}
}
}
return % monitorIndex
}
screenDims(MonNr:=1) { ;-- returns a key:value pair of width screen dimensions (only for primary monitor)
Sysget, MonitorInfo, Monitor, % MonNr
X := MonitorInfoLeft
Y := MonitorInfoTop
W := MonitorInfoRight - MonitorInfoLeft
H := MonitorInfoBottom - MonitorInfoTop
DPI := A_ScreenDPI
Orient := (W>H)?"L":"P"
yEdge := DllCall("GetSystemMetrics", "Int", SM_CYEDGE)
yBorder := DllCall("GetSystemMetrics", "Int", SM_CYBORDER)
return {X:X, Y:Y, W:W, H:H, DPI:DPI, OR:Orient, yEdge:yEdge, yBorder:yBorder}
}
IsChild(hWnd) {
WinGet Style, Style, ahk_id %hWnd%
Return Style & 0x40000000 ; WS_CHILD
}
GetStatusBarText(hWnd) {
SB_Text := ""
hParentWnd := GetParent(hWnd)
SendMessage 0x406, 0, 0,, ahk_id %hWnd% ; SB_GETPARTS
Count := ErrorLevel
If (Count != "FAIL") {
Loop %Count% {
StatusBarGetText PartText, %A_Index%, ahk_id %hParentWnd%
SB_Text .= PartText . "|"
}
}
Return SubStr(SB_Text, 1, -1)
}
GetAncestor(hWnd, Flag := 2) {
; Flag: GA_PARENT = 1, GA_ROOT = 2, GA_ROOTOWNER = 3
Return DllCall("GetAncestor", "Ptr", hWnd, "UInt", Flag, "Ptr")
}
GetClassNNEx(hWnd) {
hAncestor := GetAncestor(hWnd)
If !hAncestor
Return
WinGetClass BaseClass, ahk_id %hWnd%
NN := 0
WinGet ControlList, ControlListHwnd, % "ahk_id " . hAncestor
Loop Parse, ControlList, `n
{
WinGetClass Class, ahk_id %A_LoopField%
If (Class == BaseClass) {
NN++
If (A_LoopField == hWnd) {
Return Class . NN
}
}
}
}
IsWindowEnabled(hWnd) {
Return DllCall("IsWindowEnabled", "Ptr", hWnd)
}
ShowBorder(hWnd, Duration := 500, Color := "0x3FBBE3", r := 3) {
Local x, y, w, h, Index
WinGetPos x, y, w, h, ahk_id %hWnd%
If (!w) {
Return
}
g_Borders := []
Loop 4 {
Index := A_Index + 90
Gui %Index%: +hWndhBorder -Caption +ToolWindow +AlwaysOnTop
Gui %Index%: Color, %Color%
g_Borders.Push(hBorder)
}
Gui 91: Show, % "NA x" (x - r) " y" (y - r) " w" (w + r + r) " h" r ; Top
Gui 92: Show, % "NA x" (x - r) " y" (y + h) " w" (w + r + r) " h" r ; Bottom
Gui 93: Show, % "NA x" (x - r) " y" y " w" r " h" h ; Left
Gui 94: Show, % "NA x" (x + w) " y" y " w" r " h" h ; Right
If (Duration != -1) {
Sleep %Duration%
Loop 4 {
Index := A_Index + 90
Gui %Index%: Destroy
}
}
}
GetClassLong(hWnd, Param) {
Static GetClassLong := A_PtrSize == 8 ? "GetClassLongPtr" : "GetClassLong"
Return DllCall(GetClassLong, "Ptr", hWnd, "Int", Param)
}
GetWindowLong(hWnd, Param) {
;GetWindowLong := A_PtrSize == 8 ? "GetWindowLongPtr" : "GetWindowLong"
Return DllCall("GetWindowLong", "Ptr", hWnd, "Int", Param)
}
; Details
LoadClassInfo: ;{
Gui ListView, %hClassInfo%
LV_Delete()
SetFormat Integer, H
WinGetClass ClassName, ahk_id %g_hWnd%
ClassStyle := GetClassLong(g_hWnd, -26)
LV_Add("", "Class name", ClassName)
LV_Add("", "Control ID", GetWindowLong(g_hWnd, -12))
LV_Add("", "Font", GetFont())
LV_Add("", "Window procedure", GetClassLong(g_hWnd, -24))
LV_Add("", "Instance handle", GetClassLong(g_hWnd, -16))
LV_Add("", "Class style", ClassStyle . GetClassStyles(ClassStyle))
LV_Add("", "Icon handle", GetClassLong(g_hWnd, -14))
LV_Add("", "Small icon handle", GetClassLong(g_hWnd, -34))
LV_Add("", "Cursor handle", GetCursor(GetClassLong(g_hWnd, -12)))
LV_Add("", "Background Brush", GetSysColorName(GetClassLong(g_hWnd, -10) - 1))
LV_Add("", "Menu name", GetClassLong(g_hWnd, -8))
LV_Add("", "Window extra bytes", GetClassLong(g_hWnd, -18))
LV_Add("", "Class extra bytes", GetClassLong(g_hWnd, -20))
LV_Add("", "Class atom", GetClassLong(g_hWnd, -32))
LV_Add("", "User data", GetWindowLong(g_hWnd, -21))
SetFormat Integer, D
LV_Add("", "Unicode", DllCall("IsWindowUnicode", "Ptr", g_hWnd) ? "Yes" : "No")
LV_Add("", "Tab order index", GetTabOrderIndex(g_hWnd))
LV_Add("", "Help context ID", DllCall("GetWindowContextHelpId", "Ptr", g_hWnd))
LV_Add("", "Touch-capable", DllCall("IsTouchWindow", "Ptr", g_hWnd, "Ptr", 0))
Return ;}
GetFont() {
FontName := FontSize := FontStyle := ""
Wingetclass Class, ahk_id %g_hWnd%
If (Class == "Scintilla") {
FontName := Scintilla_GetFont(g_hWnd)
FontSize := SendMsg(2485, 32) ; SCI_STYLEGETSIZE, STYLE_DEFAULT
} Else {
Control_GetFont(g_hWnd, FontName, FontSize, FontStyle)
If (FontName == "" || FontSize > 1000) {
Return "System default"
}
}
FontInfo := FontName . ", " . Format("{:d}", FontSize)
If (FontStyle != "") {
FontInfo .= ", " . FontStyle
}
Return FontInfo
}
; www.autohotkey.com/forum/viewtopic.php?p=465438#465438
Control_GetFont(hWnd, ByRef Name, ByRef Size, ByRef Style, IsGDIFontSize := 0) {
SendMessage 0x31, 0, 0, , ahk_id %hWnd% ; WM_GETFONT
If (ErrorLevel == "FAIL") {
Return
}
hFont := Errorlevel
VarSetCapacity(LOGFONT, LOGFONTSize := 60 * (A_IsUnicode ? 2 : 1 ))
DllCall("GetObject", "Ptr", hFont, "Int", LOGFONTSize, "Ptr", &LOGFONT)
Name := DllCall("MulDiv", "Int", &LOGFONT + 28, "Int", 1, "Int", 1, "Str")
Style := Trim((Weight := NumGet(LOGFONT, 16, "Int")) == 700 ? "Bold" : (Weight == 400) ? "" : " w" . Weight
. (NumGet(LOGFONT, 20, "UChar") ? " Italic" : "")
. (NumGet(LOGFONT, 21, "UChar") ? " Underline" : "")
. (NumGet(LOGFONT, 22, "UChar") ? " Strikeout" : ""))
Size := IsGDIFontSize ? -NumGet(LOGFONT, 0, "Int") : Round((-NumGet(LOGFONT, 0, "Int") * 72) / A_ScreenDPI)
}
Scintilla_GetFont(hWnd) {
WinGet PID, PID, ahk_id %hWnd%
If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
Return
}
; LF_FACESIZE := 32
Address := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "UPtr", 32, "UInt", 0x1000, "UInt", 4, "Ptr")
SendMessage 2486, 32, Address,, ahk_id %hWnd% ; SCI_STYLEGETFONT, STYLE_DEFAULT
If (ErrorLevel != "FAIL") {
VarSetCapacity(FontName, 32, 0)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Ptr", &FontName, "UPtr", 32, "Ptr", 0)
FontName := StrGet(&FontName, "UTF-8")
}
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", Address, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
DllCall("CloseHandle", "Ptr", hProc)
Return FontName
}
Scintilla_GetLexerLanguage(hWnd) {
WinGet PID, PID, ahk_id %hWnd%
If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
Return
}
Sendmessage 4012, 0, 0,, ahk_id %hWnd% ; SCI_GETLEXERLANGUAGE
BufferSize := ErrorLevel
Address := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "UPtr", BufferSize, "UInt", 0x1000, "UInt", 4, "Ptr")
Sendmessage 4012, 0, Address,, ahk_id %hWnd% ; SCI_GETLEXERLANGUAGE
If (ErrorLevel != "FAIL") {
VarSetCapacity(LexerName, BufferSize, 0)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Ptr", &LexerName, "UPtr", 32, "Ptr", 0)
LexerName := StrGet(&LexerName, "UTF-8")
}
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", Address, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
DllCall("CloseHandle", "Ptr", hProc)
Return LexerName
}
GetClassStyles(Style) {
Static CS := {0x1: "CS_VREDRAW"
, 0x2: "CS_HREDRAW"
, 0x8: "CS_DBLCLKS"
, 0x20: "CS_OWNDC"
, 0x40: "CS_CLASSDC"
, 0x80: "CS_PARENTDC"
, 0x200: "CS_NOCLOSE"
, 0x800: "CS_SAVEBITS"
, 0x1000: "CS_BYTEALIGNCLIENT"
, 0x2000: "CS_BYTEALIGNWINDOW"
, 0x4000: "CS_GLOBALCLASS"
, 0x10000: "CS_IME"
, 0x20000: "CS_DROPSHADOW"}
Styles := " ("
For k, v in CS {
If (Style & k) {
Styles .= v ", "
}
}
Return RTrim(Styles, ", ") . ")"
}
LoadCursors() {
Static Constants := {"IDC_ARROW": 32512
, "IDC_IBEAM": 32513
, "IDC_WAIT": 32514
, "IDC_CROSS": 32515
, "IDC_UPARROW": 32516
, "IDC_SIZENWSE": 32642
, "IDC_SIZENESW": 32643
, "IDC_SIZEWE": 32644
, "IDC_SIZENS": 32645
, "IDC_SIZEALL": 32646
, "IDC_NO": 32648
, "IDC_HAND": 32649
, "IDC_APPSTARTING": 32650
, "IDC_HELP": 32651}
For Key, Value in Constants {
hCursor := DllCall("LoadCursor", "Ptr", 0, "UInt", Value, "Ptr")
Cursors[hCursor] := Key
}
}
GetCursor(CursorHandle) {
Cursor := Cursors[CursorHandle]
Return (Cursor != "") ? Cursor : CursorHandle
}
GetTabOrderIndex(hWnd) {
hParent := GetAncestor(hWnd)
WinGet ControlList, ControlListHwnd, ahk_id %hParent%
Index := 1
Loop Parse, ControlList, `n
{
If (!IsWindowVisible(A_LoopField)) {
Continue
}
WinGet Style, Style, ahk_id %A_LoopField%
If !(Style & 0x10000) { ; WS_TABSTOP
Continue
}
If (A_LoopField == hWnd) {
Return Index
}
Index++
}
Return 0
}
Tab_AddItem(hTab, Text) {
VarSetCapacity(TCITEM, 16 + A_PtrSize * 3, 0)
NumPut(0x1, TCITEM, 0, "UInt") ; TCIF_TEXT
NumPut(&Text, TCITEM, 8 + A_PtrSize, "Ptr")
SendMessage 0x1304, 0, 0,, ahk_id %hTab% ; TCM_GETITEMCOUNT
SendMessage 0x133E, %ErrorLevel%, &TCITEM, , ahk_id %hTab% ; TCM_INSERTITEMW
}
StylesTabHandler: ;{
If (A_GuiEvent == "N") {
Code := NumGet(A_EventInfo + 0, A_PtrSize * 2, "Int")
If (Code == -551) { ; TCN_SELCHANGE
SendMessage 0x130B, 0, 0,, ahk_id %hStylesTab% ; TCM_GETCURSEL
nTab := Errorlevel + 1
If (nTab == 1) {
GuiControl Hide, ListBox3
GuiControl Hide, ListBox2
GuiControl Show, ListBox1
GuiControl Hide, EdtExtraStyleSum
GuiControl Hide, EdtExStyleSum
GuiControl Show, EdtStyleSum
} Else If (nTab == 2) {
GuiControl Hide, ListBox1
GuiControl Hide, ListBox3
GuiControl Show, ListBox2
GuiControl Hide, EdtExtraStyleSum
GuiControl Hide, EdtStyleSum
GuiControl Show, EdtExStyleSum
} Else If (nTab == 3) {
GuiControl Hide, ListBox1
GuiControl Hide, ListBox2
GuiControl Show, ListBox3
GuiControl Hide, EdtStyleSum
GuiControl Hide, EdtExStyleSum
GuiControl Show, EdtExtraStyleSum
}
}
}
Return ;}
; Styles
LoadStyles: ;{
Gui Spy: Default
GuiControl,, EdtStyleSum, %g_Style%
GuiControl,, EdtExStyleSum, %g_ExStyle%
GuiControl,, EdtExtraStyleSum, %g_ExtraStyle%
WinGetClass Class, ahk_id %g_hWnd%
If (Class == "") {
Return
}
; Load control styles
LoadStyles(Class, "ListBox1")
If (Class == "ToolbarWindow32" || Class == "ReBarWindow32") {
LoadStyles("CommonControls", "ListBox1", True)
}
; Load window styles
LoadStyles("Window", "ListBox1", True)
LoadStyles("WindowEx", "ListBox2")
; Delete the third tab
SendMessage 0x1308, 2, 0,, ahk_id %hStylesTab% ; TCM_DELETEITEM
If (ErrorLevel == True) {
GuiControl Hide, ListBox3
GuiControl Show, ListBox1
SendMessage 0x1330, 0, 0,, ahk_id %hStylesTab% ; TCM_SETCURFOCUS
Sleep 0
SendMessage 0x130C, 0, 0,, ahk_id %hStylesTab% ; TCM_SETCURSEL
}
If (Class == "ComboBox" && g_Style & 0x10) { ; CBS_OWNERDRAWFIXED
Class := "ComboBoxEx"
}
; Add third tab
If (Class == "SysListView32"
|| Class == "SysTreeView32"
|| Class == "SysTabControl32"
|| Class == "ToolbarWindow32"
|| Class == "ComboBoxEx") {
Tab_AddItem(hStylesTab, RegExReplace(Class, "Sys|32|Control|Window") . " Extended Styles")
LoadStyles(Class . "Ex", "ListBox3")
}
WStyle := g_Style
Type := 0
If (Class == "Button") {
Type := WStyle & 0xF ; BS_TYPEMASK
WStyle &= ~Type
} Else If (Class == "SysListView32") {
Type := WStyle & 0x3 ; LVS_TYPEMASK
WStyle &= ~Type
} Else If (Class == "Static") {
Type := WStyle & 0x1F ; SS_TYPEMASK
WStyle &= ~Type
}
ControlGet Items, List,,, ahk_id %hLbxStyles%
Loop Parse, Items, `n
{
LStyle := StrSplit(A_LoopField, "`t")[2]
If (WStyle & LStyle || Type == LStyle) {
WStyle &= ~LStyle
GuiControl Choose, %hLbxStyles%, %A_Index%
}
}
If (WStyle) {
Leftover := Format("0x{:08X}", WStyle)
GuiControl,, %hLbxStyles%, % Leftover . "`t" . Leftover . "||"
}
SendMessage 0x115, 6, 0,, ahk_id %hLbxStyles% ; WM_VSCROLL, scroll to top
WinSet Redraw,, ahk_id %hLbxStyles%
; Extended styles
WExStyle := g_ExStyle
ControlGet Items, List,,, ahk_id %hLbxExStyles%
Loop Parse, Items, `n
{
LExStyle := StrSplit(A_LoopField, "`t")[2]
If (WExStyle & LExStyle || LExStyle == 0) {
WExStyle &= ~LExStyle
GuiControl Choose, %hLbxExStyles%, %A_Index%
}
}
If (WExStyle) {
Leftover := Format("0x{:08X}", WExStyle)
GuiControl,, %hLbxExStyles%, % Leftover . "`t" . Leftover . "||"
}
SendMessage 0x115, 6, 0,, ahk_id %hLbxExStyles% ; WM_VSCROLL, scroll to top
WinSet Redraw,, ahk_id %hLbxExStyles%
; Extra control styles (LV, TV, Toolbar, Tab)
ExtraStyle := g_ExtraStyle
ControlGet Items, List,,, ahk_id %hLbxExtraStyles%
Loop Parse, Items, `n
{
LExtraStyle := StrSplit(A_LoopField, "`t")[2]
If (ExtraStyle & LExtraStyle || LExtraStyle == 0) {
ExtraStyle &= ~LExtraStyle
GuiControl Choose, %hLbxExtraStyles%, %A_Index%
}
}
Return ;}
LoadStyles(IniSection, ListBox, Append := False) {
Static IniFile := A_ScriptDir . "\Constants\Styles.ini"
IniRead Section, %IniFile%, %IniSection%
Child := (IniSection == "Window" && IsChild(g_hWnd)) ? True : False
Values := ""
Loop Parse, Section, `n
{
Fields := StrSplit(A_LoopField, "|")
Const := Fields[1]
If (Child && (Const == "WS_MAXIMIZEBOX" || Const == "WS_MINIMIZEBOX" || Const == "WS_OVERLAPPED")) {
Continue
}
If (!Child && (Const == "WS_TABSTOP" || Const == "WS_GROUP")) {
Continue
}
Values .= Const . "`t" . Fields[2] . "|"
oStyles[Const] := {"Value": Fields[2], "Desc": Fields[3]}
}
Gui Spy: Default
GuiControl,, %ListBox%, % (Append) ? Values : "|" . Values
}
LbxStylesHandler: ;{
Gui Spy: Default
GuiControlGet hLbx, hWnd, %A_GuiControl%
GuiControl -AltSubmit, %hLbx%
GuiControlGet Items,, %hLbx%
Sum := 0
Loop Parse, Items, |
{
StringSplit Field, A_LoopField, `t
Sum += Field2
}
GuiControl,, % StrReplace(A_GuiControl, "Lbx", "Edt") . "um", % Format("0x{:08X}", Sum)
; Style description
GuiControl +AltSubmit, %hLbx%
SendMessage 0x188, 0, 0,, ahk_id %hLbx% ; LB_GETCURSEL
If (ErrorLevel != "FAIL") {
; Credits to just_me
Index := ErrorLevel
SendMessage 0x18A, %Index%, 0,, ahk_id %hLbx% ; LB_GETTEXTLEN
Len := ErrorLevel
VarSetCapacity(LB_Text, Len << !!A_IsUnicode, 0)
SendMessage 0x189, %Index%, % &LB_Text,, ahk_id %hLbx% ; LB_GETTEXT
Const := StrSplit(StrGet(&LB_Text, Len), "`t")[1]
Desc := StrReplace(oStyles[Const].Desc, "\n", "`n")
GuiControl,, GrpDesc, %Const%
GuiControl,, TxtDesc, %Desc%
}
Return ;}
ApplyStyle: ;{
SendMessage 0x130B, 0, 0,, ahk_id %hStylesTab% ; TCM_GETCURSEL
nTab := ErrorLevel + 1
If (nTab == 1) {
GuiControlGet Style,, EdtStyleSum
WinSet Style, %Style%, ahk_id %g_hWnd%
} Else If (nTab == 2) {
GuiControlGet ExStyle,, EdtExStyleSum
WinSet ExStyle, %ExStyle%, ahk_id %g_hWnd%
} Else If (nTab == 3) {
GuiControlGet ExtraStyle,, EdtExtraStyleSum
WinGetClass Class, ahk_id %g_hWnd%
If (Class == "SysListView32") {
SendMessage 0x1036, 0, %ExtraStyle%,, ahk_id %g_hWnd% ; LVM_SETEXTENDEDLISTVIEWSTYLE
} Else If (Class == "SysTreeView32") {
SendMessage 0x112C, 0, %ExtraStyle%,, ahk_id %g_hWnd% ; TVM_SETEXTENDEDSTYLE
} Else If (Class == "SysTabControl32") {
SendMessage 0x1334, 0, %ExtraStyle%,, ahk_id %g_hWnd% ; TCM_SETEXTENDEDSTYLE
} Else If (Class == "ToolbarWindow32") {
SendMessage 0x454, 0, %ExtraStyle%,, ahk_id %g_hWnd% ; TB_SETEXTENDEDSTYLE
} Else If (Class == "ComboBox" && (g_Style & 0x10)) {
SendMessage 0x40E, 0, %ExtraStyle%,, ahk_id %g_hWnd% ; CBEM_SETEXTENDEDSTYLE
}
}
; 0x17: SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
DllCall("SetWindowPos", "Ptr", g_hWnd, "UInt", 0, "Int", 0, "Int", 0, "Int", 0, "Int", 0, "UInt", 0x17)
WinSet Redraw,, ahk_id %g_hWnd%
Return ;}
ResetStyle: ;{
nTab := DllCall("SendMessage", "Ptr", hStylesTab, "UInt", 0x130B, "UInt", 0, "UInt", 0) + 1
If (nTab == 1) {
GuiControl, Spy:, EdtStyleSum, %g_Style%
} Else If (nTab == 2) {
GuiControl, Spy:, EdtExStyleSum, %g_ExStyle%
} Else If (nTab == 3) {
GuiControl, Spy:, EdtExtraStyleSum, %g_ExtraStyle%
}
GoSub LoadStyles
Return ;}
GetExtraStyle(hWnd) {
WinGetClass Class, ahk_id %hWnd%
If (Class == "SysListView32") {
Message := 0x1037 ; LVM_GETEXTENDEDLISTVIEWSTYLE
} Else If (Class == "SysTreeView32") {
Message := 0x112D ; TVM_GETEXTENDEDSTYLE
} Else If (Class == "SysTabControl32") {
Message := 0x1335 ; TCM_GETEXTENDEDSTYLE
} Else If (Class == "ToolbarWindow32") {
Message := 0x455 ; TB_GETEXTENDEDSTYLE
} Else If (Class == "ComboBox" && g_Style & 0x10) {
Message := 0x409 ; CBEM_GETEXTENDEDSTYLE
}
SendMessage %Message%, 0, 0,, ahk_id %hWnd%
Return Format("0x{:08X}", ErrorLevel)
}
ShowDescription: ;{
GuiControlGet Const,, GrpDesc
GuiControlGet Desc,, TxtDesc
Gui Desc: New, LabelDesc -SysMenu OwnerSpy
Gui Color, White
Gui Margin, 10, 0
Gui Add, CheckBox, x0 y0 w0 h0
Gui Add, Picture, x12 y12 w32 h32 Icon5, user32.dll
Gui Font, s12 c0x003399, Segoe UI
Gui Add, Text, x58 y15 w473 h23 +0x200, %Const%
Gui Font
Gui Font, s10, Segoe UI
Gui Add, Edit, vEdtDesc x55 y55 w444 Multi -VScroll -E0x200, %Desc%
Gui Font
GuicontrolGet Pos, Pos, EdtDesc
py := PosY + PosH + 20
Gui Add, Text, hWndhFooter x-1 y%py% w533 h48 -Background
Gui Font, s9, Segoe UI
Gui Add, Button, gDescClose x432 yp+12 w88 h25 Default, &Close
Gui Show, w531, Style Description
Return ;}
DescEscape: ;{
DescClose:
Gui Desc: Destroy
Return ;}
; Messages
LoadMessages: ;{
WinGetClass Class, ahk_id %g_hWnd%
Constants := GetMessages(Class)
Gui Spy: Default
GuiControlGet CurrentItem,, CbxMessages, Text
GuiControl,, CbxMessages, |%Constants%
GuiControl Text, CbxMessages, %CurrentItem%
; Common Control Messages
If (Class == "ToolbarWindow32" || Class == "ReBarWindow32") {
GuiControl,, CbxMessages, % GetMessages("CommonControls")
}
If (g_WinMsgs == "") {
g_WinMsgs := GetMessages("Window")
}
GuiControl,, CbxMessages, %g_WinMsgs%
Return ;}
GetMessages(Class) { ; collects briefs descriptions from constants file *changes here*
Static IniFile := A_ScriptDir "\Constants\Messages.ini"
If (Class == "")
Return
IniRead Section, %IniFile%, %Class%
Constants := ""
Loop Parse, Section, `n
{
msg := StrSplit(A_LoopField, "=").1
Constants .= msg "|"
IniRead Description, %IniFile%, DESCRIPTIONS, % msg
If (Description == "ERROR") or (Description == "")
Description:= "Definition needed"
Descriptions[msg] := Description
}
Sort Constants, D|
Return Constants
}
SendMsg:
PostMsg: ;{
Gui Spy: Submit, NoHide
Function := (A_ThisLabel == "SendMsg") ? "SendMessage" : "PostMessage"
If CbxMessages is Not Number
{
If (SubStr(CbxMessages, 1, 3) == "WM_") {
ClassName := "Window"
} Else {
ClassName := GetClassName(g_hWnd)
}
IniRead Message, %A_ScriptDir%\Constants\Messages.ini, %ClassName%, %CbxMessages%
If (Message == "ERROR") {
Gui Spy: +OwnDialogs
MsgBox 0x10, %AppName%, %CbxMessages%: invalid message.
Return
}
} Else {
Message := CbxMessages
}
DataTypes := {"Number": "UPtr", "String": "WStr"}
wType := DataTypes[wParamType]
lType := DataTypes[lParamType]
Result := DllCall(Function, "Ptr", g_hWnd, "UInt", Message, wType, wParam, lType, lParam)
GuiControl,, Result, % "Dec: " Result " | Hex: " GetHex(Result)
Return ;}
GetHex(hwnd) { ; *new*
return Format("0x{:x}", hwnd)
}
GetDec(hwnd) { ; *new*
return Format("{:u}", hwnd)
}
GoogleSearch: ;{
GuiControlGet Message,, CbxMessages
If (Message == "") {
Return
}
If (SubStr(Message, 1, 3) == "SCI") {
URL := "http://www.scintilla.org/ScintillaDoc.html#"
} Else {
URL := "https://www.google.com/#q="
}
Try {
Run %URL%%Message%
}
Return ;}
CopyToClipboard: ;{
Gui Spy: Default
CRLF := "`r`n"
Output := ""
If (Tab == 1) { ; General
Gui Spy: Submit, NoHide
Output .= "[General]" . CRLF
Output .= "Handle:`t" . EdtHandle . CRLF
Output .= "Text:`t" . EdtText . CRLF
Output .= "Class:`t" . EdtClass . CRLF
Output .= "ClassNN:`t" . EdtClassNN . CRLF
Output .= "Style:`t" . EdtStyle . CRLF
Output .= "Extended:`t" . EdtExStyle . CRLF
Output .= "Position:`t" . EdtPosition . CRLF
Output .= "Size:`t" . EdtSize . CRLF
Output .= "Cursor:`t" . EdtCursor . CRLF
}
Else If (Tab == 2) { ; Styles
If (g_Style) {
GuiControlGet Styles,, %hLbxStyles%
Output .= "[Styles]" . CRLF . StrReplace(Styles, "|", CRLF) . CRLF . CRLF
}
If (g_ExStyle) {
GuiControlGet ExStyles,, %hLbxExStyles%
Output .= "[ExStyles]" . CRLF . StrReplace(ExStyles, "|", CRLF) . CRLF . CRLF
}
If (g_ExtraStyle) {
GuiControlGet ExtraStyles,, %hLbxExtraStyles%
Output .= "[ExtraStyles]" . CRLF . StrReplace(ExtraStyles, "|", CRLF)
}
}
Else If (Tab == 3) { ; Details
ControlGet, ClassInfo, List,,, ahk_id %hClassInfo%
ControlGet, PropInfo, List,,, ahk_id %hPropInfo%
Output .= "[Details]" . CRLF . ClassInfo . CRLF . CRLF . "[Properties]" . CRLF . PropInfo
}
Else If (Tab == 5) { ; Extra
ControlGet, ExtraInfo, List,,, ahk_id %hExtraInfo%
Output .= "[Extra]" . CRLF . ExtraInfo
}
Else If (Tab == 6) { ; Windows
ControlGet, Child, List,,, ahk_id %hChildList%
If (Child != "") {
Output .= "[Child]" . CRLF . Child . CRLF . CRLF
}
ControlGet, Sibling, List,,, ahk_id %hSiblingList%
If (Sibling != "") {
Output .= "[Sibling]" . CRLF . Sibling . CRLF . CRLF
}
GuiControlGet ParentLink,, ParentLink
Output .= "Parent:`t" . RegExReplace(ParentLink, "\<\/?a\>") . CRLF
GuiControlGet OwnerLink,, OwnerLink
Output .= "Owner:`t" . RegExReplace(OwnerLink, "\<\/?a\>")
}
Else If (Tab == 7) { ; Process
ControlGet, ProcInfo, List,,, ahk_id %hProcInfo%
Output .= "[Process]" . CRLF . ProcInfo
}
Clipboard := RTrim(Output, CRLF)
Return ;}
ControlFromPoint(mx, my, hWnd) {
hParent := GetParent(hWnd)
If (hParent == 0) {
hParent := hWnd
}
SmallerArea := 999999999
hChildWnd := 0
WinGet List, ControlListHwnd, ahk_id %hParent% ; EnumChildWindows
Loop Parse, List, `n
{
VarSetCapacity(RECT, 16, 0)
DllCall("GetWindowRect", "Ptr", A_LoopField, "Ptr", &RECT)
Left := NumGet(RECT, 0, "Int")
Top := NumGet(RECT, 4, "Int")
Right := NumGet(RECT, 8, "Int")
Bottom := NumGet(RECT, 12, "Int")
If ((mx >= Left) && (mx <= Right) && (my >= Top) && (my <= Bottom)) {
Area := (Right - Left) * (Bottom - Top)
If (Area < SmallerArea) {
SmallerArea := Area
hChildWnd := A_LoopField
}
}
}
Return (hChildWnd == 0) ? hWnd : hChildWnd
}
; Details tab
LoadProperties: ;{
Gui Spy: ListView, %hPropInfo%
LV_Delete()
Callback := RegisterCallback("PropEnumProcEx", "F")
DllCall("EnumPropsEx", "Ptr", g_hWnd, "Ptr", Callback, "UInt", lParam := 0)
Return ;}
PropEnumProcEx(hWnd, lpszString, hData, dwData) {
Global hPropInfo
Property := StrGet(lpszString, "UTF-16")
If (Property == "") {
Property := lpszString . " (Atom)"
}
Gui Spy: ListView, %hPropInfo%
LV_Add("", Property, Format("0x{:08X}", hData))
Return True
}
LoadExtraInfo: ;{
Gui Spy: ListView, %hExtraInfo%
LV_Delete()
While (LV_GetText(foo, 0, 1)) {
LV_DeleteCol(1)
}
WinGetClass Class, ahk_id %g_hWnd%
If (Class == "Edit" || InStr(Class, "RICHEDIT")) {
LV_InsertCol(1, "169", "Property")
LV_InsertCol(2, "169", "Value")
ControlGetText Text,, ahk_id %g_hWnd%
Length := StrLen(Text) . " characters"
ControlGet Lines, LineCount,,, ahk_id %g_hWnd%
ControlGet CurLine, CurrentLine,,, ahk_id %g_hWnd%
ControlGet CurCol, CurrentCol,,, ahk_id %g_hWnd%
LV_Add("", "Length", Length)
LV_Add("", "Current line", CurLine)
LV_Add("", "Current column", CurCol)
LV_Add("", "Line count", Lines)
LV_Add("", "Text Limit", SendMsg(0xD5) . " bytes") ; EM_GETLIMITTEXT
LV_Add("", "Modified", {0: "False", 1: "True"}[SendMsg(0xB8)]) ; EM_GETMODIFY
}
Else If (InStr(Class, "Scintilla")) {
LV_InsertCol(1, "169", "Property")
LV_InsertCol(2, "169", "Value")
LexerName := Scintilla_GetLexerLanguage(g_hWnd)
CodePage := SendMsg(2137) ; SCI_GETCODEPAGE
Pos := SendMsg(2008)
Line := SendMsg(2166, Pos)
Char := SendMsg(2007, Pos)
Size := FormatBytes(SendMsg(2006), Sep, "B", 0) . " bytes"
SelSize := FormatBytes(SendMsg(2161, 0, 0) - 1, Sep, "B", 0) . " bytes"
LV_Add("", "Lexer", SendMsg(4002) . (LexerName != "" ? " (" . LexerName . ")" : "")) ; SCI_GETLEXER
LV_Add("", "Current position", Pos + 1) ; SCI_GETCURRENTPOS
LV_Add("", "Char at position", Char . " (""" . Chr(Char) . """)") ; SCI_GETCHARAT
LV_Add("", "Style at position", SendMsg(2010, Pos)) ; SCI_GETSTYLEAT
LV_Add("", "Current line", Line + 1) ; SCI_LINEFROMPOSITION
LV_Add("", "Position from line", SendMsg(2167, Line) + 1) ; SCI_POSITIONFROMLINE
LV_Add("", "Line end position", SendMsg(2136, Line) + 1) ; SCI_GETLINEENDPOSITION
LV_Add("", "Line length", SendMsg(2350, Line)) ; SCI_LINELENGTH
LV_Add("", "Current column", SendMsg(2129, Pos) + 1) ; SCI_GETCOLUMN
LV_Add("", "Line count", SendMsg(2154)) ; SCI_GETLINECOUNT
LV_Add("", "Document size", Size) ; SCI_GETLENGTH
LV_Add("", "File encoding", (CodePage == 65001 ? "UTF-8 (65001)" : CodePage)) ; SCI_GETCODEPAGE
LV_Add("", "Modified", SendMsg(2159) ? "True" : "False") ; SCI_GETMODIFY
LV_Add("", "Read only", SendMsg(2140) ? "True" : "False") ; SCI_GETREADONLY
LV_Add("", "Wrap mode", SendMsg(2269)) ; SCI_GETWRAPMODE
LV_Add("", "Tab width", SendMsg(2121)) ; SCI_GETTABWIDTH
LV_Add("", "Indent with spaces", !SendMsg(2125) ? "True" : "False") ; SCI_GETUSETABS
LV_Add("", "Show indentation guides", SendMsg(2133) ? "True" : "False") ; SCI_GETINDENTATIONGUIDES
LV_Add("", "EOL mode", {0: "CRLF", 1: "CR", 2: "LF"}[SendMsg(2030)]) ; SCI_GETEOLMODE
LV_Add("", "Paste convert EOL", SendMsg(2468) ? "True" : "False") ; SCI_GETPASTECONVERTENDINGS
LV_Add("", "Overtype mode", SendMsg(2187) ? "1 (overtype)" : "0 (insert)") ; SCI_GETOVERTYPE
LV_Add("", "Anchor position", SendMsg(2009) + 1) ; SCI_GETANCHOR
LV_Add("", "Selection start", SendMsg(2143) + 1) ; SCI_GETSELECTIONSTART
LV_Add("", "Selection end", SendMsg(2145) + 1) ; SCI_GETSELECTIONEND
LV_Add("", "Selected text length", SelSize) ; SCI_GETSELTEXT
LV_Add("", "Selection mode", SendMsg(2423)) ; SCI_GETSELECTIONMODE
LV_Add("", "Selection is rectangular", SendMsg(2372) ? "True" : "False") ; SCI_SELECTIONISRECTANGLE
LV_Add("", "Virtual space options", SendMsg(2597)) ; SCI_GETVIRTUALSPACEOPTIONS
LV_Add("", "Rectangular selection modifier", SendMsg(2599)) ; SCI_GETRECTANGULARSELECTIONMODIFIER
; SCI_GETMOUSESELECTIONRECTANGULARSWITCH
LV_Add("", "Mouse rectangular selection", SendMsg(2669) ? "True" : "False")
LV_Add("", "Selection start line position", SendMsg(2424, Line) + 1) ; SCI_GETLINESELSTARTPOSITION
LV_Add("", "Selection end line position", SendMsg(2425, Line) + 1) ; SCI_GETLINESELENDPOSITION
LV_Add("", "Multiple selection", SendMsg(2564) ? "True" : "False") ; SCI_GETMULTIPLESELECTION
; SCI_GETADDITIONALSELECTIONTYPING
LV_Add("", "Additional selection typing", SendMsg(2566) ? "True" : "False")
LV_Add("", "Multipaste", SendMsg(2615)) ; SCI_GETMULTIPASTE
LV_Add("", "Line height", SendMsg(2279, Line)) ; SCI_TEXTHEIGHT
LV_Add("", "Baseline extra ascent", SendMsg(2526)) ; SCI_GETEXTRAASCENT
LV_Add("", "Baseline extra descent", SendMsg(2528)) ; SCI_GETEXTRADESCENT
LV_Add("", "Lines on screen", SendMsg(2370)) ; SCI_LINESONSCREEN
LV_Add("", "First visible line", SendMsg(2152) + 1) ; SCI_GETFIRSTVISIBLELINE
LV_Add("", "Current line wrap count", SendMsg(2235, Line)) ; SCI_WRAPCOUNT
LV_Add("", "Mouse hover time", SendMsg(2265)) ; SCI_GETMOUSEDWELLTIME
LV_Add("", "Word start position", SendMsg(2266, Pos, 1) + 1) ; SCI_WORDSTARTPOSITION
LV_Add("", "Word end position", SendMsg(2267, Pos, 1) + 1) ; SCI_WORDENDPOSITION
LV_Add("", "Autocomplete ignore case", SendMsg(2116) ? "True" : "False") ; SCI_AUTOCGETIGNORECASE
LV_Add("", "Autocomplete list presorted", SendMsg(2661)) ; SCI_AUTOCGETORDER
LV_Add("", "Autocomplete list max rows", SendMsg(2211)) ; SCI_AUTOCGETMAXHEIGHT
LV_Add("", "Position before", SendMsg(2417, Pos) + 1) ; SCI_POSITIONBEFORE
LV_Add("", "Position after", SendMsg(2418, Pos) + 1) ; SCI_POSITIONAFTER
LV_Add("", "Current indicator", SendMsg(2501)) ; SCI_GETINDICATORCURRENT
LV_Add("", "Target start", SendMsg(2191) + 1) ; SCI_GETTARGETSTART
LV_Add("", "Target end", SendMsg(2193) + 1) ; SCI_GETTARGETEND
LV_Add("", "Search flags", SendMsg(2199)) ; SCI_GETSEARCHFLAGS
LV_Add("", "Error status", SendMsg(2383)) ; SCI_GETSTATUS
LV_Add("", "Font quality", SendMsg(2612)) ; SCI_GETFONTQUALITY
LV_Add("", "Technology (drawing API)", SendMsg(2631)) ; SCI_GETTECHNOLOGY
LV_Add("", "Buffered drawing", SendMsg(2034) ? "True" : "False") ; SCI_GETBUFFEREDDRAW
LV_Add("", "Zoom factor", SendMsg(2374)) ; SCI_GETZOOM
LV_Add("", "Edge mode", SendMsg(2362)) ; SCI_GETEDGEMODE
LV_Add("", "Edge column", SendMsg(2360) + 1) ; SCI_GETEDGECOLUMN
LV_Add("", "Scroll width", SendMsg(2275)) ; SCI_GETSCROLLWIDTH
LV_Add("", "Scroll width tracking", SendMsg(2517) ? "True" : "False") ; SCI_GETSCROLLWIDTHTRACKING
LV_Add("", "End at last line", SendMsg(2278) ? "True" : "False") ; SCI_GETENDATLASTLINE
LV_Add("", "View white space", SendMsg(2020)) ; SCI_GETVIEWWS
LV_Add("", "White space size", SendMsg(2087)) ; SCI_GETWHITESPACESIZE
LV_Add("", "View EOL characters", SendMsg(2355) ? "True" : "False") ; SCI_GETVIEWEOL
LV_Add("", "Caret width", SendMsg(2189)) ; SCI_GETCARETWIDTH
LV_Add("", "Caret blinking rate", SendMsg(2075) . " ms") ; SCI_GETCARETPERIOD
LV_Add("", "Markers in current line", SendMsg(2046, Line)) ; SCI_MARKERGET
LV_Add("", "Automatic fold", SendMsg(2664)) ; SCI_GETAUTOMATICFOLD
LV_Add("", "All lines visible", SendMsg(2236) ? "True" : "False") ; SCI_GETALLLINESVISIBLE
;LV_Add("", "", SendMsg()) ;
Loop 5 { ; The maximum number of margins
i := A_Index - 1
LV_Add("", "Margin " . A_Index . " - type, width, mask"
, SendMsg(2241, i) . ", " . SendMsg(2243, i) . ", " . SendMsg(2245, i))
; SCI_GETMARGINTYPEN, SCI_GETMARGINWIDTHN, SCI_GETMARGINMASKN
}
}
Else If (Class == "ToolbarWindow32") {
LV_InsertCol(1, "41", "Index")
LV_InsertCol(2, "85", "Command ID")
LV_InsertCol(3, "212", "Button Text")
Items := GetToolbarItems(g_hWnd)
For Each, Item in Items {
LV_Add("", A_Index, Item.ID, Item.String)
}
}
Else If (Class == "SysHeader32") {
LV_InsertCol(1, "42", "Index")
LV_InsertCol(2, "48", "Width")
LV_InsertCol(3, "248", "Text")
Items := GetHeaderInfo(g_hWnd)
For Each, Item in Items {
LV_Add("", A_Index, Item.Width, Item.Text)
}
}
Else If (Class == "msctls_progress32") {
LV_InsertCol(1, "169", "Property")
LV_InsertCol(2, "169", "Value")
LV_Add("", "Range", SendMsg(0x407, 1) . " - " . SendMsg(0x407, 0)) ; PBM_GETRANGE
LV_Add("", "Position", SendMsg(0x408)) ; PBM_GETPOS
LV_Add("", "Step increment", SendMsg(0x40D)) ; PBM_GETSTEP
LV_Add("", "State", {1: "Normal", 2: "Error", 3: "Paused"}[SendMsg(0x411)]) ; PBM_GETSTATE
}
Else If (Class ~= "ListBox" || Class ~= "ComboBox") {
LV_InsertCol(1, "38", "Line")
LV_InsertCol(2, "300", "Text")
ControlGet ItemList, List,,, ahk_id %g_hWnd%
Loop Parse, ItemList, `n
{
LV_Add("", A_Index, A_LoopField)
}
}
Else If (Class == "msctls_statusbar32") {
LV_InsertCol(1, "38", "Part")
LV_InsertCol(2, "300", "Text")
SB_Text := GetStatusBarText(g_hWnd)
Loop Parse, SB_Text, |
{
LV_Add("", A_Index, A_LoopField)
}
}
Else If (Class == "SysTabControl32") {
LV_InsertCol(1, "42", "Index")
LV_InsertCol(2, "296", "Text")
Tabs := ControlGetTabs(g_hWnd)
Loop % Tabs.Length() {
LV_Add("", A_Index, Tabs[A_Index])
}
}
Else If (Class == "SysListView32") {
SendMessage 0x101F, 0, 0,, ahk_id %g_hWnd% ; LVM_GETHEADER
hHeader := ErrorLevel
SendMessage 0x1200, 0, 0,, ahk_id %hHeader% ; HDM_GETITEMCOUNT
Columns := ErrorLevel + 1
Loop %Columns% {
ColTitle := A_Index == 1 ? "Index" : "Column " . A_Index - 1
LV_InsertCol(A_Index, "", ColTitle)
}
ControlGet ItemList, List,,, ahk_id %g_hWnd%
Loop Parse, ItemList, `n
{
Items := StrSplit(A_LoopField, A_Tab)
LV_Add("", A_Index, Items*)
}
Loop %Columns% {
LV_ModifyCol(A_Index, "AutoHdr")
}
}
; GetMenu return value: If the window is a child window, the return value is undefined.
If (!IsChild(g_hWnd) && hMenu := GetMenu(g_hWnd)) {
GuiControl Enable, %hBtnMenu%
} Else {
GuiControl Disable, %hBtnMenu%
}
Return ;}
SendMsg(Message, wParam := 0, lParam := 0) {
SendMessage %Message%, %wParam%, %lParam%,, ahk_id %g_hWnd%
Return ErrorLevel
}
Screenshot: ;{
If (!WinExist("ahk_id" . g_hWnd)) {
Gui Spy: +OwnDialogs
MsgBox 0x40010, Error, Window no longer exists.
Return
}
If (IsChild(g_hWnd)) {
WinActivate % "ahk_id" . GetAncestor(g_hWnd)
Sleep 100
If (g_ShowBorder) {
ShowBorder(g_hWnd, -1, g_BorderColor, g_BorderWidth)
Sleep 100
Send !{PrintScreen}
Sleep 200
} Else {
CaptureWindow(hSpyWnd, g_hWnd)
}
} Else {
WinActivate ahk_id %g_hWnd%
Sleep 100
Send !{PrintScreen}
}
Loop 4 {
Index := A_Index + 90
Gui %Index%: Destroy
}
WinActivate ahk_id %hSpyWnd%
Gui Spy: +OwnDialogs
MsgBox 0x40040, %AppName%, Content copied to the clipboard.
Return ;}
CaptureWindow(hwndOwner, hwnd) {
VarSetCapacity(RECT, 16, 0)
DllCall("GetWindowRect", "Ptr", hwnd, "Ptr", &RECT)
width := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
height := NumGet(RECT, 12, "Int") - NumGet(RECT, 4, "Int")
hdc := DllCall("GetDC", "Ptr", 0, "Ptr")
hdcMem := DllCall("CreateCompatibleDC", "Ptr", hdc, "UPtr")
hBmp := DllCall("CreateCompatibleBitmap", "Ptr", hdc, "Int", width, "Int", height, "UPtr")
hdcOld := DllCall("SelectObject", "Ptr", hdcMem, "Ptr", hBmp)
DllCall("BitBlt", "Ptr", hdcMem
, "Int", 0, "Int", 0, "Int", width, "Int", height
, "Ptr", hdc, "Int", Numget(RECT, 0, "Int"), "Int", Numget(RECT, 4, "Int")
, "UInt", 0x00CC0020) ; SRCCOPY
DllCall("SelectObject", "Ptr", hdcMem, "Ptr", hdcOld)
DllCall("OpenClipboard", "Ptr", hwndOwner) ; Clipboard owner
DllCall("EmptyClipboard")
DllCall("SetClipboardData", "UInt", 0x2, "Ptr", hBmp) ; CF_BITMAP
DllCall("CloseClipboard")
DllCall("ReleaseDC", "Ptr", 0, "Ptr", hdc)
Return True
}
GetToolbarItems(hToolbar) {
WinGet PID, PID, ahk_id %hToolbar%
If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
Return
}
If (A_Is64bitOS) {
Try DllCall("IsWow64Process", "Ptr", hProc, "Int*", Is32bit := true)
} Else {
Is32bit := True
}
RPtrSize := Is32bit ? 4 : 8
TBBUTTON_SIZE := 8 + (RPtrSize * 3)
SendMessage 0x418, 0, 0,, ahk_id %hToolbar% ; TB_BUTTONCOUNT
ButtonCount := ErrorLevel
IDs := [] ; Command IDs
Loop %ButtonCount% {
Address := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "UPtr", TBBUTTON_SIZE, "UInt", 0x1000, "UInt", 4, "Ptr")
SendMessage 0x417, % A_Index - 1, Address,, ahk_id %hToolbar% ; TB_GETBUTTON
If (ErrorLevel == 1) {
VarSetCapacity(TBBUTTON, TBBUTTON_SIZE, 0)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Ptr", &TBBUTTON, "UPtr", TBBUTTON_SIZE, "Ptr", 0)
IDs.Push(NumGet(&TBBUTTON, 4, "Int"))
}
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", Address, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
}
ToolbarItems := []
Loop % IDs.Length() {
ButtonID := IDs[A_Index]
;SendMessage 0x44B, %ButtonID% , 0,, ahk_id %hToolbar% ; TB_GETBUTTONTEXTW
;BufferSize := ErrorLevel * 2
BufferSize := 128
Address := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0, "UPtr", BufferSize, "UInt", 0x1000, "UInt", 4, "Ptr")
SendMessage 0x44B, %ButtonID%, Address,, ahk_id %hToolbar% ; TB_GETBUTTONTEXTW
VarSetCapacity(Buffer, BufferSize, 0)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", Address, "Ptr", &Buffer, "UPtr", BufferSize, "Ptr", 0)
ToolbarItems.Push({"ID": IDs[A_Index], "String": Buffer})
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", Address, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
}
DllCall("CloseHandle", "Ptr", hProc)
Return ToolbarItems
}
LoadWindowsTab: ;{
GoSub LoadChildList
GoSub LoadSiblingList
hParent := GetParent(g_hWnd)
ParentClass := (hParent) ? " (" GetClassName(hParent) . ")" : ""
ParentLink := "<a>" . Format("0x{:08X}", hParent) . "</a>" . ParentClass
GuiControl, Spy:, ParentLink, %ParentLink%
hOwner := GetOwner(g_hWnd)
OwnerClass := (hOwner) ? " (" GetClassName(hOwner) . ")" : ""
OwnerLink := "<a>" . Format("0x{:08X}", hOwner) . "</a>" . OwnerClass
GuiControl, Spy:, OwnerLink, %OwnerLink%
Return ;}
LinkToHandle: ;{
GuiControlGet LinkText, Spy:, %A_GuiControl%
If (RegExMatch(LinkText, "(0x\w+)", Match)) {
ShowWindowInfoIfExist(Match)
}
Return ;}
WindowsTabHandler: ;{
If (A_GuiEvent == "N") {
Code := NumGet(A_EventInfo + 0, A_PtrSize * 2, "Int")
If (Code == -551) { ; TCN_SELCHANGE
SendMessage 0x130B, 0, 0,, ahk_id %hWindowsTab% ; TCM_GETCURSEL
nTab := Errorlevel + 1
If (nTab == 1) {
GuiControl Hide, %hSiblingList%
GuiControl Show, %hChildList%
} Else {
GuiControl Hide, %hChildList%
GuiControl Show, %hSiblingList%
}
}
}
Return ;}
LoadChildList: ;{
Gui Spy: ListView, %hChildList%
LV_Delete()
WinGet ChildList, ControlListHwnd, ahk_id %g_hWnd%
Loop Parse, ChildList, `n
{
If (GetParent(A_LoopField) != g_hWnd) {
Continue
}
WinGetClass Class, ahk_id %A_LoopField%
ControlGetText Text,, ahk_id %A_LoopField%
LV_Add("", Format("0x{:08X}", A_LoopField), Class, Text)
}
Return ;}
LoadSiblingList: ;{
Gui Spy: ListView, %hSiblingList%
LV_Delete()
hParent := GetParent(g_hWnd)
If (IsChild(g_hWnd)) {
WinGet SiblingList, ControlListHwnd, ahk_id %hParent%
Loop Parse, SiblingList, `n
{
If (A_LoopField == g_hWnd) {
Continue
}
If (GetParent(A_LoopField) != hParent) {
Continue
}
WinGetClass Class, ahk_id %A_LoopField%
ControlGetText Text,, ahk_id %A_LoopField%
LV_Add("", Format("0x{:08X}", A_LoopField), Class, Text)
}
} Else {
WinGet WinList, List, % (hParent == 0) ? "" : "ahk_id " . hParent
Loop %WinList% {
hWnd := WinList%A_Index%
If (hWnd == g_hWnd) {
Continue
}
WinGetClass Class, ahk_id %hWnd%
WinGetTitle Text, ahk_id %hWnd%
LV_Add("", Format("0x{:08X}", hWnd), Class, Text)
}
}
Return ;}
ChildListHandler:
SiblingListHandler: ;{
Gui Spy: ListView, % (A_ThisLabel == "ChildListHandler") ? hChildList : hSiblingList
If (A_GuiEvent != "ColClick") {
LV_GetText(hWnd, LV_GetNext())
ShowWindowInfoIfExist(hWnd)
}
Return ;}
OnWM_KEYDOWN(wParam, lParam, msg, hWnd) {
Global
If (wParam == 112) { ; F1
GoSub ShowHelp
} Else If (wParam == 113) { ; F2
If (hParent := GetParent(g_hWnd)) {
g_hWnd := hParent
ShowWindowInfo()
}
} Else If (wParam == 114) { ; F3
GoSub ShowFindDlg
} Else If (wParam == 115) { ; F4
GoSub ShowTree
} Else If (wParam == 116) { ; F5
If (WinActive("ahk_id" . hTreeWnd)) {
Return
}
Gui Spy: Submit, NoHide
ShowWindowInfoIfExist(EdtHandle)
} Else If (wParam == 117) { ; F6
GoSub FlashWindow
} Else If (wParam == 118) { ; F7
GoSub ShowXYWHDlg
} Else If (wParam == 119) { ; F8
GoSub CopyToClipboard
} Else If (wParam == 120) { ; F9
GoSub Screenshot
}
}
UpdateTitleBar: ;{
WinGetClass Class, ahk_id %g_hWnd%
hWnd := Format("0x{:X}", g_hWnd)
WinSetTitle ahk_id %hSpyWnd%,, %AppName% [%hWnd%`, %Class%]
Return ;}
; https://autohotkey.com/board/topic/70727-ahk-l-controlgettabs/
ControlGetTabs(hTab) {
Static MAX_TEXT_LENGTH := 260
, MAX_TEXT_SIZE := MAX_TEXT_LENGTH * (A_IsUnicode ? 2 : 1)
WinGet PID, PID, ahk_id %hTab%
; Open the process for read/write and query info.
; PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION
If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
Return
}
; Should we use the 32-bit struct or the 64-bit struct?
If (A_Is64bitOS) {
Try DllCall("IsWow64Process", "Ptr", hProc, "Int*", Is32bit := true)
} Else {
Is32bit := True
}
RPtrSize := Is32bit ? 4 : 8
TCITEM_SIZE := 16 + RPtrSize * 3
; Allocate a buffer in the (presumably) remote process.
remote_item := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0
, "uPtr", TCITEM_SIZE + MAX_TEXT_SIZE
, "UInt", 0x1000, "UInt", 4, "Ptr") ; MEM_COMMIT, PAGE_READWRITE
remote_text := remote_item + TCITEM_SIZE
; Prepare the TCITEM structure locally.
VarSetCapacity(TCITEM, TCITEM_SIZE, 0)
NumPut(1, TCITEM, 0, "UInt") ; mask (TCIF_TEXT)
NumPut(remote_text, TCITEM, 8 + RPtrSize) ; pszText
NumPut(MAX_TEXT_LENGTH, TCITEM, 8 + RPtrSize * 2, "Int") ; cchTextMax
; Write the local structure into the remote buffer.
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", remote_item, "Ptr", &TCITEM, "UPtr", TCITEM_SIZE, "Ptr", 0)
Tabs := []
VarSetCapacity(TabText, MAX_TEXT_SIZE)
SendMessage 0x1304, 0, 0,, ahk_id %hTab% ; TCM_GETITEMCOUNT
Loop % (ErrorLevel != "FAIL") ? ErrorLevel : 0 {
; Retrieve the item text.
SendMessage, % (A_IsUnicode) ? 0x133C : 0x1305, A_Index - 1, remote_item,, ahk_id %hTab% ; TCM_GETITEM
If (ErrorLevel == 1) { ; Success
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", remote_text, "Ptr", &TabText, "UPtr", MAX_TEXT_SIZE, "Ptr", 0)
} Else {
TabText := ""
}
Tabs[A_Index] := TabText
}
; Release the remote memory and handle.
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", remote_item, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
DllCall("CloseHandle", "Ptr", hProc)
Return Tabs
}
SetDHW: ;{
g_DetectHidden := !g_DetectHidden
Return ;}
SetMinimize: ;{
g_Minimize := !g_Minimize
Return ;}
SetExplorerTheme(hWnd) {
DllCall("UxTheme.dll\SetWindowTheme", "Ptr", hWnd, "WStr", "Explorer", "Ptr", 0)
}
SetButtonIcon(hButton, File, Index := 1) {
himl := DllCall("ImageList_Create", "Int", 16, "Int", 16, "UInt", 0x20, "Int", 1, "Int", 1, "Ptr") ; ILC_COLOR32
IL_Add(himl, File, Index)
VarSetCapacity(BUTTON_IMAGELIST, 20 + A_PtrSize, 0)
NumPut(himl, BUTTON_IMAGELIST, 0, "Ptr")
NumPut(4, BUTTON_IMAGELIST, 16 + A_PtrSize, "UInt") ; Alignment (BUTTON_IMAGELIST_ALIGN_CENTER)
SendMessage 0x1602, 0, &BUTTON_IMAGELIST,, ahk_id %hButton% ; BCM_SETIMAGELIST
Return ErrorLevel
}
ShowXYWHDlg: ;{
Gui XYWH: New, LabelXYWH
Gui Font, s9, Segoe UI
Gui Color, White
Gui Add, GroupBox, x10 y6 w145 h105, Relative to:
Gui Add, Radio, vClientCoords gSetXYWH x25 y27 w120 h23 +Checked, Client area
Gui Add, Radio, vWindowCoords gSetXYWH x25 y51 w120 h23, Window border
Gui Add, Radio, vScreenCoords gSetXYWH x25 y75 w120 h23, Screen coords
Gui Add, GroupBox, x166 y5 w253 h105
Gui Add, Text, x182 y31 w26 h23 +0x200, X:
Gui Add, Edit, vEdtX x209 y31 w70 h21
Gui Add, UpDown, gMoveWindow Range-64000-64000 +0x80
Gui Add, Text, x303 y31 w26 h23 +0x200, Y:
Gui Add, Edit, vEdtY x330 y31 w70 h21
Gui Add, UpDown, gMoveWindow Range-64000-64000 +0x80
Gui Add, Text, x182 y69 w26 h23 +0x200, W:
Gui Add, Edit, vEdtW x209 y69 w70 h21
Gui Add, UpDown, gMoveWindow Range-64000-64000 +0x80
Gui Add, Text, x303 y69 w26 h23 +0x200, H:
Gui Add, Edit, vEdtH x330 y69 w70 h21
Gui Add, UpDown, gMoveWindow Range-64000-64000 +0x80
Gui Add, Text, x-1 y121 w460 h49 +0x200 -Background +Border
Gui Add, Button, gResetXYWH x9 y133 w88 h25, &Reset
Gui Add, Button, gMoveWindow x235 y133 w88 h25 +Default, &Apply
Gui Add, Button, gXYWHClose x331 y133 w88 h25, &Close
Gui Show, w429 h170, Position and Size
g_NewXYWH := True
GoSub SetXYWH
If (IsChild(g_hWnd)) {
GuiControl Enable, ClientCoords
GuiControl Enable, WindowCoords
GuiControl Enable, ScreenCoords
} Else {
GuiControl Disable, ClientCoords
GuiControl Disable, WindowCoords
GuiControl Disable, ScreenCoords
GuiControl,, ScreenCoords, 1
}
Return ;}
XYWHEscape:
XYWHClose: ;{
Gui XYWH: Destroy
Return ;}
SetXYWH: ;{
Gui XYWH: Submit, NoHide
If (IsChild(g_hWnd)) {
If (ClientCoords) {
GetWindowPos(g_hWnd, X, Y, W, H)
} Else If (WindowCoords) {
ControlGetPos X, Y, W, H,, ahk_id %g_hWnd%
} Else If (ScreenCoords) {
WinGetPos X, Y, W, H, ahk_id %g_hWnd%
}
} Else { ; Top-level window
WinGetPos X, Y, W, H, ahk_id %g_hWnd%
}
GuiControl, XYWH:, EdtX, %X%
GuiControl, XYWH:, EdtY, %Y%
GuiControl, XYWH:, EdtW, %W%
GuiControl, XYWH:, EdtH, %H%
If (g_NewXYWH) {
g_BackupXYWH := [X, Y, W, H]
g_NewXYWH := False
}
Return ;}
MoveWindow: ;{
Gui XYWH: Submit, NoHide
If (IsChild(g_hWnd)) {
If (ClientCoords) {
SetWindowPos(g_hWnd, EdtX, EdtY, EdtW, EdtH, 0, 0x14) ; SWP_NOACTIVATE | SWP_NOZORDER
} Else If (WindowCoords) {
ControlMove,, %EdtX%, %EdtY%, %EdtW%, %EdtH%, ahk_id %g_hWnd%
} Else If (ScreenCoords) {
VarSetCapacity(POINT, 8, 0)
NumPut(EdtX, POINT, 0)
NumPut(EdtY, POINT, 4)
DllCall("ScreenToClient", "Ptr", GetParent(g_hWnd), "Ptr", &POINT) ; PARENT
X := NumGet(POINT, 0)
Y := NumGet(POINT, 4)
SetWindowPos(g_hWnd, X, Y, EdtW, EdtH, 0, 0x14) ; SWP_NOACTIVATE | SWP_NOZORDER
}
} Else {
WinMove ahk_id %g_hWnd%,, %EdtX%, %EdtY%, %EdtW%, %EdtH%
}
WinSet Redraw,, ahk_id %g_hWnd%
Return ;}
ResetXYWH: ;{
Gui XYWH: Submit, NoHide
If (IsChild(g_hWnd)) {
GuiControl, XYWH:, ClientCoords, 1
}
GuiControl,, EdtX, % g_BackupXYWH[1]
GuiControl,, EdtY, % g_BackupXYWH[2]
GuiControl,, EdtW, % g_BackupXYWH[3]
GuiControl,, EdtH, % g_BackupXYWH[4]
GoSub MoveWindow
Return ;}
OnWM_RBUTTONDOWN(wParam, lParam, msg, hWnd) {
Global
If (hWnd == hLbxStyles || hWnd == hLbxExStyles || hWnd == hLbxExtraStyles) {
SendMessage 0x1A9, 0, lParam,, ahk_id %hWnd% ; LB_ITEMFROMPOINT
Index := ErrorLevel
SendMessage 0x18A, %Index%, 0,, ahk_id %hWnd% ; LB_GETTEXTLEN
Len := ErrorLevel
VarSetCapacity(LB_Text, Len << !!A_IsUnicode, 0)
SendMessage 0x189, %Index%, % &LB_Text,, ahk_id %hWnd% ; LB_GETTEXT
Const := StrSplit(StrGet(&LB_Text, Len), "`t")[1]
Desc := StrReplace(oStyles[Const].Desc, "\n", "`n")
GuiControl,, GrpDesc, %Const%
GuiControl,, TxtDesc, %Desc%
}
}
ShowWindowInfoIfExist(hWnd) {
If (IsWindow(hWnd)) {
g_hWnd := hWnd
ShowWindowInfo()
} Else {
Gui Spy: +OwnDialogs
MsgBox 0x40010, %AppName%, Invalid window handle.
}
}
; Returns an object containing the text and width of each item of a remote SysHeader32 control
GetHeaderInfo(hHeader) {
Static MAX_TEXT_LENGTH := 260
, MAX_TEXT_SIZE := MAX_TEXT_LENGTH * (A_IsUnicode ? 2 : 1)
WinGet PID, PID, ahk_id %hHeader%
; Open the process for read/write and query info.
; PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION
If !(hProc := DllCall("OpenProcess", "UInt", 0x438, "Int", False, "UInt", PID, "Ptr")) {
Return
}
; Should we use the 32-bit struct or the 64-bit struct?
If (A_Is64bitOS) {
Try DllCall("IsWow64Process", "Ptr", hProc, "Int*", Is32bit := True)
} Else {
Is32bit := True
}
RPtrSize := Is32bit ? 4 : 8
cbHDITEM := (4 * 6) + (RPtrSize * 6)
; Allocate a buffer in the remote process.
remote_item := DllCall("VirtualAllocEx", "Ptr", hProc, "Ptr", 0
, "UPtr", cbHDITEM + MAX_TEXT_SIZE
, "UInt", 0x1000, "UInt", 4, "Ptr") ; MEM_COMMIT, PAGE_READWRITE
remote_text := remote_item + cbHDITEM
; Prepare the HDITEM structure locally.
VarSetCapacity(HDITEM, cbHDITEM, 0)
NumPut(0x3, HDITEM, 0, "UInt") ; mask (HDI_WIDTH | HDI_TEXT)
NumPut(remote_text, HDITEM, 8, "Ptr") ; pszText
NumPut(MAX_TEXT_LENGTH, HDITEM, 8 + RPtrSize * 2, "Int") ; cchTextMax
; Write the local structure into the remote buffer.
DllCall("WriteProcessMemory", "Ptr", hProc, "Ptr", remote_item, "Ptr", &HDITEM, "UPtr", cbHDITEM, "Ptr", 0)
HDInfo := {}
VarSetCapacity(HDText, MAX_TEXT_SIZE)
SendMessage 0x1200, 0, 0,, ahk_id %hHeader% ; HDM_GETITEMCOUNT
Loop % (ErrorLevel != "FAIL") ? ErrorLevel : 0 {
; Retrieve the item text.
SendMessage, % (A_IsUnicode) ? 0x120B : 0x1203, A_Index - 1, remote_item,, ahk_id %hHeader% ; HDM_GETITEMW
If (ErrorLevel == 1) { ; Success
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", remote_item, "Ptr", &HDITEM, "UPtr", cbHDITEM, "Ptr", 0)
DllCall("ReadProcessMemory", "Ptr", hProc, "Ptr", remote_text, "Ptr", &HDText, "UPtr", MAX_TEXT_SIZE, "Ptr", 0)
} Else {
HDText := ""
}
HDInfo.Push({"Width": NumGet(HDITEM, 4, "UInt"), "Text": HDText})
}
; Release the remote memory and handle.
DllCall("VirtualFreeEx", "Ptr", hProc, "Ptr", remote_item, "UPtr", 0, "UInt", 0x8000) ; MEM_RELEASE
DllCall("CloseHandle", "Ptr", hProc)
Return HDInfo
}
SetMouseCoordMode: ;{
GuiControlGet g_MouseCoordMode, Spy:, MouseCoordMode
Return ;}
GetClientCoords(hWnd, ByRef x, ByRef y) {
VarSetCapacity(POINT, 8, 0)
NumPut(x, POINT, 0, "Int")
NumPut(y, POINT, 4, "Int")
hParent := GetParent(hWnd)
DllCall("ScreenToClient", "Ptr", (hParent == 0 ? hWnd : hParent), "Ptr", &POINT)
x := NumGet(POINT, 0, "Int")
y := NumGet(POINT, 4, "Int")
}
GetWindowCoords(hWnd, ByRef x, ByRef y) {
hParent := GetParent(hWnd)
WinGetPos px, py,,, % "ahk_id" . (hParent == 0 ? hWnd : hParent)
x := x - px
y := y - py
}
; fnbar: 0 = horizontal, 1 = vertical, 2 = hWnd is a scroll bar
GetScrollInfo(hWnd, fnBar := 1) {
Local o := {}
NumPut(VarSetCapacity(SCROLLINFO, 28, 0), SCROLLINFO, 0, "UInt")
NumPut(0x1F, SCROLLINFO, 4, "UInt") ; fMask: SIF_ALL
DllCall("GetScrollInfo", "Ptr", hWnd, "Int", fnBar, "Ptr", &SCROLLINFO)
o.Min := NumGet(SCROLLINFO, 8, "Int")
o.Max := NumGet(SCROLLINFO, 12, "Int")
o.Page := NumGet(SCROLLINFO, 16, "UInt")
o.Pos := NumGet(SCROLLINFO, 20, "Int")
Return o
}
ShowScrollBarInfo: ;{
V := H := "No"
WinGet Style, Style, ahk_id %g_hWnd%
WinGetClass Class, ahk_id %g_hWnd%
If (Class == "ScrollBar") {
If (Style & 1) { ; SBS_VERT
V := "Yes"
VSB := GetScrollInfo(g_hWnd, 2)
} Else {
H := "Yes"
HSB := GetScrollInfo(g_hWnd, 2)
}
} Else {
If (Style & 0x200000) { ; WS_VSCROLL
V := "Yes"
}
If (Style & 0x100000) { ; WS_HSCROLL
H := "Yes"
}
HSB := GetScrollInfo(g_hWnd, 0)
VSB := GetScrollInfo(g_hWnd, 1)
}
HPercent := (HSB.Pos) ? " (" . Round(HSB.Pos / (HSB.Max - HSB.Min) * 100) . "%)" : ""
VPercent := (VSB.Pos) ? " (" . Round(VSB.Pos / (VSB.Max - VSB.Min) * 100) . "%)" : ""
Gui ScrollInfo: New, LabelScrollInfo hWndhScrollInfo -MinimizeBox OwnerSpy
SetWindowIcon(hScrollInfo, ResDir . "\TreeIcons.icl", 31)
Gui Font, s9, Segoe UI
Gui Color, White
Gui Add, CheckBox, w0 y0
Gui Add, GroupBox, x15 y13 w148 h152, Horizontal Scrollbar
Gui Add, Text, x24 y32 w60 h23 +0x200, Visible:
Gui Add, Edit, x86 y36 w60 h21 -E0x200, %H%
Gui Add, Text, x24 y57 w60 h23 +0x200, Minimum:
Gui Add, Edit, x86 y61 w60 h21 -E0x200, % HSB.Min
Gui Add, Text, x24 y82 w60 h23 +0x200, Maximum:
Gui Add, Edit, x86 y86 w60 h21 -E0x200, % HSB.Max
Gui Add, Text, x24 y107 w60 h23 +0x200, Position:
Gui Add, Edit, x86 y111 w70 h21 -E0x200, % HSB.Pos . HPercent
Gui Add, Text, x24 y132 w60 h23 +0x200, Page size:
Gui Add, Edit, x86 y136 w60 h21 -E0x200, % HSB.Page
Gui Add, GroupBox, x178 y13 w148 h152, Vertical Scrollbar
Gui Add, Text, x188 y32 w56 h23 +0x200, Visible:
Gui Add, Edit, x250 y36 w60 h21 -E0x200, %V%
Gui Add, Text, x188 y57 w56 h23 +0x200, Minimum:
Gui Add, Edit, x250 y61 w60 h21 -E0x200, % VSB.Min
Gui Add, Text, x188 y82 w56 h23 +0x200, Maximum:
Gui Add, Edit, x250 y86 w60 h21 -E0x200, % VSB.Max
Gui Add, Text, x188 y107 w56 h23 +0x200, Position:
Gui Add, Edit, x250 y111 w70 h21 -E0x200, % VSB.Pos . VPercent
Gui Add, Text, x188 y132 w56 h23 +0x200, Page size:
Gui Add, Edit, x250 y136 w60 h21 -E0x200, % VSB.Page
Gui Add, Text, x-1 y180 w343 h50 -Background +Border
Gui Add, Button, gScrollInfoClose x247 y193 w84 h24 +Default, &OK
WinGetPos, X, Y,,, ahk_id %hSpyWnd%
x += 30
y += 109
Gui Show, x%x% y%y% w341 h229, Scrollbars
Return ;}
ScrollInfoEscape:
ScrollInfoClose: ;{
Gui ScrollInfo: Destroy
Return ;}
GetSysColorName(Value) {
Static SysColors := {0: "COLOR_SCROLLBAR"
, 1: "COLOR_BACKGROUND"
, 2: "COLOR_ACTIVECAPTION"
, 3: "COLOR_INACTIVECAPTION"
, 4: "COLOR_MENU"
, 5: "COLOR_WINDOW"
, 6: "COLOR_WINDOWFRAME"
, 7: "COLOR_MENUTEXT"
, 8: "COLOR_WINDOWTEXT"
, 9: "COLOR_CAPTIONTEXT"
, 10: "COLOR_ACTIVEBORDER"
, 11: "COLOR_INACTIVEBORDER"
, 12: "COLOR_APPWORKSPACE"
, 13: "COLOR_HIGHLIGHT"
, 14: "COLOR_HIGHLIGHTTEXT"
, 15: "COLOR_BTNFACE"
, 16: "COLOR_BTNSHADOW"
, 17: "COLOR_GRAYTEXT"
, 18: "COLOR_BTNTEXT"
, 19: "COLOR_INACTIVECAPTIONTEXT"
, 20: "COLOR_BTNHIGHLIGHT"
, 21: "COLOR_3DDKSHADOW"
, 22: "COLOR_3DLIGHT"
, 23: "COLOR_INFOTEXT"
, 24: "COLOR_INFOBK"
, 26: "COLOR_HOTLIGHT"
, 27: "COLOR_GRADIENTACTIVECAPTION"
, 28: "COLOR_GRADIENTINACTIVECAPTION"
, 29: "COLOR_MENUHILIGHT"
, 30: "COLOR_MENUBAR"}
Color := SysColors[Value]
Return (Color == "") ? Value : Color
}
GetWindowPos(hWnd, ByRef X, ByRef Y, ByRef W, ByRef H) {
VarSetCapacity(RECT, 16, 0)
DllCall("GetWindowRect", "Ptr", hWnd, "Ptr", &RECT)
DllCall("MapWindowPoints", "Ptr", 0, "Ptr", GetParent(hWnd), "Ptr", &RECT, "UInt", 2)
X := NumGet(RECT, 0, "Int")
Y := NumGet(RECT, 4, "Int")
w := NumGet(RECT, 8, "Int") - X
H := NumGet(RECT, 12, "Int") - Y
}
FindToolHandler: ;{
If (g_Minimize) {
WinMove ahk_id %hSpyWnd%,,,,, 78
g_Minimized := True
}
Dragging := True
GuiControl,, %hFindTool%, %Bitmap2%
DllCall("SetCapture", "Ptr", hSpyWnd)
hOldCursor := DllCall("SetCursor", "Ptr", hCrossHair, "Ptr")
Return ;}
OnWM_MOUSEMOVE(wParam, lParam, msg, hWnd) {
Static hOldWnd := 0
If (Dragging) {
MouseGetPos x, y, hWin, hCtl, 2
g_hWnd := (hCtl == "") ? hWin : hCtl
If (g_MouseCoordMode != "Screen") {
SendMessage 0x84, 0, % y << 16 | x,, ahk_id %hWnd% ; WM_NCHITTEST
HitTest := ErrorLevel
If (HitTest == 1 || hCtl != "") { ; 1 = HTCLIENT
If (g_MouseCoordMode == "Client") {
GetClientCoords(g_hWnd, x, y)
} Else If (g_MouseCoordMode == "Window") {
GetWindowCoords(g_hWnd, x, y)
}
}
}
GuiControl, Spy:, EdtCursor, %x%, %y%
If (g_DetectHidden) {
g_hWnd := ControlFromPoint(x, y, g_hWnd)
}
If (g_hWnd != hOldWnd && !IsBorder(g_hWnd)) {
ShowBorder(g_hWnd, -1)
If (IsChild(g_hWnd)) {
MouseGetPos,,,, ClassNN
LoadControlInfo(ClassNN)
} Else {
LoadWindowInfo()
}
GoSub UpdateTitleBar
}
hOldWnd := g_hWnd
}
}
OnWM_LBUTTONUP(wParam, lParam, msg, hWnd) {
If (Dragging) {
Dragging := False
DllCall("ReleaseCapture")
DllCall("SetCursor", "Ptr", hOldCursor)
GuiControl,, %hFindTool%, %Bitmap1%
Loop 4 {
Index := A_Index + 90
Gui %Index%: Destroy
}
MouseGetPos,,,, ClassNN
ShowWindowInfo()
If (g_Minimized) {
If (Workaround) {
SendMessage 0x130C, 1, 0,, ahk_id %hTab% ; TCM_SETCURSEL
SendMessage 0x1330, 0, 0,, ahk_id %hTab% ; TCM_SETCURFOCUS
Sleep 0
SendMessage 0x130C, 0, 0,, ahk_id %hTab% ; TCM_SETCURSEL
Workaround := False
}
WinMove ahk_id %hSpyWnd%,,,,, 493
}
}
}
SetWindowIcon(hWnd, Filename, Index := 1) {
Local hSmIcon := LoadPicture(Filename, "w16 Icon" . Index, ErrorLevel)
SendMessage 0x80, 0, hSmIcon,, ahk_id %hWnd% ; WM_SETICON, ICON_SMALL
Return ErrorLevel
}
GetWindowPlacement(hWnd) {
VarSetCapacity(WINDOWPLACEMENT, 44, 0)
NumPut(44, WINDOWPLACEMENT)
DllCall("GetWindowPlacement", "Ptr", hWnd, "Ptr", &WINDOWPLACEMENT)
Result := {}
Result.x := NumGet(WINDOWPLACEMENT, 7 * 4, "UInt")
Result.y := NumGet(WINDOWPLACEMENT, 8 * 4, "UInt")
Result.w := NumGet(WINDOWPLACEMENT, 9 * 4, "UInt") - Result.x
Result.h := NumGet(WINDOWPLACEMENT, 10 * 4, "UInt") - Result.y
Result.showCmd := NumGet(WINDOWPLACEMENT, 8, "UInt")
; 1 = normal, 2 = minimized, 3 = maximized
Return Result
}
GetWindowInfo(hWnd) {
NumPut(VarSetCapacity(WINDOWINFO, 60, 0), WINDOWINFO)
DllCall("GetWindowInfo", "Ptr", hWnd, "Ptr", &WINDOWINFO)
wi := Object()
wi.WindowX := NumGet(WINDOWINFO, 4, "Int")
wi.WindowY := NumGet(WINDOWINFO, 8, "Int")
wi.WindowW := NumGet(WINDOWINFO, 12, "Int") - wi.WindowX
wi.WindowH := NumGet(WINDOWINFO, 16, "Int") - wi.WindowY
wi.ClientX := NumGet(WINDOWINFO, 20, "Int")
wi.ClientY := NumGet(WINDOWINFO, 24, "Int")
wi.ClientW := NumGet(WINDOWINFO, 28, "Int") - wi.ClientX
wi.ClientH := NumGet(WINDOWINFO, 32, "Int") - wi.ClientY
wi.Style := NumGet(WINDOWINFO, 36, "UInt")
wi.ExStyle := NumGet(WINDOWINFO, 40, "UInt")
wi.Active := NumGet(WINDOWINFO, 44, "UInt")
wi.BorderW := NumGet(WINDOWINFO, 48, "UInt")
wi.BorderH := NumGet(WINDOWINFO, 52, "UInt")
wi.Atom := NumGet(WINDOWINFO, 56, "UShort")
wi.Version := NumGet(WINDOWINFO, 58, "UShort")
Return wi
}
GetParent(hWnd) {
Return DllCall("GetParent", "Ptr", hWnd, "Ptr")
}
GetOwner(hWnd) {
Return DllCall("GetWindow", "Ptr", hWnd, "UInt", 4, "Ptr") ; GW_OWNER
}
ShowWindow(hWnd, nCmdShow := 1) {
DllCall("ShowWindow", "Ptr", hWnd, "Int", nCmdShow)
}
IsWindow(hWnd) {
Return DllCall("IsWindow", "Ptr", hWnd)
}
IsWindowVisible(hWnd) {
Return DllCall("IsWindowVisible", "Ptr", hWnd)
}
GetMenu(hWnd) {
Return DllCall("GetMenu", "Ptr", hWnd, "Ptr")
}
GetSubMenu(hMenu, nPos) {
Return DllCall("GetSubMenu", "Ptr", hMenu, "Int", nPos, "Ptr")
}
GetMenuItemCount(hMenu) {
Return DllCall("GetMenuItemCount", "Ptr", hMenu)
}
GetMenuItemID(hMenu, nPos) {
Return DllCall("GetMenuItemID", "Ptr", hMenu, "Int", nPos)
}
GetMenuString(hMenu, uIDItem) {
; uIDItem: the zero-based relative position of the menu item
Local lpString, MenuItemID
VarSetCapacity(lpString, 4096)
If !(DllCall("GetMenuString", "Ptr", hMenu, "UInt", uIDItem, "Str", lpString, "Int", 4096, "UInt", 0x400)) {
MenuItemID := GetMenuItemID(hMenu, uIDItem)
If (MenuItemID > -1) {
Return "SEPARATOR"
} Else {
Return (GetSubMenu(hMenu, uIDItem)) ? "SUBMENU" : "ERROR"
}
}
Return lpString
}
GetClassName(hWnd) {
WinGetClass Class, ahk_id %hWnd%
Return Class
}
GetFileIcon(File, SmallIcon := 1) {
VarSetCapacity(SHFILEINFO, cbFileInfo := A_PtrSize + 688)
If (DllCall("Shell32.dll\SHGetFileInfoW"
, "WStr", File
, "UInt", 0
, "Ptr" , &SHFILEINFO
, "UInt", cbFileInfo
, "UInt", 0x100 | SmallIcon)) { ; SHGFI_ICON
Return NumGet(SHFILEINFO, 0, "Ptr")
}
}
SetWindowPos(hWnd, x, y, w, h, hWndInsertAfter := 0, uFlags := 0x40) { ; SWP_SHOWWINDOW
Return DllCall("SetWindowPos", "Ptr", hWnd, "Ptr", hWndInsertAfter, "Int", x, "Int", y, "Int", w, "Int", h, "UInt", uFlags)
}
ShowSettingsDlg: ;{
Gui Settings: New, LabelSettings hWndhSettingsDlg -MinimizeBox OwnerSpy
SetWindowIcon(hSettingsDlg, ResDir . "\Settings.ico")
Gui Font, s9, Segoe UI
Gui Color, White
Gui Add, GroupBox, x8 y7 w319 h56, %AppName%
Gui Add, CheckBox, vg_AlwaysOnTop x20 y27 w291 h23 Checked%g_AlwaysOnTop%, Show the window always on top
Gui Add, GroupBox, x8 y69 w319 h152, Screenshot
Gui Add, Radio, % "x20 y88 w290 h23 " . (!g_ShowBorder ? "Checked" : "")
, Capture the contents of the control only
Gui Add, Radio, vg_ShowBorder x20 y118 w290 h23 Checked%g_ShowBorder%
, Display a border around the control
Gui Add, Text, x36 y150 w78 h23 +0x200, Border color:
Gui Add, Progress, vBorderColorPreview x119 y151 w23 h23 +0x800000 c%g_BorderColor%, 100
Gui Add, Button, gChooseBorderColor x150 y150 w80 h24, Choose
Gui Add, Text, x36 y183 w79 h23 +0x200, Border width:
Gui Add, Edit, vg_BorderWidth x119 y184 w42 h21
Gui Add, UpDown, x159 y184 w18 h21, %g_BorderWidth%
Gui Add, Text, x-1 y231 w338 h48 -Background +Border
Gui Add, Button, gApplySettings x152 y243 w84 h24 +Default, &OK
Gui Add, Button, gSettingsClose x243 y243 w84 h24, &Cancel
Gui Show, w335 h278, Settings
Return ;}
SettingsEscape:
SettingsClose: ;{
Gui Settings: Destroy
Return ;}
ApplySettings: ;{
Gui Settings: Submit
WinSet AlwaysOnTop, % g_AlwaysOnTop ? "On" : "Off", ahk_id %hSpyWnd%
g_ShowBorder := (g_ShowBorder == 2) ? 1 : 0
g_BorderColor := g_BorderColorTemp
Return ;}
ChooseBorderColor: ;{
g_BorderColorTemp := g_BorderColor
If (ChooseColor(g_BorderColorTemp, hSettingsDlg)) {
GuiControl, Settings: +c%g_BorderColorTemp%, BorderColorPreview
}
Return ;}
ChooseColor(ByRef Color, hOwner := 0) {
rgbResult := ((Color & 0xFF) << 16) + (Color & 0xFF00) + ((Color >> 16) & 0xFF)
VarSetCapacity(CUSTOM, 64, 0)
NumPut(VarSetCapacity(CHOOSECOLOR, A_PtrSize * 9, 0), CHOOSECOLOR, 0)
NumPut(hOwner, CHOOSECOLOR, A_PtrSize)
NumPut(rgbResult, CHOOSECOLOR, A_PtrSize * 3)
NumPut(&CUSTOM, CHOOSECOLOR, A_PtrSize * 4) ; COLORREF *lpCustColors
NumPut(0x103, CHOOSECOLOR, A_PtrSize * 5) ; Flags: CC_ANYCOLOR | CC_RGBINIT | CC_FULLOPEN
RetVal := DllCall("comdlg32\ChooseColorA", "Str", CHOOSECOLOR)
If (ErrorLevel != 0 || RetVal == 0) {
Return False
}
rgbResult := NumGet(CHOOSECOLOR, A_PtrSize * 3)
Color := (rgbResult & 0xFF00) + ((rgbResult & 0xFF0000) >> 16) + ((rgbResult & 0xFF) << 16)
Color := Format("0x{:06X}", Color)
Return True
}
OnWM_SYSCOMMAND(wParam, lParam, msg, hWnd) {
If (wParam == 0xC0DE) {
Gui Spy: +OwnDialogs
MsgBox 0x40040, About, %AppName% %Version%`nWindow information tool`n`nCredits:`n - J Brown (WinSpy++ developer)`n - Lexicos (AutoHotkey developer)
}
}
ShowFindDlg: ;{
If (FindDlgExist) {
Gui Find: Show
} Else {
Gui Find: New, LabelFind hWndhFindDlg
Gui Font, s9, Segoe UI
Gui Color, White
Gui Add, Text, x15 y16 w81 h23 +0x200, Text or Title:
Gui Add, Edit, hWndhEdtFindByText vEdtFindByText gFindWindow x144 y17 w286 h21
Gui Add, CheckBox, vChkFindRegEx x441 y16 w120 h23, Regular Expression
Gui Add, Text, x15 y54 w79 h23 +0x200, Class Name:
Gui Add, ComboBox, vCbxFindByClass gFindWindow x144 y54 w286
Gui Add, Text, x15 y93 w110 h23 +0x200, Process ID or Name:
Gui Add, ComboBox, vCbxFindByProcess gFindWindow x144 y93 w286
Gui Add, ListView, hWndhFindList gFindListHandler x10 y130 w554 h185 +LV0x14000
, hWnd|Class|Text|Process
LV_ModifyCol(1, 0)
LV_ModifyCol(2, 133)
LV_ModifyCol(3, 285)
LV_ModifyCol(4, 112)
Gui Add, Text, x-1 y329 w576 h49 +Border -Background
Gui Add, Button, gFindOK x381 y342 w88 h25 Default, &OK
Gui Add, Button, gFindClose x477 y342 w88 h25, &Cancel
Gui Show, w574 h377, Find Window
SetExplorerTheme(hFindList)
FindDlgExist := True
}
; Unique class names
Global Classes := []
WinGet WinList, List
Loop %WinList% {
hThisWnd := WinList%A_Index%
WinGetClass WClass, ahk_id %hThisWnd%
AddUniqueClass(WClass)
WinGet ControlList, ControlListHwnd, ahk_id %hThisWnd%
Loop Parse, ControlList, `n
{
WinGetClass CClass, ahk_id %A_LoopField%
AddUniqueClass(CClass)
}
}
ClassList := ""
Loop % Classes.Length() {
ClassList .= Classes[A_Index] . "|"
}
GuiControl,, CbxFindByClass, %ClassList%
; Unique process names
Processes := []
For Process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process") {
If (Process.ProcessID < 10) {
Continue
}
Unique := True
Loop % Processes.Length() {
If (Process.Name == Processes[A_Index]) {
Unique := False
Break
}
}
If (Unique) {
Processes.Push(Process.Name)
}
}
ProcList := ""
MaxItems := Processes.Length()
Loop %MaxItems% {
ProcList .= Processes[MaxItems - A_Index + 1] . "|"
}
GuiControl,, CbxFindByProcess, %ProcList%
Return ;}
AddUniqueClass(ClassName) {
Local Unique := True
Loop % Classes.Length() {
If (ClassName == Classes[A_Index]) {
Unique := False
Break
}
}
If (Unique) {
Classes.Push(ClassName)
}
}
FindEscape:
FindClose: ;{
Gui Find: Hide
Return ;}
FindWindow: ;{
Gui Find: Submit, NoHide
Gui ListView, %hFindList%
GuiControl -Redraw, %hFindList%
LV_Delete()
WinGet WinList, List
Loop %WinList% {
hThisWnd := WinList%A_Index%
If (hThisWnd == hFindDlg) {
Continue
}
WinGetClass WClass, ahk_id %hThisWnd%
WinGetTitle WTitle, ahk_id %hThisWnd%
WinGet WProcess, ProcessName, ahk_id %hThisWnd%
WinGet WProcPID, PID, ahk_id %hThisWnd%
If (MatchCriteria(WTitle, WClass, IsNumber(CbxFindByProcess) ? WProcPID : WProcess)) {
LV_Add("", hThisWnd, WClass, WTitle, WProcess)
}
WinGet ControlList, ControlListHwnd, ahk_id %hThisWnd%
Loop Parse, ControlList, `n
{
ControlGetText CText,, ahk_id %A_LoopField%
WinGetClass CClass, ahk_id %A_LoopField%
WinGet CProcess, ProcessName, ahk_id %A_LoopField%
WinGet CProcPID, PID, ahk_id %A_LoopField%
If (MatchCriteria(CText, CClass, IsNumber(CbxFindByProcess) ? CProcPID : CProcess)) {
LV_Add("", A_LoopField, CClass, CText, CProcess)
}
}
}
GuiControl +Redraw, %hFindList%
Return ;}
MatchCriteria(Text, Class, Process) {
Global
If (EdtFindByText != "") {
If (ChkFindRegEx) {
If (RegExMatch(Text, EdtFindByText) < 1) {
Return False
}
} Else {
If (!InStr(Text, EdtFindByText)) {
Return False
}
}
}
If (CbxFindByClass != "" && !InStr(Class, CbxFindByClass)) {
Return False
}
If (CbxFindByProcess != "") {
Return IsNumber(Process) ? CbxFindByProcess == Process : InStr(Process, CbxFindByProcess)
}
Return True
}
FindOK: ;{
Gui ListView, %hFindList%
LV_GetText(hWnd, LV_GetNext())
GuiControl, Spy:, EdtHandle, %hWnd%
WinActivate ahk_id %hSpyWnd%
Gui Find: Hide
Return ;}
FindListHandler: ;{
If (A_GuiEvent == "DoubleClick") {
GoSub FindOK
}
Return ;}
CreateImageList() {
ImageList := IL_Create(32)
IL_Add(ImageList, TreeIcons, 1) ; Generic window icon
IL_Add(ImageList, TreeIcons, 2) ; Desktop (#32769)
IL_Add(ImageList, TreeIcons, 3) ; Dialog (#32770)
IL_Add(ImageList, TreeIcons, 4) ; Button
IL_Add(ImageList, TreeIcons, 5) ; CheckBox
IL_Add(ImageList, TreeIcons, 6) ; ComboBox
IL_Add(ImageList, TreeIcons, 7) ; DateTime
IL_Add(ImageList, TreeIcons, 8) ; Edit
IL_Add(ImageList, TreeIcons, 9) ; GroupBox
IL_Add(ImageList, TreeIcons, 10) ; Hotkey
IL_Add(ImageList, TreeIcons, 11) ; Icon
IL_Add(ImageList, TreeIcons, 12) ; Link
IL_Add(ImageList, TreeIcons, 13) ; ListBox
IL_Add(ImageList, TreeIcons, 14) ; ListView
IL_Add(ImageList, TreeIcons, 15) ; MonthCal
IL_Add(ImageList, TreeIcons, 16) ; Picture
IL_Add(ImageList, TreeIcons, 17) ; Progress
IL_Add(ImageList, TreeIcons, 18) ; Radio
IL_Add(ImageList, TreeIcons, 19) ; RichEdit
IL_Add(ImageList, TreeIcons, 20) ; Separator
IL_Add(ImageList, TreeIcons, 21) ; Slider
IL_Add(ImageList, TreeIcons, 22) ; Status bar
IL_Add(ImageList, TreeIcons, 23) ; Tab
IL_Add(ImageList, TreeIcons, 24) ; Text
IL_Add(ImageList, TreeIcons, 25) ; Toolbar
IL_Add(ImageList, TreeIcons, 26) ; Tooltips
IL_Add(ImageList, TreeIcons, 27) ; TreeView
IL_Add(ImageList, TreeIcons, 28) ; UpDown
IL_Add(ImageList, TreeIcons, 29) ; IE
IL_Add(ImageList, TreeIcons, 30) ; Scintilla
IL_Add(ImageList, TreeIcons, 31) ; ScrollBar
IL_Add(ImageList, TreeIcons, 32) ; SysHeader
Return ImageList
}
ShowTree: ;{
If (WinExist("ahk_id" . hTreeWnd)) {
Gui Tree: Show
SetWindowIcon(hTreeWnd, "shell32.dll", 42)
} Else {
Gui Tree: New, LabelTree hWndhTreeWnd +Resize
SetWindowIcon(hTreeWnd, "shell32.dll", 42)
Menu TreeMenu, Add, &Reload`tF5, LoadTree
Menu TreeMenu, Add
Menu TreeMenu, Add, E&xit`tEsc, TreeClose
Menu MenuBar, Add, &Tree, :TreeMenu
Menu ViewMenu, Add, Show &Hidden Windows, ToggleHiddenWindows
Menu ViewMenu, Add
Menu ViewMenu, Add, &Flash Window`tF6, FlashWindow
Menu ViewMenu, Add
Menu ViewMenu, Add, E&xpand All Nodes, ExpandAll
Menu ViewMenu, Add, &Collapse All Nodes, CollapseAll
Menu MenuBar, Add, &View, :ViewMenu
Gui Tree: Menu, MenuBar
Gui Font, s9, Segoe UI
Gui Add, TreeView, hWndhTree gTreeHandler x0 y0 w681 h445 -Lines +0x9000
Gui Show, w681 h445, %AppName% - Tree
TV_SetImageList(CreateImageList())
SetExplorerTheme(hTree)
}
GoSub LoadTree
Return ;}
TreeEscape:
TreeClose: ;{
Gui Tree: Hide
Return ;}
TreeSize: ;{
If (A_EventInfo == 1) { ; Minimized
Return
}
AutoXYWH("wh", hTree)
Return ;}
LoadTree: ;{
Global TreeIDs := {}
Gui Tree: Default
TV_Delete()
RootID := TV_Add("Desktop", 0, "Icon2")
TreeIDs[RootID] := DllCall("GetDesktopWindow", "Ptr")
WinGet WinList, List
Loop %WinList% {
hWnd := WinList%A_Index%
WinGetClass Class, ahk_id %hWnd%
WinGetTitle Title, ahk_id %hWnd%
If (Title != "") {
Title := " - " . Title
}
Invisible := !IsWindowVisible(hWnd)
If (!g_TreeShowAll && Invisible) {
Continue
}
If (Invisible) {
Title .= " (hidden)"
}
Icon := GetWindowIcon(hWnd, Class, True)
ID := TV_Add(Class . Title, RootID, "Icon" . Icon)
TreeIDs[ID] := hWnd
Tree(hWnd, ID)
}
TV_Modify(RootID, "+Expand")
For Key, Value in TreeIDs {
If (g_hWnd == Value) {
TV_Modify(Key, "Select")
}
}
Return ;}
Tree(hParentWnd, ParentID) {
WinGet WinList, ControlListHwnd, ahk_id %hParentWnd%
Loop Parse, WinList, `n
{
If (GetParent(A_LoopField) != hParentWnd) {
Continue
}
WinGetClass Class, ahk_id %A_LoopField%
If (IsChild(A_LoopField)) {
ControlGetText Text,, ahk_id %A_LoopField%
} Else {
WinGetTitle Text,, ahk_id %A_LoopField%
}
If (Text != "") {
Text := " - " . Text
}
Invisible := !IsWindowVisible(A_LoopField)
If (!g_TreeShowAll && Invisible) {
Continue
}
If (Invisible) {
Text .= " (hidden)"
}
Icon := GetWindowIcon(A_LoopField, Class)
ID := TV_Add(Class . Text, ParentID, "Icon" . Icon)
TreeIDs[ID] := A_LoopField
Tree(A_LoopField, ID)
}
}
TreeHandler: ;{
If (A_GuiEvent == "DoubleClick") {
g_hWnd := TreeIDs[A_EventInfo]
ShowWindowInfo()
}
Return ;}
GetWindowIcon(hWnd, Class, TopLevel := False) {
Static Classes := {0:0
, "#32770": 3
, "Button": 4
, "CheckBox": 5
, "ComboBox": 6
, "SysDateTimePick32": 7
, "Edit": 8
, "GroupBox": 9
, "msctls_hotkey32": 10
, "Icon": 11
, "SysLink": 12
, "ListBox": 13
, "SysListView32": 14
, "SysMonthCal32": 15
, "Picture": 16
, "msctls_progress32": 17
, "Radio": 18
, "RebarWindow32": 25
, "RichEdit": 19
, "Separator": 20
, "msctls_trackbar32": 21
, "msctls_statusbar32": 22
, "SysTabControl32": 23
, "Static": 24
, "ToolbarWindow32": 25
, "tooltips_class32": 26
, "SysTreeView32": 27
, "msctls_updown32": 28
, "Internet Explorer_Server": 29
, "Scintilla": 30
, "ScrollBar": 31
, "SysHeader32": 32}
If (Class == "Button") {
WinGet Style, Style, ahk_id %hWnd%
Type := Style & 0xF
If (Type == 7) {
Class := "GroupBox"
} Else If (Type ~= "2|3|5|6") {
Class := "CheckBox"
} Else If (Type ~= "4|9") {
Class := "Radio"
} Else {
Class := "Button"
}
} Else If (Class == "Static") {
WinGet Style, Style, ahk_id %hWnd%
Type := Style & 0x1F ; SS_TYPEMASK
If (Type == 3) {
Class := "Icon"
} Else If (Type == 14) {
Class := "Picture"
} Else If (Type == 0x10) {
Class := "Separator"
} Else {
Class := "Static"
}
} Else If (InStr(Class, "RICHED", True) == 1) {
Class := "RichEdit" ; RICHEDIT50W
}
Icon := Classes[Class]
If (Icon != "") {
Return Icon
}
SendMessage 0x7F, 2, 0,, ahk_id %hWnd% ; WM_GETICON, ICON_SMALL2
hIcon := ErrorLevel
If (hIcon == 0 && TopLevel) {
WinGet ProcessPath, ProcessPath, ahk_id %hWnd%
hIcon := GetFileIcon(ProcessPath)
}
IconIndex := (hIcon) ? IL_Add(ImageList, "HICON: " . hIcon) : 1
Return IconIndex
}
ToggleHiddenWindows: ;{
g_TreeShowAll := !g_TreeShowAll
GoSub LoadTree
Menu ViewMenu, ToggleCheck, Show &Hidden Windows
Return ;}
CollapseAll:
ExpandAll: ;{
Expand := (A_ThisLabel == "ExpandAll") ? "+Expand" : "-Expand"
ItemID := 0
Loop {
ItemID := TV_GetNext(ItemID, "Full")
If (!ItemID) {
Break
}
TV_Modify(ItemID, Expand)
}
Return ;}
FlashWindow: ;{
If (A_Gui == "Tree") {
hWnd := TreeIDs[TV_GetSelection()]
} Else {
hWnd := g_hWnd
}
ShowBorder(hWnd, 200, 0xFF0000)
Sleep 200
ShowBorder(hWnd, 200, 0xFF0000)
Sleep 200
ShowBorder(hWnd, 200, 0xFF0000)
Return ;}
; Based on a script written by Lexicos
ShowMenuViewer: ;{
If (MenuViewerExist) {
Gui MenuViewer: Show
} Else {
Gui MenuViewer: New, +LabelMenuViewer +hWndhMenuViewer +Resize
Gui Font, s9, Segoe UI
Gui Color, 0xF1F5FB
Gui Add, ListView, hWndhMenuList vLVMenu x0 y0 w600 h400 +LV0x14000, Menu Item String|Keyboard|Menu ID
LV_ModifyCol(1, 410)
LV_ModifyCol(2, 103)
LV_ModifyCol(3, "65 Integer")
SetExplorerTheme(hMenuList)
Gui Add, Edit, hWndhEdtMenuSearch vEdtMenuSearch gSearchMenu x8 y408 w200 h23 +0x2000000 ; WS_CLIPCHILDREN
DllCall("SendMessage", "Ptr", hEdtMenuSearch, "UInt", 0x1501, "Ptr", 1, "WStr", "Search")
Gui Add, Picture, hWndhSearchIcon x178 y1 w16 h16, %ResDir%\Search.ico
DllCall("SetParent", "Ptr", hSearchIcon, "Ptr", hEdtMenuSearch)
WinSet Style, -0x40000000, ahk_id %hSearchIcon% ; -WS_CHILD
ControlFocus,, ahk_id %hEdtMenuSearch%
NoAmpersands := True
Gui Add, CheckBox, vNoAmpersands gShowMenuItems x220 y408 w167 h23 Checked%NoAmpersands%
, Remove Ampersands (&&)
Gui Add, Button, vBtnMenuCopy gCopyMenuList x466 y407 w125 h25, Copy to Clipboard
Gui Show, w600 h440, Menu Viewer
MenuViewerExist := True
}
GoSub ShowMenuItems
Return ;}
ShowMenuItems: ;{
Gui MenuViewer: Default
Gui Submit, NoHide
LV_Delete()
hMenu := GetMenu(g_hWnd)
If (hMenu) {
MenuItems := []
GetMenuItems(hMenu, "", "")
}
Return ;}
GetMenuItems(hMenu, Prefix, ByRef Commands) {
Global
ItemCount := GetMenuItemCount(hMenu)
Loop %ItemCount% {
ItemString := GetMenuString(hMenu, A_Index - 1)
ItemID := GetMenuItemID(hMenu, A_Index - 1)
RegExMatch(ItemString, "\t(.+)", Keyboard)
ItemString := RegExReplace(ItemString, "\t.*")
If (ItemString == "SEPARATOR") {
ItemString := "----------------------------"
}
MenuItems.Push([ItemString, Keyboard1, ItemID])
If (NoAmpersands) {
ItemString := StrReplace(ItemString, "&")
}
LV_Add("", Prefix . ItemString, Keyboard1, ItemID)
If (ItemID == -1) { ; Submenu
hSubMenu := GetSubMenu(hMenu, A_Index - 1)
If (hSubMenu) {
Prefix .= " "
GetMenuItems(hSubMenu, Prefix, Commands)
Prefix := StrReplace(Prefix, " ", "",, 1)
Continue
}
}
}
}
SearchMenu: ;{
Gui MenuViewer: Submit, NoHide
Gui ListView, %hMenuList%
LV_Delete()
Loop % MenuItems.Length() {
MenuItem := MenuItems[A_Index][1]
Keyboard := MenuItems[A_Index][2]
MenuID := MenuItems[A_Index][3]
If (NoAmpersands) {
MenuItem := StrReplace(MenuItem, "&")
}
If (InStr(MenuItem, EdtMenuSearch)
|| InStr(Keyboard, EdtMenuSearch)
|| InStr(MenuID, EdtMenuSearch)) {
LV_Add("", MenuItem, Keyboard, MenuID)
}
}
Return ;}
CopyMenuList: ;{
Gui MenuViewer: Default
ControlGet MenuList, List,,, ahk_id %hMenuList%
Clipboard := StrReplace(MenuList, " ", "`t")
Return ;}
MenuViewerEscape:
MenuViewerClose: ;{
Gui MenuViewer: Hide
Return ;}
MenuViewerSize: ;{
If (A_EventInfo == 1) { ; Minimized
Return
}
AutoXYWH("wh", hMenuList)
AutoXYWH("y", hEdtMenuSearch)
AutoXYWH("y", hSearchIcon)
AutoXYWH("y", "NoAmpersands")
AutoXYWH("xy", "BtnMenuCopy")
Return ;}
MenuViewerContextMenu: ;{
Row := LV_GetNext()
LV_GetText(MenuString, Row, 1)
LV_GetText(MenuID, Row, 3)
If (A_GuiControl == "LVMenu" && MenuID > 0 && !InStr(MenuString, "-----")) {
Menu MenuMenu, Add, Invoke Menu Command, InvokeMenuCommand
Menu MenuMenu, Show
}
Return ;}
InvokeMenuCommand: ;{
PostMessage 0x111, %MenuID%,,, ahk_id %g_hWnd%
Return ;}
LoadProcessProperties: ;{
Gui Spy: Submit, NoHide
WinGet PID, PID, ahk_id %g_hWnd%
StrQuery := "SELECT * FROM Win32_Process WHERE ProcessId=" . PID
Enum := ComObjGet("winmgmts:").ExecQuery(StrQuery)._NewEnum
If (Enum[Process]) {
ExePath := Process.ExecutablePath
hIcon := GetFileIcon(ExePath, 0)
If (!hIcon || ExePath == "") {
hIcon := DllCall("LoadIcon", "Ptr", 0, "UInt", 32512, "Ptr") ; IDI_APPLICATION
}
GuiControl,, ProgIcon, % "HICON:" . hIcon
GuiControl,, ProgName, % Process.Name
FileGetVersion ProgVer, %ExePath%
GuiControl,, ProgVer, %ProgVer%
Gui ListView, %hProcInfo%
LV_Delete()
LV_Add("", "Path", ExePath)
LV_Add("", "Command line", Process.CommandLine)
LV_Add("", "Process ID", Process.ProcessId)
LV_Add("", "Thread ID", DllCall("GetWindowThreadProcessId", "Ptr", g_hWnd, "Ptr", 0))
CreationDate := Process.CreationDate
SubStr(CreationDate, 1, InStr(CreationDate, ".") - 1)
FormatTime CreationDate, %CreationDate% D1 T0 ; Short date and time with seconds
LV_Add("", "Started", CreationDate)
LV_Add("", "Working Size", FormatBytes(Process.WorkingSetSize, Sep))
LV_Add("", "Virtual Size", FormatBytes(Process.VirtualSize, Sep))
LV_Add("", "Image Type", GetImageType(PID))
}
Return ;}
GetImageType(PID) {
; PROCESS_QUERY_INFORMATION
hProc := DllCall("OpenProcess", "UInt", 0x400, "Int", False, "UInt", PID, "Ptr")
If (!hProc) {
Return "N/A"
}
If (A_Is64bitOS) {
; Determines whether the specified process is running under WOW64.
Try DllCall("IsWow64Process", "Ptr", hProc, "Int*", Is32Bit := True)
} Else {
Is32Bit := True
}
DllCall("CloseHandle", "Ptr", hProc)
Return (Is32Bit) ? "32-bit" : "64-bit"
}
EndProcess: ;{
GuiControlGet Filename,, ProgName
If (Filename == "N/A") {
Return
}
Gui Spy: +OwnDialogs
MsgBox 0x40031, %AppName%, Are you sure you want to exit %Filename%?
IfMsgBox OK, {
WinGet PID, PID, ahk_id %g_hWnd%
Process Close, %PID%
If (ErrorLevel == 0) {
Gui Spy: +OwnDialogs
MsgBox 0x40010, Error, The process named %Filename% with PID %PID% could not be ended.
}
}
Return ;}
OpenFolder: ;{
Gui ListView, %hProcInfo%
LV_GetText(ExePath, 1, 2)
If (ExePath != "") {
Run *open explorer.exe /select`,"%ExePath%"
}
Return ;}
FormatBytes(Value, sThousand := ".", Unit := -1, ShowUnit := True) {
If ((Unit == -1 && Value > 999) || Unit == "K") {
Value /= 1024
Unit := ShowUnit ? " K" : ""
} Else {
Unit := ShowUnit ? " B" : ""
}
a := ""
Loop % StrLen(Value) {
a .= SubStr(Value, 1 - A_Index, 1)
If (Mod(A_Index, 3) == 0) {
a .= sThousand
}
}
a := RTrim(a, sThousand)
b := ""
Loop % StrLen(a) {
b .= SubStr(a, 1 - A_Index, 1)
}
Return b . Unit
}
; http://ahkscript.org/boards/viewtopic.php?t=1079
AutoXYWH(DimSize, cList*) {
Static cInfo := {}
If (DimSize = "reset") {
Return cInfo := {}
}
For i, ctrl in cList {
ctrlID := A_Gui ":" ctrl
If (cInfo[ctrlID].x = "") {
GuiControlGet i, %A_Gui%: Pos, %ctrl%
MMD := InStr(DimSize, "*") ? "MoveDraw" : "Move"
fx := fy := fw := fh := 0
For i, dim in (a := StrSplit(RegExReplace(DimSize, "i)[^xywh]"))) {
If (!RegExMatch(DimSize, "i)" . dim . "\s*\K[\d.-]+", f%dim%)) {
f%dim% := 1
}
}
cInfo[ctrlID] := {x: ix, fx: fx, y: iy, fy: fy, w: iw, fw: fw, h: ih, fh: fh, gw: A_GuiWidth, gh: A_GuiHeight, a: a, m: MMD}
} Else If (cInfo[ctrlID].a.1) {
dgx := dgw := A_GuiWidth - cInfo[ctrlID].gw, dgy := dgh := A_GuiHeight - cInfo[ctrlID].gh
Options := ""
For i, dim in cInfo[ctrlID]["a"] {
Options .= dim . (dg%dim% * cInfo[ctrlID]["f" . dim] + cInfo[ctrlID][dim]) . A_Space
}
GuiControl, % A_Gui ":" cInfo[ctrlID].m, % ctrl, % Options
}
}
}
IsBorder(hWnd) {
Loop % g_Borders.Length() {
If (g_Borders[A_Index] == hWnd) {
Return True
}
}
Return False
}
IsNumber(n) {
If n Is Number
Return True
Return False
}
ShowHelp: ;{
Gui Spy: +OwnDialogs
MsgBox 0x40, %AppName% Keyboard Shortcuts,
(
F2: Go to the parent window
F3: Show the Find dialog
F4: Show the hierarchical window tree
F5: Reload window information
F6: Highlight window location
F7: Position and Size dialog
F8: Copy information to the clipboard
F9: Copy screenshot to the clipboard
)
Return ;}