Что нового

Идентификация конрола на окне

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Сделал скиновый слайдер, всё вроде хорошо работает, но вот если создать в окне 2 слайдера то работать будет только 1, как сделать к каждому создаваемому слайдеру свой хандл?

Код:
#include <GDIPlus.au3>

Global Const $tPOSREGUL = DllStructCreate("int Left;int Top;int Pos")
Global $hFont, $hTrack, $hToolTip, $hDisplay, $hRegular

Func GUIControlSlider_Create($Left, $Top)
	DllStructSetData($tPOSREGUL, "Left", $Left)
	DllStructSetData($tPOSREGUL, "Top", $Top)
	
	Global $hFont = GUICtrlCreatePic("", $Left, $Top, 193, 14, 0x00000200)
	UsePNGImageDecoder($hFont, @ScriptDir & "\Font.png")
	GUICtrlSetState($hFont, 128)
	GUICtrlSetState($hFont, 2048) ; $GUI_ONTOP
	
	Global $hTrack = GUICtrlCreatePic("", $Left, $Top, 0, 0, 0x00000200)
	UsePNGImageDecoder($hTrack, @ScriptDir & "\Trek.png")
    GUICtrlSetState($hTrack, 32) ; $GUI_HIDE
    GUICtrlSetState($hTrack, 128) ; $GUI_DISABLE
    GUICtrlSetState($hTrack, 2048) ; $GUI_ONTOP
	
	Global $hToolTip = GUICtrlCreatePic("", $Left, $Top, 39, 39, 0x00000200)
	UsePNGImageDecoder($hToolTip, @ScriptDir & "\ToolTip.png")
	GUICtrlSetState($hToolTip, 128) ; $GUI_DISABLE
    GUICtrlSetState($hToolTip, 32) ; $GUI_HIDE
	GUICtrlSetState($hToolTip, 2048) ; $GUI_ONTOP
	
	Global $hDisplay = GUICtrlCreateLabel('', $Left, $Top, 39, 39, 0x01)
    GUICtrlSetBkColor($hDisplay, -2) ; $GUI_BKCOLOR_TRANSPARENT
    GUICtrlSetColor($hDisplay, 0xDD796C)
    GUICtrlSetState($hDisplay, 2048) ; $GUI_ONTOP
	
	Global $hRegular = GUICtrlCreatePic("", $Left - 5, $Top - 2, 18, 18, 0x00000200)
    UsePNGImageDecoder($hRegular, @ScriptDir & "\Regular.png")
    GUICtrlSetState($hRegular, 2048) ; $GUI_ONTOP
	
    GUIRegisterMsg(0x0200, "WM_MOUSEMOVE")

	Return $tPOSREGUL
EndFunc	

Func GUIControlSlider_GetRegular($iCtrl)
	Return DllStructGetData($iCtrl, "Pos")
EndFunc	 

Func GUIControlSlider_GetPos($iCtrl)
	Local $Ret[2]
	$Ret[0] = DllStructGetData($iCtrl, "Left")
	$Ret[1] = DllStructGetData($iCtrl, "Top")
	Return $Ret
EndFunc	

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
	Switch $iMsg
	    Case 0x0200
			If IsMouseOver(GUICtrlGetHandle($hFont)) Or IsMouseOver(GUICtrlGetHandle($hRegular)) Then
				Local $hCursor = DllCall("user32.dll", "short", "GetAsyncKeyState", "int", 01)
				If $hCursor[0] Then
					Local $aPos = MouseGetPos()
					Local $tPoint = DllStructCreate("int X;int Y")
	                DllStructSetData($tPoint, "X", $aPos[0])
	                DllStructSetData($tPoint, "Y", $aPos[1])
					Local $aMouse = DllStructGetData($tPoint, "X")
					Local $aWindow = WinGetPos($hWnd)
					Local $aX = ($aMouse - $aWindow[0]) - 10
                    Local $FontPos = ControlGetPos($hWnd, "", $hFont)
					If $aX < $FontPos[0] Then $aX = DllStructGetData($tPOSREGUL, "Left") - 6
					If $aX > ($FontPos[2] + $FontPos[0] - 15) Then $aX = ($FontPos[2] + DllStructGetData($tPOSREGUL, "Left")) - 13
					If $aX < ($FontPos[0] + 1) Then GUICtrlSetState($hTrack, 32) ; $GUI_HIDE
					If $aX > DllStructGetData($tPOSREGUL, "Left") Then GUICtrlSetState($hTrack, 16) ; $GUI_SHOW
					GUICtrlSetPos($hTrack, DllStructGetData($tPOSREGUL, "Left") + 2, DllStructGetData($tPOSREGUL, "Top"), ($aX - DllStructGetData($tPOSREGUL, "Left")) + 2, 14)	
					GUICtrlSetPos($hRegular, $aX, DllStructGetData($tPOSREGUL, "Top") - 2, 18, 18)
					GUICtrlSetState($hToolTip, 16) ; $GUI_SHOW
					GUICtrlSetState($hDisplay, 16) ; $GUI_SHOW
					GUICtrlSetPos($hToolTip, $aX - 10, DllStructGetData($tPOSREGUL, "Top") - 45, 39, 39)
					GUICtrlSetPos($hDisplay, $aX - 10, DllStructGetData($tPOSREGUL, "Top") - 35, 39, 20)
					GUICtrlSetData($hDisplay, DllStructGetData($tPOSREGUL, "Pos"))
	
					Local $iPosition = $aMouse - ($aWindow[0] + DllStructGetData($tPOSREGUL, "Left")) 
					Local $hStep = ($FontPos[2] / 100)
					Local $SetPos = (($iPosition - $hStep) / 2) + 1.5
					If Round($SetPos) >= 100 Then $SetPos = 100
					If Round($SetPos) <= 0 Then $SetPos = 0	
					DllStructSetData($tPOSREGUL, "Pos", Round($SetPos)) 
				EndIf
			Else
				GUICtrlSetState($hDisplay, 32) ; $GUI_HIDE
	            GUICtrlSetState($hToolTip, 32) ; $GUI_HIDE
			EndIf	
	EndSwitch
	Return 'GUI_RUNDEFMSG'	
EndFunc


Func IsMouseOver($hWnd)
	Local $tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
	Local $tPoint = DllStructCreate("long X;long Y")
    DllCall("user32.dll", "bool", "GetWindowRect", "hwnd", $hWnd, "ptr", DllStructGetPtr($tRect))
	DllCall("user32.dll", "bool", "GetCursorPos", "ptr", DllStructGetPtr($tPoint))
	Local $Ret = DllCall("user32.dll", "bool", "PtInRect", "ptr", DllStructGetPtr($tRect), "long", DllStructGetData($tPoint, "X"), "long", DllStructGetData($tPoint, "Y"))
    If @error Then Return SetError(@error, @extended, False)
	Return $Ret[0]
EndFunc

Func UsePNGImageDecoder($iPic, $sPNGFile)
    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPNGFile)
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, 0x172, 0, $hBitmap))
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc

Сделал инклудом, вот всё что требуется для него, дело в том что у меня вместо хэндела контрола выступает самописная структура в которой находятся данные, мне с ней легче работать, так как там можно как хранить всё так и вытащить данные которые требуются, можноли как то присваивать ID для переменной, чтоб на окне больше не создавался контрол с таким же ID?
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Опять наткнулся на эти ID контролов, сделал скиновую PNG кнопку с 3 состояниями (Normal, Hover, Click), и при создании больше чем одной такой кнопки, из них полноценно будет работать только одна (последняя созданая), то есть остальные будут работать но не будут менять картинки, подскажите, как сделать, уже голову поломал.....

Пример:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Button.au3>

$hForm = GUICreate("Skining Button", 400, 120)
GUISetBkColor(0xFF7F7F)
$Button = GUIControlButton_Create(40, 40)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
		Case $Button
            MsgBox(32, "Info", "Click Button")			
    EndSwitch
WEnd

Инклуда:
Код:
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
#include <Misc.au3>

Global $__skButton, $iClick = False, $iHover = False

Func GUIControlButton_Create($Left, $Top)
	$__skButton = GUICtrlCreatePic("", $Left, $Top, 94, 33)
	UsePNGImageDecoder($__skButton, @ScriptDir & "\1.png")
    GUIRegisterMsg(0x0111, "WM_COMMAND")
	GUIRegisterMsg(0x0200, "WM_MOUSEMOVE")
	Return $__skButton
EndFunc	

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
	If $lParam = GUICtrlGetHandle($__skButton) Then
		AdlibRegister("Click", 1)
	EndIf
	Return 'GUI_RUNDEFMSG'	
EndFunc

Func WM_MOUSEMOVE($hWnd, $iMsg, $wParam, $lParam)
	Switch $iMsg
	    Case 0x0200
			AdlibRegister("Hover", 1)
    EndSwitch			
	Return 'GUI_RUNDEFMSG'
EndFunc	

Func Click()
	If _IsPressed(01) = 1 Then
		If $iClick = False Then
			GUICtrlSendMsg($__skButton, 0x172, 0, "")
			UsePNGImageDecoder($__skButton, @ScriptDir & "\3.png")
			$iClick = True
		EndIf	
	ElseIf _IsPressed(01) = 0 Then
		If $iClick = True Then
			GUICtrlSendMsg($__skButton, 0x172, 0, "")
			UsePNGImageDecoder($__skButton, @ScriptDir & "\1.png")	
			$iClick = False
			AdlibUnRegister("Click")
		EndIf	
	EndIf	
EndFunc	

Func Hover()
	If IsMouseOver(GUICtrlGetHandle($__skButton)) Then
		If $iHover = False Then
			GUICtrlSendMsg($__skButton, 0x172, 0, "")
			UsePNGImageDecoder($__skButton, @ScriptDir & "\2.png")
			$iHover = True
		EndIf	
	Else
		If $iHover = True Then
			GUICtrlSendMsg($__skButton, 0x172, 0, "")
			UsePNGImageDecoder($__skButton, @ScriptDir & "\1.png")	
			$iHover = False
		    AdlibUnRegister("Hover")
		EndIf	
	EndIf	
EndFunc
	
Func IsMouseOver($hWnd)
	Local $tRect = DllStructCreate("int Left;int Top;int Right;int Bottom")
	Local $tPoint = DllStructCreate("long X;long Y")
    DllCall("user32.dll", "bool", "GetWindowRect", "hwnd", $hWnd, "ptr", DllStructGetPtr($tRect))
	DllCall("user32.dll", "bool", "GetCursorPos", "ptr", DllStructGetPtr($tPoint))
	Local $Ret = DllCall("user32.dll", "bool", "PtInRect", "ptr", DllStructGetPtr($tRect), "long", DllStructGetData($tPoint, "X"), "long", DllStructGetData($tPoint, "Y"))
    If @error Then Return SetError(@error, @extended, False)
	Return $Ret[0]
EndFunc

Func UsePNGImageDecoder($iPic, $sPNGFile)
    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPNGFile)
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, 0x172, 0, $hBitmap))
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc

И архив
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Я вам вроде давал Skin.au3, откуда вы могли бы взять идею...


Для разных кнопок нужны разные переменные или массив. Далее, при поступлении сообщений, ищите в массиве нужный Control.



Добавлено:
Сообщение автоматически объединено:

Если вы собираетесь писать UDF, то обильное использование GUIRegisterMsg() не есть хорошая идея, т.к. эта функция действует на весь скрипт.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Сделал, но если мышкой быстро водить по кнопкам то кнопки остаются в режиме HOVER, и так хотелось чтоб в скрипт можно было писать как можно меньше, и функцию пришлось в цикл ставить.

Пример:
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Button.au3>

$hForm = GUICreate("Skining Button", 400, 120)
GUISetBkColor(0xFF7F7F)
$Button1 = GUIControlButton_Create(40, 40)
$Button2 = GUIControlButton_Create(140, 40)
$Button3 = GUIControlButton_Create(240, 40)
GUISetState()

While 1
	GUIButtonEvent()
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
		Case $Button1
            MsgBox(32, "Info", "Button 1")		
		Case $Button2
			MsgBox(32, "Info", "Button 2")	
		Case $Button3
            MsgBox(32, "Info", "Button 3")			
    EndSwitch
WEnd

Инклуда:
Код:
#include <GDIPlus.au3>
#include <WinAPIEx.au3>
#include <Misc.au3>

Global $__ControlID[1] = [0], $aControlID, $iClick = False, $iHover = False

Func GUIControlButton_Create($Left, $Top)
	Local $__skButton = GUICtrlCreatePic("", $Left, $Top, 94, 33)
	
	$__ControlID[0] += 1
	ReDim $__ControlID[$__ControlID[0] + 1]
	$__ControlID[$__ControlID[0]] = $__skButton
	
	UsePNGImageDecoder($__skButton, @ScriptDir & "\1.png")

	Return $__skButton
EndFunc	

Func GUIButtonEvent()

	Local $aCursor = GUIGetCursorInfo()
	If Not @error Then
		
		For $i = 1 To $__ControlID[0]
		    If $aCursor[4] = $__ControlID[$i] Then $aControlID = $__ControlID[$i]
		Next

		If ($aCursor[4] = $aControlID) Then
			If $iHover = False Then
				$iHover = True
				GUICtrlSendMsg($aControlID, 0x172, 0, "")
				UsePNGImageDecoder($aControlID, @ScriptDir & "\2.png")
			EndIf	
        Else
			If $iHover = True Then
				$iHover = False
			    GUICtrlSendMsg($aControlID, 0x172, 0, "")
				UsePNGImageDecoder($aControlID, @ScriptDir & "\1.png")
            EndIf
		EndIf
		
		If ($aCursor[4] And $aCursor[2]) = $aControlID Then
			If $iClick = False Then
				$iClick = True
				GUICtrlSendMsg($aControlID, 0x172, 0, "")
				UsePNGImageDecoder($aControlID, @ScriptDir & "\3.png")
			EndIf	
		Else
			If $iClick = True Then
				$iClick = False
				GUICtrlSendMsg($aControlID, 0x172, 0, "")
				UsePNGImageDecoder($aControlID, @ScriptDir & "\1.png")
			EndIf
		EndIf
			
    EndIf		
EndFunc

Func UsePNGImageDecoder($iPic, $sPNGFile)
    _GDIPlus_Startup()
    Local $hImage = _GDIPlus_ImageLoadFromFile($sPNGFile)
    Local $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, 0x172, 0, $hBitmap))
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_ImageDispose($hImage)
    _GDIPlus_Shutdown()
EndFunc
 
Верх