autohotkey 辅助工具
;AHK v1.1 x64/x32 compatible update by jeeswg of:
;Get Info from Context Menu - Scripts and Functions - AutoHotkey Community
;https://autohotkey.com/board/topic/19754-get-info-from-context-menu/
;
; AutoHotkey Version: 1.x
; Language: English
; Platform: Win9x/NT
; Author: micha
;
; Script Function:
; Demonstrates how to retrieve infos from a context/ popup menu
;
/*
This is the struct we are using.
typedef struct tagMENUITEMINFO {
UINT cbSize;
UINT fMask;
UINT fType;
UINT fState;
UINT wID;
HMENU hSubMenu;
HBITMAP hbmpChecked;
HBITMAP hbmpUnchecked;
ULONG_PTR dwItemData;
LPTSTR dwTypeData;
UINT cch;
HBITMAP hbmpItem;
} MENUITEMINFO, *LPMENUITEMINFO;
*/
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
#Persistent
RunAsAdmin()
SetTimer, Demo, 500
return
Demo:
;constants
MFS_ENABLED = 0
MFS_CHECKED = 8
MFS_DEFAULT = 0x1000
MFS_DISABLED = 2
MFS_GRAYED = 1
MFS_HILITE = 0x80
;MFS_UNCHECKED = 0
;MFS_UNHILITE = 0
;Get mouse position and handle to wnd under the mouse cursor
MouseGetPos, MouseScreenX, MouseScreenY, MouseWindowUID, MouseControlID
WinGet,ControlHwnd, ID,ahk_id %MouseWindowUID%
;Get count of menu items
ContextMenCnt := GetContextMenuCount(ControlHwnd)
if ContextMenCnt < 1
{
Tooltip,
return
}
TooltipText =
;Read info for each menu item
loop, %ContextMenCnt%
{
IsEnabled := GetContextMenuState(ControlHwnd, a_index-1)
{
CurrentText =
;~ if IsEnabled = 0
;~ CurrentText = %CurrentText% Enabled
;~ if (IsEnabled & MFS_CHECKED)
;~ CurrentText = %CurrentText% Checked
;~ if (IsEnabled & MFS_DEFAULT)
;~ CurrentText = %CurrentText% Default
;~ if (IsEnabled & MFS_DISABLED)
;~ CurrentText = %CurrentText% Disabled
;~ if (IsEnabled & MFS_GRAYED)
;~ CurrentText = %CurrentText% Grayed
;~ if (IsEnabled & MFS_HILITE)
;~ CurrentText = %CurrentText% Highlight
;~ TooltipText = %TooltipText%%a_index%:%CurrentText%`n
if (IsEnabled & MFS_HILITE)
{
CurrentText := GetContextMenuID(ControlHwnd, a_index-1) . A_Tab . GetContextMenuText(ControlHwnd, a_index-1)
TooltipText := CurrentText
}
}
}
;~ TextText =
;~ loop, %ContextMenCnt%
;~ {
;~ StrSize := GetContextMenuText(ControlHwnd, a_index-1)
;~ nID := GetContextMenuID(ControlHwnd, a_index-1)
;~ TextText = %TextText%%a_index%:%StrSize%-ID=%nID%`n
;~ }
CoordMode, Tooltip, Screen
Tooltip, %TooltipText%---`n%TextText%, 0, 0
return
/***************************************************************
* returns the count of menu items
***************************************************************
*/
GetContextMenuCount(hWnd)
{
WinGetClass, WindowClass, ahk_id %hWnd%
;All popups should have the window class #32768
if WindowClass <> #32768
{
return 0
}
; Retrieve menu handle from window
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
menuitemcount:=DllCall("GetMenuItemCount", Ptr,hMenu)
Return, menuitemcount
}
/***************************************************************
* returns the state of a menu entry
***************************************************************
*/
GetContextMenuState(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;We need to allocate a struct
VarSetCapacity(MenuItemInfo, 60, 0)
;Set Size of Struct to the first member
NumPut(A_PtrSize=8?80:48, MenuItemInfo, 0, "UInt")
;Get only Flags from dllcall GetMenuItemInfo MIIM_TYPE = 1
NumPut(1, MenuItemInfo, 4, "UInt")
;GetMenuItemInfo: Handle to Menu, Index of Position, 0=Menu identifier / 1=Index
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes != 0
return -1
;Get Flag from struct
GetMenuItemInfoRes := NumGet(MenuItemInfo, 12, "UInt")
/*
IsEnabled = 1
if GetMenuItemInfoRes > 0
IsEnabled = 0
return IsEnabled
*/
return GetMenuItemInfoRes
}
/***************************************************************
* returns the ID of a menu entry
***************************************************************
*/
GetContextMenuID(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;UINT GetMenuItemID( HMENU hMenu, int nPos);
InfoRes := DllCall("user32.dll\GetMenuItemID", Ptr,hMenu, Int,Position, UInt)
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes != 0
return -1
return InfoRes
}
/***************************************************************
* returns the text of a menu entry (standard windows context menus only!!!)
***************************************************************
*/
GetContextMenuText(hWnd, Position)
{
WinGetClass, WindowClass, ahk_id %hWnd%
if WindowClass <> #32768
{
return -1
}
SendMessage, 0x01E1, , , , ahk_id %hWnd%
;Errorlevel is set by SendMessage. It contains the handle to the menu
hMenu := errorlevel
;We need to allocate a struct
VarSetCapacity(MenuItemInfo, 200, 0)
;Set Size of Struct (48) to the first member
NumPut(A_PtrSize=8?80:48, MenuItemInfo, 0, "UInt")
;Retrieve string MIIM_STRING = 0x40 = 64 (/ MIIM_TYPE = 0x10 = 16)
NumPut(64, MenuItemInfo, 4, "UInt")
;Set type - Get only size of string we need to allocate
;NumPut(0, MenuItemInfo, 8, "UInt")
;GetMenuItemInfo: Handle to Menu, Index of Position, 0=Menu identifier / 1=Index
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
if InfoRes = 0
return -1
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes <> 0
return -1
;Get size of string from struct
GetMenuItemInfoRes := NumGet(MenuItemInfo, A_PtrSize=8?64:40, "UInt")
;If menu is empty return
If GetMenuItemInfoRes = 0
return "{Empty String}"
;+1 should be enough, we'll use 2
GetMenuItemInfoRes += 2
;Set capacity of string that will be filled by windows
VarSetCapacity(PopupText, GetMenuItemInfoRes, 0)
;Set Size plus 0 terminator + security ;-)
NumPut(GetMenuItemInfoRes, MenuItemInfo, A_PtrSize=8?64:40, "UInt")
NumPut(&PopupText, MenuItemInfo, A_PtrSize=8?56:36, "Ptr")
InfoRes := DllCall("user32.dll\GetMenuItemInfo", Ptr,hMenu, UInt,Position, Int,1, Ptr,&MenuItemInfo)
if InfoRes = 0
return -1
InfoResError := errorlevel
LastErrorRes := DllCall("GetLastError", UInt)
if InfoResError <> 0
return -1
if LastErrorRes <> 0
return -1
return PopupText
}
;PrintScreen::reload
RunAsAdmin() {
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
}
;Reveal information on windows, controls, etc.
;by toralf
;requires AHK 1.0.44.04
;www.autohotkey.com/forum/topic8976.html
ScriptName := "AHK 窗口信息捕获 1.7"
,左键:="LButton"
,中键:="MButton"
,右键:="RButton"
; License: Attribution-NonCommercial-ShareAlike 2.5 licence from Creative Commons
; for details see: http://creativecommons.org/licenses/by-nc-sa/2.5/legalcode
;
; export code by sosaited www.autohotkey.com/forum/viewtopic.php?t=8732&p=53372#53372
; idea and lot of code of frame drawing by shimanov
; several ideas from Chris and other users of the AHK forum
; initial ideas taken from these scripts:
; Ahk Window Spy 1.3.3 by Decarlo www.autohotkey.com/forum/viewtopic.php?t=4679
; WinInfo Menu by Jon www.autohotkey.com/forum/viewtopic.php?t=8617
;changes since 1.6
; - added a small gap in the mouse picker grid to identify the center (thanks fade2gray)
; - adjusted groupbox size and tab size
; - added reset of picker to default color on dimensional change
;changes since 1.5
; - Groupboxes with bold text have been set -wrap, to fix line breaks on some windows themes
; - BGR is made default for color picker
; - update is stopped when mouse moves over its own gui, allowing easier graping of data, since no Pause key needs to be pressed.
;changes since 1.4
; - "H" replaced with Hwnd; "P" and "S" with "Pos" and "Size" on advanced tab for Control
; - GroupBox names have bold font
; - Mouse color picker is only updated when mouse tab is visible. Otherwise set to gray
; - set default for color picker to 15x15, since it only influences CPU load when the mouse tab is visible
; - controls list items are only updated when advanced tab is visible. Otherwise set to ">>>not updated<<<""
; - windows statusbar text is only updated when advanced tab is visible. Otherwise set to ">>>not updated<<<""
; - fast/slow visible/hidden window text are only updated when advanced tab is visible. Otherwise set to ">>>not updated<<<""
;todo
; - Window Info should be tested on Windows 9x
;changes since 1.3
; - last tab gets remembered between starts
; - large list hides automatically when tab is not "Advanced"
; - by default not rectangle is drawn around controls
; - gui starts NoActivate
; - fixed a problem with hidden gui and pause key
; - reduced impact in hidden mode on CPU load to nearly 0
; - to support 800x600 screen resolutions the advanced tab initial height is 600
; - instead of auto-update, update of data can be done on mouse click (button can be L/M/R, default M)
; - when started with "HideGui" turned on: GUI starts hidden, after 500 ms data is collected and GUI shown
; - changed licence to Attribution-NonCommercial-ShareAlike 2.5 licence from Creative Commons
;changes since 1.2
; - added: Control handle to advanced and list view
; - improved: fixed some spelling mistakes
; - fixed: option "Show tooltip at cursor" had no effect
; - fixed: option "Show tooltip at cursor" wasn't remembered between sessions
; - improved: For all DllCall's the types are put in quotes
; - changed: coordinates and sizes will have a space after the comma when put on clipboard
; - changed: the number of characters in the GUI for the list items is limited to 200. Clipboard will receive all
; - changed: "Introduction - Please Read" button moved to new info tab
; - changed: Renamed "active control in window" to "focused control in window".
; - fixed: Window Info refused to minimize while the right-side list was displayed.
; - changed: While Window Info is minimized, updating of data is turned off
; - fixed: Coordinates of GUI got stored when GUI got closed minimized
;changes since 1.1
; - added: OnExit routine that cleans up frame gui if script exits unexpectedly
; - changed: Tooltip of control frame disappears when mouse gets moved onto it.
; - changed: font size of GUI is now 6pt
;changes since 1.0
; - improved: specified the font for the GUI, MS Sans Serif, 8 point
; - changed: for some OS (WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME) the icon is changed to ID 57
; - improved: small features that simplify maintenance
; + combine update routines
; + simplify options actions
; + simplify Pause Key actions
; + reorder code
; - improved: new method to capture fast/slow visible/hidden window text (Thanks Chris)
; - changed: Gui (advanced) now holds fields for fast/slow visible/hidden window text
; - added: option to switch color picker between RGB and BGR
; - improved: color picker only updates when mouse moves or color below mouse changes. This reduces jittery update.
; - changed: Color picker now has a 15x15 color matrix
; - changed: checkbox "Show right List" changed to button that alternates between "More Info >>" and "<< Less Info".
; - added: check for minium required AHK version
; - added: new option to turn auto-update automatically ON when Gui gets inactive (if it had been turned off (by pause or by the large list))
/*
Requests:
[quote="Chris"]Sometimes pressing Window Info's minimize button fails to work.[/quote]I still can't reproduce it. I tried it 20 times any each time the window minimized
[quote="Chris"]I've made a note to test it on Win9x prior to distribution.[/quote]Please do. Or is there someone else out there to do the testing. Would be very much appreaciated.
[quote="Chris"]Minor typos in source code comments: "or less or" should be "or else" in 2 places.[/quote]The two cases where "or less or" is written are actually correct.
*/
AHK_version := "1.0.44.04"
if not A_IsCompiled ;if it is a script
CheckAHKVersion(AHK_version) ;check if minimum AHK Version is installed
InformationText =
(LTrim
This Gui will reveal information on windows, controls, etc.
This software is under the GNU General Public License for details see: www.autohotkey.com/docs/license.htm
Move your mouse over the area of interest and see the data in this GUI changing accordingly (auto-update). The auto-update stops when this GUI becomes the active one. To achieve this without moving the mouse you can use Alt+Tab to change to %ScriptName%. Or you can use a hotkey to turn the auto-update off. The default hotkey is the Pause key.
When the data for the large list is collected (advanced tab), the auto-update of the data is stopped automatically to allow you to work with the data. Use the toggle hotkey (see below) to create a new snapshot of data. Or turn on the option, to start updating again when the GUI gets deactivated.
These shortcuts exist:
=================
=> Toggle Auto-Update Hotkey (default: Pause):
---------------------------------------------------------------------------
Toggles (start/stop) auto-updating data in GUI OR creates a new snapshot of data when auto-update has been stopped automatically.
=> Left-Mouse Button:
---------------------------------------
Copies the content of a control to the clipboard. This is achieved in the code with OnMessage(), thus it should not interfere with any of your own hotkeys.
=> Middle-Mouse Button:
---------------------------------------
Toggles AlwaysOnTop status of this window. Click inside the window, it will not work on the titlebar. This is achieved in the code with OnMessage(), thus it should not interfere with any of your own hotkeys.
=> Win+s hotkey combination:
------------------------------------------------
Exports data to file. It will only work, when auto-update has been stopped.
Remarks:
=======
- You can change the toggle auto-update hotkey in the advanced options (you will not see keys that do not produces visible characters, e.g. the default Pause key). A key has to be specified. A single Ctrl, Shift, Alt, Win key or their combinations are not allowed.
- The advanced option "Hide/Show Gui" allows you to create snapshots of data while the GUI is hidden. The toggle auto-update hotkey will toggle the visibility of the GUI. Just before the GUI is shown again the data gets collected and the GUI updated.
- Log to file only works when auto-update has been stopped.
- Specify a file name you want to save the data too. Insert #'s into the filename, if you want %ScriptName% to number the files automatically.
)
#SingleInstance force
;set working dir, in case this script is called from some other script in a different dir
SetWorkingDir, %A_ScriptDir%
gosub, ReadIni
gosub, CreateTrayMenu
gosub, BuildGui
WindowControlTextSize = 32767 ; Must be 32767 or less or it won't work on Windows 95.
VarSetCapacity(WindowControlText, WindowControlTextSize)
ControlTextSize = 512 ; Must be 32767 or less or it won't work on Windows 95.
VarSetCapacity(ControlText, ControlTextSize)
;activate auto-update toggle hotkey
Hotkey, %HtkPauseAction%, PauseAction, On
;toggle AOT attribute of GUI with middle mouse click
WM_MButtonDOWN = 0x207
OnMessage(WM_MBUTTONDOWN, "ToggleOnTopGui1")
;initialize Save hotkey, so it can be easily turned on/off
Hotkey, #s, BtnSaveExport, Off
;initialize update on click hotkey, so it can be easily turned on/off
Hotkey, IfWinNotActive, ahk_id %Gui1UniqueID%
Hotkey, ~%CbbHtkUpdate%, UpdateOnClick, Off
Hotkey, IfWinNotActive
;activate update on click
if RadUpdateOnClick {
Hotkey, IfWinNotActive, ahk_id %Gui1UniqueID%
Hotkey, ~%CbbHtkUpdate%, On
Hotkey, IfWinNotActive
}else{
;activate auto-start updating at Gui inactivity
WM_ACTIVATE = 0x6
if ChkAutoStartUpdate
OnMessage(WM_ACTIVATE, "WM_ACTIVATE")
;set timer once, so that it knows its interval and can be easily turned on/off
UpdateIsStopped := True
SetTimer, UpdateInfo, %CbbUpdateInterval%
if ChkHideGui {
Sleep, 500
gosub, PauseAction
ToolTip("暂停以隐藏界面", 2000)
}else
UpdateIsStopped := False
}
;activate copy-on-click for left mouse click
WM_LButtonDOWN = 0x201
if ChkCopyToCB
OnMessage(WM_LBUTTONDOWN, "WM_LBUTTONDOWN")
;set static parameters to draw frames around control and window
SysGet, ScreenWidth, 78 ; get Screen size from virtual Screen
SysGet, ScreenHeight, 79
frame_cc = 0x0000FF ;set color for frame, 0x00BBGGRR
frame_cw = 0x00FF00 ;set color for frame, 0x00BBGGRR
frame_t = 2 ;set line thickness for frame, 1-10
gosub, ToogleExportActions
gosub, PrepareFrameDraw ;create or destroy frame drawing objects
OnExit, ExitSub
return
;######## End of Auto-Exec-Section
ExitSub:
gosub, CleanUpFrameGui
Sleep,50
ExitApp
return
ReadIni:
SplitPath, A_ScriptName, , , , OutNameNoExt
IniFile = %OutNameNoExt%.ini
IniRead, Gui1Pos , %IniFile%, Settings, Gui1Pos , x0 y0
IniRead, Gui1AOTState , %IniFile%, Settings, Gui1AOTState , 1
IniRead, Tab1 , %IniFile%, Settings, Tab1 , 1
IniRead, RadWindow , %IniFile%, Settings, RadWindow , 2
IniRead, RadControl , %IniFile%, Settings, RadControl , 2
IniRead, SelectedRadList , %IniFile%, Settings, SelectedRadList , 1
IniRead, ChkShowList , %IniFile%, Settings, ChkShowList , 0
IniRead, HtkPauseAction , %IniFile%, Settings, HtkPauseAction , Pause
IniRead, ChkCopyToCB , %IniFile%, Settings, ChkCopyToCB , 1
IniRead, ChkHideGui , %IniFile%, Settings, ChkHideGui , 0
IniRead, ChkUseSaveHotkey , %IniFile%, Settings, ChkUseSaveHotkey , 0
IniRead, ChkExportMousePosScreen , %IniFile%, Export , ChkExportMousePosScreen, 1
IniRead, ChkExportMousePosAWin , %IniFile%, Export , ChkExportMousePosAWin , 0
IniRead, ChkExportMousePosWin , %IniFile%, Export , ChkExportMousePosWin , 1
IniRead, ChkExportMousePointer , %IniFile%, Export , ChkExportMousePointer , 0
IniRead, ChkExportMouseColorRGB , %IniFile%, Export , ChkExportMouseColorRGB , 0
IniRead, ChkExportMouseColorHex , %IniFile%, Export , ChkExportMouseColorHex , 0
IniRead, ChkExportCtrlText , %IniFile%, Export , ChkExportCtrlText , 1
IniRead, ChkExportCtrlClass , %IniFile%, Export , ChkExportCtrlClass , 1
IniRead, ChkExportCtrlPos , %IniFile%, Export , ChkExportCtrlPos , 0
IniRead, ChkExportCtrlSize , %IniFile%, Export , ChkExportCtrlSize , 0
IniRead, ChkExportCtrlListItems , %IniFile%, Export , ChkExportCtrlListItems , 0
IniRead, ChkExportWinTitle , %IniFile%, Export , ChkExportWinTitle , 1
IniRead, ChkExportWinPos , %IniFile%, Export , ChkExportWinPos , 0
IniRead, ChkExportWinSize , %IniFile%, Export , ChkExportWinSize , 0
IniRead, ChkExportWinClass , %IniFile%, Export , ChkExportWinClass , 1
IniRead, ChkExportWinProcess , %IniFile%, Export , ChkExportWinProcess , 1
IniRead, ChkExportWinUID , %IniFile%, Export , ChkExportWinUID , 0
IniRead, ChkExportWinPID , %IniFile%, Export , ChkExportWinPID , 0
IniRead, ChkExportWinStatusText , %IniFile%, Export , ChkExportWinStatusText , 1
IniRead, ChkExportWinText , %IniFile%, Export , ChkExportWinText , 1
IniRead, ChkExportLargeList , %IniFile%, Export , ChkExportLargeList , 1
IniRead, EdtExportFile , %IniFile%, Export , EdtExportFile , AHK_Window_Info_Data_###.txt
IniRead, ChkExportAutoNumber , %IniFile%, Export , ChkExportAutoNumber , 1
IniRead, ChkExportAppend , %IniFile%, Export , ChkExportAppend , 0
IniRead, ChkShowInfoToolTip , %IniFile%, Advanced, ChkShowInfoToolTip , 1
IniRead, ChkDrawRectCtrl , %IniFile%, Advanced, ChkDrawRectCtrl , 0
IniRead, ChkDrawRectWin , %IniFile%, Advanced, ChkDrawRectWin , 0
IniRead, ChkTtpMaster , %IniFile%, Advanced, ChkTtpMaster , 0
IniRead, ChkTtpMSPos , %IniFile%, Advanced, ChkTtpMSPos , 0
IniRead, ChkTtpMWPos , %IniFile%, Advanced, ChkTtpMWPos , 1
IniRead, ChkTtpMColor , %IniFile%, Advanced, ChkTtpMColor , 1
IniRead, ChkTtpCClass , %IniFile%, Advanced, ChkTtpCClass , 1
IniRead, ChkTtpCPos , %IniFile%, Advanced, ChkTtpCPos , 0
IniRead, ChkTtpCSize , %IniFile%, Advanced, ChkTtpCSize , 0
IniRead, ChkTtpWClass , %IniFile%, Advanced, ChkTtpWClass , 1
IniRead, ChkTtpWTitle , %IniFile%, Advanced, ChkTtpWTitle , 1
IniRead, CbbUpdateInterval , %IniFile%, Advanced, CbbUpdateInterval , 100
IniRead, CbbColorPickDim , %IniFile%, Advanced, CbbColorPickDim , 15x15
IniRead, RadColorPick , %IniFile%, Advanced, RadColorPick , 2
IniRead, ChkAutoStartUpdate , %IniFile%, Advanced, ChkAutoStartUpdate , 1
IniRead, CbbHtkUpdate , %IniFile%, Advanced, CbbHtkUpdate , MButton
IniRead, RadUpdateOnClick , %IniFile%, Advanced, RadUpdateOnClick , 0
IniRead, RadUpdateAuto , %IniFile%, Advanced, RadUpdateAuto , 1
return
CreateTrayMenu:
;location of icon file
IconFile := A_WinDir "\system" iif(A_OSType = "WIN32_WINDOWS","","32") "\shell32.dll"
;create traybar menu
;icon for taskbar and for proces in task manager
if A_OSVersion in WIN_2000,WIN_NT4,WIN_95,WIN_98,WIN_ME
Menu, Tray, Icon, %IconFile%, 57
else
Menu, Tray, Icon, %IconFile%, 172
Menu, Tray, NoStandard
Menu, Tray, Tip, %ScriptName%
Menu, Tray, Add, 显示, GuiShow
Menu, Tray, Default, 显示
Menu, Tray, Add, 退出, GuiClose
Menu, Tray, Click, 1
return
GuiShow:
Gui, 1:Show ;show window again if it has been hidden
return
BuildGui:
GuiIsVisible := False
Gui, 1: +Resize +LastFound
;~ Gui, 1: +Resize +LastFound
Gui1UniqueID := WinExist()
Gui, 1:Font, s10, MS Sans Serif
Gui, 1:Margin, 0, 0
;~ Gui, 1:Add, Tab, w287 h145 vTab1 gTab1 AltSubmit -Wrap , 简洁|高级|鼠标|选项|信息
Gui, 1:Add, Tab, vTab1 gTab1 AltSubmit -Wrap , 简洁(&S)|高级(&V)|鼠标(&M)|选项(&O)|信息(&I)
Gui, 1:Tab, 简洁
Gui, 1:Add, Text, x5 y28 , 窗口标题
Gui, 1:Add, Edit, x+2 yp-3 w211 vEdtEasyWindowTitle,
;~ Gui, 1:Add, Edit, x+2 yp-3 w211 vEdtEasyWindowTitle,
Gui, 1:Add, Text, x5 y+5, 窗口类(Class)
Gui, 1:Add, Edit, x+2 yp-3 w206 vEdtEasyWindowClass,
Gui, 1:Add, Text, x5 y+5, 控件(ClassNN)
Gui, 1:Add, Edit, x+2 yp-3 w196 vEdtEasyControlClass,
Gui, 1:Add, Text, x5 y+5, 控件文本(Text)
Gui, 1:Add, Edit, x+2 yp-3 w216 vEdtEasyControlText,
Gui, 1:Add, Text, x5 y+5, 鼠标位置(相对窗口)
Gui, 1:Add, Edit, x+2 yp-3 w110 vEdtEasyMousePosWin,
Gui, 1:Tab, 高级
Gui, 1:Add, Text, x5 y28 Section, 鼠标位置(相对窗口)
Gui, 1:Add, Edit, x+2 yp-3 w80 vEdtDataMousePosWin,
Gui, 1:Add, Button, x+28 yp-1 vBtnShowList gBtnShowList -Wrap, % iif(ChkShowList,"<< Less Info","More Info >>")
Gui, 1:Font, bold
Gui, 1:Add, GroupBox, xs w274 h114 -wrap, 控件
Gui, 1:Font, normal
Gui, 1:Add, Text, xs+4 yp+18, 文本
Gui, 1:Add, Edit, x+2 yp-3 w104 vEdtControlText,
Gui, 1:Add, Text, x+5 yp+3, ClassNN
Gui, 1:Add, Edit, x+2 yp-3 w91 vEdtControlClass,
Gui, 1:Add, Text, xs+4 y+5, 位置
Gui, 1:Add, Edit, x+2 yp-3 w60 vEdtControlPos,
Gui, 1:Add, Text, x+5 yp+3, 尺寸
Gui, 1:Add, Edit, x+2 yp-3 w65 vEdtControlSize,
Gui, 1:Add, Text, x+5 yp+3, Hwnd
Gui, 1:Add, Edit, x+2 yp-3 w59 vEdtControlHwnd,
Gui, 1:Add, Text, xs+4 y+3, 列表`n项目
Gui, 1:Add, Edit, x+4 r2 w237 vEdtListItems,
Gui, 1:Font, bold
Gui, 1:Add, GroupBox, xs w274 h492 -wrap vGrbAdvancedWindow, 窗口
Gui, 1:Font, normal
Gui, 1:Add, Text, xs+4 yp+18 , 标题
Gui, 1:Add, Edit, x+2 yp-3 w244 vEdtWindowTitle,
Gui, 1:Add, Text, xs+4 y+5, 位置
Gui, 1:Add, Edit, x+2 yp-3 w88 vEdtWindowPos,
Gui, 1:Add, Text, x+5 yp+3, 大小
Gui, 1:Add, Edit, x+2 yp-3 w112 vEdtWindowSize,
Gui, 1:Add, Text, xs+4 y+5, 类
Gui, 1:Add, Edit, x+2 yp-3 w100 vEdtWindowClass,
Gui, 1:Add, Text, x+5 yp+3, 进程
Gui, 1:Add, Edit, x+2 yp-3 w94 vEdtWindowProcess,
Gui, 1:Add, Text, xs+4 y+5, Unique ID
Gui, 1:Add, Edit, x+2 yp-3 w77 vEdtWindowUID,
Gui, 1:Add, Text, x+5 yp+3, 进程 ID
Gui, 1:Add, Edit, x+2 yp-3 w80 vEdtWindowPID,
Gui, 1:Add, Text, xs+4 y+3, 状态栏文本 (栏# - 文本)
Gui, 1:Add, ListBox, xs+4 y+2 r4 w266 vLsbStatusbarText,
Gui, 1:Add, Text, xs+4 y+3 Section, 快速可视文本
Gui, 1:Add, Edit, y+2 r6 w132 vEdtWindowTextFastVisible,
Gui, 1:Add, Text, x+2 ys, 快速隐藏文本
Gui, 1:Add, Edit, y+2 r6 w132 vEdtWindowTextFastHidden,
Gui, 1:Add, Text, xs y+3 Section vTxtWindowTextSlowVisible, 慢速可视文本
Gui, 1:Add, Edit, y+2 r6 w132 vEdtWindowTextSlowVisible,
Gui, 1:Add, Text, x+2 ys vTxtWindowTextSlowHidden, 慢速隐藏文本
Gui, 1:Add, Edit, y+2 r6 w132 vEdtWindowTextSlowHidden,
Gui, 1:Tab, 鼠标
Gui, 1:Add, Text, x5 y28, 鼠标指针相关数据
Gui, 1:Add, Text, x5 y+5, 窗口
Gui, 1:Add, Edit, x+2 yp-3 w106 vEdtMousePosWin,
Gui, 1:Add, Text, x+5 yp+3, 屏幕
Gui, 1:Add, Edit, x+2 yp-3 w88 vEdtMousePosScreen,
Gui, 1:Add, Text, x5 y+5, 激活窗口
Gui, 1:Add, Edit, x+2 yp-3 w73 vEdtMousePosAWin,
Gui, 1:Add, Text, x+5 yp+3, 指针
Gui, 1:Add, Edit, x+2 yp-3 w92 vEdtMousePointer,
Gui, 1:Add, Text, x5 y+5, RGB 颜色
Gui, 1:Add, Edit, x+2 yp-3 w95 vEdtMouseColorRGB,
Gui, 1:Add, Text, x+5 yp+3, RGB 颜色
Gui, 1:Add, Edit, x+2 yp-3 w72 vEdtMouseColorHex,
Gui, 1:Font, bold
Gui, 1:Add, GroupBox, x5 y+10 Section w274 h305 -wrap, 颜色拾取
Gui, 1:Font, normal
Gui, 1:Add, Text, xs+4 yp+18, 范围:
Gui, 1:Add, ComboBox, x+5 yp-3 w55 vCbbColorPickDim gRefreshControlStates, 1x1|3x3||5x5|7x7|9x9|15x15
Gui, 1:Add, Radio, x+5 yp+3 vRadColorPick gRefreshControlStates, RGB
Gui, 1:Add, Radio, x+5 Checked gRefreshControlStates, BGR
Gui, 1:Add, Text, xs+4 y+5 w10 h5 Section, ;only to create a gap to the color matix
loop, 15 {
Row = %A_Index%
dy := (Row = 8 OR Row = 9) ? "y+2" : ""
Gui, 1:Add, Progress, xs+5 %dy% w17 h17 vPgbColorPicker%Row%_1,
loop, 14 {
Column := A_Index + 1
dx := (A_Index = 7 OR A_Index = 8) ? 2 : 0
Gui, 1:Add, Progress, x+%dx% w17 h17 vPgbColorPicker%Row%_%Column%,
}
}
Gui, 1:Tab, 选项
Gui, 1:Add, Text, x5 y25 Section , 显示窗口与控件数据
Gui, 1:Add, Radio, xs y+5 vRadWindow gRefreshControlStates, 激活窗口(&I)
Gui, 1:Add, Radio, xs y+5 Checked gRefreshControlStates, 鼠标指针下窗口(&M)
Gui, 1:Add, Button, x+55 y25 gBtnShowOptions1, 高级选项(&A)
Gui, 1:Add, Text, xs y+35, 显示控件数据
Gui, 1:Add, Radio, xs y+5 vRadControl gRefreshControlStates, 窗口焦点控件(&H)
Gui, 1:Add, Radio, xs y+5 Checked gRefreshControlStates, 鼠标指针下控件(&T)
Gui, 1:Add, Checkbox, xs y+15 vChkTtpMaster gRefreshControlStates Checked%ChkTtpMaster%, 指针显示提示(&P)
Gui, 1:Add, Button, x+3 yp-5 gBtnShowOptions2, 数据过滤选项(&D)
Gui, 1:Add, Text, xs y+10 , 显示捕捉边缘
Gui, 1:Add, Checkbox, x+5 vChkDrawRectCtrl gChkDrawRectCtrl Checked%ChkDrawRectCtrl%, 控件[红](&C)
Gui, 1:Add, Checkbox, y+5 vChkDrawRectWin gChkDrawRectWin Checked%ChkDrawRectWin%, 窗口[绿](&W)
ExportOptions = ;collect all checkboxes, so they can be Parsed in a loop
(LTrim Join,
ChkExportMousePosScreen,ChkExportMousePosAWin,ChkExportMousePosWin
ChkExportMousePointer,ChkExportMouseColorRGB,ChkExportMouseColorHex
ChkExportCtrlText,ChkExportCtrlClass,ChkExportCtrlPos
ChkExportCtrlSize,ChkExportCtrlListItems,ChkExportWinTitle,ChkExportWinPos
ChkExportWinSize,ChkExportWinClass,ChkExportWinProcess
ChkExportWinUID,ChkExportWinPID,ChkExportWinStatusText
ChkExportWinText,ChkExportLargeList
)
Gui, 1:Add, Text, xs y+15, 记录数据文件
Gui, 1:Add, Button, x+5 yp-5 gBtnShowOptions3, 记录选项(&R)
Gui, 1:Add, Button, x+5 vBtnSaveExport gBtnSaveExport, 保存到文件(&F)
Gui, 1:Add, Edit, xs w255 vEdtExportFile, %EdtExportFile%
Gui, 1:Add, Button, x+2 yp-1 gBtnBrowseExportFile,...
Gui, 1:Tab, 信息
Gui, 1:Add, Text, x5 y25 Section ,
(
This GUI will reveal information on windows, controls, etc.,
but only when this GUI is not the active window.
- To start/stop updating data press the Auto-Update
toggle Hotkey (default: Pause).
- To put the content of a field on the clipboard click with
the left mouse button into the field.
- To toggle the always-on-top state of this GUI use the
middle mouse button.
)
Gui, 1:Add, Button, x70 y+5 vBtnShowInfo gBtnShowInfo, 更多信息 - 请阅读
Gui, 1:Tab
GuiControl, Choose, Tab1, %Tab1%
Gui, 1:Add, Radio, x290 y2 Section vRadList1 gRadList, Info on all Controls of one window
Gui, 1:Add, Radio, x+5 vRadList2 gRadList, Info on all Windows (Click radio buttons again to refresh list)
Gui, 1:Add, ListView, xs y+5 w370 h339 vLV1 Count200
, Z or Stack Order|Unique ID or Handle|Window PID|Class(NN)|Process Name|Hidden|Title or Text|X|Y|Width|Height|Style|ExStyle|Selected|CurrentCol|CurrentLine|LineCount|Choice|Tab|Enabled|Checked
;Apply settings
if RadWindow = 1
GuiControl, 1:, RadWindow, 1
if RadControl = 1
GuiControl, 1:, RadControl, 1
if RadColorPick = 1
GuiControl, 1:, RadColorPick, 1
GuiControl, 1:, RadList%SelectedRadList%, 1
GuiControl, 1:ChooseString, CbbColorPickDim, %CbbColorPickDim%
StringSplit, Dim, CbbColorPickDim, x ;prepare color picker dimensions
Dim = %Dim1%
HalfDim := Dim // 2 + 1
gosub, ShowHideList
if Gui1AOTState {
Gui, 1:+AlwaysOnTop
TitleExtension = - *AOT*
}
if ChkHideGui
ShowOption = Hide
else
ShowOption = NoActivate
Gui, 1:Show, %Gui1Pos% %ShowOption% AutoSize , %ScriptName% %TitleExtension%
if !ChkHideGui
GuiIsVisible := True
return
;###############################################################################
;### prepare hotkey or mouse interaction with GUI ##########################
;###############################################################################
WM_LBUTTONDOWN(wParam, lParam, msg, hwnd){ ;Copy-On-Click for controls
global
local Content
if A_GuiControl is Space ;Control is not known
return
if A_GuiControl not contains Edt,Lsb,Pgb ;Control is something else then edit, listbox or Progressbar Control
return
;Check for full text vars
Fulltext = %A_GuiControl%Full
if (%Fulltext% <> "")
Content := %Fulltext%
else {
if A_GuiControl contains Pgb ;get value from color pickers (Progressbar)
Content := %A_GuiControl%
else
GuiControlGet, Content, , %A_GuiControl% ;get Controls content
}
if Content is Space ;content is empty or couldn't be retrieved
return
if A_GuiControl contains Class ;change data for specific fields
Content = ahk_class %Content%
else if A_GuiControl contains UID
Content = ahk_id %Content%
else if A_GuiControl contains PID
Content = ahk_pid %Content%
else if A_GuiControl contains Process
Content = ahk_pname %Content%
else if A_GuiControl contains Pos,Size
{
StringReplace, Content, Content, x
StringReplace, Content, Content, y
StringReplace, Content, Content, w
StringReplace, Content, Content, h
StringReplace, Content, Content, %A_Space%, `,%A_Space%
}
else if A_GuiControl contains Pgb
Content = 0x%Content%
ClipBoard = %Content% ;put content in clipboard
if ChkShowInfoToolTip {
if (StrLen(Content) > 200){ ;give feedback (limit size to 200 characters)
StringLeft, Content, Content, 200
Content = %Content% ...
}
ToolTip("ClipBoard = " Content)
}
}
WM_ACTIVATE(wParam, lParam, msg, hwnd){
Global UpdateIsStopped, ChkHideGui
if (wParam AND !ChkHideGui)
UpdateIsStopped := False
}
UpdateOnClick:
UpdateIsStopped := False ;needs to be set if large list had set it to true
gosub, UpdateInfo ;collect data
return
PauseAction: ;user has pressed toogle auto-update hotkey
if ChkHideGui { ;user wants hide/show Toggle
UpdateIsStopped := False ;needs to be set if large list had set it to true
if GuiIsVisible {
Gui, 1:Hide
}else{
SetTimer, UpdateInfo, Off ;turn timer off, to collect only once data
UpdateIsStopped := False ;turn update on
UpdateAfterPause := True ;set flag to update all
gosub, UpdateInfo ;collect data
UpdateAfterPause := False ;turn off flag to update all
UpdateIsStopped := True ;turn update off
SetTimer, UpdateInfo, %CbbUpdateInterval% ;turn timer back on
gosub, GuiShow ;bring Gui to front
}
GuiIsVisible := not GuiIsVisible
if ChkShowInfoToolTip
ToolTip(iif(UpdateIsStopped,"Press " HtkPauseAction " to hide Gui","Wait for " HtkPauseAction " key to`nupdate data and show Gui"),2000)
}else {
UpdateIsStopped := not UpdateIsStopped ;Toggle update status and show feedback
if UpdateIsStopped ;when stopped, bring Gui to front
gosub, GuiShow
if ChkShowInfoToolTip ;give feedback
ToolTip(Scriptname "`n----------------------------`nUpdate data : " iif(UpdateIsStopped,"Off","On"))
}
gosub, ToogleExportActions
gosub, PrepareFrameDraw ;create or destroy frame drawing objects
return
ToogleExportActions:
;Disable Export Save button during update
GuiControl, 1:Enable%UpdateIsStopped%, BtnSaveExport
;Enable Export Save hotkey when update is stopped and hotkey wanted
if (ChkUseSaveHotkey AND UpdateIsStopped)
Hotkey, #s, , On
else ; ... otherwise de-activate Export Save Hotkey
Hotkey, #s, , Off UseErrorLevel
return
PrepareFrameDraw: ;create or destroy frame drawing objects
if (UpdateIsStopped OR (ChkDrawRectCtrl = 0 AND ChkDrawRectWin = 0)){
gosub, CleanUpFrameGui
;create GUI Only if Gui doesn't exist yet and is needed.
}else if ( (ChkDrawRectCtrl OR ChkDrawRectWin) And not FrameGuiExists ){
FrameGuiExists := True
;create transparent GUI covering the whole screen
Gui, 2:+Lastfound +AlwaysOnTop
Gui, 2:Color, Black
WinSet, TransColor, Black
Gui, 2: -Caption +ToolWindow
Gui, 2:Show, x0 y0 w%ScreenWidth% h%ScreenHeight%, FrameDrawGui2
UniqueIDGui2 := WinExist()
;create draw objects for that window
CreateDrawHandles(UniqueIDGui2, ScreenWidth, ScreenHeight, frame_cc, frame_cw)
}
;set previous control/window to nothing, so that the frames start to draw immediatly
PreviousControlID =
PreviousWindowID =
return
CleanUpFrameGui:
DeleteObject( h_brushC ) ;destroy objects
DeleteObject( h_brushW )
DeleteObject( h_region )
DeleteObject( hbm_buffer )
DeleteDC( hdc_frame )
DeleteDC( hdc_buffer )
Gui, 2:Destroy ;destroy Gui
FrameGuiExists := False
ToolTip, , , , 2 ;remove Control frame ToolTip
ToolTip, , , , 3 ;remove window frame ToolTip
return
;###############################################################################
;### Interactions with GUI controls ########################################
;###############################################################################
Tab1:
GuiControlGet, Tab1, 1: ;get current value
gosub, ClearNotUsedControls
if (Tab1 = 1){ ;adjust tab height based on visible tab
GuiControl, 1:Move, Tab1, h145
}else if (Tab1 = 2) {
GuiControl, 1:Move, Tab1, h570
}else if (Tab1 = 3) {
GuiControl, 1:Move, Tab1, h430
}else if (Tab1 = 4) {
GuiControl, 1:Move, Tab1, h274
}else if (Tab1 = 5) {
GuiControl, 1:Move, Tab1, h174
}
ChkShowList := False
gosub, ShowHideList
Gui, 1:Show, AutoSize ;autosize Gui
return
ClearNotUsedControls:
if (Tab1 <> 2) {
GuiControl, 1:, EdtListItems, >>>未更新<<<
GuiControl, 1:, LsbStatusbarText, |>>>未更新<<<
GuiControl, 1:, EdtWindowTextFastVisible, >>>未更新<<<
GuiControl, 1:, EdtWindowTextSlowVisible, >>>未更新<<<
GuiControl, 1:, EdtWindowTextFastHidden, >>>未更新<<<
GuiControl, 1:, EdtWindowTextSlowHidden, >>>未更新<<<
}
if (Tab1 <> 3) {
loop, %Dim% {
Row := A_Index + 8 - HalfDim
loop, %Dim% {
y++
Control := "PgbColorPicker" (A_Index + 8 - HalfDim) "_" Row
GuiControl, 1:+BackgroundECE9D8,%Control%
}
}
}
return
ShowHideList:
GuiControl, 1:, BtnShowList, % iif(ChkShowList,"<< 减少信息(&L)","更多信息(&M) >>")
GuiControl, 1:Show%ChkShowList%, RadList1 ;show/hide Controls
GuiControl, 1:Show%ChkShowList%, RadList2
GuiControl, 1:Show%ChkShowList%, LV1 ;show/hide large list
return
BtnShowList:
ChkShowList := not ChkShowList
gosub, ShowHideList
Gui, 1:Show, AutoSize ;autosize Gui
if ChkShowList
gosub, GetDataForLargeList ;get data
return
RadList:
LV_Delete() ;clear Controls
StringRight, SelectedRadList, A_GuiControl, 1 ;get which got pressed
loop, 2 ;deactivate the other
if (A_Index <> SelectedRadList)
GuiControl, 1:, RadList%A_Index%, 0
Gui, 1:Submit, NoHide
gosub, GetDataForLargeList ;get data
return
GetDataForLargeList:
if (RadList1 = 1){ ;get data depending on choice
WindowUniqueID = %EdtWindowUID%
if EdtWindowUID is not Space
gosub, GetControlListInfo
}
else
gosub, GetAllWindowsInfo
return
RefreshControlStates:
Gui, 1:Submit, NoHide ;get current values of all Controls
StringSplit, Dim, CbbColorPickDim, x ;prepare color picker dimensions
Dim = %Dim1%
HalfDim := Dim // 2 + 1
loop, 15 {
Row = %A_Index%
loop, 15
GuiControl, 1:+BackgroundDefault ,PgbColorPicker%Row%_%A_Index%
}
return
ChkDrawRectCtrl:
GuiControlGet, ChkDrawRectCtrl, 1: ;get current value
gosub, PrepareFrameDraw
ToolTip, , , , 2
return
ChkDrawRectWin:
GuiControlGet, ChkDrawRectWin, 1: ;get current value
gosub, PrepareFrameDraw
ToolTip, , , , 3
return
;###############################################################################
;### GUI actions ###########################################################
;###############################################################################
GuiSize:
if (A_EventInfo = 0) { ;restored, or resized
GuiControl, 1:Move, Tab1, h%A_GuiHeight%
w := A_GuiWidth - 290
h := A_GuiHeight - 22
GuiControl, 1:Move, LV1, w%w% h%h%
h -= 143
GuiControl, 1:Move, GrbAdvancedWindow, h%h%
h := (h - 218) / 2
;~ GuiControl, 1:Move, EdtWindowTextFastVisible, h%h%
;~ GuiControl, 1:Move, EdtWindowTextFastHidden, h%h%
y := A_GuiHeight - h - 24
GuiControl, 1:Move, TxtWindowTextSlowVisible, y%y%
GuiControl, 1:Move, TxtWindowTextSlowHidden, y%y%
y += 15
;~ GuiControl, 1:Move, EdtWindowTextSlowVisible, y%y% h%h%
;~ GuiControl, 1:Move, EdtWindowTextSlowHidden, y%y% h%h%
if (LastEventInfo = 1){ ;Gui got restored
;start updating again
UpdateIsStopped := False
;reactivate frame
gosub, PrepareFrameDraw
}
}else if (A_EventInfo = 1) { ;minimized
;stop updating
UpdateIsStopped := True
;remove frames
gosub, PrepareFrameDraw
}
LastEventInfo = %A_EventInfo%
return
WriteIni:
Gui, 1:Submit, NoHide
WinGetPos, PosX, PosY, SizeW, SizeH, %WinNameGui1%
loop, 2
if (RadList%A_Index% = 1)
IniWrite, %A_Index% , %IniFile%, Settings, SelectedRadList
if (PosX > -4 and PosY > -4)
IniWrite, x%PosX% y%PosY% , %IniFile%, Settings, Gui1Pos
IniWrite, %Gui1AOTState% , %IniFile%, Settings, Gui1AOTState
IniWrite, %Tab1% , %IniFile%, Settings, Tab1
IniWrite, %RadWindow% , %IniFile%, Settings, RadWindow
IniWrite, %RadControl% , %IniFile%, Settings, RadControl
IniWrite, %ChkShowList% , %IniFile%, Settings, ChkShowList
IniWrite, %HtkPauseAction% , %IniFile%, Settings, HtkPauseAction
IniWrite, %ChkCopyToCB% , %IniFile%, Settings, ChkCopyToCB
IniWrite, %ChkHideGui% , %IniFile%, Settings, ChkHideGui
IniWrite, %ChkUseSaveHotkey% , %IniFile%, Settings, ChkUseSaveHotkey
loop, Parse, ExportOptions, `,
IniWrite, % %A_LoopField% , %IniFile%, Export , %A_LoopField%
IniWrite, %EdtExportFile% , %IniFile%, Export , EdtExportFile
IniWrite, %ChkExportAutoNumber%, %IniFile%, Export , ChkExportAutoNumber
IniWrite, %ChkExportAppend% , %IniFile%, Export , ChkExportAppend
IniWrite, %ChkShowInfoToolTip% , %IniFile%, Advanced, ChkShowInfoToolTip
IniWrite, %ChkDrawRectCtrl% , %IniFile%, Advanced, ChkDrawRectCtrl
IniWrite, %ChkDrawRectWin% , %IniFile%, Advanced, ChkDrawRectWin
IniWrite, %ChkTtpMaster% , %IniFile%, Advanced, ChkTtpMaster
IniWrite, %ChkTtpMSPos% , %IniFile%, Advanced, ChkTtpMSPos
IniWrite, %ChkTtpMWPos% , %IniFile%, Advanced, ChkTtpMWPos
IniWrite, %ChkTtpMColor% , %IniFile%, Advanced, ChkTtpMColor
IniWrite, %ChkTtpCClass% , %IniFile%, Advanced, ChkTtpCClass
IniWrite, %ChkTtpCPos% , %IniFile%, Advanced, ChkTtpCPos
IniWrite, %ChkTtpCSize% , %IniFile%, Advanced, ChkTtpCSize
IniWrite, %ChkTtpWClass% , %IniFile%, Advanced, ChkTtpWClass
IniWrite, %ChkTtpWTitle% , %IniFile%, Advanced, ChkTtpWTitle
IniWrite, %CbbUpdateInterval% , %IniFile%, Advanced, CbbUpdateInterval
IniWrite, %CbbColorPickDim% , %IniFile%, Advanced, CbbColorPickDim
IniWrite, %RadColorPick% , %IniFile%, Advanced, RadColorPick
IniWrite, %ChkAutoStartUpdate% , %IniFile%, Advanced, ChkAutoStartUpdate
IniWrite, %CbbHtkUpdate% , %IniFile%, Advanced, CbbHtkUpdate
IniWrite, %RadUpdateOnClick% , %IniFile%, Advanced, RadUpdateOnClick
IniWrite, %RadUpdateAuto% , %IniFile%, Advanced, RadUpdateAuto
return
GuiClose:
GuiEscape:
gosub, WriteIni
ExitApp
return
;###############################################################################
;### GUI for information text ##############################################
;###############################################################################
BtnShowInfo:
GuiControl, 1:Disable, BtnShowInfo
Gui, 3:+Owner1 +AlwaysOnTop +ToolWindow +Resize
Gui, 3:Font, s12, MS Sans Serif
Gui, 3:Add, Button, gCloseInfoGui, 关闭
;~ Gui, 3:Add, Edit, w600 h400 vEdtInfoText, %InformationText%
Gui, 3:Add, Edit, w600 h400 vEdtInfoText, %InformationText%
Gui, 3:Show, AutoSize, 信息 - %ScriptName%
return
3GuiClose:
3GuiEscape:
CloseInfoGui:
GuiControl, 1:Enable, BtnShowInfo
Gui, 3:Destroy
return
3GuiSize:
w := A_GuiWidth - 20
h := A_GuiHeight - 45
GuiControl, 3:Move, EdtInfoText, w%w% h%h%
return
;###############################################################################
;### GUI for options #######################################################
;###############################################################################
BtnShowOptions1:
ChangeToTab := 1
gosub, BtnShowOptions
return
BtnShowOptions2:
ChangeToTab := 2
gosub, BtnShowOptions
return
BtnShowOptions3:
ChangeToTab := 3
gosub, BtnShowOptions
return
subCbbHtkUpdate:
CbbHtkUpdate:=%CbbHtkUpdateV%
return
BtnShowOptions:
UpdateIsStopped := True
Hotkey, IfWinNotActive, ahk_id %Gui1UniqueID%
Hotkey, ~%CbbHtkUpdate%, Off
Hotkey, IfWinNotActive
Gui, 1:+Disabled
Gui, 4:+Owner1 +AlwaysOnTop +ToolWindow
Gui, 4:Font, s12, MS Sans Serif
Gui, 4:Add, Tab, Section w435 h580 vTab2 AltSubmit -Wrap, 高级(&V)|提示(&T)|记录文件(&R)
Gui, 4:Tab, 高级
Gui, 4:Add, GroupBox, w410 h95, 更新数据
Gui, 4:Add, Radio, x40 yp+22 Checked%RadUpdateOnClick% vRadUpdateOnClick gRadUpdate, 点击(&K)
;~ Gui, 4:Add, ComboBox, x+5 yp-3 w80 vCbbHtkUpdate, LButton|MButton||RButton
Gui, 4:Add, DropDownList, x+5 yp-3 w80 vCbbHtkUpdateV gsubCbbHtkUpdate, 左键|中键||右键
Gui, 4:Add, Radio, x40 y+8 Checked%RadUpdateAuto% vRadUpdateAuto gRadUpdate, 自动更新[毫秒](&T):
Gui, 4:Add, ComboBox, x+5 yp-3 w50 vCbbUpdateInterval, 100||200|300|400|500|1000|2000
Gui, 4:Add, Checkbox, x22 y+20 vChkChangePauseHotkey gChkChangePauseHotkey, (&S)更改切换自动更新热键 [默认: Pause)]
Gui, 4:Add, Hotkey, xp+15 y+5 w150 vHtkPauseAction gHtkPauseAction Disabled, %HtkPauseAction%
Gui, 4:Add, Checkbox, xp-15 y+5 vChkHideGui Checked%ChkHideGui%, (&G)通过上述热键隐藏/显示 GUI`; GUI 显示前将收集数据.
Gui, 4:Add, Checkbox, y+5 vChkAutoStartUpdate Checked%ChkAutoStartUpdate%, (&D)在自动更新关闭后, GUI 重新开始更新数据.
Gui, 4:Add, Checkbox, y+5 vChkCopyToCB Checked%ChkCopyToCB%, (&P)在收集数据区域点击左键复制数据到粘贴板.
Gui, 4:Add, Text, y+20, 更新关闭时:
Gui, 4:Add, Checkbox, vChkUseSaveHotkey Checked%ChkUseSaveHotkey%, (&F)使用热键 Win+S 记录数据到文件
Gui, 4:Add, Checkbox, y+20 Section vChkShowInfoToolTip Checked%ChkShowInfoToolTip%, (&O)显示数据提示
Gui, 4:Tab, 提示
Gui, 4:Add, Text, , 选择鼠标指针显示数据
Gui, 4:Add, Checkbox, vChkTtpMSPos Checked%ChkTtpMSPos%, (&S) 屏幕鼠标位置 *
Gui, 4:Add, Checkbox, vChkTtpMWPos Checked%ChkTtpMWPos%, (&W) 窗口幕鼠标位置
Gui, 4:Add, Checkbox, vChkTtpMColor Checked%ChkTtpMColor%, (&I) 鼠标下像素颜色
Gui, 4:Add, Checkbox, vChkTtpCClass Checked%ChkTtpCClass%, (&T) 鼠标指针下控件类 *
Gui, 4:Add, Checkbox, vChkTtpCPos Checked%ChkTtpCPos%, (&P) 控件位置
Gui, 4:Add, Checkbox, vChkTtpCSize Checked%ChkTtpCSize%, (&Z) 控件大小
Gui, 4:Add, Checkbox, vChkTtpWClass Checked%ChkTtpWClass%, (&L) 窗口类 *
Gui, 4:Add, Checkbox, vChkTtpWTitle Checked%ChkTtpWTitle%, (&E) 窗口标题 *
Gui, 4:Add, Text, , (* = GUI 隐藏时有效)
Gui, 4:Tab, 记录文件
Gui, 4:Add, GroupBox, Section w274 R3 , 记录鼠标数据
Gui, 4:Add, Checkbox, vChkExportMousePosScreen Checked%ChkExportMousePosScreen% xs+4 yp+18, 屏幕鼠标位置
Gui, 4:Add, Checkbox, vChkExportMousePosAWin Checked%ChkExportMousePosAWin% xs+125 yp, 相对激活窗口位置
Gui, 4:Add, Checkbox, vChkExportMousePosWin Checked%ChkExportMousePosWin% xs+4 y+5, 相对窗口位置
Gui, 4:Add, Checkbox, vChkExportMousePointer Checked%ChkExportMousePointer% xs+125 yp, 指针类型
Gui, 4:Add, Checkbox, vChkExportMouseColorRGB Checked%ChkExportMouseColorRGB% xs+4 y+5, RGB 颜色
Gui, 4:Add, Checkbox, vChkExportMouseColorHex Checked%ChkExportMouseColorHex% xs+125 yp, Hex 颜色
Gui, 4:Add, GroupBox, xs w274 R3 , 记录控件数据
Gui, 4:Add, Checkbox, vChkExportCtrlText Checked%ChkExportCtrlText% xs+4 yp+18, 控件文本
Gui, 4:Add, Checkbox, vChkExportCtrlClass Checked%ChkExportCtrlClass% xs+125 yp, 控件 ClassNN
Gui, 4:Add, Checkbox, vChkExportCtrlPos Checked%ChkExportCtrlPos% xs+4 y+5, 控件位置
Gui, 4:Add, Checkbox, vChkExportCtrlSize Checked%ChkExportCtrlSize% xs+125 yp, 控件大小
Gui, 4:Add, Checkbox, vChkExportCtrlListItems Checked%ChkExportCtrlListItems% xs+4 y+5, 控件列表项
Gui, 4:Add, GroupBox, xs w274 R4 , 记录窗口数据
Gui, 4:Add, Checkbox, vChkExportWinTitle Checked%ChkExportWinTitle% xs+4 yp+18, 窗口标题
Gui, 4:Add, Checkbox, vChkExportWinPos Checked%ChkExportWinPos% xs+4 y+5, 窗口位置
Gui, 4:Add, Checkbox, vChkExportWinSize Checked%ChkExportWinSize% xs+125 yp, 窗口大小
Gui, 4:Add, Checkbox, vChkExportWinClass Checked%ChkExportWinClass% xs+4 y+5, 窗口类
Gui, 4:Add, Checkbox, vChkExportWinProcess Checked%ChkExportWinProcess% xs+125 yp, 窗口进程
Gui, 4:Add, Checkbox, vChkExportWinUID Checked%ChkExportWinUID% xs+4 y+5, 窗口 UID
Gui, 4:Add, Checkbox, vChkExportWinPID Checked%ChkExportWinPID% xs+125 yp, 窗口 PID
Gui, 4:Add, Checkbox, vChkExportWinStatusText Checked%ChkExportWinStatusText% xs+4 y+5, 状态栏文本
Gui, 4:Add, Checkbox, vChkExportWinText Checked%ChkExportWinText% xs+125 yp, 窗口文本
Gui, 4:Add, Checkbox, xs y+25 vChkExportLargeList Checked%ChkExportLargeList%, 记录大列表 选择:
Gui, 4:Add, Button, x+2 yp-5 gBtnExportCheckAll, 全部
Gui, 4:Add, Button, x+2 gBtnExportCheckNone , 无
Gui, 4:Add, Button, x+2 gBtnExportCheckReverse , 反选
Gui, 4:Add, Text, xs y+5, 附加数据选项:
Gui, 4:Add, Checkbox, y+5 Section vChkExportAutoNumber gChkExportAutoNumber Checked%ChkExportAutoNumber%, 使用数字替换文件名中的 "#"
Gui, 4:Add, Checkbox, y+5 vChkExportAppend gChkExportAppend Checked%ChkExportAppend%, 附加数据到文件
Gui, 4:Tab
Gui, 4:Add, Button, xm gApplyOptions, 应用(&A)
Gui, 4:Add, Button, x+5 g4GuiClose, 取消(&C)
if RadUpdateOnClick {
GuiControl, 4:Disable, ChkChangePauseHotkey
GuiControl, 4:Disable, ChkHideGui
GuiControl, 4:Disable, ChkAutoStartUpdate
}
GuiControl, 4:ChooseString, CbbHtkUpdate, %CbbHtkUpdate%
GuiControl, 4:ChooseString, CbbUpdateInterval, %CbbUpdateInterval%
gosub, ChkExportAutoNumber
gosub, ChkExportAppend
GuiControl, 4:Choose, Tab2, %ChangeToTab%
Gui, 4:Show,, Options - %ScriptName%
return
RadUpdate:
if (A_GuiControl = "RadUpdateOnClick"){
GuiControl, 4:, RadUpdateAuto, 0
GuiControl, 4:, ChkChangePauseHotkey, 0
GuiControl, 4:Disable, ChkChangePauseHotkey
GuiControl, 4:Disable, HtkPauseAction
GuiControl, 4:, ChkHideGui, 0
GuiControl, 4:Disable, ChkHideGui
GuiControl, 4:, ChkAutoStartUpdate, 0
GuiControl, 4:Disable, ChkAutoStartUpdate
}else{
GuiControl, 4:, RadUpdateOnClick, 0
GuiControl, 4:Enable, ChkChangePauseHotkey
GuiControl, 4:Enable, ChkHideGui
GuiControl, 4:Enable, ChkAutoStartUpdate
GuiControl, 4:, ChkAutoStartUpdate, 1
}
return
ApplyOptions:
Gui, 4:Submit
if ChkCopyToCB
OnMessage( WM_LButtonDOWN, "WM_LButtonDOWN" ) ;activate copy-on-Click
else
OnMessage( WM_LButtonDOWN, "" ) ;deactivate copy-on-Click
if ChkAutoStartUpdate
OnMessage(WM_ACTIVATE, "WM_ACTIVATE") ;activate auto-start updating at Gui inactivity
else
OnMessage(WM_ACTIVATE, "" ) ;deactivate auto-start updating
if RadUpdateAuto {
SetTimer, UpdateInfo, %CbbUpdateInterval%
}else{
SetTimer, UpdateInfo, Off
Hotkey, IfWinNotActive, ahk_id %Gui1UniqueID%
Hotkey, ~%CbbHtkUpdate%, UpdateOnClick, On
Hotkey, IfWinNotActive
}
gosub, PauseAction
4GuiClose:
4GuiEscape:
UpdateIsStopped := False
Gui, 1:-Disabled
Gui, 4:Destroy
return
ChkChangePauseHotkey:
GuiControlGet, ChkChangePauseHotkey, 4: ;get current value
if ChkChangePauseHotkey {
;de-activate current auto-update toggle hotkey
Hotkey, %HtkPauseAction%, Off
GuiControl, 4:Enable, HtkPauseAction
}else
gosub, HtkPauseAction
return
HtkPauseAction:
GuiControlGet, HtkPauseAction, 4: ;get current value
if HtkPauseAction {
if HtkPauseAction in ^,+,! ;don't react on simple modifiers
return
;activate new auto-update toggle hotkey
Hotkey, %HtkPauseAction%, PauseAction, On
GuiControl, 4:Disable, HtkPauseAction
GuiControl, 4:, ChkChangePauseHotkey, 0
}else{
GuiControl, 4:, ChkChangePauseHotkey, 1
GuiControl, 4:Enable, HtkPauseAction
ToolTip("You need to specify a Hotkey", 2000)
}
return
BtnExportCheckAll:
loop, Parse, ExportOptions, `,
GuiControl, 4:, %A_LoopField%, 1
return
BtnExportCheckNone:
loop, Parse, ExportOptions, `,
GuiControl, 4:, %A_LoopField%, 0
return
BtnExportCheckReverse:
Gui, 1:Submit, NoHide
loop, Parse, ExportOptions, `,
GuiControl, 4:, %A_LoopField%, % not %A_LoopField%
return
ChkExportAutoNumber:
Gui, 4:Submit, NoHide
if ChkExportAutoNumber
GuiControl, 4:Disable, ChkExportAppend
else
GuiControl, 4:Enable, ChkExportAppend
return
ChkExportAppend:
Gui, 4:Submit, NoHide
if ChkExportAppend
GuiControl, 4:Disable, ChkExportAutoNumber
else
GuiControl, 4:Enable, ChkExportAutoNumber
return
;###############################################################################
;### getting the data #####################################################
;###############################################################################
UpdateInfo:
if UpdateIsStopped
return
if (WinActive("A") = Gui1UniqueID ) ;don't update when window becomes the active one
return
if (Tab1 > 3 ) ;don't update when tab 4 or tab 5 are visible
return
SetBatchLines, -1
;get mouse pos and make sure mouse is not on frames or tooltips or on it's own gui
MouseIsOnFrameGui := False
gosub, CheckForFramesAndTipsAndGetMousePos
if MouseIsOnFrameGui
return
gosub, SetWhichWindow
gosub, SetWhichControl
if (ChkHideGui And ChkTtpMaster And !GuiIsVisible) ;update only small info when Gui is hidden if tool tips are wanted
gosub, UpdateMinimumInfo
else if (!ChkHideGui Or UpdateAfterPause) ;update only when Gui not set to HideGui or if Pause is release and one update is needed
gosub, UpdateAllInfo
;draw frames if wanted
if ( ( ChkDrawRectCtrl OR ChkDrawRectWin ) ;user wants to see at least one of the frames
AND PreviousControlID <> ControlID ;the control has changed
AND StatusDrawFrame ){ ;AND the Mouse is not on the active window which should be drawn
if not FrameGuiExists ;create frame Gui if it had been destroyed, e.g. by viewing the large list
gosub, PrepareFrameDraw
DrawFrameAroundControl(ControlID, WindowUniqueID, frame_t)
}
;memorize IDs
PreviousControlID = %ControlID%
PreviousWindowID = %WindowID%
if UpdateIsStopped { ;when update stopped within this Run, behave as if Toggle Hotkey was pressed
gosub, ToogleExportActions
gosub, PrepareFrameDraw ;create or destroy frame drawing objects
gosub, GuiShow
}
return
;check if frames or tool tips are under mouse pointer
CheckForFramesAndTipsAndGetMousePos:
;get mouse positions relative to screen
CoordMode, Mouse, Screen
MouseGetPos, MouseScreenX, MouseScreenY, MouseWindowUID, MouseControlID
WinGetClass, WindowClass, ahk_id %MouseWindowUID%
WinGetTitle, WindowTitle, ahk_id %MouseWindowUID%
if ( MouseWindowUID = UniqueIDGui2 ;if window is frame Gui
OR MouseWindowUID = Gui1UniqueID ;or real gui
OR (WindowClass = "tooltips_class32" ;or window is tooltip
AND ( WindowTitle = PreviousControlID ;and has the title of the last control
OR WindowTitle = PreviousWindowID ;or has the title of the last window
OR InStr(WindowTitle,Scriptname)) ) ) ;{ ;or has a title that contains the script name, then it might be one of the info tooltips
MouseIsOnFrameGui := True
if (MouseIsOnFrameGui AND WindowTitle = PreviousControlID) ;remove Control frame ToolTip if Mouse is on it, to be able to see Screen below
ToolTip, , , , 2
return
;set UID of window for which the following data should be retrieved
SetWhichWindow:
StatusDrawFrame := True
if (RadWindow = 1){ ;for active window
WinGet, WindowUniqueID, ID, A
if (WindowUniqueID <> MouseWindowUID) ;Mouse is not in active window, don't redraw frames
StatusDrawFrame := False
}else ;for window under Mouse pointer
WindowUniqueID = %MouseWindowUID%
return
;set control ID for which the data should be retrieved
SetWhichControl:
if (RadControl = 1) ;for active Control
ControlGetFocus, ControlID, ahk_id %WindowUniqueID%
else ;for Control under Mouse pointer
ControlID = %MouseControlID%
return
UpdateMinimumInfo:
;optional tooltip
if ChkTtpMaster {
InfoString := iif(ChkTtpMSPos,"MScreen: " MouseScreenX "," MouseScreenY "`n")
. iif(ChkTtpCClass,"Control ClassNN: " MouseControlID "`n")
. iif(ChkTtpWClass,"Window Class: " WindowClass "`n")
. iif(ChkTtpWTitle,"Window Title: " WindowTitle "`n")
StringTrimRight, InfoString, InfoString, 1 ;remove last `n
if InfoString
ToolTip(Scriptname "`n----------------------------`n" InfoString)
}
return
UpdateAllInfo:
;ToolTip, UpdateAllInfo - %A_Now% ;??? for debug
gosub, GetMouseInfo
gosub, GetControlInfo
;optional tooltip
if ChkTtpMaster {
InfoString := iif(ChkTtpMSPos,"MScreen: " MouseScreenX "," MouseScreenY "`n")
. iif(ChkTtpMWPos,"MWindow: " MouseWindowX "," MouseWindowY "`n")
. iif(ChkTtpMColor,"MColor: " MouseColorRGB "`n")
. iif(ChkTtpCClass,"Control ClassNN: " MouseControlID "`n")
. iif(ChkTtpCPos,"Control Pos: " ControlX "," ControlY "`n")
. iif(ChkTtpCSize,"Control Size: " ControlWidth "," ControlHeight "`n")
. iif(ChkTtpWClass,"Window Class: " WindowClass "`n")
. iif(ChkTtpWTitle,"Window Title: " WindowTitle "`n")
StringTrimRight, InfoString, InfoString, 1 ;remove last `n
if InfoString
ToolTip(Scriptname "`n----------------------------`n" InfoString)
}
gosub, GetWindowInfo
if (Tab1 = 2) ;get window text only when advanced tab is active
gosub, GetWindowText
if ChkShowList { ;if large list is shown
if RadList1 = 1 ;get data depending on choice
gosub, GetControlListInfo
else
gosub, GetAllWindowsInfo
UpdateIsStopped := True ;give feedback and stop updating
if ChkShowInfoToolTip
ToolTip("Stopped to update data to allow working with "
. iif(SelectedRadList = 1,"list of Controls")
. iif(SelectedRadList = 2,"list of windows")
. "`nPress Pause key to create a new snapshot", 2000)
}
return
GetMouseInfo:
;get mouse pos relative to windows
WinGetPos, WindowActiveX, WindowActiveY,,, A
WinGetPos, WindowX, WindowY,,, ahk_id %MouseWindowUID%
MouseWindowActiveX := MouseScreenX - WindowActiveX
MouseWindowActiveY := MouseScreenY - WindowActiveY
MouseWindowX := MouseScreenX - WindowX
MouseWindowY := MouseScreenY - WindowY
GuiControl, 1:, EdtMousePosScreen, x%MouseScreenX% y%MouseScreenY%
GuiControl, 1:, EdtMousePosWin, x%MouseWindowX% y%MouseWindowY%
GuiControl, 1:, EdtEasyMousePosWin, x%MouseWindowX% y%MouseWindowY%
GuiControl, 1:, EdtDataMousePosWin, x%MouseWindowX% y%MouseWindowY%
GuiControl, 1:, EdtMousePosAWin, x%MouseWindowActiveX% y%MouseWindowActiveY%
;get pointer shape
GuiControl, 1:, EdtMousePointer, %A_Cursor%
;get color below mouse pointer
CoordMode, Pixel, Screen
PixelGetColor, MouseColorRGB, %MouseScreenX%, %MouseScreenY%, RGB
StringMid, MouseColorR, MouseColorRGB, 3, 2
StringMid, MouseColorG, MouseColorRGB, 5, 2
StringMid, MouseColorB, MouseColorRGB, 7, 2
GuiControl, 1:, EdtMouseColorRGB, % "R" HEXtoDEC(MouseColorR) " G" HEXtoDEC(MouseColorG)" B" HEXtoDEC(MouseColorB)
GuiControl, 1:, EdtMouseColorHex, %MouseColorRGB%
if (Tab1 = 3) { ;Only update color picker when Mouse tab is active
if ( MouseScreenX MouseScreenY <> OldPosition or MouseColorRGB <> OldMouseColorRGB){ ;only update color picker when Mouse moves or color changes
x := MouseScreenX - HalfDim
loop, %Dim% {
x++
Row := A_Index + 8 - HalfDim
y := MouseScreenY - HalfDim
loop, %Dim% {
y++
PixelGetColor, ColorRGB, %x%, %y%, % iif(RadColorPick = 1, "RGB")
StringTrimLeft, ColorRGB, ColorRGB, 2
Control := "PgbColorPicker" (A_Index + 8 - HalfDim) "_" Row
%Control% = %ColorRGB%
if RadColorPick = 2
PixelGetColor, ColorRGB, %x%, %y%, RGB
GuiControl, 1:+Background%ColorRGB%,%Control%
}
}
}
OldPosition = %MouseScreenX%%MouseScreenY%
OldMouseColorRGB = %MouseColorRGB%
}
return
GetControlInfo:
GuiControl, 1:, EdtControlClass, %ControlID%
GuiControl, 1:, EdtEasyControlClass, %ControlID%
;get Pos, Size, Text
ControlGetPos, ControlX, ControlY, ControlWidth, ControlHeight, %ControlID%, ahk_id %WindowUniqueID%
GuiControl, 1:, EdtControlPos, x%ControlX% y%ControlY%
GuiControl, 1:, EdtControlSize, w%ControlWidth% h%ControlHeight%
ControlGet, ControlHwnd, Hwnd,, %ControlID%, ahk_id %WindowUniqueID%
GuiControl, 1:, EdtControlHwnd, %ControlHwnd%
;Chris suggests to avoid any call to ControlGetText or WinGetText because they force the OS to copy an
; unlimited amount of text across process boundaries. This text could be several megabytes or more if
; someone has a big text file or Word document open. Instead use WM_GETTEXT.
; ControlGetText, ControlText, %ControlID%, ahk_id %WindowUniqueID%
MouseGetPos,,,,ControlHWND, 2
SendMessage, 0xD, ControlTextSize, &ControlText,, ahk_id %ControlHWND% ; 0xD is WM_GETTEXT.
EdtControlTextFull := ShowOnlyAPartInGui("EdtControlText", ControlText, 100)
EdtEasyControlTextFull := ShowOnlyAPartInGui("EdtEasyControlText", ControlText, 100)
if (Tab1 = 2) { ;get Control list data only when advanced tab is active
ControlGet, ControlListItems, List, , %ControlID%, ahk_id %WindowUniqueID%
EdtListItemsFull := ShowOnlyAPartInGui("EdtListItems", ControlListItems, 200)
}
return
GetWindowInfo:
;get Title, Pos, Size, PID, Process, Class
WinGetTitle, WindowTitle, ahk_id %WindowUniqueID%
WinGetPos, WindowX, WindowY, WindowWidth, WindowHeight, ahk_id %WindowUniqueID%
WinGet, WindowPID, PID, ahk_id %WindowUniqueID%
WinGet, WindowProcessName, ProcessName, ahk_pid %WindowPID%
WinGetClass, WindowClass, ahk_id %WindowUniqueID%
GuiControl, 1:, EdtWindowTitle, %WindowTitle%
GuiControl, 1:, EdtEasyWindowTitle, %WindowTitle%
GuiControl, 1:, EdtWindowPos, x%WindowX% y%WindowY%
GuiControl, 1:, EdtWindowSize, w%WindowWidth% h%WindowHeight%
GuiControl, 1:, EdtWindowClass, %WindowClass%
GuiControl, 1:, EdtEasyWindowClass, %WindowClass%
GuiControl, 1:, EdtWindowProcess, %WindowProcessName%
GuiControl, 1:, EdtWindowUID, %WindowUniqueID%
GuiControl, 1:, EdtWindowPID, %WindowPID%
if (Tab1 = 2) { ;get advanced window data only when advanced tab is active
;get and set statusbartext (maximum 10)
ListOfStatusbarText =
loop, 10 {
StatusBarGetText, StatusBarText, %A_Index%, ahk_id %WindowUniqueID%
if StatusBarText
ListOfStatusbarText = %ListOfStatusbarText%%A_Index% - %StatusBarText%|
}
if ListOfStatusbarText is Space
ListOfStatusbarText = No text found in statusbar
GuiControl, 1:, LsbStatusbarText, |%ListOfStatusbarText%
}
return
GetWindowText:
EdtWindowTextFastVisible =
EdtWindowTextSlowVisible =
EdtWindowTextFastHidden =
EdtWindowTextSlowHidden =
;Suggested by Chris
WinGet, ListOfControlHandles, ControlListHwnd, ahk_id %WindowUniqueID% ; Requires v1.0.43.06+.
loop, Parse, ListOfControlHandles, `n
{
text_is_fast := true
if not DllCall("GetWindowText", "uint", A_LoopField, "str", WindowControlText, "int", WindowControlTextSize){
text_is_fast := false
SendMessage, 0xD, WindowControlTextSize, &WindowControlText,, ahk_id %A_LoopField% ; 0xD is WM_GETTEXT
}
if (WindowControlText <> ""){
ControlGet, WindowControlStyle, Style,,, ahk_id %A_LoopField%
if (WindowControlStyle & 0x10000000){ ; Control is visible vs. hidden (WS_VISIBLE).
if text_is_fast
EdtWindowTextFastVisible = %EdtWindowTextFastVisible%%WindowControlText%`r`n
else
EdtWindowTextSlowVisible = %EdtWindowTextSlowVisible%%WindowControlText%`r`n
}else{ ; Hidden text.
if text_is_fast
EdtWindowTextFastHidden = %EdtWindowTextFastHidden%%WindowControlText%`r`n
else
EdtWindowTextSlowHidden = %EdtWindowTextSlowHidden%%WindowControlText%`r`n
}
}
}
EdtWindowTextFastVisibleFull := ShowOnlyAPartInGui("EdtWindowTextFastVisible", EdtWindowTextFastVisible, 400)
EdtWindowTextSlowVisibleFull := ShowOnlyAPartInGui("EdtWindowTextSlowVisible", EdtWindowTextSlowVisible, 400)
EdtWindowTextFastHiddenFull := ShowOnlyAPartInGui("EdtWindowTextFastHidden", EdtWindowTextFastHidden, 400)
EdtWindowTextSlowHiddenFull := ShowOnlyAPartInGui("EdtWindowTextSlowHidden", EdtWindowTextSlowHidden, 400)
return
ShowOnlyAPartInGui(Control, FullContent, Limit=200){
Content = %FullContent%
if (StrLen(Content) > Limit){ ;limits the Control text in the Gui. An unlimited length caused on some PCs 100% CPU load
StringLeft, Content, Content, %Limit%
Content = %Content% ...
}
GuiControl, 1:, %Control%, %Content%
return FullContent
}
GetControlListInfo:
;get list of controls in z order
WinGet, ControlList, ControlList, ahk_id %WindowUniqueID%
;get all data for these controls
loop, Parse, ControlList, `n
{
ControlID0 = %A_Index%
ControlID = %A_LoopField%
ControlID%A_Index% = %ControlID%
ControlGetPos, ControlX%A_Index%, ControlY%A_Index%, ControlWidth%A_Index%, ControlHeight%A_Index%, %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlHwnd%A_Index%, Hwnd,, %ControlID%, ahk_id %WindowUniqueID%
ControlGetText, ControlText%A_Index%, %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlChecked%A_Index%, Checked, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlEnabled%A_Index%, Enabled, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlVisible%A_Index%, Visible, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlTab%A_Index%, Tab, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlChoice%A_Index%, Choice, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlLineCount%A_Index%, LineCount, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlCurrentLine%A_Index%, CurrentLine, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlCurrentCol%A_Index%, CurrentCol, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlSelected%A_Index%, Selected, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlStyle%A_Index%, Style, , %ControlID%, ahk_id %WindowUniqueID%
ControlGet, ControlExStyle%A_Index%, ExStyle, , %ControlID%, ahk_id %WindowUniqueID%
}
;add all data to listview
GuiControl, -Redraw, LV1 ; speed up adding data
LV_Delete() ; remove old data
loop, %ControlID0% {
LV_Add(""
, A_Index ; Z or Stack Order
, ControlHwnd%A_Index% ; Unique ID
, "" ; Window PID
, ControlID%A_Index% ; Window Class
, "" ; Window Process Name
, ControlVisible%A_Index% ; Visible or Hidden?
, ControlText%A_Index% ; Title or Text
, ControlX%A_Index% ; X
, ControlY%A_Index% ; Y
, ControlWidth%A_Index% ; Width
, ControlHeight%A_Index% ; Height
, ControlStyle%A_Index% ; Style
, ControlExStyle%A_Index% ; ExStyle
, ControlSelected%A_Index% ; Selected
, ControlCurrentCol%A_Index% ; CurrentCol
, ControlCurrentLine%A_Index% ; CurrentLine
, ControlLineCount%A_Index% ; LineCount
, ControlChoice%A_Index% ; Choice
, ControlTab%A_Index% ; Tab
, ControlEnabled%A_Index% ; Enabled
, ControlChecked%A_Index%) ; Checked
}
LV_ModifyCol() ; Auto-size all columns
LV_ModifyCol(1, "Integer Left") ; column Z Order
LV_ModifyCol(3, 0) ; hide column Window PID
LV_ModifyCol(5, 0) ; hide column Window Process Name
LV_ModifyCol(7, "150") ; column Text
GuiControl, +Redraw, LV1
return
GetAllWindowsInfo:
;get list of all visible windows in stack order
DetectHiddenWindows, Off
WinGet, WinIDs, List
loop, %WinIDs%
winListIDsVisible := winListIDsVisible WinIDs%A_Index% "`n"
;get list of all windows in stack order
DetectHiddenWindows, On
WinGet, WinIDs, List
;get all data for all windows
loop, %WinIDs% {
UniqueID := "ahk_id " WinIDs%A_Index%
WinGetPos, WindowX%A_Index%, WindowY%A_Index%, WindowWidth%A_Index%, WindowHeight%A_Index%, %UniqueID%
WinGet, winPID%A_Index%, PID, %UniqueID%
WinGet, ProcessName%A_Index%, ProcessName, % "ahk_pid " winPID%A_Index%
WinGetTitle, winTitle%A_Index%, %UniqueID%
WinGetClass, winClass%A_Index%, %UniqueID%
}
DetectHiddenWindows, off
;add all data to listview
GuiControl, -Redraw, LV1 ; speed up adding data
LV_Delete() ; remove old data
loop, %WinIDs% {
LV_Add(""
, A_Index ; Z or Stack Order
, WinIDs%A_Index% ; Unique ID
, winPID%A_Index% ; Window PID
, winClass%A_Index% ; Window Class
, processName%A_Index% ; Process Name
, iif(InStr(winListIDsVisible,WinIDs%A_Index%),"","Hidden") ; Visible or Hidden?
, winTitle%A_Index% ; Title or Text
, WindowX%A_Index% ; X
, WindowY%A_Index% ; Y
, WindowWidth%A_Index% ; Width
, WindowHeight%A_Index%) ; Height
}
LV_ModifyCol() ; Auto-size all columns
LV_ModifyCol(1, "Integer Left") ; column Stack Order
LV_ModifyCol(4, "100") ; column Class
LV_ModifyCol(7, "150") ; column Title
GuiControl, +Redraw, LV1
return
;draw frames around controls and/or windows
DrawFrameAroundControl(ControlID, WindowUniqueID, frame_t){
global h_brushC, h_brushW, ChkDrawRectCtrl, ChkDrawRectWin
;get coordinates of Window and control again
;(could have been past into the function but it seemed too much parameters)
WinGetPos, WindowX, WindowY, WindowWidth, WindowHeight, ahk_id %WindowUniqueID%
ControlGetPos, ControlX, ControlY, ControlWidth, ControlHeight, %ControlID%, ahk_id %WindowUniqueID%
;find upper left corner relative to screen
StartX := WindowX + ControlX
StartY := WindowY + ControlY
;show ID in upper left corner
CoordMode, ToolTip, Screen
;show frame gui above AOT apps
Gui, 2: +AlwaysOnTop
if ChkDrawRectWin {
;if windows upper left corner is outside the screen
; it is assumed that the window is maximized and the frame is made smaller
if ( WindowX < 0 AND WindowY < 0 ){
WindowX += 4
WindowY += 4
WindowWidth -= 8
WindowHeight -= 8
}
;remove old rectangle from screen and save/buffer screen below new rectangle
BufferAndRestoreRegion( WindowX, WindowY, WindowWidth, WindowHeight )
;draw rectangle frame around window
DrawFrame( WindowX, WindowY, WindowWidth, WindowHeight, frame_t, h_brushW )
;show tooltip above window frame when enough space
if ( WindowY > 22)
WindowY -= 22
;Show tooltip with windows unique ID
ToolTip, %WindowUniqueID%, WindowX, WindowY, 3
}
else
;remove old rectangle from screen and save/buffer screen below new rectangle
BufferAndRestoreRegion( StartX, StartY, ControlWidth, ControlHeight )
if ChkDrawRectCtrl {
;draw rectangle frame around control
DrawFrame( StartX, StartY, ControlWidth, ControlHeight, frame_t, h_brushC )
;show tooltip above control frame when enough space, or below
if ( StartY > 22)
StartY -= 22
else
StartY += ControlHeight
;show control tooltip left of window tooltip if position identical (e.g. Windows Start Button on Taskbar)
if (StartY = WindowY
AND StartX < WindowX + 50)
StartX += 50
;Show tooltip with controls unique ID
ToolTip, %ControlID%, StartX, StartY, 2
}
;set back ToolTip position to default
CoordMode, ToolTip, Relative
}
;###############################################################################
;### export the data ######################################################
;###############################################################################
BtnBrowseExportFile:
Gui, 1:Submit, NoHide
SelectFile("EdtExportFile", EdtExportFile, "email")
return
BtnSaveExport:
Gui, 1:Submit, NoHide
;return if no filename is given
if EdtExportFile is Space
{
ToolTip("No filename for export specified.", 3000)
MsgBox, 48, Problem , No export filename is given.
return
}
;return if no data is selected for export
NumberOfExports = 0
loop, Parse, ExportOptions, `,
NumberOfExports := NumberOfExports + %A_LoopField%
if (NumberOfExports = 0){
ToolTip("No data selected for export.", 3000)
return
}
;get filename
if (ChkExportAutoNumber){
FileNameForExport := GetAvailableFileName(EdtExportFile)
if not FileNameForExport {
ToolTip("Could get filename for export.`n" ErrorLevel, 3000)
return
}
}else
FileNameForExport = %EdtExportFile%
GuiControl, 1:Disable, BtnSaveExport
gosub, ExportDataToFile
GuiControl, 1:Enable, BtnSaveExport
if ChkShowInfoToolTip
ToolTip("Data exported to file: " FileNameForExport, 3000)
return
ExportDataToFile:
if ChkExportAppend
FileAppend, `n===========next snapshot===========`n, %FileNameForExport%
else
FileDelete, %FileNameForExport%
ExportString := "Data exported from " ScriptName " at " A_Now "`n`nMouse Data`n"
. iif(ChkExportMousePosScreen,"Mouse position Relative to Screen :`n" EdtMousePosScreen "`n`n")
. iif(ChkExportMousePosWin,"Mouse position Relative to window under Mouse pointer :`n" EdtMousePosWin "`n`n")
. iif(ChkExportMousePosAWin,"Mouse position Relative to active window :`n" EdtMousePosAWin "`n`n")
. iif(ChkExportMousePointer,"Mouse cursor style :`n" EdtMousepointer "`n`n")
. iif(ChkExportMouseColorRGB,"Pixel Color in RGB format under Mouse pointer :`n" EdtMouseColorRGB "`n`n")
. iif(ChkExportMouseColorHex,"Pixel Color in Hex format (RGB) Mouse pointer :`n" EdtMouseColorHex "`n`n")
. "`nControl data for "
. iif(RadControl = 1,"active Control of " iif(RadWindow = 1,"active window","window under Mouse pointer") ,"Control under Mouse pointer")
. "`n"
. iif(ChkExportCtrlText,"Control text :`n" EdtControlText "`n`n")
. iif(ChkExportCtrlClass,"Control classNN :`n" EdtControlClass "`n`n")
. iif(ChkExportCtrlPos,"Control position :`n" EdtControlPos "`n`n")
. iif(ChkExportCtrlSize,"Control size :`n" EdtControlSize "`n`n")
. iif(ChkExportCtrlListItems,"Control list items :`n" EdtListItems "`n`n")
. "`nWindow data for "
. iif(RadWindow = 1,"active window","window under Mouse pointer")
. "`n"
. iif(ChkExportWinTitle,"Window title :`n" EdtWindowTitle "`n`n")
. iif(ChkExportWinPos,"Window position :`n" EdtWindowPos "`n`n")
. iif(ChkExportWinSize,"Window size :`n" EdtWindowSize "`n`n")
. iif(ChkExportWinClass,"Window class :`n" EdtWindowClass "`n`n")
. iif(ChkExportWinProcess,"Window Process name:`n" EdtWindowProcess "`n`n")
. iif(ChkExportWinUID,"Window unique ID :`n" EdtWindowUID "`n`n")
. iif(ChkExportWinPID,"Window PID :`n" EdtWindowPID "`n`n")
FileAppend, %ExportString%, %FileNameForExport%
ExportString =
if ChkExportWinStatusText {
StringReplace, StatusbarText, ListOfStatusbarText, |, `n, All
ExportString := "`n######## Window Statusbar Text (Part# - Text) :`n" StatusbarText "`n`n"
}
if ChkExportWinText
ExportString := ExportString
. iif(EdtWindowTextFastVisible,"`n######## Fast Visible Window Text :`n" EdtWindowTextFastVisible "`n`n")
. iif(EdtWindowTextSlowVisible,"`n######## Slow Visible Window Text :`n" EdtWindowTextSlowVisible "`n`n")
. iif(EdtWindowTextFastHidden,"`n######## Fast Hidden Window Text :`n" EdtWindowTextFastHidden "`n`n")
. iif(EdtWindowTextSlowHidden,"`n######## Slow Hidden Window Text :`n" EdtWindowTextSlowHidden "`n`n")
FileAppend, %ExportString%, %FileNameForExport%
if ChkExportLargeList {
if LV_GetCount() {
ExportString := "`n########"
. iif(RadList3,"Data of all Controls of the " iif(RadWindow = 1,"active window","window under the Mousepointer") ,"Data of all windows")
ExportString = %ExportString% :`n
(LTrim Join`s
Process Name, Hidden, Title or Text, X, Y, Width, Height, Style,
ExStyle, Selected, CurrentCol, CurrentLine, LineCount, Choice,
Tab, Enabled, Checked
)
Columns := LV_GetCount("Col")
loop, % LV_GetCount() {
Row = %A_Index%
loop %Columns% {
LV_GetText(Text, Row , A_Index)
ExportString = %ExportString%%Text%,
}
StringTrimRight,ExportString,ExportString,1 ;remove last comma
ExportString = %ExportString%`n ;start new line
}
}
if ExportString
FileAppend, %ExportString%, %FileNameForExport%
}
return
;###############################################################################
;### small helper functions ################################################
;###############################################################################
iif(expr, a, b:=""){
if expr
return a
return b
}
ToggleOnTopGui1(wParam, lParam, msg, hwnd) {
Global Gui1UniqueID, Gui1AOTState
WinGetTitle, CurrentTitle , ahk_id %Gui1UniqueID%
if (Gui1AOTState){
Gui, 1: -AlwaysOnTop
StringTrimRight, CurrentTitle, CurrentTitle, 8
WinSetTitle, ahk_id %Gui1UniqueID%, , %CurrentTitle%
}else {
Gui, 1: +AlwaysOnTop
WinSetTitle, ahk_id %Gui1UniqueID%, , %CurrentTitle% - *AOT*
}
Gui1AOTState := not Gui1AOTState
}
ToolTip(Text, TimeOut:=1000){
ToolTip, %Text%
SetTimer, RemoveToolTip, %TimeOut%
return
}
RemoveToolTip:
ToolTip
return
HEXtoDEC(HEX){
StringUpper, HEX, HEX
loop, % StrLen(HEX) {
StringMid, Col, HEX, % (StrLen(HEX) + 1) - A_Index, 1
if Col is integer
DEC1 := Col * 16 ** (A_Index - 1)
else
DEC1 := (Asc(Col) - 55) * 16 ** (A_Index - 1)
DEC += %DEC1%
}
return DEC
}
SelectFile(Control, OldFile, Text){
Gui, 1:+OwnDialogs
StringReplace, OutputVar, OldFile, #, *, All
IfExist %A_ScriptDir%\%OutputVar%
StartFolder = %A_ScriptDir%
else ifExist %OldFile%
SplitPath, OldFile, , StartFolder
else
StartFolder =
FileSelectFile, SelectedFile, S18, %StartFolder%, Select file for %Text%, Text file (*.txt)
if SelectedFile {
StringReplace, SelectedFile, SelectedFile, %A_ScriptDir%\
GuiControl, 1: ,%Control%, %SelectedFile%
}
}
CheckAHKVersion(AHK_version){
StringSplit, A, A_AHKVERSION, .
StringSplit, B, AHK_version, .
Ax = 0
Bx = 0
loop, %A0%{ ; create unique number for both versions, max. verion 999.999.999.999 leads to 999999999999
Ax := Ax + A%A_Index% * 1000 ** ( A0 - A_Index )
Bx := Bx + B%A_Index% * 1000 ** ( A0 - A_Index )
}
if ( Bx > Ax ) {
MsgBox, 16, Old AHK version,
(LTrim
This script requires a newer version of AHK.
Installed version = %A_AHKVERSION%
Required version = %AHK_version%
Please download latest version and install it.
This Program will exit and open the webpage
where you can download the latest AHK version.
)
Run, http://www.autoHotkey.com/download
ExitApp
}
}
;############# Get next free/available File Name ##########################
GetAvailableFileName(ExportFileName){
;separate FileName and FileDir
SplitPath, ExportFileName, FileName, FileDir
;return ExportFileName if FileName doesn't contain "#"
if (InStr(FileName, "#") = 0)
return, ExportFileName
;add "\" to FileDir again
if FileDir
FileDir = %FileDir%\
;split FileName with #
StringSplit, NameArray, FileName, #
;Search from StartID = 1
StartID = 1
loop {
Number := A_Index + StartID - 1
;untill number is too large ...
if ( StrLen(Number) > NameArray0 - 1 ) {
ErrorLevel =
(LTrim
All files exist for >%ExportFileName%<
with all "#" between %StartID% and %Number%.
)
return 0
}
;otherwise fill number with leading zeros
loop, % NameArray0 - 1 - StrLen(Number)
Number = 0%Number%
;split number in an array
StringSplit, NumberArray, Number
;mix and concatenate the names array with the numbers array
FileName =
loop, %NameArray0%
FileName := FileName . NameArray%A_Index% . NumberArray%A_Index%
;check if GivenFileName doesn't exist
if not FileExist(FileDir . FileName)
return FileDir . FileName
}
}
;############# destroy draw objects #######################################
DeleteObject( p_object ) {
;deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources
DllCall( "gdi32.dll\DeleteObject", "uint", p_object )
}
DeleteDC( p_dc ) {
;deletes the specified device context (DC).
DllCall( "gdi32.dll\DeleteDC", "uint", p_dc )
}
;############# create draw objects ########################################
CreateDrawHandles(UniqueID, ScreenWidth, ScreenHeight, frame_cc, frame_cw){
global hdc_frame, hdc_buffer, h_region, h_brushC, h_brushW
;Get handle to display device context (DC) for the client area of a specified window
hdc_frame := DllCall( "GetDC"
, "uint", UniqueID )
;create buffer to store old color data to remove drawn rectangles
hdc_buffer := DllCall( "gdi32.dll\CreateCompatibleDC"
, "uint", hdc_frame )
;Create Bitmap buffer to remove drawn rectangles
hbm_buffer := DllCall( "gdi32.dll\CreateCompatibleBitmap"
, "uint", hdc_frame
, "int", ScreenWidth
, "int", ScreenHeight )
;Select Bitmap buffer in buffer to remove drawn rectangles
DllCall( "gdi32.dll\SelectObject"
, "uint", hdc_buffer
, "uint", hbm_buffer )
;create a dummy rectangular region.
h_region := DllCall( "gdi32.dll\CreateRectRgn"
, "int", 0
, "int", 0
, "int", 0
, "int", 0 )
;specify the color of the control frame.
h_brushC := DllCall( "gdi32.dll\CreateSolidBrush"
, "uint", frame_cc )
;specify the color of the window frame.
h_brushW := DllCall( "gdi32.dll\CreateSolidBrush"
, "uint", frame_cw )
}
;############# remove old rectangle and save screen below new rectangle ###
BufferAndRestoreRegion( p_x, p_y, p_w, p_h ) {
global hdc_frame, hdc_buffer
static buffer_state, old_x, old_y, old_w, old_h
;Copies the source rectangle directly to the destination rectangle.
SRCCOPY = 0x00CC0020
;remove previously drawn rectangle (restore previoulsy buffered color data)
if ( buffer_state = "full")
;perform transfer of color data of rectangle from source DC into destination DC
; from buffer to screen, erasing the previously darwn reactangle
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_frame
, "int", old_x
, "int", old_y
, "int", old_w
, "int", old_h
, "uint", hdc_buffer
, "int", 0
, "int", 0
, "uint", SRCCOPY )
else
buffer_state = full
;remember new rectangle for next loop (to be removed)
old_x := p_x
old_y := p_y
old_w := p_w
old_h := p_h
; Store current color data of new rectangle in buffer
DllCall( "gdi32.dll\BitBlt"
, "uint", hdc_buffer
, "int", 0
, "int", 0
, "int", p_w
, "int", p_h
, "uint", hdc_frame
, "int", p_x
, "int", p_y
, "uint", SRCCOPY )
}
;############# draw frame #################################################
DrawFrame( p_x, p_y, p_w, p_h, p_t, h_brush ) {
global hdc_frame, h_region
; modify dummy rectangular region to desired reactangle
DllCall( "gdi32.dll\SetRectRgn"
, "uint", h_region
, "int", p_x
, "int", p_y
, "int", p_x+p_w
, "int", p_y+p_h )
; draw region frame with thickness (width and hight are the same)
DllCall( "gdi32.dll\FrameRgn"
, "uint", hdc_frame
, "uint", h_region
, "uint", h_brush
, "int", p_t
, "int", p_t )
}