Sign in to follow this  
Followers 0
Lucid

Using PNG Resources

7 posts in this topic

#1 ·  Posted (edited)

I'm hoping someone can help point me in the right direction on something - I think I'm just overthinking this and there's an easy answer.

I'm trying to add a .PNG as a resource to my compiled .EXE file and then use that in my code. I can get it to work just fine if I put in the name of the file (see my example) and have it in the same directory of course, but I want to use the file I added as part of the .EXE.

I've done some things in the past with "resources.au3", but I can't get that to work for this utility. Can anyone show me how I can replace the static name of my .PNG file in this example code with the reference to the included resource, and have it work when compiled?

Thanks!

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=Test_x86.exe
#AutoIt3Wrapper_Outfile_x64=Test_x64.exe
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_File_Add=background.png, rt_rcdata, BACKGROUND
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;Built using AutoIT SciTE version 3.3.6 (running AutoIT 3.3.10.0)

#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include "resources.au3"

Global Const $AC_SRC_ALPHA = 1
$picPNG = "background.png"

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($picPNG)

$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)

$iWindow_Left = (@DesktopWidth - $iWidth)
$iWindow_Top = (@DesktopHeight - $iHeight)

$hGUI = GUICreate("TEST", $iWidth, $iHeight, $iWindow_Left, $iWindow_Top, $WS_POPUP, $WS_EX_LAYERED)
SetBitmap($hGUI, $hImage, 255)
GUISetState(@SW_SHOW, $hGUI)

While 1
    ;just hang out and do nothing for this test
WEnd

_GDIPlus_Shutdown()

Exit


; ~$~----------------------------------------~$~
Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc ;==>SetBitmap
Edited by Lucid

Share this post


Link to post
Share on other sites



Resources are included in AutoIt, you don't need a UDF. You've just forgotten to Install the resource file (i.e. unpack it from exe).

This works:

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Outfile=Test_x86.exe
#AutoIt3Wrapper_Outfile_x64=Test_x64.exe
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_File_Add=background.png, rt_rcdata, BACKGROUND
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
;Built using AutoIT SciTE version 3.3.6 (running AutoIT 3.3.10.0)

#include <GUIConstantsEx.au3>
#include <GUIConstants.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <StaticConstants.au3>
#include <GDIPlus.au3>

Global Const $AC_SRC_ALPHA = 1
If FileExists(@ScriptDir & "\background.png") = 0 Then FileInstall("background.png", @ScriptDir & "\background.png")
$picPNG = @ScriptDir & "\background.png"

_GDIPlus_Startup()

$hImage = _GDIPlus_ImageLoadFromFile($picPNG)

$iWidth = _GDIPlus_ImageGetWidth($hImage)
$iHeight = _GDIPlus_ImageGetHeight($hImage)

$iWindow_Left = (@DesktopWidth - $iWidth)
$iWindow_Top = (@DesktopHeight - $iHeight)

$hGUI = GUICreate("TEST", $iWidth, $iHeight, $iWindow_Left, $iWindow_Top, $WS_POPUP, $WS_EX_LAYERED)
SetBitmap($hGUI, $hImage, 255)
GUISetState(@SW_SHOW, $hGUI)

While 1
    ;just hang out and do nothing for this test
WEnd

_GDIPlus_Shutdown()

Exit


; ~$~----------------------------------------~$~
Func SetBitmap($hGUI, $hImage, $iOpacity)
    Local $hScrDC, $hMemDC, $hBitmap, $hOld, $pSize, $tSize, $pSource, $tSource, $pBlend, $tBlend
    $hScrDC = _WinAPI_GetDC(0)
    $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC)
    $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
    $hOld = _WinAPI_SelectObject($hMemDC, $hBitmap)
    $tSize = DllStructCreate($tagSIZE)
    $pSize = DllStructGetPtr($tSize)
    DllStructSetData($tSize, "X", _GDIPlus_ImageGetWidth($hImage))
    DllStructSetData($tSize, "Y", _GDIPlus_ImageGetHeight($hImage))
    $tSource = DllStructCreate($tagPOINT)
    $pSource = DllStructGetPtr($tSource)
    $tBlend = DllStructCreate($tagBLENDFUNCTION)
    $pBlend = DllStructGetPtr($tBlend)
    DllStructSetData($tBlend, "Alpha", $iOpacity)
    DllStructSetData($tBlend, "Format", $AC_SRC_ALPHA)
    _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, $pSize, $hMemDC, $pSource, 0, $pBlend, $ULW_ALPHA)
    _WinAPI_ReleaseDC(0, $hScrDC)
    _WinAPI_SelectObject($hMemDC, $hOld)
    _WinAPI_DeleteObject($hBitmap)
    _WinAPI_DeleteDC($hMemDC)
EndFunc ;==>SetBitmap

Share this post


Link to post
Share on other sites

So there's not an easy way to use an image file directly as a resource without unpacking it and putting the file somewhere first?

I'm not sure the utility I'm working on will always have a good spot that it can write to - so I'm trying to avoid installing/copying/saving files that are used as part of the GUI.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

This should work:

#AutoIt3Wrapper_Res_File_Add=background.png, rt_rcdata, BACKGROUND
...
#include "resources.au3"
...
$picPNG = "BACKGROUND"
...
;$hImage = _GDIPlus_ImageLoadFromFile($picPNG)
$hImage = _ResourceGetAsImage($picPNG)
Also look at my example resource_test.au3 in my resources UDF

'?do=embed' frameborder='0' data-embedContent>>

Edited by Zedna

Share this post


Link to post
Share on other sites

Thanks for verifying that command is the right one Zedna. I can get it to work fine in my test script, but for some reason, in my larger script it hiccups when I compile it - spiting out a "variable used without being declared" error. And I'm using the same .PNG file in both scripts.

If I use this line: Local $hImage2 = _ResourceGetAsImage("BACKGROUND")

it doesn't work when compiled.

And I've got the following towards the top of my script:

#AutoIt3Wrapper_Res_File_Add=background.png, rt_rcdata, BACKGROUND

#include "resources.au3"

AutoItSetOption("MustDeclareVars", 1)

If I track down where the error is happening when compiled, it looks like it barks on Line 150 of the "resources.au3" file:

$hImage = DllCall($ghGDIPDll,"int","GdipCreateBitmapFromStream", "ptr",$pStream, "ptr*",0)

Am I missing something, or not supplying the right info? Thanks!

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

In resources.au3 use this fix to be working also with AutoItSetOption("MustDeclareVars", 1)
 

this:

Func _ResourceGetAsImage($ResName, $ResType = 10, $DLL = -1) ; $RT_RCDATA = 10
Local $ResData, $nSize, $hData, $pData, $pStream, $pBitmap, $hBitmap

change to:

Func _ResourceGetAsImage($ResName, $ResType = 10, $DLL = -1) ; $RT_RCDATA = 10
Local $ResData, $nSize, $hData, $pData, $pStream, $hImage, $pBitmap, $hBitmap
Edited by Zedna

Share this post


Link to post
Share on other sites

Adjusting that line did the trick. Thanks Zedna!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0