Hi,
wie so oft hab ich ein Problem mit gdiplus,
Ich muss aus einer dll ICONS in die GUI zeichnen lassen
(muss mit gdiplus sein).
Wenn das möglich ist, wie?
Hi,
wie so oft hab ich ein Problem mit gdiplus,
Ich muss aus einer dll ICONS in die GUI zeichnen lassen
(muss mit gdiplus sein).
Wenn das möglich ist, wie?
Hier ein Beispiel:
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
_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)
$iW = _GDIPlus_ImageGetWidth($hBitmap)
$iH = _GDIPlus_ImageGetHeight($hBitmap)
$hGUI = GUICreate("", $iW * 2, $iH * 2, -1, -1, $WS_POPUPWINDOW)
GUISetState()
$hGFX = _GDIPlus_GraphicsCreateFromHWND($hGUI)
_GDIPlus_GraphicsDrawImage($hGFX, $hBitmap, $iW / 2, $iH / 2)
Do
Until GUIGetMsg()= -3
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_GraphicsDispose($hGFX)
_GDIPlus_Shutdown()
GUIDelete()
Exit
[/autoit] [autoit][/autoit] [autoit]; #FUNCTION# ======================================================================================
; Name ..........: __IconDock__IconDock_IconToGdiPlus()
; Description ...: Internal Function
; Author ........: Eukalyptus
; =================================================================================================
Func __IconDock_IconToGdiPlus($hIcon, $iWidth, $iHeight)
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)
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)
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]
Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow())
Local $hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphics)
Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
_GDIPlus_GraphicsDrawImage($hContext, $hBitmapTemp, 0, 0)
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_BitmapDispose($hBitmapTemp)
_WinAPI_DeleteObject($hBmp)
_GDIPlus_GraphicsDispose($hContext)
_GDIPlus_GraphicsDispose($hGraphics)
_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
Gruß,
UEZ
Hmm... Warum hab ich das damals eigentlich so kompliziert gemacht?!
Das hier ist eine wesentlich elegantere Methode:
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
Opt("GUIOnEventMode", 1)
[/autoit] [autoit][/autoit] [autoit]_GDIPlus_Startup()
[/autoit] [autoit][/autoit] [autoit]Global $iWidth = 300
Global $iHeight = 200
Global $hGui = GUICreate("Test", $iWidth, $iHeight)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
GUISetState()
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)
Global $hBmpIcon1 = _Load_GdiPlus_Icon("Shell32.dll", 4, 32, 32)
Global $hBmpIcon2 = _Load_GdiPlus_Icon("Explorer.exe", 0, 128, 128)
_Draw()
[/autoit] [autoit][/autoit] [autoit]GUIRegisterMsg($WM_PAINT, "WM_PAINT")
GUIRegisterMsg($WM_ERASEBKGND, "WM_PAINT")
While 1
Sleep(10)
WEnd
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]
$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]
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]
_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)
Return $hBitmap
EndFunc ;==>_Load_GdiPlus_Icon
Func _Draw()
_GDIPlus_GraphicsClear($hGfxBuffer, 0xFF440000)
_GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpIcon1, 10, 10)
_GDIPlus_GraphicsDrawImage($hGfxBuffer, $hBmpIcon2, 110, 10)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
EndFunc ;==>_Draw
Func WM_PAINT($hWnd, $uMsgm, $wParam, $lParam)
_GDIPlus_GraphicsDrawImage($hGraphics, $hBmpBuffer, 0, 0)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_PAINT
Func _Exit()
_GDIPlus_BitmapDispose($hBmpIcon1)
_GDIPlus_BitmapDispose($hBmpIcon2)
_GDIPlus_GraphicsDispose($hGfxBuffer)
_GDIPlus_BitmapDispose($hBmpBuffer)
_GDIPlus_GraphicsDispose($hGraphics)
_GDIPlus_Shutdown()
Exit
EndFunc ;==>_Exit
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