Jump to content

Using PNG Resources


Lucid
 Share

Recommended Posts

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
Link to comment
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
Link to comment
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.

Link to comment
Share on other sites

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
Link to comment
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!

Link to comment
Share on other sites

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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...