GDI+, gezeichnetes löschen

  • Hey hey,

    ich wollte mich mal bischen mit GDI+ beschäftigen aber fand zu meinem problem keine lösung. undzwar sollte es so aussehen:
    von einem bestimmten punkt aus, wird eine linie in richtung der maus gezogen und wenn sich die maus position ändert, zieht die linie mit.

    problem ist hier, dass die alten schon gezeichneten linien bestehen bleiben und das soll nicht sein.

    hab die gui aus diesem forum übernommen und dann mein teil versucht:

    Spoiler anzeigen

    steuerung: numpad1 drucken (oben links aufn bildschirm) und numpad2 (unten rechts)

    wie gesagt, hab mich eig. nie wirklich mit gdi+ beschäftigt und wollte mal bischen rum testen..
    ich dachte _GDIPlus_GraphicsClear($hBackBuffer) würde reichen, aber leider passiert damit irgentwie nichts...
    wenn ich _WinAPI_RedrawWindow($hGUI) benutze, flackert alles... dazu muss man nen doppelbuffer(?) benutzen, soweit ich gelesen habe..

    da hier im forum sehr viel mit GDI+ gecodet wird, könnt ihr mir sicher helfen.

    MfG

    omer36

  • Rein theoretisch musst du nur in der Farbe 0xFFABCDEF den alten Strich übermalen.

    Das klappt jedoch nicht immer. Wenn ich mich recht erinnere, dann geht das zwar mit FillRect, aber nicht mit FillEllipse oder DrawLine!
    GraphicsClear scheint auch nicht zu funktionieren... so als ob Windows nicht immer 100% die richtige Farbe erwischt ;)

    Probier mal das hier:

    Spoiler anzeigen
    [autoit]

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

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

    HotKeySet("{ESC}", "_Exit")

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

    $iWidth = @DesktopWidth
    $iHeight = @DesktopHeight

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

    _GDIPlus_Startup()

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

    $hGui = GUICreate("", $iWidth, $iHeight, 0, 0, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST, $WS_EX_TRANSPARENT))
    GUISetState()

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

    $aMPos_Old = MouseGetPos()

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

    While Sleep(10)
    $aMPos = MouseGetPos()
    If $aMPos[0] <> $aMPos_Old[0] Or $aMPos[1] <> $aMPos_Old[1] Then
    _UpdateWindow($hGui, $iWidth, $iHeight, $aMPos)
    $aMPos_Old = $aMPos
    EndIf
    WEnd

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

    Func _UpdateWindow($hWnd, $iW, $iH, $aMPos)
    Local $tSize = DllStructCreate("long X;long Y")
    DllStructSetData($tSize, "X", $iW)
    DllStructSetData($tSize, "Y", $iH)

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

    Local $tSource = DllStructCreate("long X;long Y")

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

    Local $tBlendI = DllStructCreate("byte Op;byte Flags;byte Alpha;byte Format")
    DllStructSetData($tBlendI, "Alpha", 0xFF)
    DllStructSetData($tBlendI, "Format", 1)

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

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hWnd)
    Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

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

    $hPen = _GDIPlus_PenCreate(0xFFFF0000, 2)
    _GDIPlus_GraphicsDrawLine($hContext, $iW / 2, $iH / 2, $aMPos[0], $aMPos[1], $hPen)

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

    Local $hDC = _WinAPI_GetDC($hWnd)
    Local $hDCS = _WinAPI_CreateCompatibleDC($hDC)
    Local $hBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    Local $hOrig = _WinAPI_SelectObject($hDCS, $hBmp)

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

    _WinAPI_UpdateLayeredWindow($hWnd, $hDC, 0, DllStructGetPtr($tSize), $hDCS, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlendI), 2)

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

    _GDIPlus_PenDispose($hPen)

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

    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphics)

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

    _WinAPI_SelectObject($hDCS, $hOrig)
    _WinAPI_DeleteObject($hBmp)
    _WinAPI_ReleaseDC($hWnd, $hDC)
    EndFunc ;==>_UpdateWindow

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

    Func _Exit()
    _GDIPlus_Shutdown()
    GUIDelete($hGui)
    Exit
    EndFunc ;==>_Exit

    [/autoit]
  • das scheint ja zu klappen, doch hab trozdem ein problem:
    hab bisher eig nie variablen üeergebende funktionen genutz, darum kann ich das jetz in meins oben einbauen...

    _UpdateWindow($hGui, $iWidth, $iHeight, $aMPos)

    $hGui und $aMPos sollten eig klar sein, aber welche nutz ich jetz als $iWidth und $iHeight?

    dachte mir könnte das sein:
    $iWidth = (($mPosUR[0]-$mPosOL[0])/2)+$mPosOL[0]
    $iHeight = $mPosUR[1]

    aber war es leider nicht... :D

    vllt kannste mir bitte nochma zur hand gehen ^^

  • hmm.. eig wollte ich das ja grade als übung nehmen :p

    hätte jetz nicht gedacht, dass das "löschen" von gezeichneten linien so kompliziert sein würde...


    hättest du vllt einpar vorschläge, womit ich gut für den anfang üben könnte?

  • hätte jetz nicht gedacht, dass das "löschen" von gezeichneten linien so kompliziert sein würde...


    Betrachte GDI+ wie ein Grafikprogramm. Wenn du z.B. in MSPaint ein Foto hast und einen roten Strich drauf malst, wie löschst du diesen, ohne die "Rückgangig" Funktion zu benutzen? ;)

    Nimm für den Anfang keine transparenten Fenster und werde mit den einfachen Zeichenfunktionen (DrawLine, FillRect, DrawImage...) vertraut.
    Dann mach ein paar Versuche mit Backbuffer und RegisterMsg ($WM_PAINT)

    Hier ein gutes Tutorial: Gdi+ Tutorial [Part 5]

    Um GDI+ auf LayeredWindows zu benutzen, bedarf es schon eines gewissen Grundverständnisses und gehört schon eher zum Expertenlevel.
    Deshalb mach mal das Tutorial durch und versuch dich dann an einfachen Spielen wie Pong oder Snake

    E