PNG from DLL

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
Qma
Posts: 3
Joined: 18 May 2021, 14:21

PNG from DLL

Post by Qma » 18 May 2021, 14:28

Hi everyone! I'm pretty new to AHK scripting and so far I've been having a good time creating a GUI and using Icons from a .dll.

I was wondering if there is a way to use PNG files from a dll also, searched around but couldn't find anything.

Thanks in advance!
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: PNG from DLL

Post by teadrinker » 18 May 2021, 15:08

Hi
Can you share your dll?
Qma
Posts: 3
Joined: 18 May 2021, 14:21

Re: PNG from DLL

Post by Qma » 18 May 2021, 15:17

teadrinker wrote:
18 May 2021, 15:08
Hi
Can you share your dll?
gofile.io/d/gARmFp Here you go! It's just a sample with a few backgrounds.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: PNG from DLL

Post by teadrinker » 18 May 2021, 16:52

There is some problem with your file:
 
 Image
Qma
Posts: 3
Joined: 18 May 2021, 14:21

Re: PNG from DLL

Post by Qma » 18 May 2021, 17:59

teadrinker wrote:
18 May 2021, 16:52
There is some problem with your file:
 
 Image Broken Link for safety
Weird, got a new link from Mega:

mega.nz/file/4cUAlTbA#MK-YU8n_joGtHErlEZsqe2ZmoxDtrflic1OCQ69sSBo

Virus Total From the File: https://www.virustotal.com/gui/file/4e867fc27c907b2c3489676a6a0ecc5353f2cde3bafee98b6fc9e6c6d6dcd293/detection

Virus Total From Mega: https://www.virustotal.com/gui/url/51592d40940681f3eca1c5fe7ac0a7b498a6cc6e774abc27830ce17f54bf47d9/detection 1 from 89 detected it as Malware thou.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: PNG from DLL

Post by teadrinker » 18 May 2021, 19:24

Code: Select all

modulePath := A_ScriptDir . "\png.dll"

if !hLib := DllCall("LoadLibraryEx", "Str", modulePath, "Ptr", 0, "UInt", LOAD_LIBRARY_AS_DATAFILE := 0x2, "Ptr")
   throw "Failed to load dll, error: " . A_LastError

Names := []
pEnumProc := RegisterCallback("EnumProc", "F", 4)
DllCall("EnumResourceNames", "Ptr", hLib, "Str", "PNG", "Ptr", pEnumProc, "Ptr", pNames := Object(Names))
ObjRelease(pNames)
DllCall("GlobalFree", "Ptr", pEnumProc, "Ptr")

Gdip := new GDIplus
Gui, Margin, 1, 1

for k, v in Names {
   if !hRes := DllCall("FindResource", "Ptr", hLib, "Int", v, "Str", "PNG", "Ptr")
      throw "FindResource failed, error: " . A_LastError
   hGl := DllCall("LoadResource", "Ptr", hLib, "Ptr", hRes, "Ptr")
   pRes := DllCall("LockResource", "Ptr", hGl, "Ptr")
   size := DllCall("SizeofResource", "Ptr", hLib, "Ptr", hRes)
   
   pStream := DllCall("Shlwapi\SHCreateMemStream", "Ptr", pRes, "UInt", size, "Ptr")
   pBitmap := Gdip.CreateBitmapFromStream(pStream)
   hBitmap%k% := Gdip.CreateHBITMAPFromBitmap(pBitmap)
   Gdip.DisposeImage(pBitmap)
   ObjRelease(pStream)
   
   Gui, Add, Pic, w400 h-1, % "HBITMAP:" . hBitmap%k%
}
Gdip := ""
DllCall("FreeLibrary", "Ptr", hLib)
Gui, Show
Return

GuiClose:
   ExitApp

EnumProc(hModule, Type, Name, lp) {
	(Name>>16 && Name := StrGet(Name))
	Object(lp).Push(Name)
	Return true
}

class GDIplus {
   __New() {
      if !DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
         DllCall("LoadLibrary", "Str", "gdiplus")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
      this.token := pToken
   }
   __Delete() {
      DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
      if hModule := DllCall("GetModuleHandle", "Str", "gdiplus", "Ptr")
         DllCall("FreeLibrary", "Ptr", hModule)
   }
   CreateBitmapFromStream(pStream) {
      DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pStream, "PtrP", pBitmap)
      Return pBitmap
   }
   CreateHBITMAPFromBitmap(pBitmap, background := 0xffffffff) {
      DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "UInt", background)
      return hbm
   }
   DisposeImage(pBitmap) {
      return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
   }
}
CubanB
Posts: 8
Joined: 20 Aug 2022, 07:27

Re: PNG from DLL

Post by CubanB » 20 Aug 2022, 11:18

Is it possible to adapt this script to work with a single png image, for example loading a small png from a dll to use in a GUI? I tried to adapt it but didn't have any luck. I was able to get .bmp working using a different function, but some of he stuff I'm doing involves a lot large images, and png would be preferred in terms of keeping the file size of the dll smaller.

What I have for bmp is..

Code: Select all


BMPFromDll( "2", "623", "0", "24", "22", DLL_Path, "2",  "Pic01B", "Closelink")  ; Close Button in GUI
; GUI Show etc


; Function
BMPFromDll(GuiID, X, Y, W, H, DllFile, DllID, V, G, flags=0x0) {
	global
	Gui, %GuiID%:Add, Picture, x%X% y%Y% w%W% h%H% +0xE v%V% g%G% hWndPic1
	hModule := DllCall( "LoadLibrary", Str, DllFile )
	hBitmap := DllCall( "LoadImageA", UInt, hModule, UInt, DllID, UInt, (IMAGE_BITMAP:=0x0)
						, UInt, W, UInt, H, UInt, (LR_SHARED := 0x8000))
	SendMessage, 0x172, flags, hBitmap, , ahk_id %Pic1%
	DllCall("FreeLibrary", "UInt", hModule)
	Return, %Errorlevel%
	}

Is it possible to have something similar for PNG files? I have tried searching around but haven't had any luck so far.
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: PNG from DLL

Post by teadrinker » 20 Aug 2022, 12:17

CubanB wrote: Is it possible to adapt this script to work with a single png image
Yep, but you have to share your dll.
CubanB
Posts: 8
Joined: 20 Aug 2022, 07:27

Re: PNG from DLL

Post by CubanB » 21 Aug 2022, 01:03

teadrinker wrote:
20 Aug 2022, 12:17
CubanB wrote: Is it possible to adapt this script to work with a single png image
Yep, but you have to share your dll.
No problems, that's great news. I've uploaded a sample DLL to Mega.nz.

https://mega.nz/file/wupE3aqA#FhXo_2IYTYgQ11jjjHe8xW6aenpdjUaY36g_txuXOVs

An example of the usage would be..

Code: Select all

t::
Gui, Color, 383637
Gui, +ToolWindow -MinimizeBox -MaximizeBox +AlwaysOnTop -SysMenu -Caption
Gui, Add, Picture, x229 y2 gCloselink, Close.png ; PNG #2 from DLL extracted and renamed
Gui, Show, w250 h160
return

Closelink:
ExitApp
Escape::
ExitApp
teadrinker
Posts: 4326
Joined: 29 Mar 2015, 09:41
Contact:

Re: PNG from DLL

Post by teadrinker » 21 Aug 2022, 08:04

Code: Select all

modulePath := "D:\Downloads\PNGfromDLL_Example.dll"

hBitmap := GetHBitmapFromImageResource(modulePath, "2", "PNG")

Gui, Color, 383637
Gui, +ToolWindow -MinimizeBox -MaximizeBox +AlwaysOnTop -SysMenu -Caption
Gui, Add, Picture, x229 y2 gEsc, HBITMAP: %hBitmap%
Gui, Show, w250 h160
return

Esc:: ExitApp

GetHBitmapFromImageResource(modulePath, resName, resType) {
   size := GetResourceData(modulePath, resName, resType, pData)
   Return GetHBitmapFromImageData(pData, size)
}

GetResourceData(modulePath, resName, resType, ByRef pRes) {
   if !hLib := DllCall("LoadLibraryEx", "Str", modulePath, "Ptr", 0, "UInt", LOAD_LIBRARY_AS_DATAFILE := 0x2, "Ptr")
      throw "Failed to load dll, error: " . A_LastError

   if !hRes := DllCall("FindResource", "Ptr", hLib, "Str", "#" . resName, "Str", resType, "Ptr")
      throw "FindResource failed, error: " . A_LastError

   hGl := DllCall("LoadResource", "Ptr", hLib, "Ptr", hRes, "Ptr")
   pRes := DllCall("LockResource", "Ptr", hGl, "Ptr")
   Return DllCall("SizeofResource", "Ptr", hLib, "Ptr", hRes)
}

GetHBitmapFromImageData(pData, size) {
   Gdip := new GDIplus
   pStream := DllCall("Shlwapi\SHCreateMemStream", "Ptr", pData, "UInt", size, "Ptr")
   pBitmap := Gdip.CreateBitmapFromStream(pStream)
   hBitmap := Gdip.CreateHBITMAPFromBitmap(pBitmap)
   Gdip.DisposeImage(pBitmap)
   ObjRelease(pStream)
   Return hBitmap
}

class GDIplus {
   __New() {
      this.hLib := DllCall("LoadLibrary", "Str", "gdiplus", "Ptr")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", "UPtrP", pToken, "Ptr", &si, "Ptr", 0)
      this.token := pToken
   }
   __Delete() {
      DllCall("gdiplus\GdiplusShutdown", "Ptr", this.token)
      DllCall("FreeLibrary", "Ptr", this.hLib)
   }
   CreateBitmapFromStream(pStream) {
      DllCall("gdiplus\GdipCreateBitmapFromStream", "Ptr", pStream, "PtrP", pBitmap)
      Return pBitmap
   }
   CreateHBITMAPFromBitmap(pBitmap, background := 0xffffffff) {
      DllCall("gdiplus\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hbm, "UInt", background)
      return hbm
   }
   DisposeImage(pBitmap) {
      return DllCall("gdiplus\GdipDisposeImage", "Ptr", pBitmap)
   }
}
CubanB
Posts: 8
Joined: 20 Aug 2022, 07:27

Re: PNG from DLL

Post by CubanB » 22 Aug 2022, 12:46

Works great teadrinker.. thanks!
Post Reply

Return to “Ask for Help (v1)”