GDI+ Problem

  • Hey@all
    So es ist so weit, ich lerne endlich mal gdi+ :D . Da ich ja erst damit anfange habe ich ein paar Fragen an euch:
    -welches registermsg fehlt noch? - zeichnet nicht neu nach fenster überlappung
    -zeichnet farbe nicht drüber, sondern "vermischt" mit der vorherigen, wie kann ich das ändern?
    -und sonst pls mal drüber gucken ob das so vormell richtig ist
    -Wie kann man RGB to ARGB konventivern? gibt kein _colorgetalpha() ;(

    Mein Skript:

    Spoiler anzeigen
    [autoit]

    #include <GuiConstantsEx.au3>
    #include <GDIPlus.au3>
    #include <WindowsConstants.au3>
    #include <Array.au3>
    ;#include <Color.au3>
    ;#include <Misc.au3>
    Local $hGUI, $hWnd, $hGraphic, $hBrushDunkel, $hFormat, $hFamily, $hFont, $tLayout, $hPenDunkel, $hPenHell, $hBrushHell, $ZifferFormat[11], $ZifferFont, $hBrushMittel, $hPenMittel
    Local $iWidth=700, $iHeight=500, $WindowWidth=500, $WindowHeight=300, $PenWidth=5, $xy=Round($PenWidth/2,1), $TitelHeight=25, $BigAbstand=5
    GUIRegisterMsg($WM_PAINT, "_ReDraw")
    OnAutoItExitRegister("_Exit")

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

    $hGUI = GUICreate("GDI+", $iWidth, $iHeight)
    GUISetState()
    _GDIPlus_Startup()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    $hFormat = _GDIPlus_StringFormatCreate()
    $hFamily = _GDIPlus_FontFamilyCreate("Arial")
    $hFont = _GDIPlus_FontCreate($hFamily,12,1)
    $tLayout = _GDIPlus_RectFCreate($iWidth/2-$WindowWidth/2+2.5,$iHeight/2-$WindowHeight/2+2.5,$WindowWidth+2.5,20)
    $hPenDunkel=_GDIPlus_PenCreate(0x7F00007F,$PenWidth)
    $hBrushDunkel = _GDIPlus_BrushCreateSolid(0x7F00007F)
    $hPenHell=_GDIPlus_PenCreate(0x5F00005F,$PenWidth)
    $hBrushHell=_GDIPlus_BrushCreateSolid(0x1E00001E)
    $hPenMittel = _GDIPlus_PenCreate(0x2E00002E)
    $hBrushMittel = _GDIPlus_BrushCreateSolid(0x2F00002F)
    $ZifferFont = _GDIPlus_FontCreate($hFamily,25,1)
    _ReDraw()
    While 1
    Switch GUIGetMsg()
    Case $GUI_EVENT_CLOSE
    Exit
    EndSwitch
    WEnd

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

    Func _ReDraw()
    _GDIPlus_GraphicsDrawRect($hGraphic,$xy,$xy,$iWidth-$PenWidth,$iHeight-$PenWidth,$hPenDunkel)
    _GDIPlus_GraphicsFillRect($hGraphic,$xy,$xy,$iWidth-$PenWidth,$iHeight-$PenWidth,$hBrushHell)
    _GDIPlus_GraphicsDrawRect($hGraphic,$iWidth/2-$WindowWidth/2,$iHeight/2-$WindowHeight/2,$WindowWidth,$TitelHeight,$hPenDunkel)
    _GDIPlus_GraphicsFillRect($hGraphic,$iWidth/2-$WindowWidth/2,$iHeight/2-$WindowHeight/2,$WindowWidth,$TitelHeight,$hBrushMittel)
    _GDIPlus_GraphicsDrawStringEx($hGraphic, "Bitte Code eingeben zum entsperren des Fensters", $hFont, $tLayout, $hFormat, $hBrushDunkel)
    _GDIPlus_GraphicsDrawRect($hGraphic,$iWidth/2-$WindowWidth/2,$iHeight/2-$WindowHeight/2+$TitelHeight,$WindowWidth,$WindowHeight-$TitelHeight,$hPenDunkel)
    _GDIPlus_GraphicsFillRect($hGraphic,$iWidth/2-$WindowWidth/2,$iHeight/2-$WindowHeight/2+$TitelHeight,$WindowWidth,$WindowHeight-$TitelHeight,$hBrushMittel)
    $e=0
    For $i=0 To 10
    $extra=0
    $txt=$i
    $Plus=$BigAbstand*2+50
    $x=$iWidth/2-$WindowWidth/2+$BigAbstand+$PenWidth+$Plus
    $y=$iHeight/2-$WindowHeight/2+$BigAbstand+$PenWidth+$TitelHeight
    If $x-$Plus+$Plus*$i+50>$iWidth/2-$WindowWidth/2+$WindowWidth Then
    $x=$x-$Plus+$Plus*$e
    $e=$e+1
    $y=$y+50+$BigAbstand*2
    Else
    If $e<>0 Then
    $x=$x-$Plus+$Plus*$e
    $y=$y+50+$BigAbstand*2
    Else
    $x=$x-$Plus+$Plus*$i
    EndIf
    EndIf
    _GDIPlus_GraphicsDrawRect($hGraphic,$x,$y,50,50,$hPenDunkel)
    _GDIPlus_GraphicsFillRect($hGraphic,$x,$y,50,50,$hBrushHell)
    If $i=10 Then
    $txt="OK"
    $extra=$BigAbstand*3
    EndIf
    $ZifferFormat[$i]=_GDIPlus_RectFCreate($x+$BigAbstand+$PenWidth-$extra,$y+$BigAbstand-2+$PenWidth)
    _GDIPlus_GraphicsDrawStringEX($hGraphic, $txt, $ZifferFont, $ZifferFormat[$i], $hFormat, $hBrushDunkel)
    Next
    EndFunc

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

    Func _Exit()
    _GDIPlus_FontDispose($hFont)
    _GDIPlus_FontFamilyDispose($hFamily)
    _GDIPlus_StringFormatDispose($hFormat)
    For $i=0 To 9
    _GDIPlus_StringFormatDispose($ZifferFormat[$i])
    Next
    _GDIPlus_BrushDispose($hBrushDunkel)
    _GDIPlus_BrushDispose($hBrushMittel)
    _GDIPlus_BrushDispose($hBrushHell)
    _GDIPlus_PenDispose($hPenDunkel)
    _GDIPlus_PenDispose($hPenMittel)
    _GDIPlus_PenDispose($hPenHell)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()
    EndFunc

    [/autoit]


    (Skript ist noch nicht fertig)
    MfG AntiSpeed

    Nur keine Hektik - das Leben ist stressig genug

  • welches registermsg fehlt noch? - zeichnet nicht neu nach fenster überlappung


    Einfach eine While Schleife die immer zeichnet fertig

    -zeichnet farbe nicht drüber, sondern "vermischt" mit der vorherigen, wie kann ich das ändern?


    Wenn mann den Alpha Wert auf FF ( 255) setzt dann hats volle deckkraft

    -Wie kann man RGB to ARGB konventivern? gibt kein _colorgetalpha() ;(


    Der Hex Wert besteht bei 6 Stellen aus
    Hexwert für Rotanteile der Farbe dann Hexwert für Grünanteile und dann Hexwert für Blauanteile

    um das zu 'konvertieren' brauchst du nur ein FF voranstellen d.h. aus 0xEA8877 wird 0xFFEA8877

    PS: die Hex Tabelle lässt sich ganz einfach ermitteln
    führe mal fogenden Code aus

    [autoit]

    For $x = 0 To 255 Step 5
    ConsoleWrite($x & " ist: " & Hex($x, 2) & @TAB & $x + 1 & " ist: " & Hex($x + 1, 2) & @TAB & $x + 3 & " ist: " & Hex($x + 3, 2) _
    & @TAB & $x + 4 & " ist: " & Hex($x + 4, 2) & @TAB & $x + 5 & " ist: " & Hex($x + 5, 2) & @CRLF)
    If $x = 255 Then ExitLoop
    Next

    [/autoit]
  • 1. Das Problem hatte ich bei meinem Minigame auch, ich hab es so gemacht (in die Hauptschleife einfügen):

    [autoit]

    If NOT WinActive("FENSTERNAME") Then
    Do
    sleep(100)
    Until WinActive("FENSTERNAME")
    ;zeichne neu
    EndIf

    [/autoit]

    2. Entweder keine Transparenz nehmen (0xFF) oder alles neu zeichnen/ein Rechteck in der Hintergrundfarbe malen
    4. Das löse ich so:

    [autoit]

    $rgb = _ChooseColor(2)
    $0x = StringLeft($rgb, 2)
    $rgb = StringRight($rgb, 6)
    $argb = $0x & "FF" & $rgb

    [/autoit]
  • -welches registermsg fehlt noch? - zeichnet nicht neu nach fenster überlappung


    Bei mir schon

    -zeichnet farbe nicht drüber, sondern "vermischt" mit der vorherigen, wie kann ich das ändern?

    [autoit]

    _GDIPlus_GraphicsClear($hGraphic,0xFFF0F0F0)

    [/autoit]


    in Zeile 36


    -und sonst pls mal drüber gucken ob das so vormell richtig ist


    Also ich würd mit nem Backbuffer arbeiten, dann sollte es nicht so stark flackern.

    -Wie kann man RGB to ARGB konventivern? gibt kein _colorgetalpha() ;([/quote]
    Im Normalfall ist die Transparenz 255, also FF. RGB (0x00FF00 - Grün) -> ARGB (0xFF00FF00) wäre dann

    [autoit]

    $iARGB = 0xFF000000 + 0x00FF00

    [/autoit]
  • Danke für die Antworten.
    Jetzt funktioniert alles, aber noch eine Frage:

    Zitat

    Also ich würd mit nem Backbuffer arbeiten, dann sollte es nicht so stark flackern.


    Wie geht das? (Nur kurz 1,2 befehle). Bei mir flackerts überhaupt net 8| why das? (ist mein pc etwa zu schnell ^^ )

    Nur keine Hektik - das Leben ist stressig genug

  • [autoit]

    $hGraphics=_GDIPlus_GraphicsCreateFromHWND($hGUI) ; Graphicobjekt von der GUI erstellen
    $hBitmap=_GDIPlus_BitmapCreateFromGraphics(500, 500, $hGraphics) ; Bitmap vom Grafikobjekt erstellen
    $hBuffer=_GDIPlus_ImageGetGraphicsContext($hBitmap) ; Context erstellen, wodrauf gemalt wird
    ; Sachen, die auf den Buffer gemalt werden sollen
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, "WIDTH", "HEIGHT") ; Buffer auf das Grafikobjekt malen
    _GDIPlus_GraphicsClear($hBuffer, "0xFFFFFFFF") ; Du musst nur den Buffer cleanen, nicht das Grafikobjekt !
    ; Und zu guter letzt wieder alles disposen
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_GraphicsDispose($hBuffer)
    _GDIPlus_BitmapDispose($hBitmap)

    [/autoit]
  • Ich verwende immer diese zwei:

    [autoit]

    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND")

    [/autoit][autoit]

    Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return $GUI_RUNDEFMSG
    EndFunc ;==>WM_PAINT

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

    Func WM_ERASEBKGND($hWnd, $uMsgm, $wParam, $lParam)
    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    Return True
    EndFunc ;==>WM_ERASEBKGND

    [/autoit]

    wobei ich mir nicht mal sicher bin, welche der beiden wann zum Einsatz kommt ;)

    mfgE