GDI+ Anfängerfragen

  • Hallo zusammen,

    leider muss ich euch in nächster Zeit ein wenig nerven! ;(
    Ich muss mich doch ein "wenig" mit GDI+ befassen und stoße da recht schnell auf Probleme, die aus meinem Unwissen resultieren.
    Naja ich fang mal an...

    1. Folgendes Beispiel Skript erstellt eine einfache GUI und schreibt einen Text darauf. So weit so gut, nur wie lösche ich den wieder??
    Das standardmäßige Übermalen geht nicht, da der Hintergrund später ein Bild ist. Muss man da alles komplett neu zeichnen (also mit Bild usw.) oder geht das auch nur für den einen String??

    Spoiler anzeigen

    Wahrscheinlich kein Ding für euch...

    THX

    Gruß
    Balti

    • Offizieller Beitrag

    Man verwendet einen Buffer! Den löscht man, dann zeichnet man alles hinein (erst den Hintergrund, dann den Text) und anschließend zeichnet man den Buffer auf die Gui-Graphic.
    Hier mal ein Beispiel:

  • Sry das ich mich erst so spät melde... RL....

    @Oscar
    THX, das reicht mir schon so. Das mit dem Buffer vergess ich immer wieder (mal gelesen vor einiger Zeit) und hätte es, auch wenn ich dran gedacht hätte, nicht alleine hinbekommen.
    Dank Dir

    Ich lass mal noch offen, da da garantiert noch was kommt.

  • So, da hab ich schon wieder ein kleines Problem. Hab mich durch die Hilfe gelesen, bekomme es aber nicht hin.
    Ich möchte das nur ein Teil der GUI neu gezeichnet wird. Im Moment versuche ich es so:

    Spoiler anzeigen
    AutoIt
    $g_tRECT = DllStructCreate($tagRect)
    DllStructSetData($g_tRECT, "Left", 0)
    DllStructSetData($g_tRECT, "Top", 0)
    DllStructSetData($g_tRECT, "Right", 50)
    DllStructSetData($g_tRECT, "Bottom", 50)
    
    
    _WinAPI_RedrawWindow($hGui, $tagRect, 0, $RDW_VALIDATE + $RDW_ALLCHILDREN)


    Leider wird aber immernoch die ganze GUI neu gezeichnet.
    Also wieder: Was mache ich falsch?

  • Bist du dir sicher, dass es das ist, was du willst? Mit RedrawWindow sendest du WM_PAINT an das Fenster. Verarbeitest du irgendwo in deinem Skript diese Nachricht (GuiRegisterMsg)? Wenn nicht, dann bist du auf dem Holzweg. Wenn du einfach nur einen bestimmten (bemalten) Bereich der GUI neuzeichnen willst, sodass der Rest unberührt bleibt... Dann würde ich auf einem entsprechend positioniertem Child-Window zeichnen.

    Edit:
    Ich hab mal kurz ein Beispiel geschrieben:

    [autoit]


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

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

    $hMainWnd = GUICreate("Test", 600, 400)
    $cLabel = GUICtrlCreateLabel("Dieser Text bleibt unberührt!", 0, 0)
    $hGraphicsWnd = GUICreate("", 100, 100, 100, 100, $WS_POPUP, $WS_EX_MDICHILD, $hMainWnd)
    GUISetState(@SW_SHOW, $hGraphicsWnd)
    GUISetState(@SW_SHOW, $hMainWnd)

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

    _GDIPlus_Startup()
    $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGraphicsWnd)
    $hBmp = _GDIPlus_BitmapCreateFromGraphics(600, 400, $hGfx)
    $hBuf = _GDIPlus_ImageGetGraphicsContext($hBmp)

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

    While True
    Switch GUIGetMsg()
    Case -3
    Exit
    EndSwitch

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

    _GDIPlus_GraphicsClear($hBuf, 0xffffffff)
    _GDIPlus_GraphicsFillEllipse($hBuf, 0, 0, 100, 100)
    _GDIPlus_GraphicsDrawImage($hGfx, $hBmp, 0, 0)
    WEnd

    [/autoit]
  • @chesstiger

    Die Child GUI ist die Lösung!! Danke, bin ich einfach nicht drauf gekommen. Funktioniert perfekt. THX

    P.S.: Nicht ganz. Nun flackert das _IECreateEmbedded() jedesmal wenn ich es ansteuere...Das ist in der $hMainWnd erstellt

    Einmal editiert, zuletzt von MrB (9. November 2015 um 19:37)

  • Gut, wenn das IE-Control das nicht verträgt... Dann kannst du auch das Graphics von $hMainWnd als Zeichenfläche verwenden und alle Koordinaten umrechnen. Dann darfst du aber nicht GraphicsClear verwenden. Du musst mit GraphicsFillRect überzeichnen. Und du musst im definierten Bereich bleiben. Ist ein bisschen tricky.

  • Sry das ich mich erst so spät wieder melde. Viel um die Ohren gehabt.

    Du musst mit GraphicsFillRect überzeichnen.

    Da hab ich ein Verständnisproblem. Ich hab ja ein Bild als Hintergrund, also wie überzeichne ich das dann? Hmm, irgendwie bekam man doch auch transparente GUIs hin. Wäre auch noch ne Alternative. Mal suchenn....

  • Du verwendest einfach _GDIPlus_GraphicsDrawImageRectRect() um einen best. Teil deines Bildes auf einen best. Teil des Buffers zu zeichnen.

    Edit: Was du probieren könntest ist den Bildauschnitt auf dem dein IE liegt "auzuschneiden".
    Also den Alpha-Channel der Pixel auf 0 setzen und dann das Bild komplett zu zeichnen.

    Einmal editiert, zuletzt von CentuCore (11. November 2015 um 21:54)