Bsp.: Mit Button-UDF erstellten Button einfärben

    • Offizieller Beitrag

    Als erstes mag man sich natürlich fragen, wozu man einen Button mit der UDF erstellen sollte. In 99% aller Fälle ist das nicht notwendig und somit sei auch davon abzuraten. :D
    Aber es gibt halt den Fall, dass man z.B. auf einer Rebar einen Button platzieren möchte. Das geht ausschließlich über die Button-UDF (ebenso wie alle Buttontypen wie Radio/Checkbox, Edit und Combo). Das in der Hilfe angeführte Bsp. zur Rebar ist definitiv falsch. Holt man sich, wie dort gezeigt, die Handle von nativ erstellten Ctrl um diese im Rebar einzubetten, werden sie zwar angezeigt, tummeln sich aber alle nach HIDE/SHOW od. MIN/MAX an der Pos. 0,0 übereinander.
    Mit den per UDF erstellten Ctrl funktioniert alles wie gewollt.
    Aber:
    Wie sieht es aus mit Einfärben eines Button? Einfach ID rausfischen mit _WinAPI_GetDlgCtrlID() und auf diese native Colorfunktionen anwenden führt zu nichts.
    Hier mal ein Bsp. wie sich das Lösen läßt. Der Style $BS_OWNERDRAW ist dafür erforderlich. Das führt aber auch dazu, dass der Button sich nicht mehr "normal" verhält. Das optische Anklicken habe ich im Bsp. simuliert, kann aber leider auf einer Rebar nicht verwendet werden.
    Um ein 3-Dimensionales Aussehen zu erzeugen muss man den linken und oberen Rand hell, den rechten und unteren Rand dunkel färben. Alle wichtigen Details sind im Code kommentiert.


    Spoiler anzeigen
    [autoit]


    #include <ButtonConstants.au3>
    #include <FontConstants.au3>
    #include <GuiButton.au3>
    #include <GUIConstantsEx.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)
    OnAutoItExitRegister('_OnExit')

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global Const $ODA_DRAWENTIRE = 1
    Global Const $ODT_BUTTON = 4

    [/autoit] [autoit][/autoit] [autoit]

    Global $hBrush, $hFont, $Gui, $hBtn1, $hBtn2, $bt1, $bt2
    Global $sFont = 'Comic Sans MS', $iHeight = 16, $iWidth = 7, $iWeight = $FW_MEDIUM;$FW_SEMIBOLD;$FW_NORMAL

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $Gui = GUICreate("Test")
    GUISetBkColor(0xD3DAED)

    [/autoit] [autoit][/autoit] [autoit]

    $hBtn1 = _GUICtrlButton_Create($Gui, 'Button-1', 20, 20, 70, 22, BitOR($BS_OWNERDRAW,$BS_NOTIFY))
    $hBtn2 = _GUICtrlButton_Create($Gui, 'Button-2', 20, 50, 70, 22, BitOR($BS_OWNERDRAW,$BS_NOTIFY))
    Global $aBtnInfo[3][6] = [[2], _ ; == [0][0]=Anzahl, [[Handle-Button, Button-BG-Color, Button-Text-Color(-1=schwarz), Top/Left-Border-Color, Right/Bottom-Border-Color, ArrayPos(rel. in Client)]]
    [$hBtn1, 0x00FFFF, 0xFF0000, 0xFAF5F2, 0xC0C0C0, ControlGetPos($Gui, '', _WinAPI_GetDlgCtrlID($hBtn1))], _
    [$hBtn2, 0xFF00FF, -1, 0xFAF5F2, 0xC0C0C0, ControlGetPos($Gui, '', _WinAPI_GetDlgCtrlID($hBtn2))]]
    ; == Man kann das Array auch noch erweitern um Font-Informationen einzeln zu jedem Button zu speichern

    [/autoit] [autoit][/autoit] [autoit]

    $bt1 = GUICtrlCreateDummy()
    $bt2 = GUICtrlCreateDummy()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
    _WinAPI_RedrawWindow($Gui)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW, $Gui)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While True
    Switch GUIGetMsg()
    Case -3
    Exit
    Case $GUI_EVENT_PRIMARYDOWN ; == DOWN- und UP dienen nur zur optischen Darstellung des Buttonklicks
    _Event_PrimaryDownUp(1)
    Case $GUI_EVENT_PRIMARYUP
    _Event_PrimaryDownUp(0)
    Case $bt1
    ConsoleWrite('Button-1' & @LF)
    Case $bt2
    ConsoleWrite('Button-2' & @LF)
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _OnExit()
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_DeleteObject($hFont)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; == Man könnte sich die Dummy-Ctrls sparen und hier in der "WM_COMMAND"-Func die Befehle der Button ausführen.
    ; == Davon ist aber abzuraten! Die Msg-Routinen sollten schnellstmöglich verlassen werden, deshalb besser ein Dummy befeuern
    ; == und dieses Event in der Standard-Msg-Auswertung abarbeiten.
    Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg
    If BitShift($wParam, 16) <> $BN_CLICKED Then Return $GUI_RUNDEFMSG ; == nur Click soll ausgewertet werden
    Local $ID
    Switch $lParam ; == Button-Handle auswerten
    Case $hBtn1
    $ID = $bt1 ; == Dummy-ID zuweisen
    Case $hBtn2
    $ID = $bt2
    EndSwitch
    ; == Nachricht an gewählte Dummy-ID absetzen
    DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $Gui, "uint", 273, "wparam", $ID, "lparam", 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $DRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _
    "hwnd hItm;hwnd hDC;dword itmRect[4];dword itmData", $lParam)
    If DllStructGetData($DRAWITEMSTRUCT, "cType") <> $ODT_BUTTON Then Return $GUI_RUNDEFMSG ; == nur OWNERDRAW-Button
    If DllStructGetData($DRAWITEMSTRUCT, "itmAction") <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG ; == nur Neuzeichnen-Event

    [/autoit] [autoit][/autoit] [autoit]

    Local $hDC = DllStructGetData($DRAWITEMSTRUCT, "hDC")
    Local $hItm = DllStructGetData($DRAWITEMSTRUCT, "hItm")
    Local $sText = _GUICtrlButton_GetText($hItm) ; == Text des zu zeichnenden Button abfragen
    Local $iColBG, $iColTxt, $iColBorderLT, $iColBorderRB, $iIndex ; == Variablen für Buttonfarben u. Index im Array
    _GetBtnColor($hItm, $iColBG, $iColTxt, $iColBorderLT, $iColBorderRB, $iIndex) ; == Farben für diesen Button aus Array abfragen
    Local $tRECT = DllStructCreate('int;int;int;int;', DllStructGetPtr($DRAWITEMSTRUCT, "itmRect")) ; == Rect des Button

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
    $hBrush = _WinAPI_CreateSolidBrush($iColBG)
    Local $hBrushOld = _WinAPI_SelectObject($hDC, $hBrush)
    _WinAPI_FillRect($hDC, DllStructGetPtr($DRAWITEMSTRUCT, "itmRect"), $hBrush) ; == Button-Hintergrundfarbe zeichnen
    Local $iColOld = _WinAPI_SetTextColor($hDC, $iColTxt) ; == Textfarbe anwählen

    [/autoit] [autoit][/autoit] [autoit]

    ; == Infos für Font könnten auch einzeln für jeden Button im Array hinterlegt werden
    Local $nHeight = $iHeight, $nWidth = $iWidth, $nEscape = 0, $nOrientn = 0, $fnWeight = $iWeight, $bItalic = False, $bUnderline = False
    Local $bStrikeout = False, $nCharset = $DEFAULT_CHARSET, $nOutputPrec = $OUT_DEFAULT_PRECIS, $nClipPrec = $CLIP_DEFAULT_PRECIS
    Local $nQuality = $DEFAULT_QUALITY, $nPitch = 0, $szFace = $sFont
    $hFont = _WinAPI_CreateFont($nHeight, $nWidth, $nEscape, $nOrientn, $fnWeight, $bItalic, $bUnderline, _
    $bStrikeout, $nCharset, $nOutputPrec, $nClipPrec, $nQuality, $nPitch, $szFace)
    Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_CENTER,$DT_VCENTER,$DT_SINGLELINE)) ; == Button-Text schreiben
    _WinAPI_SetTextColor($hDC, $iColOld) ; == Textfarbe zurücksetzen
    _WinAPI_DrawButtonRect($hDC, $tRECT, $iColBorderLT, $iColBorderRB, 1) ; == Button-Ränder zeichnen (Left u. Top hell / Right u. Bottom dunkel)
    _WinAPI_SelectObject($hDC, $hBrushOld)
    _WinAPI_SelectObject($hDC, $hOldFont)

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_DRAWITEM

    [/autoit] [autoit][/autoit] [autoit]

    Func _Event_PrimaryDownUp($_iDown)
    Local $oldMode = Opt('MouseCoordMode', 2), $aSize[4], $aMouse = MouseGetPos()
    Local $hWndBtn = _GetBtnHwndFromMouse($aMouse[0], $aMouse[1], $aSize)
    Opt('MouseCoordMode', $oldMode)
    If $hWndBtn = 0 Then Return
    Switch $_iDown
    Case 0
    ControlMove($Gui, '', _WinAPI_GetDlgCtrlID($hWndBtn), $aSize[0]-1, $aSize[1]-1)
    Case 1
    ControlMove($Gui, '', _WinAPI_GetDlgCtrlID($hWndBtn), $aSize[0]+1, $aSize[1]+1)
    EndSwitch
    EndFunc ;==>_Event_PrimaryDownUp

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetBtnColor($_hWnd, ByRef $_iColBG, ByRef $_iColTxt, ByRef $_iColBorderLT, ByRef $_iColBorderRB, ByRef $_iIndex)
    For $i = 1 To $aBtnInfo[0][0]
    If $aBtnInfo[$i][0] = $_hWnd Then
    $_iColBG = $aBtnInfo[$i][1]
    $_iColTxt = $aBtnInfo[$i][2]
    If $aBtnInfo[$i][2] = -1 Then $aBtnInfo[$i][2] = 0x000000
    $_iColBorderLT = $aBtnInfo[$i][3]
    $_iColBorderRB = $aBtnInfo[$i][4]
    $_iIndex = $aBtnInfo[$i][5]
    Return
    EndIf
    Next
    EndFunc ;==>_GetBtnColor

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetBtnHwndFromMouse($_iX, $_iY, ByRef $_aSize)
    Local $aCtrl
    For $i = 1 To $aBtnInfo[0][0]
    $aCtrl = $aBtnInfo[$i][5]
    If ($aCtrl[0] <= $_iX And $_iX <= $aCtrl[2]+$aCtrl[0]) And ($aCtrl[1] <= $_iY And $_iY <= $aCtrl[3]+$aCtrl[1]) Then
    $_aSize = $aCtrl
    Return $aBtnInfo[$i][0]
    EndIf
    Next
    Return 0
    EndFunc ;==>_GetBtnHwndFromMouse

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_DrawButtonRect(ByRef $_hDC, $_tpRECT, $_iPenColorLT, $_iPenColorRB, $_iPenSize=1)
    Local $tRECT
    If IsDllStruct($_tpRECT) Then
    $tRECT = $_tpRECT
    ElseIf IsPtr($_tpRECT) Then
    $tRECT = DllStructCreate('int;int;int;int;', $_tpRECT)
    EndIf
    Local $hPenLT = _WinAPI_CreatePen($PS_SOLID, $_iPenSize, $_iPenColorLT)
    Local $hPenRB = _WinAPI_CreatePen($PS_SOLID, $_iPenSize, $_iPenColorRB)
    Local $left = DllStructGetData($tRECT, 1), $top = DllStructGetData($tRECT, 2), $right = DllStructGetData($tRECT, 3), $bottom = DllStructGetData($tRECT, 4)
    _WinAPI_SelectObject($_hDC, $hPenLT)
    _WinAPI_DrawLine($_hDC, $left, $top, $left, $bottom-$_iPenSize) ; == Left
    _WinAPI_DrawLine($_hDC, $left, $top, $right, $top) ; == Top
    _WinAPI_SelectObject($_hDC, $hPenRB)
    _WinAPI_DrawLine($_hDC, $right-$_iPenSize, $top, $right-$_iPenSize, $bottom-$_iPenSize) ; == Right
    _WinAPI_DrawLine($_hDC, $left, $bottom-$_iPenSize, $right-$_iPenSize, $bottom-$_iPenSize) ; == Bottom
    _WinAPI_DeleteObject($hPenLT)
    _WinAPI_DeleteObject($hPenRB)
    EndFunc ;==>_WinAPI_DrawButtonRect

    [/autoit]
    • Offizieller Beitrag

    Hi,
    ich habe jetzt eine passable Lösung gefunden um den Klick auf einen Button in einer Rebar optisch zu simulieren. Dazu überschreibe ich während des Events MOUSEDOWN den linken und oberen Seitenrand des Buttons mit der dunklen Farbe (wie rechts/unten). Optisch wirkt es wie ein Versenken des Button. :D
    Das im letzten Bsp. gezeigt Simulieren mit WinMove ist hier schlecht umsetzbar, da die Rebar beim Einfügen von Controls ihre Höhe an diesen ausrichtet. Somit ist nicht genug Platz um das Ctrl um 1 px diagonal zu versetzen.
    Da auf einer Rebar die Control nicht fix sind und auch aus dieser herausgezogen werden können, speichere ich die Controlposition beim Erstellen nicht mehr im Array ab, sondern frage diese bei Bedarf immer neu ab.

    Spoiler anzeigen
    [autoit]

    #include <ButtonConstants.au3>
    #include <Constants.au3>
    #include <FontConstants.au3>
    #include <GuiButton.au3>
    #include <GUIConstantsEx.au3>
    #include <GuiReBar.au3>
    #include <RebarConstants.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #Region - TimeStamp
    ; 2013-03-27 11:41:19
    #EndRegion - TimeStamp

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt('MustDeclareVars', 1)
    OnAutoItExitRegister('_OnExit')

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Global Const $ODA_DRAWENTIRE = 1
    Global Const $ODT_BUTTON = 4

    [/autoit] [autoit][/autoit] [autoit]

    Global $nMsg, $hBrush, $hFont, $Gui, $hBtn1, $hBtn2, $hBtn3, $bt1, $bt2, $bt3, $hReBar
    Global $sFont = 'Comic Sans MS', $iHeight = 16, $iWidth = 7, $iWeight = $FW_MEDIUM;$FW_SEMIBOLD;$FW_NORMAL

    [/autoit] [autoit][/autoit] [autoit]

    $Gui = GUICreate("Test")
    GUISetBkColor(0xD3DAED)

    [/autoit] [autoit][/autoit] [autoit]

    $hBtn1 = _GUICtrlButton_Create($Gui, 'Button-1', 0, 0, 70, 22, BitOR($BS_OWNERDRAW,$BS_NOTIFY))
    $hBtn2 = _GUICtrlButton_Create($Gui, 'Button-2', 0, 0, 70, 22, BitOR($BS_OWNERDRAW,$BS_NOTIFY))
    $hBtn3 = _GUICtrlButton_Create($Gui, 'Button-3', 0, 0, 70, 22, BitOR($BS_OWNERDRAW,$BS_NOTIFY))
    Global $aBtnInfo[4][5] = [[3], _ ; == [0][0]=Anzahl, [[Handle-Button, Button-BG-Color, Button-Text-Color(-1=schwarz), Top/Left-Border-Color, Right/Bottom-Border-Color]]
    [$hBtn1, 0x0000FF, -1, 0xFAF5F2, 0xC0C0C0], _
    [$hBtn2, 0x00FF00, 0xFF0000, 0xFAF5F2, 0xC0C0C0], _
    [$hBtn3, 0xFF0000, 0xFFFFFF, 0xFAF5F2, 0xC0C0C0]]
    ; == Man kann das Array auch noch erweitern um Font-Informationen einzeln zu jedem Button zu speichern
    $bt1 = GUICtrlCreateDummy()
    $bt2 = GUICtrlCreateDummy()
    $bt3 = GUICtrlCreateDummy()

    [/autoit] [autoit][/autoit] [autoit]

    $hReBar = _GUICtrlRebar_Create($Gui, BitOR($CCS_TOP, $RBS_AUTOSIZE, $RBS_BANDBORDERS))
    _GUICtrlRebar_AddBand($hReBar, $hBtn1, 110, 70)
    _GUICtrlRebar_AddBand($hReBar, $hBtn2, 110, 70)
    _GUICtrlRebar_AddBand($hReBar, $hBtn3, 110, 70)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
    GUIRegisterMsg($WM_DRAWITEM, "WM_DRAWITEM")
    _WinAPI_RedrawWindow($Gui)

    [/autoit] [autoit][/autoit] [autoit]

    GUISetState(@SW_SHOW, $Gui)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While True
    $nMsg = GUIGetMsg()
    Switch $nMsg
    Case -3
    Exit
    Case $GUI_EVENT_PRIMARYDOWN, $GUI_EVENT_PRIMARYUP ; == DOWN- und UP dienen nur zur optischen Darstellung des Buttonklicks
    _Event_PrimaryDownUp($nMsg)
    Case $bt1
    ConsoleWrite('Button-1' & @LF)
    Case $bt2
    ConsoleWrite('Button-2' & @LF)
    Case $bt3
    ConsoleWrite('Button-3' & @LF)
    EndSwitch
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _OnExit()
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_DeleteObject($hFont)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; == Man könnte sich die Dummy-Ctrls sparen und hier in der "WM_COMMAND"-Func die Befehle der Button ausführen.
    ; == Davon ist aber abzuraten! Die Msg-Routinen sollten schnellstmöglich verlassen werden, deshalb besser ein Dummy befeuern
    ; == und dieses Event in der Standard-Msg-Auswertung abarbeiten.
    Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    #forceref $hWnd, $Msg
    If BitShift($wParam, 16) <> $BN_CLICKED Then Return $GUI_RUNDEFMSG ; == nur Click soll ausgewertet werden
    Local $ID
    Switch $lParam ; == Button-Handle auswerten
    Case $hBtn1
    $ID = $bt1 ; == Dummy-ID zuweisen
    Case $hBtn2
    $ID = $bt2
    Case $hBtn3
    $ID = $bt3
    EndSwitch
    ; == Nachricht an gewählte Dummy-ID absetzen
    DllCall("user32.dll", "lresult", "SendMessageW", "hwnd", $Gui, "uint", 273, "wparam", $ID, "lparam", 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_COMMAND

    [/autoit] [autoit][/autoit] [autoit]

    Func WM_DRAWITEM($hWnd, $Msg, $wParam, $lParam)
    Local $DRAWITEMSTRUCT = DllStructCreate("uint cType;uint cID;uint itmID;uint itmAction;uint itmState;" & _
    "hwnd hItm;hwnd hDC;dword itmRect[4];dword itmData", $lParam)
    If DllStructGetData($DRAWITEMSTRUCT, "cType") <> $ODT_BUTTON Then Return $GUI_RUNDEFMSG ; == nur OWNERDRAW-Button
    If DllStructGetData($DRAWITEMSTRUCT, "itmAction") <> $ODA_DRAWENTIRE Then Return $GUI_RUNDEFMSG ; == nur Neuzeichnen-Event

    [/autoit] [autoit][/autoit] [autoit]

    Local $hDC = DllStructGetData($DRAWITEMSTRUCT, "hDC")
    Local $hItm = DllStructGetData($DRAWITEMSTRUCT, "hItm")
    Local $sText = _GUICtrlButton_GetText($hItm) ; == Text des zu zeichnenden Button abfragen
    Local $iColBG, $iColTxt, $iColBorderLT, $iColBorderRB ; == Variablen für Buttonfarben im Array
    _GetBtnColor($hItm, $iColBG, $iColTxt, $iColBorderLT, $iColBorderRB) ; == Farben für diesen Button aus Array abfragen
    Local $tRECT = DllStructCreate('int;int;int;int;', DllStructGetPtr($DRAWITEMSTRUCT, "itmRect")) ; == Rect des Button

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_SetBkMode($hDC, $TRANSPARENT)
    $hBrush = _WinAPI_CreateSolidBrush($iColBG)
    Local $hBrushOld = _WinAPI_SelectObject($hDC, $hBrush)
    _WinAPI_FillRect($hDC, DllStructGetPtr($DRAWITEMSTRUCT, "itmRect"), $hBrush) ; == Button-Hintergrundfarbe zeichnen
    Local $iColOld = _WinAPI_SetTextColor($hDC, $iColTxt) ; == Textfarbe anwählen

    [/autoit] [autoit][/autoit] [autoit]

    ; == Infos für Font könnten auch einzeln für jeden Button im Array hinterlegt werden
    Local $nHeight = $iHeight, $nWidth = $iWidth, $nEscape = 0, $nOrientn = 0, $fnWeight = $iWeight, $bItalic = False, $bUnderline = False
    Local $bStrikeout = False, $nCharset = $DEFAULT_CHARSET, $nOutputPrec = $OUT_DEFAULT_PRECIS, $nClipPrec = $CLIP_DEFAULT_PRECIS
    Local $nQuality = $DEFAULT_QUALITY, $nPitch = 0, $szFace = $sFont
    $hFont = _WinAPI_CreateFont($nHeight, $nWidth, $nEscape, $nOrientn, $fnWeight, $bItalic, $bUnderline, _
    $bStrikeout, $nCharset, $nOutputPrec, $nClipPrec, $nQuality, $nPitch, $szFace)
    Local $hOldFont = _WinAPI_SelectObject($hDC, $hFont)

    [/autoit] [autoit][/autoit] [autoit]

    _WinAPI_DrawText($hDC, $sText, $tRECT, BitOR($DT_CENTER,$DT_VCENTER,$DT_SINGLELINE)) ; == Button-Text schreiben
    _WinAPI_SetTextColor($hDC, $iColOld) ; == Textfarbe zurücksetzen
    _WinAPI_DrawButtonRect($hDC, $tRECT, $iColBorderLT, $iColBorderRB, 1) ; == Button-Ränder zeichnen (Left u. Top hell / Right u. Bottom dunkel)
    _WinAPI_SelectObject($hDC, $hBrushOld)
    _WinAPI_SelectObject($hDC, $hOldFont)

    [/autoit] [autoit][/autoit] [autoit]

    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_DRAWITEM

    [/autoit] [autoit][/autoit] [autoit]

    Func _Event_PrimaryDownUp($_iEVENT)
    Local $oldMode = Opt('MouseCoordMode', 2), $aMouse = MouseGetPos(), $iColBorderRB
    Opt('MouseCoordMode', $oldMode)
    Local $hWndBtn = _GetBtnHwndFromMouse($aMouse[0], $aMouse[1], $iColBorderRB)
    If $hWndBtn = 0 Then Return
    Local $aCtrlPos = ControlGetPos($Gui, '', _WinAPI_GetDlgCtrlID($hWndBtn)) ; == Pos. im Rebar ist variabel, daher immer neu abfragen
    Local Static $DC = _WinAPI_GetDC($Gui)
    Switch $_iEVENT
    Case $GUI_EVENT_PRIMARYUP
    _WinAPI_ReleaseDC($Gui, $DC)
    Case $GUI_EVENT_PRIMARYDOWN
    Local $hPenLT = _WinAPI_CreatePen($PS_SOLID, 1, $iColBorderRB) ; == Farbe von Right/Bottom verwenden
    _WinAPI_SelectObject($DC, $hPenLT)
    _WinAPI_DrawLine($DC, $aCtrlPos[0], $aCtrlPos[1], $aCtrlPos[0], $aCtrlPos[1]+$aCtrlPos[3]-1) ; == Left
    _WinAPI_DrawLine($DC, $aCtrlPos[0], $aCtrlPos[1], $aCtrlPos[0]+$aCtrlPos[2], $aCtrlPos[1]) ; == Top
    _WinAPI_DeleteObject($hPenLT)
    EndSwitch
    EndFunc ;==>_Event_PrimaryDownUp

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetBtnColor($_hWnd, ByRef $_iColBG, ByRef $_iColTxt, ByRef $_iColBorderLT, ByRef $_iColBorderRB)
    For $i = 1 To $aBtnInfo[0][0]
    If $aBtnInfo[$i][0] = $_hWnd Then
    $_iColBG = $aBtnInfo[$i][1]
    If $aBtnInfo[$i][2] = -1 Then $aBtnInfo[$i][2] = 0x000000
    $_iColTxt = $aBtnInfo[$i][2]
    $_iColBorderLT = $aBtnInfo[$i][3]
    $_iColBorderRB = $aBtnInfo[$i][4]
    Return
    EndIf
    Next
    EndFunc ;==>_GetBtnColor

    [/autoit] [autoit][/autoit] [autoit]

    Func _GetBtnHwndFromMouse($_iX, $_iY, ByRef $_iColBorderRB)
    Local $aCtrl
    For $i = 1 To $aBtnInfo[0][0]
    $aCtrl = ControlGetPos($Gui, '', _WinAPI_GetDlgCtrlID($aBtnInfo[$i][0]))
    If ($aCtrl[0] <= $_iX And $_iX <= $aCtrl[2]+$aCtrl[0]) And ($aCtrl[1] <= $_iY And $_iY <= $aCtrl[3]+$aCtrl[1]) Then
    $_iColBorderRB = $aBtnInfo[$i][4]
    Return $aBtnInfo[$i][0]
    EndIf
    Next
    Return 0
    EndFunc ;==>_GetBtnHwndFromMouse

    [/autoit] [autoit][/autoit] [autoit]

    Func _WinAPI_DrawButtonRect(ByRef $_hDC, $_tpRECT, $_iPenColorLT, $_iPenColorRB, $_iPenSize=1)
    Local $tRECT
    If IsDllStruct($_tpRECT) Then
    $tRECT = $_tpRECT
    ElseIf IsPtr($_tpRECT) Then
    $tRECT = DllStructCreate('int;int;int;int;', $_tpRECT)
    EndIf
    Local $hPenLT = _WinAPI_CreatePen($PS_SOLID, $_iPenSize, $_iPenColorLT)
    Local $hPenRB = _WinAPI_CreatePen($PS_SOLID, $_iPenSize, $_iPenColorRB)
    Local $left = DllStructGetData($tRECT, 1), $top = DllStructGetData($tRECT, 2), $right = DllStructGetData($tRECT, 3), $bottom = DllStructGetData($tRECT, 4)
    _WinAPI_SelectObject($_hDC, $hPenLT)
    _WinAPI_DrawLine($_hDC, $left, $top, $left, $bottom-$_iPenSize) ; == Left
    _WinAPI_DrawLine($_hDC, $left, $top, $right, $top) ; == Top
    _WinAPI_SelectObject($_hDC, $hPenRB)
    _WinAPI_DrawLine($_hDC, $right-$_iPenSize, $top, $right-$_iPenSize, $bottom-$_iPenSize) ; == Right
    _WinAPI_DrawLine($_hDC, $left, $bottom-$_iPenSize, $right-$_iPenSize, $bottom-$_iPenSize) ; == Bottom
    _WinAPI_DeleteObject($hPenLT)
    _WinAPI_DeleteObject($hPenRB)
    EndFunc ;==>_WinAPI_DrawButtonRect

    [/autoit]
  • Danke Bugfix.
    Aber bei mir unter WinXP - Klassische Ansicht, da wird der Button beim Klicken rot, dann aber nicht mehr blau. erst wenn ich ein Fenster drüberlege oder die Gui aus dem Desktopbereich und wieder herein bewege isst er wieder blau.
    Beim ersten Beispiel, wenn man klickt die Maus gedrückt lässt und dann neben dem Button loslässt, dann bleibt der Button optisch 'gedrückt'.

    • Offizieller Beitrag

    Aber bei mir unter WinXP - Klassische Ansicht, da wird der Button beim Klicken rot, dann aber nicht mehr blau. erst wenn ich ein Fenster drüberlege oder die Gui aus dem Desktopbereich und wieder herein bewege isst er wieder blau.

    Ich habe das mal in meinem VirtualXP getestet:
    Unter XP wird die Rebar gar nicht erstellt! In dem Bsp. sind 3 Button, die werden einfach alle übereinander geschoben (da sie für die Rebar alle x und y =0 haben) und beim Klick wird ein anderer sichtbar. Mal sehen woran das liegt. Ich hatte zumindest erwartet, dass die Funktionen auch unter XP lauffähig sind.

    Beim ersten Beispiel, wenn man klickt die Maus gedrückt lässt und dann neben dem Button loslässt, dann bleibt der Button optisch 'gedrückt'.

    Das ist aber auch gemein von dir aus der Schaltfläche rauszurutschen... :D
    Dann muß man für diesen Fall wohl auch zusätzlich MOUSEMOVE registrieren um das Verlassen des Button ohne UP-Event zu bemerken (oder einfach ein _MouseTrap() auf dem Button :D).


    Edit: Habs gerade nochmal mit dem Hilfe-Bsp. getestet: XP kann keine Rebar darstellen! - Was ein Schei... :wacko: