Что нового

[Окна, Диалоги] Выделение GUI стороннего приложения как это делает AutoIt Window Info

zarius

Новичок
Сообщения
8
Репутация
0
Есть ли возможность выделять элементы диалога (цветом/окантовкой и т.д.) стороннего приложения? Так, как это делает AutoIt Window Info. Как это сделать собственными силами?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Код:
#include <GuiConstants.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>

Opt("GuiOnEventMode", 1)

HotKeySet("{ESC}", "_QuitApp")

Global $hSquare_GUI = -1
Global $hCtrl = -1
Global $Last_hControl = -1

Global $Frame_Color = 0xFF0000
Global $Frame_Width = 3

$Main_GUI = GUICreate("Highlight Controls Demo")
WinSetOnTop($Main_GUI, "", 1)

GUISetOnEvent($GUI_EVENT_CLOSE, "_QuitApp")
GUIRegisterMsg($WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED")

GUICtrlCreateButton("Button", 20, 20)
GUICtrlCreateCheckbox("CheckBox", 20, 60)

GUICtrlCreateLabel("Info: ", 20, 150)
GUICtrlSetFont(-1, 9, 800)

$Info_Edit = GUICtrlCreateEdit("", 80, 150, 300, 220, $GUI_SS_DEFAULT_EDIT + $ES_READONLY)

GUISetState()

While 1
	Sleep(10) ;So the CPU will not increes "badly" while we play with the mouse cursor :)
	_IdleWait()
	
	If _IsPressed(1) Then
		_GUIDeleteSquare($hSquare_GUI)
		
		While _IsPressed(1)
			Sleep(10)
			_Check_Highlight_Controls_Proc()
		WEnd
		
		$Last_hControl = -1
	EndIf
	
	_Check_Highlight_Controls_Proc()
WEnd

Func _Check_Highlight_Controls_Proc()
	Local $hCtrl = _ControlGetHovered()

	If $hCtrl <> 0 And $Last_hControl <> $hCtrl And $hSquare_GUI <> $hCtrl Then
		$Last_hControl = $hCtrl
		Local $aCtrlPos = WinGetPos($hCtrl)

		GUICtrlSetData($Info_Edit, _
				"X = " & $aCtrlPos[0] & @CRLF & _
				"Y = " & $aCtrlPos[1] & @CRLF & _
				"W = " & $aCtrlPos[2] & @CRLF & _
				"H = " & $aCtrlPos[3] & @CRLF & @CRLF & _
				"Control/Win Class Name: " & _WinGetClassNameNN($hCtrl) & @CRLF & _
				"Control/Win Handle: " & $hCtrl & @CRLF & _
				"Control ID: " & _HwndToID($hCtrl) & @CRLF & @CRLF & _
				"Control Data:" & @CRLF & ControlGetText($hCtrl, "", ""))

		_GUIDeleteSquare($hSquare_GUI)
		$hSquare_GUI = _GUICreateSquare($aCtrlPos[0], $aCtrlPos[1], $aCtrlPos[2], $aCtrlPos[3])
	EndIf
EndFunc

Func _GUICreateSquare($i_X = -1, $i_Y = -1, $i_W = -1, $i_H = -1)
	Local $hSquare_GUI = GUICreate("", $i_W, $i_H, $i_X, $i_Y, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
	GUISetBkColor($Frame_Color)
	
	_GUISetHole($hSquare_GUI, $Frame_Width, $Frame_Width, $i_W - ($Frame_Width * 2), $i_H - ($Frame_Width * 2))
	
	GUISetState(@SW_SHOWNOACTIVATE, $hSquare_GUI)
	
	Return $hSquare_GUI
EndFunc

Func _GUIDeleteSquare($hSquare_GUI)
	If IsHWnd($hSquare_GUI) And $hSquare_GUI <> $Main_GUI Then GUIDelete($hSquare_GUI)
EndFunc

Func _ControlGetHovered()
	Local $tPoint = DllStructCreate($tagPOINT)
	
	DllStructSetData($tPoint, "x", MouseGetPos(0))
    DllStructSetData($tPoint, "y", MouseGetPos(1))

	Local $aRet = _WinAPI_WindowFromPoint($tPoint)
	
	If @error Or Not $aRet Then Return SetError(1, 0, 0)
	Return HWnd($aRet)
EndFunc

Func _HwndToID($hWnd)
	If Not IsHWnd($hWnd) Then Return SetError(1, 0, "")
	
	Local $aRet = DllCall("user32.dll", "int", "GetDlgCtrlID", "hwnd", $hWnd)
	If Not IsArray($aRet) Then Return SetError(2, 0, "")
	
	Return $aRet[0]
EndFunc

Func _WinGetClassName($hWnd)
	$aClassName = DllCall("user32.dll", "int", "GetClassName", "hWnd", $hWnd, "str", "", "int", 64)
	If Not @error And $aClassName[0] <> 0 Then Return $aClassName[2]
	Return ""
EndFunc

Func _WinGetClassNameNN($hCtrlWnd)
	$hParent = _WinAPI_GetAncestor($hCtrlWnd, $GA_ROOTOWNER)
	$hCtrlWnd = ControlGetHandle($hParent, "", $hCtrlWnd)
	$sClassList = StringSplit(StringStripCR(_WinGetNumeratedClassList($hParent)), @LF)
	
	For $i = $sClassList[0] To 1 Step -1
		If $sClassList[$i] = "" Then ContinueLoop
		
		If ControlGetHandle($hParent, "", $sClassList[$i]) = $hCtrlWnd Then Return $sClassList[$i]
	Next
	
	Return _WinGetClassName($hCtrlWnd)
EndFunc

Func _WinGetNumeratedClassList($sTitle, $sText = "")
	Local $sClassList = WinGetClassList($sTitle, $sText)
	Local $aClassList = StringSplit($sClassList, @CRLF)
	Local $sRetClassList = "", $sHold_List = "|"
	Local $aiInHold, $iInHold
	
	For $i = 1 To UBound($aClassList) - 1
		If $aClassList[$i] = "" Then ContinueLoop
		
		If StringRegExp($sHold_List, "\|" & $aClassList[$i] & "~(\d+)\|") Then
			$aiInHold = StringRegExp($sHold_List, ".*\|" & $aClassList[$i] & "~(\d+)\|.*", 1)
			$iInHold = Number($aiInHold[UBound($aiInHold) - 1])
			
			If $iInHold = 0 Then $iInHold += 1
			
			$aClassList[$i] &= "~" & $iInHold + 1
			$sHold_List &= $aClassList[$i] & "|"
			
			$sRetClassList &= $aClassList[$i] & @CRLF
		Else
			$aClassList[$i] &= "~1"
			$sHold_List &= $aClassList[$i] & "|"
			$sRetClassList &= $aClassList[$i] & @CRLF
		EndIf
	Next
	
	Return StringReplace(StringStripWS($sRetClassList, 3), "~", "")
EndFunc

Func _GUISetHole($hWin, $i_X, $i_Y, $i_SizeW, $i_SizeH)
	Local $aWinPos, $Outer_Rgn, $Inner_Rgn, $Wh, $Combined_Rgn
	Local Const $RGN_DIFF = 4
	$aWinPos = WinGetPos($hWin)

	$Outer_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", $aWinPos[2], "long", $aWinPos[3])
	$Inner_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", $i_Y, "long", $i_Y, "long", $i_Y + $i_SizeW, _
			"long", $i_Y + $i_SizeH)
	$Combined_Rgn = DllCall("gdi32.dll", "long", "CreateRectRgn", "long", 0, "long", 0, "long", 0, "long", 0)
	DllCall("gdi32.dll", "long", "CombineRgn", "long", $Combined_Rgn[0], "long", $Outer_Rgn[0], "long", $Inner_Rgn[0], _
			"int", $RGN_DIFF)
	DllCall("user32.dll", "long", "SetWindowRgn", "hwnd", $hWin, "long", $Combined_Rgn[0], "int", 1)
EndFunc

Func _IdleWait($IdleSec = 0)
	Local $iSave, $stLastInput = DllStructCreate("uint;dword")
	DllStructSetData($stLastInput, 1, DllStructGetSize($stLastInput))
	DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($stLastInput))
	
	Do
		$iSave = DllStructGetData($stLastInput, 2)
		Sleep(20)
		DllCall("user32.dll", "int", "GetLastInputInfo", "ptr", DllStructGetPtr($stLastInput))
	Until (DllStructGetData($stLastInput, 2) - $iSave) > $IdleSec
	
	Return DllStructGetData($stLastInput, 2) - $iSave
EndFunc

Func WM_WINDOWPOSCHANGED($hWndGUI, $MsgID, $WParam, $LParam)
	If $hWndGUI <> $Main_GUI Then Return $GUI_RUNDEFMSG
	_GUIDeleteSquare($hSquare_GUI)
	_Check_Highlight_Controls_Proc()
	$Last_hControl = -1
EndFunc

Func _QuitApp()
	Exit
EndFunc
 
Автор
Z

zarius

Новичок
Сообщения
8
Репутация
0
Спасибо! Это то что нужно! :IL_AutoIt_1:
 
Верх