GUI: gestreckte PNG als Buttons (Popup-Style)

  • Hallo AutoIt-Community,

    Wieder einmal habe ich eine Frage zum Theme Darstellung von Bildern.
    Ich versuche eine GUI aus PNG-Bildern und Jpg's zusammenzustellen.

    Jetzt das Problem, auf das ich gestoßen bin:
    Wenn ich versuche ein PNG zu laden, einen Teil zu extrahieren, dann zu strecken, um es dann darzustellen, dann scheitere ich jedesmal.

    Um die "geskinnte" GUI umzusetzten stütze ich mich auf das tolle Beispiel von Greenhorn!
    Hier der Quellcode meines Bsp:

    Spoiler anzeigen
    [autoit]

    #include-once
    #include <GuiConstantsEx.au3>
    #include <Array.au3>
    #include <INet.au3>
    #include <Constants.au3>
    #include <WindowsConstants.au3>
    #include <StaticConstants.au3>
    #include <GDIPlus.au3>
    #include <WinAPI.au3>
    #include <Zip.au3>

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

    Opt('MustDeclareVars', 1) ; 1 = Variables must be pre-declared

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

    Global $SC_Width = 800
    Global $SC_Height = 566
    Global $SC_Titlebar_Height =26
    Global $SC_Footer_Height =26
    _GDIPlus_Startup()

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

    Global $h_SC = GUICreate('', $SC_Width, 566, -1, -1, $WS_POPUP)
    Global $Title = GUICtrlCreatePic('', 0, 0, $SC_Width, $SC_Titlebar_Height, BitOR($SS_NOTIFY, $WS_CLIPCHILDREN, $WS_GROUP, $WS_CLIPSIBLINGS), BitOR($WS_EX_LAYERED, $GUI_WS_EX_PARENTDRAG))

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

    ;==================
    ;Hier soll nun das Bild in die Titelzeile hinein
    ;Dabei soll das Bild gestreckt werden auf die Gesamtbreite der GUI.
    ;allerdings soll zur Skalierung nur ein Teil des PNG genommen werden
    _GUICtrlStatic_SetPictureFrame('Title.png', $Title) ;<======= hier habe ich die Probleme

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

    ;Ab hier weiter das Beispiel von Greenhorn
    Global $WndMin = GUICtrlCreatePic('min0.bmp', $SC_Width-26-43, 0, 26, 17, BitOR($SS_NOTIFY, $WS_GROUP, $WS_CLIPSIBLINGS))
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetTip(-1, 'Minimieren')

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

    Global $WndClose = GUICtrlCreatePic('close0.bmp', $SC_Width-43, 0, 43, 17, BitOR($SS_NOTIFY, $WS_GROUP, $WS_CLIPSIBLINGS))
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetTip(-1, 'Schliessen')

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

    Global $btnBeenden = GUICtrlCreatePic('BtnStpD.bmp', $SC_Width-80, $SC_Height-27, 80, 27, BitOR($SS_NOTIFY, $WS_GROUP, $WS_CLIPSIBLINGS))
    GUICtrlSetState(-1, $GUI_ONTOP)
    GUICtrlSetTip(-1, 'Programm beenden')

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

    GUISetState()

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

    While 1

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

    Switch GUIGetMsg()

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

    Case $WndClose
    Exit
    Case $btnBeenden
    Exit
    EndSwitch

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

    _PicButtonFromFile($h_SC, $WndMin, 'min0.bmp', 'min1.bmp', 'min2.bmp', 'Minimize')
    _PicButtonFromFile($h_SC, $WndClose, 'close0.bmp', 'close1.bmp', 'close2.bmp', 'Terminate')
    _PicButtonFromFile($h_SC, $btnBeenden, 'BtnStpD.bmp', 'BtnStpH.bmp', 'BtnStpH.bmp', 'Terminate')

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

    WEnd

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

    Func Minimize()

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

    GUISetState(@SW_MINIMIZE)

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

    EndFunc

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

    Func Terminate()
    _GDIPlus_ShutDown ()
    Exit

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

    EndFunc

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

    Func _PicButtonFromFile($myhWnd, $controlID, $defaultPic, $onHooverPic, $onClickPic, $Function = '', $parameters = '')

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

    Local $resFunc, $cMsg
    If $onClickPic = '' Or $onClickPic = -1 Then $onClickPic = $onHooverPic
    $cMsg = GUIGetCursorInfo($myhWnd)
    If $cMsg[4] = $controlID Then
    GUICtrlSetImage($controlID, $onHooverPic)
    $cMsg = GUIGetCursorInfo($myhWnd)
    While $cMsg[4] = $controlID
    If GUIGetMsg() = $controlID Then
    GUICtrlSetImage($controlID, $onClickPic)
    $resFunc = Execute($Function & '(' & $parameters & ')') ; auf klick Funktion ausführen.
    EndIf
    Sleep(10)
    $cMsg = GUIGetCursorInfo($myhWnd)
    WEnd
    GUICtrlSetImage($controlID, $defaultPic)
    Return $resFunc
    EndIf

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

    EndFunc ;==>_PicButtonFromFile

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

    Func _GUICtrlStatic_SetPictureFrame($File, $CtrlId)
    ;~ msgbox(0,"",$File)
    local $h_Image = _GDIPlus_ImageLoadFromFile($File)
    local $hScrDC = _WinAPI_GetDC(0)
    local $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    local $iWidth = _GDIPlus_ImageGetWidth ($h_Image)/2
    ;Es soll nur ein Teil des PNG genommen werden zum Strecken/Darstellen; Hier der Einfachheit halber die Hälfte

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

    local $iHeight = _GDIPlus_ImageGetHeight ($h_Image)
    local $h_Bitmap = _GDIPlus_BitmapCloneArea($h_Image, 0, 0, $iWidth, $iHeight)
    $h_Bitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($h_Bitmap)

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

    _GDIPlus_ImageDispose ($h_Image)

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

    GUICtrlSetImage($CtrlId, "")
    _SetBitmapToCtrl($CtrlId, $h_Bitmap)
    _WinAPI_DeleteObject ($h_Bitmap)

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

    ; Das hier scheint nicht zu funktionieren :( das ist mein momentaner Ansatz zum Skalieren des Bildes
    ControlMove (WinGetTitle( $h_SC), "", $CtrlId, Default, Default, $SC_Width, $SC_Height)

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

    EndFunc

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

    Func _SetBitmapToCtrl($CtrlId, $hBitmap) ; <== Diese Funktion habe ich aus einem anderen Bsp. kopiert. Sie hilft beim übertragen des PNG-Images in das Control
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0
    Local Const $SS_BITMAP = 0xE
    Local Const $GWL_STYLE = -16

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

    Local $hWnd = GUICtrlGetHandle($CtrlId)
    If $hWnd = 0 Then Return SetError(1, 0, 0)

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

    ; set SS_BITMAP style to control
    Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE)
    If @error Then Return SetError(2, 0, 0)
    DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP))
    If @error Then Return SetError(3, 0, 0)

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

    Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
    If @error Then Return SetError(4, 0, 0)
    If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0])
    Return 1
    EndFunc

    [/autoit]

    Kann mir jemand Hilfestellung geben?
    Danke im Voraus sagt

    JStaxton

    Edit1: Hallo, ich habe gerede festgestellt, dass man der GUI einen Namen geben muss! Sonst findet die Funktion WinGetTitle( $h_SC) kein Fenster! So scheint es zu funktionieren.

    2 Mal editiert, zuletzt von JStaxton (22. November 2009 um 17:51)

  • Hallo liebe Community,

    Wie im edit beschrieben scheint es mit dem Move-Befehl jetzt zu klappen!
    Trotzdem frage ich mich ob das eine gute Lösung ist, oder einfach "von-hinten-durch-die-Brust-ins-Auge".


    Danke für euer Interesse! (Man sieht ja, dass Leute das File heruntergeladen haben)
    JStaxton