_GDIPlus: Graphic wieder leeren?

  • hi :)
    Ich habe eine Frage zu GDI+. Ich habe versucht eine Uhr zu bauen mit den _GDIPlus_Graphics... Funktionen. Den Zeiger zu zeichnen ist kein Problem nur wie bekomm ich ihn wieder weg um einen neuen zu zeichnen der etwas weiter ist? Bei _GDIPlus_GraphicsClear wird das Bild einfach nur schwarz bzw. eine andere Farbe, jenachdem was ich eingebe. Jedenfalls wollte ich den Ausgangszustand meines Bildes wiederherstellen wie er war bevor ich den ersten Zeiger gezeichnet habe.
    Das ist mein Code:

    Spoiler anzeigen
    [autoit]

    #include <GDIPlus.au3>
    #include <GUIConstantsEx.au3>
    #include <StructureConstants.au3>
    #include <WinAPI.au3>
    #include <WindowsConstants.au3>

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

    Global Const $AC_SRC_ALPHA = 1
    ;~ Global Const $ULW_ALPHA = 2

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

    _GDIPlus_Startup()
    $pngSrc = @ScriptDir & "\uhr.png"
    $hImage = _GDIPlus_ImageLoadFromFile($pngSrc)
    $width = _GDIPlus_ImageGetWidth($hImage)
    $height = _GDIPlus_ImageGetHeight($hImage)

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

    $GUI = GUICreate("Uhr", $width, $height, -1, -1, $WS_POPUP, $WS_EX_LAYERED) ;Alles um eine durchsichtige PNG Datei als Hintergrund zu nehmen
    SetBitmap($GUI, $hImage, 0)
    GUIRegisterMsg($WM_NCHITTEST, "WM_NCHITTEST")
    GUISetState()
    WinSetOnTop($GUI, "", 1)
    For $i = 0 To 255 Step 10
    SetBitmap($GUI, $hImage, $i)
    Next

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

    $controlGui = GUICreate("ControlGUI", $width, $height, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $GUI)
    GUICtrlCreatePic(@ScriptDir & "\grey.gif", 0, 0, $width, $height)
    GUICtrlSetState(-1, $GUI_DISABLE)
    GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT)
    GUICtrlSetColor(-1, 0xFFFFFF)
    GUISetState()
    $gr = _GDIPlus_GraphicsCreateFromHWND($controlGui)
    $whitebrush = _GDIPlus_BrushCreateSolid(0xFFFFFFFF)
    $redbrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
    $emptybrush = _GDIPlus_BrushCreateSolid(0x00FFFFFF)
    _GDIPlus_GraphicsFillEllipse($gr, 95, 95, 10, 10, $whitebrush)
    $count = 0
    While 1
    _GDIPlus_GraphicsClear($gr, 0x00FFFFFF)
    _GDIPlus_GraphicsFillEllipse($gr, 95, 95, 10, 10, $whitebrush)
    _GDIPlus_GraphicsFillPie($gr, 0, 0, 200, 200, $count , 5, $redbrush)
    sleep(100)
    $count += 1 ;Nur zum test, änder ich natürlich später noch
    WEnd

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

    GUIDelete($controlGui)
    For $i = 255 To 0 Step -10
    SetBitmap($GUI, $hImage, $i)
    Next
    _GDIPlus_GraphicsDispose($gr)
    _WinAPI_DeleteObject($hImage)
    _GDIPlus_Shutdown()

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

    Func WM_NCHITTEST($hWnd, $iMsg, $iwParam, $ilParam)
    If ($hWnd = $GUI) And ($iMsg = $WM_NCHITTEST) Then Return $HTCAPTION
    EndFunc ;==>WM_NCHITTEST

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

    Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend

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

    $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", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 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]

    Danke schonmal :)


    Edit: Problem gelöst. Neues Problem steht weiter unten.

    3 Mal editiert, zuletzt von Carsten8 (1. März 2009 um 12:24)

  • So nächstes Problem. Ich wollte das ganze jetzt etwas verschönern indem ich grafiken verwende. Die wollte ich jetzt mit den Matrix Funktionen drehen, was aber nicht so geht wie es soll.
    Bei Microsoft hab ich jetzt das gefunden: http://msdn.microsoft.com/de-de/library/awacs0xh.aspx

    Das RotateAt wäre genau das was ich bräuchte, allerdings gibts sowas scheinbar nicht in AutoIt.
    Lässt es sich irgendwie anders realisieren ein Bild um einen bestimmten Punkt zu drehen?

    Lg
    Carsten

  • Bei den .NET Klassen wird warscheinlich der Winkel gespeichert und dann die Differenz berechent und dann gedreht... So kannst du es jedenfalls machen.

    [autoit]

    $Alter_Winkel=0

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

    Func _DreheZu($Mtrix, $Winkel)
    $zuDrehen = $Alter_Winkel+$Winkel
    _GDUiPLus_Rotate(...)
    If $Erfolg Then
    $Alter_Winkel = $Winkel
    Return 1
    EndIf
    Return 0
    EndFunc

    [/autoit]
  • ich weiß nicht ob du mich richtig verstanden hast. Ich meine, wie ich die Grafik um einen bestimmten Punkt (z.B. die Mitte) drehen kann. Denn einfach matrixrotate dreht die ganze Grafik um die linke obere ecke. Das ist bei meiner Uhr schwachsinnig.

  • versuch mal, ein tranlate zu verwenden ;)
    _GDIPlus_MatrixTranslate(...)
    entweder vor oder nach der Rotation, dabei X, Y auf den Mittelpunkt setzen ;)