Gdiplus und Icons

  • Hier ein Beispiel:

    Spoiler anzeigen
    [autoit]


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

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

    _GDIPlus_Startup()

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

    $sFile = "Shell32.dll"
    $iIndex = 4;Random(0, 200, 1)
    $iSizeW = 32
    $iSizeH = 32
    $aRet = DllCall('shell32.dll', 'int', 'SHExtractIconsW', 'wstr', $sFile, 'int', $iIndex, 'int', $iSizeW, 'int', $iSizeH, 'ptr*', 0, 'ptr*', 0, 'int', 1, 'int', 0)
    $hIcon = $aRet[5]
    $hBitmap = __IconDock_IconToGdiPlus($hIcon, $iSizeW, $iSizeH)
    _WinAPI_DestroyIcon($hIcon)

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

    $iW = _GDIPlus_ImageGetWidth($hBitmap)
    $iH = _GDIPlus_ImageGetHeight($hBitmap)
    $hGUI = GUICreate("", $iW * 2, $iH * 2, -1, -1, $WS_POPUPWINDOW)
    GUISetState()

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

    $hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    _GDIPlus_GraphicsDrawImage($hGFX, $hBitmap, $iW / 2, $iH / 2)

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

    Do
    Until GUIGetMsg()= -3

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

    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_GraphicsDispose($hGFX)
    _GDIPlus_Shutdown()
    GUIDelete()

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

    Exit

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

    ; #FUNCTION# ======================================================================================
    ; Name ..........: __IconDock__IconDock_IconToGdiPlus()
    ; Description ...: Internal Function
    ; Author ........: Eukalyptus
    ; =================================================================================================
    Func __IconDock_IconToGdiPlus($hIcon, $iWidth, $iHeight)

    [/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]
    Local $hBmp = $aRet[0]
    Local $hOrig = _WinAPI_SelectObject($hDC, $hBmp)
    _WinAPI_DrawIconEx($hDC, 0, 0, $hIcon, $iWidth, $iHeight)

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

    Local $bAlpha = False
    Local $tData = DllStructCreate("dword[" & $iWidth * $iHeight & "]", $pBits)
    For $i = 1 To $iWidth * $iHeight
    If BitAND(DllStructGetData($tData, 1, $i), 0xFF000000) Then
    $bAlpha = True
    ExitLoop
    EndIf
    Next
    Switch $bAlpha
    Case True
    $aRet = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iWidth, "int", $iHeight, "int", $iWidth * 4, "int", 0x26200A, "ptr", $pBits, "int*", 0)
    Local $hBitmapTemp = $aRet[6]

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

    Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow())
    Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

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

    _GDIPlus_GraphicsDrawImage($hContext, $hBitmapTemp, 0, 0)

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

    _GDIPlus_BitmapDispose($hBitmapTemp)
    _WinAPI_DeleteObject($hBmp)
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_GraphicsDispose($hGraphics)

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

    _WinAPI_SelectObject($hDC, $hOrig)
    _WinAPI_DeleteDC($hDC)
    Case Else
    $aRet = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromHICON", "hwnd", $hIcon, "int*", 0)
    Local $hBitmap = $aRet[2]
    _WinAPI_SelectObject($hDC, $hOrig)
    _WinAPI_DeleteObject($hBmp)
    _WinAPI_DeleteDC($hDC)
    EndSwitch
    Return $hBitmap
    EndFunc ;==>__IconDock_IconToGdiPlus

    [/autoit]

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯

    2 Mal editiert, zuletzt von UEZ (13. Juli 2012 um 22:20)

  • Hmm... Warum hab ich das damals eigentlich so kompliziert gemacht?!

    Das hier ist eine wesentlich elegantere Methode:

    Spoiler anzeigen
    [autoit]

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

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

    Opt("GUIOnEventMode", 1)

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

    _GDIPlus_Startup()

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

    Global $iWidth = 300
    Global $iHeight = 200

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

    Global $hGui = GUICreate("Test", $iWidth, $iHeight)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUISetState()

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

    Global $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGui)
    Global $hBmpBuffer = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
    Global $hGfxBuffer = _GDIPlus_ImageGetGraphicsContext($hBmpBuffer)
    _GDIPlus_GraphicsSetSmoothingMode($hGfxBuffer, 2)
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFFABCDEF)

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

    Global $hBmpIcon1 = _Load_GdiPlus_Icon("Shell32.dll", 4, 32, 32)
    Global $hBmpIcon2 = _Load_GdiPlus_Icon("Explorer.exe", 0, 128, 128)

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

    _Draw()

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

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

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

    While 1
    Sleep(10)
    WEnd

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

    Func _Load_GdiPlus_Icon($sFile, $iIndex, $iW = 32, $iH = 32)
    Local $aResult = DllCall("shell32.dll", "int", "SHExtractIconsW", "wstr", $sFile, "int", $iIndex, "int", $iW, "int", $iH, "ptr*", 0, "ptr*", 0, "int", 1, "int", 0)
    If @error Then Return SetError(1, 1, False)
    If Not $aResult[5] Then Return SetError(1, 2, False)
    Local $hIcon = $aResult[5]

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

    $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0)
    If @error Then Return SetError(1, 3, False)
    Local $hBitmap = $aResult[6]

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

    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)

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

    $aResult = DllCall($ghGDIPDll, "uint", "GdipGetDC", "ptr", $hContext, "hwnd*", 0)
    If @error Then Return SetError(1, 4, False)
    Local $hDC = $aResult[2]

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

    _WinAPI_DrawIconEx($hDC, 0, 0, $hIcon, $iW, $iH)

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

    DllCall($ghGDIPDll, "uint", "GdipReleaseDC", "ptr", $hContext, "hwnd", $hDC)
    _GDIPlus_GraphicsDispose($hContext)
    _WinAPI_DestroyIcon($hIcon)

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

    Return $hBitmap
    EndFunc ;==>_Load_GdiPlus_Icon

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

    Func _Draw()
    _GDIPlus_GraphicsClear($hGfxBuffer, 0xFF440000)

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

    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpIcon1, 10, 10)
    _GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpIcon2, 110, 10)

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

    _GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
    EndFunc ;==>_Draw

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/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][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _GDIPlus_BitmapDispose($hBmpIcon1)
    _GDIPlus_BitmapDispose($hBmpIcon2)

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

    _GDIPlus_GraphicsDispose($hGfxBuffer)
    _GDIPlus_BitmapDispose($hBmpBuffer)
    _GDIPlus_GraphicsDispose($hGraphics)
    _GDIPlus_Shutdown()
    Exit
    EndFunc ;==>_Exit

    [/autoit]

    E

  • Hi eukalyptus,

    bei deiner 2. Methode geht leider die Transparenz flöten (zumindest bei mir unter Win7 x64 + Aero). ;)

    Wenn du die 2 _GDIPlus_GraphicsClear() auskommentierst, kannst du sehen, dass die Icons nicht richtig transparent sind.

    In _GUICtrlMenu_CreateBitmap() v0.60 Build 2012-01-07 beta - Erstellt Icons für GUI Menüs ist auch noch eine Variante, aber dein Code aus IconDock fand ich hier passender.

    Gruß,
    UEZ

    Auch am Arsch geht ein Weg vorbei...

    ¯\_(ツ)_/¯