GDI+ Buffer auf Transparenter GUI

  • Moin (und sorry für den "Walloftext"...hab gar nicht gemerkt wie viel ich da geschrieben habe ^^)

    Wie vieleicht einige von euch mitbekommen haben, bin ich neben Programmierforen auch aktiv in einem Entwicklerforum für CryEngine-Games aktiv.
    So als Zwischenarbeit (weil ich Momentan weder dort noch hier ein Projekt effektiv am Laufen habe) habe ich mal wieder eine frühere Idee aufgegriffen.
    Eigentlich wollte ich das ganze ohne "fremde" Hilfe hinkriegen, aber da ich sowieso schon im ersten Schritt dagegen verstossen musste macht es jetzt eh keinen Unterschied mehr ;)
    Folgendes ist geplant:
    Das Programm ersetzt die Taskleiste komplett, in einem späteren Schritt vieleicht auch noch explorer und einige wichtige Programme, aber das tut aktuell noch nichts zur Sache.
    Das ganze ist nicht Performancefixiert, ich versuche natürlich trotzdem das ganze auf einem emöglichst niedrigen Level zu halten, allerdings ist das bloss 2. Rangig.
    Ausserdem wird das Skript auf Developer-PC's (überwiegend high-end hardware) laufen welche damit ja sowieso kaum Probleme haben werden.
    Im Vordergrund steht das Design, quasi mehr ein Skript um etwas zu "protzen" :D . Ich bin ja allgemein ein Liebhaber von schön gestalteten Oberflächen, quasi ein "Design-Fachmann" ( :whistling: ).

    Also hier mein aktueller Code (um es zum Laufen zu bringen, müsst ihr dann aber natürlich die angehängte Datei herunterladen):

    Spoiler anzeigen
    [autoit]

    ;Includeblock
    #include <GuiConstants.au3>
    #include <GdiPlus.au3>
    #include <WindowsConstants.au3>

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

    ;Variablendeklarationsblock
    $StartCoords1 = 0
    $StartCoords2 = -35
    $HexPerLine1 = (Round(@DesktopWidth / 50, 0)) * 50
    $HexPerLine2 = (Round(@DesktopWidth / 50, 0) + 1) * 50

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

    ;Programmstart (Abschlussbedingungen, GUI erstellen etc.)
    OnAutoItExitRegister("_end")
    $Gui = GUICreate("", @DesktopWidth, 91, 0, @DesktopHeight - 91, BitOR($WS_SYSMENU,$WS_POPUP), BitOR($WS_EX_TOPMOST,$WS_EX_WINDOWEDGE,$WS_EX_LAYERED))
    GUISetBkColor(0xABCDEF)
    _WinAPI_SetLayeredWindowAttributes($Gui, 0xABCDEF, 255)
    GUISetState(@SW_SHOW)

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

    ;GDI+ starten, Bilder laden
    _GDIPlus_Startup()
    $hGraphics = _GDIPlus_GraphicsCreateFromHWND($Gui)
    $hHexagon = _GDIPlus_ImageLoadFromFile(@ScriptDir &"\Images\hexagon.png")
    $hHome = _GDIPlus_ImageLoadFromFile(@ScriptDir &"\Images\home.png")
    _GDIPlus_SetInterpolationMode($hGraphics, 2)

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

    ;1. Ebene Hex-Muster zeichnen (beginnt unten)
    For $i = $StartCoords1 To $HexPerLine1 Step 70
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hHexagon, $i, 66, 50, 50)
    Sleep(10)
    Next

    ;2. Ebene Hex-Muster
    For $j = $StartCoords2 To $HexPerLine2 Step 70
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hHexagon, $j, 45, 50, 50)
    Sleep(10)
    Next

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

    ;Startmenu öffnen
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hHome, 2, 27, 47, 47)

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

    ;Quickstart Icons (gibts halt noch keine)
    ;~ _GDIPlus_GraphicsDrawImageRect($hGraphics, $hIconXXX, 5, 77, 40, 40)

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

    ;Hauptschleife, hier besteht eigentlich mein eigentliches Problem
    While 1
    $yCoords = MouseGetPos(1)
    $xCoords = MouseGetPos(0)
    If $yCoords >= @DesktopHeight - 91 And $yCoords <= @DesktopHeight - 21 Then
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hHome, 2, 10, 47, 47)
    Else
    _GDIPlus_GraphicsDrawImageRect($hGraphics, $hHome, 2, 27, 47, 47)
    EndIf
    WEnd

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

    ;Exit-Funktion
    Func _end()
    _GDIPlus_GraphicsDispose($hGraphics) ;Grafik Objekt freigeben
    _GDIPlus_ImageDispose($hHexagon) ;Bild Objekt freigeben
    _GDIPlus_Shutdown() ;Ressourcen freigeben
    EndFunc

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

    ;Damit werden die Kanten der Hexagons geglättet
    Func _GDIPlus_SetInterpolationMode($hGFX, $iMode)
    DllCall($ghGDIPDll, 'uint', 'GdipSetInterpolationMode', 'hwnd', $hGFX, 'int', $iMode)
    EndFunc

    [/autoit]

    Aus Sicherheitsgründen hab ich jetzt die 2 Zeilen weggelassen, in denen die Originale Taskleiste ausgeblendet wird, ich will hier betonen dass das Programm nicht ansatzweise Schaden zufügen soll, es wird grundsätzlich nicht mal etwas zusätzliches installiert und sobald das Skript beendet wird, bleiben keine Rückstände und die Taskleiste wird dann im Original auch wieder eingeblendet. Ich schreibe das, weil ich mich meiner Meinung nach durch das Verstecken der Taskleiste in eine Grauzone bewegen würde und ich will mir unnötige Warnungen etc. ersparen.
    So nun aber zu meinem Problem. Wer das Skript mal startet wird es relativ schnell bemerken. Alles ist per GDI+ auf eine Transparente GUI gezeichnet. Das Home-Icon hat zudem einen Hover-Effekt da ich allerdings eine Transparente GUI habe und dadurch nicht mit einem Backbuffer arbeiten kann (so wie ich das verstanden habe ein Rect für den kompletten Hintergrund der alles gezeichnete übermalt), bleibt das "ungehoverte" Bild ebenfalls bestehen was natürlich nicht wirklich schön aussieht. Vieleicht bin ich gerade nicht so "fantasievoll", das kann ja nicht so schwer sein? Trotzdem bin ich völlig ratlos und wäre froh, wenn mit jemand ne kleine (gerne auch ne grössere) Denkstütze geben könnte.

    lg Gene


    PS: Ich hab noch den kompletten ISN-Projektordner angehängt, es sind allerdings nur die beiden Bildchen im Ordner "Images" die ihr braucht.

  • Zitat

    da ich allerdings eine Transparente GUI habe und dadurch nicht mit einem Backbuffer arbeiten kann


    Da liegst du falsch. ;) Ich hab im Moment leider keine Zeit dir dein Script umzuschreiben o.Ä., aber ich kann dir Beispiele anbieten.
    Davon wurden hier nämlich schon einige gepostet, die zeigen wie man mit GDI+ auf eine transparente GUI zeichnen kann (auch mit Alpha Blending). Ob du einen Buffer verwendest oder nicht wirkt sich nicht auf das Verhalten aus das du beschreibst. Aber bei diesen Scripten funktioniert es.

    Ein Beispiel von vielen.

  • Hmm...also ich habs jetzt eine Weile versucht. Leider bin ich Punkto DLL's leider absolut unbelehrbar. Ich verstehe also niacht mal die Hälfte deines Beispiels (sorry ^^).
    Aufgrund dessen ist es für mich also praktisch unmöglich, den Codefluss zu verfolgen :S
    Dass es nichts mit dem Buffer zu tun hat ist aber eg. einleuchtend :whistling:

    Bild1: Ich beim debuggen

    Einmal editiert, zuletzt von General Kaboom (26. März 2013 um 10:11)