GDI+ unterschiedliche Icon-Transparenz

    • Offizieller Beitrag

    Ich bräuchte mal Hilfe von den GDI+ Profis.
    Und zwar geht es um dieses Skript-Beispiel (Icon im Anhang):

    Spoiler anzeigen
    [autoit]


    #include <GDIPlus.au3>
    _GDIPlus_Startup()
    $hIcon = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\item11.ico')
    $hGui = GUICreate('Test', 250, 200)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics(250, 200, $hGraphic)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    GUISetState()
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hIcon, 50, 50, 128, 128)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    Do
    Until GUIGetMsg() = -3
    _GDIPlus_ImageDispose($hIcon)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

    [/autoit]

    Wenn ich das unter Windows7 ausführe, dann erhalte ich das hier (gewünscht):
    autoit.de/wcf/attachment/11339/

    Unter WindowsXP hingegen bekomme ich das zu sehen (unerwünscht):
    autoit.de/wcf/attachment/11340/

    Sieht für mich wie eine fehlerhafte Transparenz aus.
    Frage ist nun: Gibt es eine Möglichkeit, dass das auch unter WindowsXP richtig aussieht?

  • Ich dachte immer das jpg-Bilder nur 100% Transparens speichen können, also keine Semitransparens. ^^
    Naja, soweit ich weiß funktionieren PNG Bilder korrekt unter WinXP. Du könntest das Bild einfach als .png-Format speichern und verwenden! :D

    War zu dumm zu lesen, sorry! :pinch:

  • Ich bin gerade auf folgenden Thread gestoßen: [ offen ] Icon aus *.exe auslesen und mit GDI+ auf die GUI zeichnen

    Zitat von UEZ

    Das funzt leider mit GDI+ nur begrenzt, sprich volle Transparenz wird leider nicht unterstützt! -> _GUICtrlMenu_CreateBitmap() v0.5 Build 2010-06-12 - Erstellt Icons für GUI Menüs


    Jedoch funktioniert folgendes Script:

    Spoiler anzeigen
    [autoit]

    #include <WinAPI.au3>

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

    $hIcon = _WinAPI_PrivateExtractIcon(@ScriptDir & '\item11.ico', 0, 256, 256)

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

    $hGui = GUICreate("Test", 256, 256)

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

    GUISetState()

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

    $hDC = _WinAPI_GetDC($hGui)

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

    _WinAPI_DrawIconEx($hDC, 0, 0, $hIcon, 256, 256)

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

    While GUIGetMsg() <> -3
    Sleep(20)
    WEnd

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

    _WinAPI_DestroyIcon($hIcon)

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

    Func _WinAPI_PrivateExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)

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

    Local $hIcon, $tIcon = DllStructCreate('hwnd'), $tID = DllStructCreate('hwnd')
    Local $Ret = DllCall('user32.dll', 'int', 'PrivateExtractIcons', 'str', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr', DllStructGetPtr($tIcon), 'ptr', DllStructGetPtr($tID), 'int', 1, 'int', 0)

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

    If (@error) Or ($Ret[0] = 0) Then
    Return SetError(1, 0, 0)
    EndIf
    $hIcon = DllStructGetData($tIcon, 1)
    If ($hIcon = Ptr(0)) Or (Not IsPtr($hIcon)) Then
    Return SetError(1, 0, 0)
    EndIf
    Return $hIcon
    EndFunc ;==>_WinAPI_PrivateExtractIcon

    [/autoit]
  • Muss das Bild unbeldingt als Icon gespeichert werden? Ich mein es gibt doch genügend andere Formate, mit dennen das besser geht :D

  • Du hättest dem Bild nen Weßen Bg geben können und den GUI auch , wäre auch ne lösung

    Meine Projekte :

    Taschenrechner [X]
    JamLegend Auto-Player [Canceld]
    Launcher [X]
    Multi-Game-Quest-Viewer [Canceld]


    [autoit]

    If $goffy or not $brain Then $DeleteInetCable

    [/autoit]
  • Ich hab nun endlich eine Lösung für das Problem gefunden:
    Das funktioniert allerdings nur mit 32bit-Icons,
    bei anderen kann man GdipCreateBitmapFromHICON verwenden

    Spoiler anzeigen
    [autoit]

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

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

    _GDIPlus_Startup()
    $hIcon = _WinAPI_ShellExtractIcon(@ScriptDir & '\item11.ico', 0, 128, 128)

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

    Local $hBmpDestroy
    $hBitmapIcon = _IconToGdiPlus($hIcon, 128, 128, $hBmpDestroy)
    _WinAPI_DestroyIcon($hIcon)

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

    $hGui = GUICreate('Test', 250, 200)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGui)
    $hBitmap = _GDIPlus_BitmapCreateFromGraphics(250, 200, $hGraphic)
    $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    GUISetState()

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

    _GDIPlus_GraphicsClear($hBackbuffer, 0xFF006600)
    _GDIPlus_GraphicsDrawImageRect($hBackbuffer, $hBitmapIcon, 50, 50, 128, 128)

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

    Do
    Sleep(10)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 0, 0)
    Until GUIGetMsg() = -3

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

    _GDIPlus_ImageDispose($hBitmapIcon)
    _WinAPI_DeleteObject($hBmpDestroy)
    _GDIPlus_GraphicsDispose($hBackbuffer)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_Shutdown()

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

    Func _IconToGdiPlus($hIcon, $iWidth, $iHeight, ByRef $hBmp)

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

    Local $tBITMAPINFO = DllStructCreate("dword Size;long Width;long Height;word Planes;word BitCount;dword Compression;dword SizeImage;long XPelsPerMeter;long YPelsPerMeter;dword ClrUsed;dword ClrImportant;dword RGBQuad")
    DllStructSetData($tBITMAPINFO, 'Size', DllStructGetSize($tBITMAPINFO) - 4)
    DllStructSetData($tBITMAPINFO, 'Width', $iWidth)
    DllStructSetData($tBITMAPINFO, 'Height', -$iHeight)
    DllStructSetData($tBITMAPINFO, 'Planes', 1)
    DllStructSetData($tBITMAPINFO, 'BitCount', 32)
    DllStructSetData($tBITMAPINFO, 'Compression', 0)
    DllStructSetData($tBITMAPINFO, 'SizeImage', 0)

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

    Local $hDC = _WinAPI_CreateCompatibleDC(0)
    Local $aRet = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', 'hwnd', 0, 'ptr', DllStructGetPtr($tBITMAPINFO), 'uint', 0, 'ptr*', 0, 'ptr', 0, 'dword', 0)
    Local $pBits = $aRet[4]
    $hBmp = $aRet[0]
    Local $hOrig = _WinAPI_SelectObject($hDC, $hBmp)
    _WinAPI_DrawIconEx($hDC, 0, 0, $hIcon, $iWidth, $iHeight)

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

    $aRet = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iWidth * 4, "int", 0x26200A, "ptr", $pBits, "int*", 0)
    Local $hBitmap = $aRet[6]
    _WinAPI_SelectObject($hDC, $hOrig)
    _WinAPI_DeleteDC($hDC)

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

    Return $hBitmap
    EndFunc ;==>_IconToGdiPlus

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

    ; #FUNCTION# ====================================================================================================================
    ; Name...........: _WinAPI_ShellExtractIcon
    ; Description....: Extracts the icon with the specified dimension from the specified file.
    ; Syntax.........: _WinAPI_ShellExtractIcon ( $sIcon, $iIndex, $iWidth, $iHeight )
    ; Parameters.....: $sIcon - Path and name of the file from which the icon are to be extracted.
    ; $iIndex - Index of the icon to extract.
    ; $iWidth - Horizontal icon size wanted.
    ; $iHeight - Vertical icon size wanted.
    ; Return values..: Success - Handle to the extracted icon.
    ; Failure - 0 and sets the @error flag to non-zero.
    ; Author.........: Yashied
    ; Modified.......:
    ; Remarks........: If the icon with the specified dimension is not found in the file, it will choose the nearest appropriate icon and
    ; change to the specified dimension. When you are finished using the icon, destroy it using the _WinAPI_DestroyIcon()
    ; function.
    ; Related........:
    ; Link...........: @@MsdnLink@@ SHExtractIcons
    ; Example........: Yes
    ; ===============================================================================================================================

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

    Func _WinAPI_ShellExtractIcon($sIcon, $iIndex, $iWidth, $iHeight)
    Local $Ret = DllCall('shell32.dll', 'int', 'SHExtractIconsW', 'wstr', $sIcon, 'int', $iIndex, 'int', $iWidth, 'int', $iHeight, 'ptr*', 0, 'ptr*', 0, 'int', 1, 'int', 0)
    If (@error) Or (Not $Ret[0]) Or (Not $Ret[5]) Then
    Return SetError(1, 0, 0)
    EndIf
    Return $Ret[5]
    EndFunc ;==>_WinAPI_ShellExtractIcon

    [/autoit]

    mfgE

  • Und noch ein Tipp: Auch mit GDI lässt sich ein Backbuffer realisieren (siehe CreateCompatibleDC und CreateCompatibleBitmap)

  • Klar:

    Spoiler anzeigen
    [autoit]

    #include<WinAPI.au3>
    #include<WindowsConstants.au3>
    $hGUI = GUICreate("test")

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

    ; erstellen
    $hDC = _WinAPI_GetDC($hGUI)

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

    $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC, 100, 200)
    $hBitmapDC = _WinAPI_CreateCompatibleDC($hDC)

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

    _WinAPI_SelectObject($hBitmapDC, $hBitmap)

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

    _WinAPI_ReleaseDC($hGUI, $hDC)

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

    GUISetState()

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

    ; in Buffer zeichen
    $tRect = DllStructCreate("long[4]")
    DllStructSetData($tRect, 1, 20, 1)
    DllStructSetData($tRect, 1, 20, 2)
    DllStructSetData($tRect, 1, 60, 3)
    DllStructSetData($tRect, 1, 80, 4)
    _WinAPI_FillRect($hBitmapDC, DllStructGetPtr($tRect), _WinAPI_GetSysColorBrush(2))

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

    ; Zeichnen
    $hDC = _WinAPI_GetDC($hGUI)

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

    _WinAPI_BitBlt($hDC, 10, 10, 100, 200, $hBitmapDC, 0, 0, $SRCCOPY)

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

    _WinAPI_ReleaseDC($hGUI, $hDC)

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

    Do
    Until GUIGetMsg()=-3

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

    ; freigeben
    _WinAPI_DeleteDC($hBitmapDC)
    _WinAPI_DeleteObject($hBitmap)

    [/autoit]