autohotkey 辅助工具

autohotkey 辅助工具

AHKV1的

1
;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
	}
}

2

;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 )
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值