Registriert eine benutzerdefinierte Funktion für eine Windows-Message-ID (WM_MSG).
GUIRegisterMsg ( msgID, "function" )
msgID | Eine Windows-Message-ID (siehe Anhang: Windows-Nachrichtencodes). |
function | Der Name der aufzurufenden Benutzerfunktion, wenn die Nachricht erscheint oder ein leerer String "", um eine Nachricht zu deregistrieren. |
Erfolg: | 1. |
Fehler: | 0. |
!!! Um die Benutzerfunktion ausführbar zu machen, darf sie mit maximal 4 Funktionsparametern definiert werden, andernfalls wird die Funktion nicht aufgerufen !!!
z.B.:
Func MyUserFunction($hWndGUI, $MsgID, $WParam, $LParam)
...
EndFunc
Oder
Func MyUserFunction($hWndGUI, $MsgID)
...
EndFunc
Wenn die Benutzerfunktion aufgerufen wird, haben diese 4 Parameter die folgenden Werte:
Position
Parameter
Bedeutung
1
hWnd
Das Fensterhandle der GUI, in der die Nachricht erscheint.
2
Msg
Die Windows-Message-ID.
3
wParam
Der erste Nachrichtenparameter als Hexadezimalwert.
4
lParam
Der zweite Nachrichtenparameter als Hexadezimalwert.
Bis zu 256 Benutzerfunktionen können für Message-ID's registriert werden.
Standardmäßig wird der interne Message-Handler von AutoIt (falls es einen für diese Nachricht gibt) ausgeführt, nachdem die Benutzerfunktion beendet wurde.
Der interne Message-Handler von AutoIt wird ebenfalls ausgeführt, wenn das Schlüsselwort Return mit der Konstante $GUI_RUNDEFMSG (in GUIConstantsEx.au3) verwendet wird.
Wenn jedoch Return mit einem anderen Wert verwendet wird (einschließlich gar keinem Wert), wird der interne Message-Handler von AutoIt NICHT ausgeführt (siehe WM_COMMAND im Beispiel).
Daher erfordert eine vorzeitige Rückkehr von der Benutzerfunktion Return $GUI_RUNDEFMSG, wenn der interne AutoIt-Handler für diese Nachricht ausgeführt werden soll (siehe andere Beispiele).
Warnung: Das Blockieren laufender Benutzerfunktionen, die Fenstermeldungen mit Befehlen wie "MsgBox()") ausführen, kann zu unerwartetem Verhalten führen - die Rückkehr zum System sollte so schnell wie möglich erfolgen!!!
Einige Controls nutzen intern spezifische Windows-Message-ID's, sodass eine Registrierung dieser Nachrichten keinen Effekt hat, z.B: werden WM_CHAR, WM_KEYDOWN und WM_KEYUP von einem Edit-Control belegt.
- - - - - - - - Erklärung der Controls - - - - - - - -
#include <ButtonConstants.au3>
#include <FrameConstants.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <MsgBoxConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
;Erzeugt einen selbstgezeichneten eigenen Button
Example()
Func Example()
Local $hGUI = GUICreate("Mein selbstgezeichneter Button", 300, 200)
Local $idButton = GUICtrlCreateButton("", 90, 50, 120, 30)
GUICtrlSetStyle($idButton, BitOR($WS_TABSTOP, $BS_NOTIFY, $BS_OWNERDRAW)) ; Setzt den Ownerdrawn-Flag
Local $idButton2 = GUICtrlCreateButton("Normaler Button", 90, 110, 120, 30)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
; WM_DRAWITEM muss vor anzeigen der GUI registriert werden andernfalls wird der initialisierte Zeichenvorgang nicht vollzogen
GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
GUISetState(@SW_SHOW, $hGUI)
Local $iMsg
While 1
$iMsg = GUIGetMsg()
Switch $iMsg
Case $GUI_EVENT_CLOSE
ExitLoop
Case $idButton
; Sollte normalerweise nicht laufen, wegen unserer WM_COMMAND Funktion
MsgBox($MB_SYSTEMMODAL, "Info", "Button gedrückt")
Case $idButton2
; Sollte normalerweise nicht laufen, wegen unserer WM_COMMAND Funktion
MsgBox($MB_SYSTEMMODAL, "Info", "Button2 gedrückt")
EndSwitch
WEnd
GUIDelete()
EndFunc ;==>Example
; Reagiert auf einen Buttonklick
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
Local $nNotifyCode = _WinAPI_HiWord($wParam)
Local $iId = _WinAPI_LoWord($wParam)
Local $hCtrl = $lParam
If $iId <> 2 And $nNotifyCode = 0 Then ; Prüft auf IDCANCEL - 2
; Ownerdrawn Buttons senden keine Nachricht wenn ENTER gedrückt wird
; Also, IDOK - 1 tritt auf, prüfe nun das Control mit dem aktuellen Fokus
If $iId = 1 Then
Local $hFocus = _WinAPI_GetFocus()
Local $idControl = _WinAPI_GetDlgCtrlID($hFocus)
PostButtonClick($hWnd, $idControl)
Else
MsgBox($MB_SYSTEMMODAL, "WM_COMMAND", "GUIHWnd" & @TAB & ":" & $hWnd & @CRLF & _
"MsgId" & @TAB & ":" & $iMsg & @CRLF & _
"wParam" & @TAB & ":" & $wParam & @CRLF & _
"lParam" & @TAB & ":" & $lParam & @CRLF & @CRLF & _
"WM_COMMAND - Infos:" & @CRLF & _
"-----------------------------" & @CRLF & _
"Code" & @TAB & ":" & $nNotifyCode & @CRLF & _
"CtrlId" & @TAB & ":" & $iId & @CRLF & _
"CtrlHWnd" & @TAB & ":" & $hCtrl)
EndIf
Return 0 ; Wird nur zurückgegeben, wenn Button gedrückt wurde
EndIf
; Führt beim beenden die Standard 'Autoit3 internal message commands' aus.
; Es wird auch ausgeführt, wenn "Return" $GUI_RUNDEFMSG wie folgt zurückgibt
; Wird "Return" mit jedem anderen Wert verwendet (oder kein Wert, so bedeutet dies, das der AutoIt handler nicht startet
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
; Sendet eine WM_COMMAND Nachricht zu einem Control in einem GUI Fenster
Func PostButtonClick($hWnd, $idControl)
DllCall("user32.dll", "int", "PostMessage", _
"hwnd", $hWnd, _
"int", $WM_COMMAND, _
"int", _WinAPI_LoWord($idControl), _
"hwnd", GUICtrlGetHandle($idControl))
EndFunc ;==>PostButtonClick
; Zeichnet den Button
Func WM_DRAWITEM($hWnd, $iMsg, $wParam, $lParam)
#forceref $iMsg, $wParam, $lParam
Local Const $tagDRAWITEMSTRUCT = "uint;uint;uint;uint;uint;hwnd;handle;long[4];ulong_ptr"
Local $tDrawItem = DllStructCreate($tagDRAWITEMSTRUCT, $lParam)
Local Const $ODT_BUTTON = 4
Local $nCtlType = DllStructGetData($tDrawItem, 1)
If $nCtlType = $ODT_BUTTON Then
; Local $idControl = DllStructGetData($tDrawItem, 2)
Local $nItemState = DllStructGetData($tDrawItem, 5)
Local $hCtrl = DllStructGetData($tDrawItem, 6)
Local $hDC = DllStructGetData($tDrawItem, 7)
Local $iLeft = DllStructGetData($tDrawItem, 8, 1)
Local $iTop = DllStructGetData($tDrawItem, 8, 2)
Local $iRight = DllStructGetData($tDrawItem, 8, 3)
Local $iBottom = DllStructGetData($tDrawItem, 8, 4)
Local $sText = "Ownerdrawn Button"
Local $nTextColor = 0x5555DD
Local $nBackColor = 0xFFEEDD
DrawButton($hWnd, $hCtrl, $hDC, $iLeft, $iTop, $iRight, $iBottom, $nItemState, $sText, $nTextColor, $nBackColor)
$tDrawItem = 0
Return 1 ; Der interne AutoIt Nachrichten handler startet nicht
EndIf
$tDrawItem = 0
Return $GUI_RUNDEFMSG ; Führt die Standard 'Autoit internal message commands' aus.
EndFunc ;==>WM_DRAWITEM
; Die Hauptprozedur des Zeichenvorgangs
Func DrawButton($hWnd, $hCtrl, $hDC, $iLeft, $iTop, $iRight, $iBottom, $nItemState, $sText, $nTextColor, $nBackColor)
#forceref $hWnd
Local Const $ODS_SELECTED = 0x0001
Local Const $ODS_GRAYED = 0x0002
Local Const $ODS_DISABLED = 0x0004
Local Const $ODS_FOCUS = 0x0010
Local $bFocused = BitAND($nItemState, $ODS_FOCUS)
Local $bGrayed = BitAND($nItemState, BitOR($ODS_GRAYED, $ODS_DISABLED))
Local $bSelected = BitAND($nItemState, $ODS_SELECTED)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
Local $nClrTxt = 0
If $bGrayed Then
$nClrTxt = _WinAPI_SetTextColor($hDC, _WinAPI_GetSysColor($COLOR_HIGHLIGHTTEXT))
ElseIf $nTextColor = -1 Then
$nClrTxt = _WinAPI_SetTextColor($hDC, _WinAPI_GetSysColor($COLOR_BTNTEXT))
Else
$nClrTxt = _WinAPI_SetTextColor($hDC, $nTextColor)
EndIf
Local $hBrush, $nClrSel
If $nBackColor = -1 Then
$hBrush = _WinAPI_GetSysColorBrush($COLOR_BTNFACE)
$nClrSel = _WinAPI_GetSysColor($COLOR_BTNFACE)
Else
$hBrush = _WinAPI_CreateSolidBrush($nBackColor)
$nClrSel = $nBackColor ;
EndIf
Local $nClrBk = _WinAPI_SetBkColor($hDC, $nClrSel)
Local $hOldBrush = _WinAPI_SelectObject($hDC, $hBrush)
Local $nTmpLeft = $iLeft
Local $nTmpTop = $iTop
Local $nTmpRight = $iRight
Local $nTmpBottom = $iBottom
If $bSelected Then
InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -1, -1)
Local $hBrushSel = _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_BTNSHADOW))
FrameRect($hDC, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, $hBrushSel)
_WinAPI_DeleteObject($hBrushSel)
Else
If $bFocused And Not $bSelected Then InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -1, -1)
DrawFrameControl($hDC, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, $DFC_BUTTON, $DFCS_BUTTONPUSH)
EndIf
$nTmpLeft = $iLeft
$nTmpTop = $iTop
$nTmpRight = $iRight
$nTmpBottom = $iBottom
If $bSelected Then
InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -2, -2)
Else
If $bFocused And Not $bSelected Then
InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -3, -3)
$nTmpLeft -= 1
$nTmpTop -= 1
Else
InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -2, -2)
$nTmpLeft -= 1
$nTmpTop -= 1
EndIf
EndIf
FillRect($hDC, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, $hBrush)
If $bSelected Or $bGrayed Then
$nTmpLeft = $nTmpLeft + 2
$nTmpTop = $nTmpTop + 2
EndIf
Local $iFlags = BitOR($DT_NOCLIP, $DT_CENTER, $DT_VCENTER)
If Not BitAND(_WinAPI_GetWindowLong($hCtrl, $GWL_STYLE), $BS_MULTILINE) Then $iFlags = BitOR($iFlags, $DT_SINGLELINE)
DrawText($hDC, $sText, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, $iFlags)
If $bGrayed Then
$nTmpLeft = $iLeft
$nTmpTop = $iTop
$nTmpRight = $iRight
$nTmpBottom = $iBottom
$nTmpLeft -= 1
$nClrTxt = _WinAPI_SetTextColor($hDC, _WinAPI_GetSysColor($COLOR_GRAYTEXT))
DrawText($hDC, $sText, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, BitOR($DT_NOCLIP, $DT_CENTER, $DT_VCENTER, $DT_SINGLELINE))
EndIf
$nTmpLeft = $iLeft
$nTmpTop = $iTop
$nTmpRight = $iRight
$nTmpBottom = $iBottom
If $bFocused Then
$hBrush = _WinAPI_CreateSolidBrush(0)
FrameRect($hDC, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, $hBrush)
$nTmpLeft = $iLeft
$nTmpTop = $iTop
$nTmpRight = $iRight
$nTmpBottom = $iBottom
InflateRect($nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom, -4, -4)
DrawFocusRect($hDC, $nTmpLeft, $nTmpTop, $nTmpRight, $nTmpBottom)
EndIf
_WinAPI_SelectObject($hDC, $hOldBrush)
_WinAPI_DeleteObject($hBrush)
_WinAPI_SetTextColor($hDC, $nClrTxt)
_WinAPI_SetBkColor($hDC, $nClrBk)
Return 1 ; Der interne AutoIt Nachrichten handler startet nicht
EndFunc ;==>DrawButton
Func DrawFrameControl($hDC, $iLeft, $iTop, $iRight, $iBottom, $iType, $iState)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_DrawFrameControl($hDC, $tRECT, $iType, $iState)
EndFunc ;==>DrawFrameControl
Func DrawFocusRect($hDC, $iLeft, $iTop, $iRight, $iBottom)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_DrawFocusRect($hDC, $tRECT)
EndFunc ;==>DrawFocusRect
Func DrawText($hDC, $sText, $iLeft, $iTop, $iRight, $iBottom, $iFlags)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_DrawText($hDC, $sText, $tRECT, $iFlags)
EndFunc ;==>DrawText
Func FillRect($hDC, $iLeft, $iTop, $iRight, $iBottom, $hBrush)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_FillRect($hDC, $tRECT, $hBrush)
EndFunc ;==>FillRect
Func FrameRect($hDC, $iLeft, $iTop, $iRight, $iBottom, $hBrush)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_FrameRect($hDC, $tRECT, $hBrush)
EndFunc ;==>FrameRect
Func InflateRect(ByRef $iLeft, ByRef $iTop, ByRef $iRight, ByRef $iBottom, $iDX, $iDY)
Local $tRECT = DllStructCreate($tagRECT)
DllStructSetData($tRECT, 'Left', $iLeft)
DllStructSetData($tRECT, 'Top', $iTop)
DllStructSetData($tRECT, 'Right', $iRight)
DllStructSetData($tRECT, 'Bottom', $iBottom)
_WinAPI_InflateRect($tRECT, $iDX, $iDY)
$iLeft = DllStructGetData($tRECT, 'Left')
$iTop = DllStructGetData($tRECT, 'Top')
$iRight = DllStructGetData($tRECT, 'Right')
$iBottom = DllStructGetData($tRECT, 'Bottom')
EndFunc ;==>InflateRect