nur Hover über sichtbaren Teil

  • Hallo,

    ich bastel mir gerade eine schöne GUI zusammen und dazu gehört auch natürlich ein Hover bei Buttons.
    Jetzt bin ich zu einem Punkt gekommen um den Hover effekt zu verschönern.

    Wenn man die Maus über das Bild (den Button) fährt, dann ändert es sich zu dem Hoverbild. Das passiert auch, wenn man über den transparenten Teil fährt.
    Da ich aber ein Button erstellen möchte habe ich den Cursor auch ändern lassen. Dieser ändert sich aber erst dann, wenn man die Maus über einen sichtbaren Teil fährt und nicht über den transparenten Teil.
    Dadurch kam mir der Gedanken, dass es doch bestimmt möglich ist den Hover auch erst dann auftauchen zu lassen, wenn die Maus erst den sichtbaren Teil trift.
    Ich vermute, dass es möglich ist, weil, wenn ich abfrage ob der Button bzw. das Bild geklickt wurde, dann reagiert es erst, wenn man auf den sichtbaren Teil drückt.
    Nun habe ich die ganze Zeit rumprobiert aber bekomme es nicht hin :(

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <SendMessage.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>

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

    Global $hGUI
    Global $aHover[1], $iHover = False

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

    _GDIPlus_Startup()

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

    $hGUI = GUICreate("hans", 450, 610, (@DesktopWidth / 2) - 400, -1, $WS_POPUP, $WS_EX_LAYERED); + $WS_EX_TOPMOST)
    $hGUI_child = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_MDICHILD, $hGUI)

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

    $hImage = _GDIPlus_ImageLoadFromFile("bg.png")
    SetBitmap($hGUI, $hImage, 0xFF)
    GUISetBkColor(0, $hGUI_child)
    GUIRegisterMsg($WM_LBUTTONDOWN, "_WM_LBUTTONDOWN")
    GUISetState(@SW_SHOW, $hGUI)
    GUISetState(@SW_SHOW, $hGUI_child)
    _WinAPI_SetLayeredWindowAttributes($hGUI_child, 0x00, 0xff)
    $hButton = _GUICtrlCreateImageButton($hGUI, "start.png", "start_hover.png", 750, 600)

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

    While 1
    _Funktion()
    WEnd

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

    Func _Funktion()
    $msg = GUIGetMsg()
    Switch $msg
    Case -3
    Exit
    Case $hButton
    SetBitmap($aHover[0][1], $aHover[0][3], 0xFF)
    EndSwitch

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

    EndFunc ;==>_Funktion

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

    Func SetBitmap($hGUI, $hImage, $iOpacity = 255)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", 1)
    _WinAPI_UpdateLayeredWindow($hGUI, $hGUI, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
    EndFunc ;==>SetBitmap

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

    Func _WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam)
    _SendMessage($hGUI, $WM_SYSCOMMAND, 0xF012, 0)
    EndFunc ;==>_WM_LBUTTONDOWN

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

    Func _GUICheckHoverButtons()
    $hover = False

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

    For $i = 0 To UBound($aHover) - 1
    $aMouse = GUIGetCursorInfo($aHover[$i][1])
    ToolTip($aMouse[4], 0, 20, $aHover[$i][1])
    If ($aMouse[4] > 0 And $aHover[$i][4] = False) Then
    SetBitmap($aHover[$i][1], $aHover[$i][3], 0xFF)
    $aHover[$i][4] = True
    ElseIf ($aMouse[4] == 0 And $aHover[$i][4] = True) Then
    SetBitmap($aHover[$i][1], $aHover[$i][2], 0xFF)
    $aHover[$i][4] = False
    EndIf
    Next
    EndFunc ;==>_GUICheckHoverButtons

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

    Func _GUICtrlCreateImageButton($gui_parent, $image, $image_hover, $left, $top)
    $hImage = _GDIPlus_ImageLoadFromFile($image)
    $hImageHover = _GDIPlus_ImageLoadFromFile($image_hover)
    $width = _GDIPlus_ImageGetWidth($hImage)
    $height = _GDIPlus_ImageGetHeight($hImage)
    $gui = GUICreate("Button_" & Random(1, 9999), $width, $height, $left, $top, $WS_POPUP, $WS_EX_LAYERED, $gui_parent)
    GUISetCursor(0, 1, $gui)
    $GUIActiveX = GUICtrlCreateLabel("", -1, -1, $width + 1, $height + 1)
    GUICtrlSetCursor(-1, 0)
    SetBitmap($gui, $hImage, 0xFF)
    GUISetState(@SW_SHOW, $gui)
    $handle = SetError(0, $gui, $GUIActiveX);
    ;~ MsgBox(0,"", $handle)

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

    ReDim $aHover[UBound($aHover)][5];
    $aHover[UBound($aHover) - 1][0] = $handle
    $aHover[UBound($aHover) - 1][1] = $gui
    $aHover[UBound($aHover) - 1][2] = $hImage
    $aHover[UBound($aHover) - 1][3] = $hImageHover
    $aHover[UBound($aHover) - 1][4] = False;

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

    If ($iHover == False) Then
    AdlibRegister("_GUICheckHoverButtons", 200);
    $iHover = True
    EndIf

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

    Return $handle
    EndFunc ;==>_GUICtrlCreateImageButton

    [/autoit]

    Hat jemand eine Idee für mein Problem?

  • Vielleicht gibt es eine bessere Lösung (warscheinlich). Aber:
    Eventuell gibt _GDIPlus_BitmapGetPixel ( $hBitmap, $iX, $iY ) an, ob der Pixel transparent ist. Wenn ja einfach den Pixel an der aktuellen Mausposition abfragen. (Evtl. gibt es da auch ne andere Funktion für)


    Wäre das mit mehren Buttons nicht etwas langsam? Ich habe natürlich noch andere Funktionen nebenbei laufen da sind ja nicht nur einfache Buttons :D

    Ich würds vermutlich mit GuiGetCursorInfo() versuchen. Damit die Positionen der Controls ermiteln, die diesen HOver Effekt haben sollen und dann mit Switch das Control ändern.
    Aber auch nur, weil ich noch nie mit GDI gearbeitet habe. Da gibt es sicherlich bessere Möglichkeiten.


    Zeil 71 >.> + Erklärung im Thread

    Hierfür gibt es bereits eine passende UDF.

    http://www.autoitscript.com/forum/files/fi…guictrlonhover/


    Danke, das schaue mich mir jetzt sofort an :)

    /Edit:
    Letzte Variante funktioniert problemlos :)

    Einmal editiert, zuletzt von Freaky (12. März 2015 um 12:15)