Search the Community
Showing results for tags 'Z-order ClassnameNN controls'.
-
Hover Window info utility & _WinGetClassnameNNList()
Malkey posted a topic in AutoIt Example Scripts
This hover Window info utility highlights in red the control window or GUI window the mouse is hovering over. The window, mouse and control information is displayed in a tooltip. To work, the windows the mouse is over does not have to be active nor the top most window. The tooltip Displays Window info:- Title: Class: Handle: Mouse info:- Absolute position: Control info:- ClassnameNN: ID: Handle: Position: - Relative to the underlying GUI or control window; and, The absolute position which is relative to the desktop. Size: - Width, length - size in pixels of red highlighted control. ControlClickCoords: - Position relative to the top, left corner of the red highlighted control. No. of Ctrl Layers under Mouse: - The number of controls at the mouse position. Ctrl Layers ClassNN/Hndl: - List of all controls under mouse. Appears when more than one Ctrl layer. Things to know. Pressing Alt + s keys toggles reversing the detection order of the layered controls. (If a control that the mouse is hovering is not being selected but the control at the bottom of the layers is selected, then pressing the Alt+s keys may enable that topmost control to be selected.) Press Alt + UP keys when the Alt + s keys are in the "have not been pressed state". Each Alt+UP keys press selects in green the next control below the previous control for 2 secs. At the bottom of the tooltip each "Ctrl Layer" progressively climbs up from the bottom of the red highlighted control in the list. Press Alt + DOWN keys when the Alt + s keys are in the "have been pressed state". Each Alt+Down keys press selects in green, for 2 secs, the next below layered control. At the bottom of the tooltip each "Ctrl Layer" progressively decended away from the top red highlighted control in the list. Note: While scrolling up or down through the layers once if they exist, the mouse must not move. However, slightly move the mouse to scroll up or down once again. Press Alt + q keys to quit Press Alt + h keys for this help window. #include <WinApi.au3> #include <Misc.au3> #include <Array.au3> #include <WindowsConstants.au3> #include <GuiConstantsEx.au3> _Singleton(@ScriptFullPath) Global $iCtrlOrder = 1, $iLayers, $sLayersNN, $hTopControl, $iUpVal = 0, $iTTx, $iTTy Local $aMouse, $tPoint, $hWnd, $hNextWin, $windowList, $hControl, $iPosX, $iPosY, $hOldTopControl = 0, $x, $y Local $aPos, $sClassNN, $sClass, $iCount, $iId, $sCtrl, $aPos, $aWinList, $aUniqList, $iInstances, $iStart Local $aClassNNList, $tRect, $sWin, $ExitBut, $WinClass, $WinAtPtFlag HotKeySet("!h", "_Help") HotKeySet("!s", "_CtrlOrder") HotKeySet("!q", "_Exit") HotKeySet("!{UP}", "_UpLayers") HotKeySet("!{DOWN}", "_UpLayers") While 1 $tPoint = _WinAPI_GetMousePos() $x = DllStructGetData($tPoint, "x") $y = DllStructGetData($tPoint, "y") If ($x <> $iTTx Or $y <> $iTTy) Then $WinAtPtFlag = 0 $iUpVal = 0 $hWnd = _WinAPI_GetAncestor(_WinAPI_WindowFromPoint($tPoint), 2); 2 = $GA_ROOT $WinClass = _WinAPI_GetClassName($hWnd) $hNextWin = "" $hTopControl = "" ; -------- ClassNN List ------------------------------ $windowList = WinGetClassList($hWnd) ;ConsoleWrite($windowList & @LF) $aWinList = StringRegExp($windowList, "[^\v]+", 3) $aUniqList = _ArrayUnique($aWinList) ;_ArrayDisplay($aUniqList) If IsArray($aUniqList) Then For $j = 1 To $aUniqList[0] StringRegExpReplace($windowList, "(?sm)^(" & $aUniqList[$j] & ")$", "") ; The number of replacements performed is stored in @extended. $iInstances = @extended ;ConsoleWrite($aUniqList[$j] & " " & $iInstances & @LF) For $k = $iInstances To 1 Step -1 $iStart = StringInStr($windowList, $aUniqList[$j] & @LF, 2, $k) $windowList = StringRegExpReplace($windowList, "(?sm)^(.{" & $iStart - 1 & "}^" & $aUniqList[$j] & ")$", "${1}" & $k) Next Next ;ConsoleWrite($windowList & @LF & "-----------" & @LF) $aClassNNList = StringRegExp($windowList, "[^\v]+", 3) ; --------> End of ClassNN List ------------------------------ ; --------- Get all layers under Mouse ---------------- $iLayers = 0 $sLayersNN = "" For $j = 0 To UBound($aClassNNList) - 1 $hControl = ControlGetHandle($hWnd, "", $aClassNNList[$j]) ;ConsoleWrite($aClassNNList[$j] & " " & $hControl & @LF) $tRect = _WinAPI_GetWindowRect($hControl) If ControlCommand($hWnd, "", $aClassNNList[$j], "IsVisible") And _ ; Check if control is visible under mouse DllStructGetData($tRect, "Left") <= $x And DllStructGetData($tRect, "Right") >= $x And _ ; Check if control is under mouse DllStructGetData($tRect, "Top") <= $y And DllStructGetData($tRect, "Bottom") >= $y Then $sLayersNN &= @TAB & @TAB & @TAB & $aClassNNList[$j] & @TAB & $hControl & @TAB & @LF ; Add ClassnameNN & Ctrl handle to string. $iLayers += 1 ; Number of controls (layers) If $iCtrlOrder = 0 And $iLayers = 1 Then ; After Alt+s keys has been pressed, the top most control is the first control encountered. $hTopControl = $hControl $sClassNN = $aClassNNList[$j] ElseIf $iCtrlOrder <> 0 Then ; Before Alt+s keys is pressed, the top most control is the last control encountered in the For-Next loop. $hTopControl = $hControl $sClassNN = $aClassNNList[$j] EndIf #cs ; _WinAPI_GetWindow() was found not to be useful in this application. ConsoleWrite($aClassNNList[$j] & " HWNDFIRST: " & _WinAPI_GetWindow($hControl & $iCount, 0) & _ " HWNDLAST: " & _WinAPI_GetWindow($hControl & $iCount, 1) & _ " HWNDNEXT: " & _WinAPI_GetWindow($hControl & $iCount, 2) & _ " HWNDPREV: " & _WinAPI_GetWindow($hControl & $iCount, 3) & _ " OWNER: " & _WinAPI_GetWindow($hControl & $iCount, 4) & _ " CHILD: " & _WinAPI_GetWindow($hControl & $iCount, 5) & @LF) #ce ;ConsoleWrite("From Pt " & _WinAPI_WindowFromPoint($tPoint)& @LF) EndIf Next ;ConsoleWrite("-------------------" & @LF) ; -----> End of "Get all layers under Mouse" ---------------- EndIf ; ------------- Gather all info for Tooltip -------------- $sWin = ">>>>Window<<<< Press Alt+h for Help" & @LF & _ "Title:" & @TAB & WinGetTitle("[Handle:" & $hWnd & "]", "") & @LF & _ "Class:" & @TAB & $WinClass & @LF & _ "Handle:" & @TAB & $hWnd & @LF & @LF & _ ">>>>Mouse<<<< " & @LF & _ "Absolute Position: " & DllStructGetData($tPoint, "x") & ", " & DllStructGetData($tPoint, "y") & @LF _WinAPI_ScreenToClient($hTopControl, $tPoint) If $hTopControl = "" Then ; Window only - no controls under mouse. $sCtrl = "" $tRect = _WinAPI_GetWindowRect($hWnd) Else $tRect = _WinAPI_GetWindowRect($hTopControl) $iId = _WinAPI_GetDlgCtrlID($hTopControl) If $iId = 0 Then $iId = "" $aPos = ControlGetPos($hWnd, "", $sClassNN) $sCtrl = @LF & _ ">>>>Control<<<< " & @LF & _ "ClassNameNN:" & @TAB & $sClassNN & @LF & _ "ID:" & @TAB & @TAB & $iId & @LF & _ "Handle:" & @TAB & @TAB & $hTopControl & @LF & _ "Position:" & @TAB & @TAB & $aPos[0] & ", " & $aPos[1] & "; Abs:" & DllStructGetData($tRect, "Left") & ", " & DllStructGetData($tRect, "Top") & @LF & _ "Size:" & @TAB & @TAB & $aPos[2] & ", " & $aPos[3] & @LF & _ "ControlClick Coords: " & DllStructGetData($tPoint, "x") & ", " & DllStructGetData($tPoint, "y") & @LF & _ "No. of Ctrl Layers under Mouse: " & @TAB & $iLayers & @LF If $iLayers > 1 Then $sCtrl &= "Ctrl Layers ClassNN/Hnd:- " & @LF & $sLayersNN EndIf ; ----- Tooltip ---- $aPos = MouseGetPos() $iPosX = ($aPos[0] - 400) * ($aPos[0] > @DesktopWidth - 400) + ($aPos[0] <= @DesktopWidth - 400) * ($aPos[0] + 20) $iPosY = ($aPos[1] - 400) * ($aPos[1] > @DesktopHeight - 400) + ($aPos[1] <= @DesktopHeight - 400) * ($aPos[1] + 20) ToolTip($sWin & $sCtrl, $iPosX, $iPosY) ; ---> Eng of Tooltip ---- $iTTx = $x ; For "If ($x <> $iTTx Or $y <> $iTTy) Then" line @ top of While loop - Steadies tooltip display. $iTTy = $y If $hOldTopControl <> $hTopControl Then ; - Steadies red outline display. _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN) ; Clears Red outline graphics. $hOldTopControl = $hTopControl EndIf _DrawtRect($tRect) EndIf Sleep(30) WEnd Func _Help() Local $myedit, $msg, $Text ToolTip("") $Text = @LF & @TAB & @TAB & @TAB & _ " Hot Keys" & @LF & @LF & _ " Press Alt + s keys toggles reversing the detection order of the" & @LF & _ " layered controls. (If a control that the mouse" & @LF & _ " is hovering is not being selected but the control " & @LF & _ " at the bottom of the layers is selected, pressing the" & @LF & _ " Alt+s keys may enable that top control to be selected.);" & @LF & @LF & _ ' Press Alt + UP keys when the Alt + s keys are in the "have not been pressed' & @LF & _ ' state". Each Alt+UP keys press selects in green the' & @LF & _ " next below layered control. At the bottom of the" & @LF & _ ' tooltip each "Ctrl Layer" progressively climbs up' & @LF & _ " from the bottom of the red highlited control in the list." & @LF & @LF & _ ' Press Alt + DOWN keys when the Alt + s keys are in the "have been pressed' & @LF & _ ' state". Each Alt+Down keys press selects in green, for' & @LF & _ " 2 secs, the next below layered control. At the bottom of" & @LF & _ ' the tooltip each "Ctrl Layer" progressively decended away' & @LF & _ " from the top red highlited control in the list." & @LF & @LF & _ " Note: While scrolling up and down through the layers, the mouse must not move." & @LF & @LF & _ " Press Alt + q keys to quit;" & @LF & @LF & _ " Press Alt + h keys for this help window." GUICreate("Help Window", 450, 450) ; will create a dialog box that when displayed is centered GUISetFont(9) $myedit = GUICtrlCreateLabel($Text, 2, 0) $ExitBut = GUICtrlCreateButton('Continue', 190, 410, 70, 20) GUISetState() While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Or $msg = $ExitBut Then ExitLoop WEnd GUIDelete() EndFunc ;==>_Help Func _UpLayers() Local $aLay, $iIndex, $tRect, $tRectGrn, $iUbIndx ;ConsoleWrite(@HotKeyPressed & @LF) $iUpVal += 1 $aLay = StringRegExp($sLayersNN, "\h(0x[^\s]+)", 3) If IsArray($aLay) Then $iUbIndx = UBound($aLay) - 1 $iIndex = _ArraySearch($aLay, $hTopControl) ;if $iIndex < $iUbIndx then $iIndex += $iUpVal Switch @HotKeyPressed Case "!{UP}" If $iIndex - $iUpVal >= 0 Then $iIndex -= $iUpVal Else $iIndex = 0 EndIf Case "!{DOWN}" If $iIndex + $iUpVal <= $iUbIndx Then $iIndex += $iUpVal Else $iIndex = $iUbIndx EndIf EndSwitch $tRect = _WinAPI_GetWindowRect($hTopControl) $tRectGrn = _WinAPI_GetWindowRect($aLay[$iIndex]) ;ConsoleWrite($iUpVal & " " & $aLay[$iIndex] & @LF) _DrawtRect($tRect) _DrawtRect($tRectGrn, 0x00ff00) While Sleep(2000) = 0 WEnd _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN) EndIf EndFunc ;==>_UpLayers Func _CtrlOrder() If $iCtrlOrder = 1 Then ; Alt+S has not been pressed. $iCtrlOrder = 0 ; Means Alt+S has been pressed. Else $iCtrlOrder = 1 ; Alt+S is in not been pressed state. EndIf EndFunc ;==>_CtrlOrder ; Draws coloured rectangle on screen. Func _DrawtRect($tRect, $color = 0xFF, $PenWidth = 2) Local $hDC, $hPen, $obj_orig, $x1, $x2, $y1, $y2 $x1 = DllStructGetData($tRect, "Left") $x2 = DllStructGetData($tRect, "Right") $y1 = DllStructGetData($tRect, "Top") $y2 = DllStructGetData($tRect, "Bottom") $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop) $hPen = _WinAPI_CreatePen($PS_SOLID, $PenWidth, $color) $obj_orig = _WinAPI_SelectObject($hDC, $hPen) _WinAPI_DrawLine($hDC, $x1, $y1, $x2, $y1) ; horizontal to right _WinAPI_DrawLine($hDC, $x2, $y1, $x2, $y2) ; vertical down on right _WinAPI_DrawLine($hDC, $x2, $y2, $x1, $y2) ; horizontal to left right _WinAPI_DrawLine($hDC, $x1, $y2, $x1, $y1) ; vertical up on left ; clear resources _WinAPI_SelectObject($hDC, $obj_orig) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) EndFunc ;==>_DrawtRect Func _Exit() _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_ALLCHILDREN) Exit EndFunc ;==>_Exit Comments One thing I have discovered using this tool was in Internet Explorer. The "AutoIt v3 Window Info" tool shows the IE address bar as ClassnameNN: ToolbarWindow322. This Hover Window Info tool also shows the IE address bar as ClassnameNN:ToolbarWindow322 with six layers of controls. Pressing Alt+Up Arrow keys the next control above the ToolbarWindow322 control in the tooltip list, "Edit1", was highlighted in green and appeared inside the ToolbarWindow322 control. So, ControlGetText("[Class:IEFrame]","","Edit1") returned the address from Internet Explorer's address bar. This tool is of no use in Firefox. I could not find any window controls in the Mozilla Firefox window. The AutoIt Help file made a good test window. ZOrder.au3 This test GUI, "ZOrder.au3", was used to scroll up or down the layered control. I came across some layered controls which would only highlight the bottom most layer on the screen which was the top most control in the list on the tooltip. I found by reversing the layer selection in the list from top to bottom (by pressing Alt+s keys) this info tool worked correctly on the layered controls. And Alt+Down also worked to scroll down through the layered controls. The top control of the tooltip list being the red highlighted control. In the test "ZOrder" window this is how the left side works - Alt+s needs to be pressed. For normal selection of the screen's top most control which appears at the bottom of the tooltip list, Alt+s need not be press. If Alt+s is press, Alt+s needs to be pressed again to return to normal mode which is as though Alt+s had never been pressed. The right side of the test "ZOrder" window does not need Alt+s pressed. Alt+Up is used to scroll up through the list of layered controls on the tooltip. The bottom control of the tooltip list being the red highlighted control. #include <WindowsConstants.au3> #include <EditConstants.au3> Local $Button_1, $myedit1, $myedit2, $myedit3, $myedit4, $myedit5, $myedit6, $myedit7, $myedit8, $Button_2, $label GUICreate("ZOrder Test GUI ", 650, 650, -1, -1) ;GUISetBkColor(0xE0FFFF) $Button_1 = GUICtrlCreateButton("First Control declared - $WS_EX_TOPMOST", 45, 250, 220, -1, -1, $WS_EX_TOPMOST) $myedit1 = GUICtrlCreateEdit("First Edit declared - $WS_EX_TOPMOST" & @CRLF, 120, 120, 180, 300, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), BitOR($WS_EX_TOPMOST, $WS_EX_STATICEDGE)) $myedit2 = GUICtrlCreateEdit("Second Edit declared - $WS_EX_TOPMOST" & @CRLF, 80, 80, 220, 400, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), BitOR($WS_EX_TOPMOST, $WS_EX_STATICEDGE)) $myedit3 = GUICtrlCreateEdit("Third Edit declared - $WS_EX_TOPMOST" & @CRLF, 40, 40, 260, 500, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), BitOR($WS_EX_TOPMOST, $WS_EX_STATICEDGE)) $myedit4 = GUICtrlCreateEdit("Forth Edit declared - $WS_EX_TOPMOST" & @CRLF, 2, 2, 298, 600, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), BitOR($WS_EX_TOPMOST, $WS_EX_STATICEDGE)) $myedit5 = GUICtrlCreateEdit("Fifth Edit declared" & @CRLF, 327, 2, 298, 600, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), $WS_EX_STATICEDGE) $myedit6 = GUICtrlCreateEdit("Sixth Edit declared" & @CRLF, 365, 40, 260, 500, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), $WS_EX_STATICEDGE) $myedit7 = GUICtrlCreateEdit("Seventh Edit declared" & @CRLF, 405, 80, 220, 400, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), $WS_EX_STATICEDGE) $myedit8 = GUICtrlCreateEdit("Eighth Edit declared" & @CRLF, 445, 120, 203, 300, BitOR($ES_AUTOVSCROLL, $WS_VSCROLL), $WS_EX_STATICEDGE) $Button_2 = GUICtrlCreateButton("Last Control declared", 370, 250, 180, -1, -1) $label = GUICtrlCreateLabel('The LHS (Left Hand Side) controls of this window are not detected by the "Hover for Info" script nor the "Au3Info" utility.' & _ ' By pressing the Alt+S keys while the "Hover for Info" script is running enables detection of the LHS controls and not the RHS controls. ' & _ ' Press the Alt+S keys again to detect the RHS controls again.', 50, 606, 550, 44) GUISetState() While GUIGetMsg() <> -3 WEnd _WinGetClassnameNNList function This _WinGetClassnameNNList function I thought would compliment the _WinGetClassList. The array of all the ClassnameNNs from a window using _WinGetClassnameNNList() are in the same order as the list of Classes from the same window using _WinGetClassList(). #include <Array.au3> Opt("WinTitleMatchMode", -2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase ;Local $Process = "C:\Program Files (x86)\Mozilla Firefox\firefox.exe" ;Local $Process = "ZOrder.exe" Local $Process = "Calc.exe" Local $sTitle = StringRegExpReplace($Process, "(^.*\\)|(\..*$)", "") ;ConsoleWrite($sTitle & @LF) Local $PID = Run($Process) WinActivate($sTitle) Local $hWnd = WinWaitActive($sTitle, "", 3) Local $sWindowList = WinGetClassList($hWnd) ConsoleWrite($sWindowList & @LF) Local $aCNN = _WinGetClassnameNNList($hWnd) _ArrayDisplay($aCNN, "ClassnameNN List") If $PID Then ProcessClose($PID) ; Returns an array of all ClassnameNNs of a window in the same order as the classes are returned using WinGetClassList(). Func _WinGetClassnameNNList($hWnd) Local $aWinList, $aUniqList, $iInstances, $k, $i, $iStart, $sUniqTestStr Local $sWindowList = WinGetClassList($hWnd) ; Window's string of classes list. ;ConsoleWrite("---- Class ----" & @lf & $sWindowList & @LF) $aWinList = StringRegExp($sWindowList, "[^\v]+", 3) If @error = 1 Then MsgBox(1, "Error", "Window has no controls", 2) Return EndIf ; ---- Routine instead of _ArrayUnique() ----- $sUniqTestStr = @LF & $aWinList[0] & @LF For $i = 1 To UBound($aWinList) - 1 If StringInStr($sUniqTestStr, @LF & $aWinList[$i] & @LF, 2) = 0 Then $sUniqTestStr &= $aWinList[$i] & @LF ; A string of unique classes EndIf Next ;ConsoleWrite($sUniqTestStr & @LF) $aUniqList = StringRegExp($sUniqTestStr, "([^\v]+)", 3) ; An array of unique classes ; ----> End of Routine instead of _ArrayUnique() ----- For $j = 0 To UBound($aUniqList) - 1 StringRegExpReplace($sWindowList, "(?sm)^(" & $aUniqList[$j] & ")$", "") ; The number of replacements performed is stored in @extended. $iInstances = @extended ;ConsoleWrite( $aUniqList[$j] & " " & $iInstances & @LF) For $k = $iInstances To 1 Step -1 $iStart = StringInStr($sWindowList, $aUniqList[$j] & @LF, 2, $k) $sWindowList = StringRegExpReplace($sWindowList, "(?sm)^(.{" & $iStart - 1 & "}^" & $aUniqList[$j] & ")$", "${1}" & $k); Append instance to class in Window's string of classes list. ;ConsoleWrite("(?s)^(.{" & $iStart - 1 & "}" & $aUniqList[$j] & ")" & @lf & $sWindowList & @LF) Next Next ;ConsoleWrite("-- ClassnameNN --" & @lf & $sWindowList & @LF) Return StringRegExp($sWindowList, "[^\v]+", 3) ; Return an array of ClassnameNNs. EndFunc ;==>_WinGetClassnameNNList