- Offizieller Beitrag
Servus.
Ich suche schon seit langem nach einer Möglichkeit, Bilddateien aus einer DLL zu laden.
Dabei habe ich im Englischen Forum eine UDF von Zedna gefunden http://www.autoitscript.com/forum/index.php?showtopic=51103&hl=resourcesudf&st=0.
Leider habe ich die UDF nicht zum laufen bekommen, das laden von Bilddatein funktioniert leider nicht aus einer DLL Datei.
Kurzenhand habe ich mit dann eine eigene Funktion gebastelt, die ich euch nicht vorenthalten möchte.
Spoiler anzeigen
#include <WinAPI.au3>
#include <Memory.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <Constants.au3>
Global Const $RT_BITMAP = 2
Global Const $RT_RCDATA = 10
Opt("MustDeclareVars", 1)
Global $gui = GUICreate("Data from resources", 800, 600)
Global $backpic = GUICtrlCreatePic("", 0, 0, 800, 600)
_SetImagefromResource($backpic, "BACKGROUND", @ScriptDir & "\Test.dll", $RT_BITMAP)
Global $pic1 = GUICtrlCreatePic("", 620, 350, 160, 72)
GUISetBkColor(0xc0c0c0)
_SetImagefromResource($pic1, "BUTTON_1", @ScriptDir & "\Test.dll", $RT_RCDATA)
Global $pic2 = GUICtrlCreatePic("", 620, 430, 160, 72)
_SetImagefromResource($pic2, "BUTTON_2", @ScriptDir & "\Test.dll", $RT_RCDATA)
Global $pic3 = GUICtrlCreatePic("", 620, 510, 160, 72)
_SetImagefromResource($pic3, "BUTTON_3", @ScriptDir & "\Test.dll", $RT_RCDATA)
GUISetState(@SW_SHOW)
While 1
Global $msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd
Func _SetImagefromResource($CtrlID, $Resname, $Resfile = -1, $ResType = 10)
;Diese Funktion basiert auf der UDF von [email='Zedna@Autitscript.com'][/email] und Code von [email='Progandy@AutoIt.de'][/email]
Local Const $IMAGE_BITMAP = 0
Local Const $STM_SETIMAGE = 0x0172
Local $hmod, $hwnd, $InfoBlock, $ResSize, $Mem, $pMem, $dll, $dll2, $hData, $pData, $pStream, $ret, $hBitmap, $pBitmap
If $Resfile = -1 Then
$hmod = _WinAPI_GetModuleHandle("")
Else
$hmod = _WinAPI_LoadLibrary($Resfile)
EndIf
If $ResType = $RT_BITMAP Then
$hBitmap = _WinAPI_LoadImage($hmod, $Resname, $IMAGE_BITMAP, 0, 0, 0)
If @error Then Return SetError(1, 0, 0)
$hwnd = GUICtrlGetHandle($CtrlID)
If $hwnd = 0 Then Return SetError(2, 0, 0)
DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hwnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
If @error Then Return SetError(3, 0, 0)
Else
$InfoBlock = DllCall("kernel32.dll", "int", "FindResourceA", "int", $hmod, "str", $Resname, "long", $ResType)
If @error Then Return SetError(4, 0, 0)
$InfoBlock = $InfoBlock[0]
If $InfoBlock = 0 Then Return SetError(5, 0, 0)
$ResSize = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hmod, "int", $InfoBlock)
If @error Then Return SetError(6, 0, 0)
$ResSize = $ResSize[0]
If $ResSize = 0 Then Return SetError(7, 0, 0)
$Mem = DllCall("kernel32.dll", "int", "LoadResource", "int", $hmod, "int", $InfoBlock)
If @error Then Return SetError(8, 0, 0)
$Mem = $Mem[0]
If $Mem = 0 Then Return SetError(9, 0, 0)
$pMem = DllCall("kernel32.dll", "int", "LockResource", "int", $Mem)
If @error Then Return SetError(8, 0, 0)
$pMem = $pMem[0]
If $pMem = 0 Then Return SetError(10, 0, 0)
If $Resfile <> -1 Then DllCall("Kernel32.dll", "int", "FreeLibrary", "str", $hmod)
$hData = _MemGlobalAlloc($ResSize, 2)
$pData = _MemGlobalLock($hData)
_MemMoveMemory($pMem, $pData, $ResSize)
_MemGlobalUnlock($hData)
$ret = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hData, "long", 1, "Int*", 0)
$pStream = $ret[3]
_GDIPlus_Startup()
$pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
$pBitmap = $pBitmap[2]
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($pBitmap)
$hwnd = GUICtrlGetHandle($CtrlID)
If $hwnd = 0 Then Return SetError(11, 0, 0)
DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hwnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
If @error Then Return SetError(12, 0, 0)
_GDIPlus_BitmapDispose($pBitmap)
_GDIPlus_Shutdown()
$dll = DllStructCreate("Uint", $pStream)
$dll2 = DllStructCreate("uInt", DllStructGetData($dll, 1) +
DllCall("", "UInt", DllStructGetData($dll2, 1), "UInt", $pStream)
_WinAPI_DeleteObject($pStream)
$pStream = 0
_MemGlobalFree($hData)
EndIf
EndFunc ;==>_SetImagefromResource
Um eine GIF oder JPG Datei in einer DLL zu speichern benutzt Ihr am besten Reshacker. Dabei müssen die Bildateien als RCDATA gespeichert werden.
Bei BMP Dateien muß BITMAP als Resourcenformat verwendet werden.
Ich hoffe die Funktion kann jemand brauchen.
PS: Die Dll Datei ist als Zip angehängt.