Zedna

Resources UDF

640 posts in this topic

#21 ·  Posted

I did search for some GDI plus reference about loading images (BMP,GIF,JPG,PNG,TIFF,WMF,...) and found only this MSDN link

about Image Functions. There are functions GdipLoadImageFromFile() and GdipLoadImageFromStream() but there is no detailed description.

Can somebody tell me where is detailed reference of these GDI plus functions.

Note:

GdipLoadImageFromFile() is in Auto3Lib

GdipLoadImageFromStream() is not in Auto3Lib and maybe could be used to load compressed images (GIF,JPG,PNG) from resources

I found some reference links and

I'm on the right way with loading GIF,JPG,PNG images directly from resources using GdipLoadImageFromStream() API,

stay tuned...

Share this post


Link to post
Share on other sites



#22 ·  Posted

Till I will finish implementing GdipLoadImageFromStream() API

here is example of using RT_HTML resource type.

It can be used by embeded IE COM obj control to show HTML and/or images (GIF,JPG,PNG,...) from resources.

Example is very simple:

note: 23 is constant for RT_HTML

resource_test_ie.au3

#compiler_useupx=n
#compiler_run_after=ResHacker.exe -add %out%, %out%, test_1.htm, 23, TEST_HTML_1, 0
#compiler_run_after=ResHacker.exe -add %out%, %out%, test_1.gif, 23, TEST_GIF_1, 0
#compiler_run_after="c:\program files\Autoit3\Aut2Exe\upx.exe" --compress-resources=0 "%out%"

$oIE = ObjCreate("Shell.Explorer.2")
$gui = GUICreate("HTML from resources test",900,700)
$ie_ctrl = GUICtrlCreateObj ($oIE, 0, 0 , 900, 700)
GUISetState(@SW_SHOW)

; html from resource (with embeded image from resources)
$oIE.navigate("res://" & @AutoItExe & "/test_html_1")
Sleep(3000)
; image from resource
$oIE.navigate("res://" & @AutoItExe & "/test_gif_1")

While 1
      If GUIGetMsg() = -3 Then Exit
WEnd

test_1.htm

<html><BR><body><BR><FONT face="Verdana" size="2" color="#3366FF">Test <B>HTML</B> text.

<BR><img border="0" src="test_gif_1" width="800" height="600"><BR></body><BR></html>

test_1.gif is 800x600 for fit to my example GUI

Share this post


Link to post
Share on other sites

#23 ·  Posted (edited)

Hi There, i love the way how to attach resources to an exe.

i created a wrapper for attaching bulk stuff to an exe.

you just have to add

#AutoIt3Wrapper_useupx=n
#AutoIt3Wrapper_run_after="add_ress.exe "%out%""

at the header of your script.

and copy add_ress.exe reshacker.exe and upx.exe from my example into the script dir.

if you add a folder called "resources" to your script dir and put any text or bmp file in they will be included into the exe automatically during the build process.

in the example there is the sourcecode of add_ress.exe you can clean up the code and do it a better way, i just did an example with it and its very dirty written.

feel free to write a much better wrapper with this code.

kind regards,

JR.

EDIT: added html example...

Edited by JRSmile

$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites

#24 ·  Posted (edited)

Hi There, i love the way how to attach resources to an exe.

i created a wrapper for attaching bulk stuff to an exe.

you just have to add

#AutoIt3Wrapper_useupx=n<BR>  #AutoIt3Wrapper_run_after="add_ress.exe "%out%""

at the header of your script.

Hi and thanks for your wrapper.

I like your idea but I think #AutoIt3Wrapper resource directive will be better (and AutoIt3Wrapper is standard part of Scite4Autoit so no aditional files).

When I will finish my UDF (I'm busy now but this week it could be done - I have all needed API calls prepared) I will make request to JdeB to make some AutoIt3Wrapper resource directive.

In my my new UDF will be following functions for even more simple examples:

_ResourceGet($ResName, $ResType, $ResLang = 0)

_ResourceGetAsString($ResName, $ResType, $ResLang = 0)

_ResourceGetAsBytes($ResName, $ResType, $ResLang = 0)

_ResourceSetImageToCtrl($CtrlId, $ResName, $ResType)

Look at my post #2

I prefer this kind of AutoIt3Wrapper directive:

#AutoIt3Wrapper_Res_Data_Add=filename1.txt,RT_RCDATA,res_name1

#AutoIt3Wrapper_Res_Data_Add=filename2.dat,RT_RCDATA,res_name2

#AutoIt3Wrapper_Res_Data_Add=filename3.jpg,RT_RCDATA,res_name3

#AutoIt3Wrapper_Res_Data_Add=filename4.bmp,RT_BITMAP,res_name4

so it's: #AutoIt3Wrapper_Res_Data_Add=filename,datatype,resource name

- resource name can be optional, if not used then will be the same as file name

Notes about your wrapper:

- dynamic numbers in resource names are danger, rather I would used resource name identical to file name instead (it can be used with no problems)

- lack of way to define resource type is bad by my opinion

I want to make resource directives to be the most general and the most similar to other dev. languages (VB,Delphi,...)

Edited by Zedna

Share this post


Link to post
Share on other sites

#25 ·  Posted

Hi and thanks for your wrapper.

I like your idea but I think #AutoIt3Wrapper resource directive will be better (and AutoIt3Wrapper is standard part of Scite4Autoit so no aditional files).

When I will finish my UDF (I'm busy now but this week it could be done - I have all needed API calls prepared) I will make request to JdeB to make some AutoIt3Wrapper resource directive.

In my my new UDF will be following functions for even more simple examples:

Look at my post #2

I prefer this kind of AutoIt3Wrapper directive:

so it's: #AutoIt3Wrapper_Res_Data_Add=filename,datatype,resource name

- resource name can be optional, if not used then will be the same as file name

Notes about your wrapper:

- dynamic numbers in resource names are danger, rather I would used resource name identical to file name instead (it can be used with no problems)

- lack of way to define resource type is bad by my opinion

I want to make resource directives to be the most general and the most similar to other dev. languages (VB,Delphi,...)

in your way there must be a manual entered line of code in every script that specifies which file and type will be added, what if you want to add 300 pictures and some mp3s, do you want to add them all by Hand?

maybe we can add a menu to scite for adding resources. :)


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites

#26 ·  Posted (edited)

in your way there must be a manual entered line of code in every script that specifies which file and type will be added, what if you want to add 300 pictures and some mp3s, do you want to add them all by Hand?

maybe we can add a menu to scite for adding resources. :)

For such big numbers of resources can be used precompiled resources in RES file which can be included in AU3 by

#AutoIt3Wrapper_Res_Add=filename1.res

#AutoIt3Wrapper_Res_Add=filename2.res

filename1.res - can contain hundreds of files see source RC example in my post #2

filename1.rc:

TEST_1 RCDATA "test_1.txt"

TEST_2 RCDATA "test_2.gif"

TEST_3 RCDATA "test_3.jpg"

But consider that for each resource you must write also AU3 code, so hundreds is too much.

In the most cases there will be only several resources used so this syntax will be OK:

#AutoIt3Wrapper_Res_Data_Add=filename1.txt,RT_RCDATA,res_name1

#AutoIt3Wrapper_Res_Data_Add=filename2.dat,RT_RCDATA,res_name2

#AutoIt3Wrapper_Res_Data_Add=filename3.jpg,RT_RCDATA,res_name3

#AutoIt3Wrapper_Res_Data_Add=filename4.bmp,RT_BITMAP,res_name4

Edited by Zedna

Share this post


Link to post
Share on other sites

#27 ·  Posted

could you please upload the following files:

* RC.EXE

* RCDLL.DLL

i don't want to install the VB IDE just for two files :)

for now my regards to you. ;)


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites

#28 ·  Posted (edited)

could you please upload the following files:

* RC.EXE

* RCDLL.DLL

i don't want to install the VB IDE just for two files :)

for now my regards to you. ;)

Here it is ...

Version 5.1 works also on WIN98

Version 5.2 works on WINXP (not on WIN98)

Consider thet #AutoIt3Wrapper_Res_Add=filename1.res directive doesn't exist, it's only my proposition for future.

But for now you can add precompiled RES files to EXE by Reshacker I think.

EDIT:

Really you can prepare (compile) all resources to one RES file and then in AU3 script add only that one RES file by one line of some directive

From ResHacker helpfile:

To add all items in Images.res to MyProg.exe (but fail if any item already exists)

ResHacker.exe -add MyProg.exe, MyProgNew.exe, Images.res ,,,

EDIT2:

MSDN

The Microsoft Windows Resource Compiler (RC) is available in Visual Studio and the Microsoft Windows Software Development Kit (SDK).

rc51.zip

rc52.zip

Edited by Zedna

Share this post


Link to post
Share on other sites

#29 ·  Posted

Here it is ...

Version 5.1 works also on WIN98

Version 5.2 works on WINXP (not on WIN98)

Consider thet #AutoIt3Wrapper_Res_Add=filename1.res directive doesn't exist, it's only my proposition for future.

But for now you can add precompiled RES files to EXE by Reshacker I think.

thx for the upload, will try to wrap something around :)


$a=StringSplit("547275737420796F757220546563686E6F6C75737421","")For $b=1 To UBound($a)+(-1*-1*-1)step(2^4/8);&$b+=1*2/40*µ&Asc(4)Assign("c",Eval("c")&Chr(Dec($a[$b]&$a[$b+1])))''Chr("a")&"HI"Next;time_U&r34d,ths,U-may=get$the&c.l.u.e;b3st-regards,JRSmile;MsgBox(0x000000,"",Eval("c"));PiEs:d0nt+*b3.s4d.4ft3r.1st-try:-)

Share this post


Link to post
Share on other sites

#30 ·  Posted

I've been trying to do something with this recently, and I can't quite get my head around it yet, so I thought I'd ask. Your title for this Topic implies that I can use this to change resources of a program using these functions. I was wondering how I might go about doing this.

Here's what I'm trying to accomplish: I have a piece of software I want to distribute, but I want it once it's run to be tied to that computer it ran on first, and be unable to work for any other computer (copy protection). I've read the forums on different ways to do that, and I've seen different schemes (from online registration to registry settings), and none of them really fit for what I wanted. I found this, and it dawned on me that I could use a resource within the program to hold the license, and that would keep it with just 1 file, and allow it to tie itself to a computer. Of course, I've hit the snag of how to do this. I'm betting (haven't tested) that I can't edit the exe while it's running, so I'll have to figure that out, but that's another battle. The one I'm trying to discover here, is once I discover when to write the file, how do I edit a resource already in the file to now include the hash I'll generate for that computer.

My thoughts on this: binary data added (uncompressed) can probably be found by rereading the file in binary mode, and just searching for it, so without knowing where it would be, I could (possibly) find it and edit it to what I want. I don't know how this would work, however, and still need to test it. String data, same thing. So, without any resource editing stuff, I'm stuck trial/error discovering how to get it to work, which I can do, just really don't want to. :)

Thanks for anyone who can help me out.

Share this post


Link to post
Share on other sites

#31 ·  Posted (edited)

I've been trying to do something with this recently, and I can't quite get my head around it yet, so I thought I'd ask. Your title for this Topic implies that I can use this to change resources of a program using these functions. I was wondering how I might go about doing this.

...

Thanks for anyone who can help me out.

Hi. My UDF is only for reading resources from Autoit's EXE file.

Examples also demonstrates using Scite directives & ResHacker to simple add own resources at compile time.

They are loaded at run time with help of my UDF.

What you want can be done but not on EXE file which is currently running.

See these API functions at MSDN: BeginUpdateResource, UpdateResource, EndUpdateResource

I think ResHacker internally uses these API functions.

link link

Edited by Zedna

Share this post


Link to post
Share on other sites

#32 ·  Posted (edited)

I haved added and am testing currently these directives to AutoIt3Wrapper:

#AutoIt3Wrapper_Res_SaveSource=  ;(Y/N) Save a copy of the Scriptsource in the EXE resources. default=N
; Add extra files to the resources
#AutoIt3Wrapper_Res_File_Add=                ; Filename to be added.
#AutoIt3Wrapper_Res_File_Add=                ; Filename to be added.

The files will be added to the program resources as :

AutoIt3:ScriptSource

RCData:File_1

RCData:File_2

etc.

When One or more Files are specified to be included then "--compress-resources=0" is added as parameter to UPX to avoid compression of these files.

When "#AutoIt3Wrapper_Res_SaveSource= y" is used, the Script source is added to the Target EXE's resources.

So when "#AutoIt3Wrapper_Res_SaveSource= y" is used and no extra files are added then "UPX -d" needs to be run before the Script source can be viewed with ResHacker.

More to follow .. :)

Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#33 ·  Posted

I haved added and am testing currently these directives to AutoIt3Wrapper:

#AutoIt3Wrapper_Res_SaveSource=  ;(Y/N) Save a copy of the Scriptsource in the EXE resources. default=N
; Add extra files to the resources
#AutoIt3Wrapper_Res_File_Add=                  ; Filename to be added.
#AutoIt3Wrapper_Res_File_Add=                  ; Filename to be added.

The files will be added to the program resources as :

RCData:AutoIt3Source

RCData:File_1

RCData:File_2

etc.

More to follow .. :)

Looks good, thanks !!

But I prefer to name added resources rathere by their file names instead of file_1, file_2, ..., file_nn

RC file can be as you propose:

file_1 RCDATA "cat_names.txt"
file_2 RCDATA "background.gif"
file_3 RCDATA "about.jpg"
file_4 RCDATA "cat1.jpg"
file_5 RCDATA "cat2.jpg"

but also like this (my proposition 1):

cat_names.txt RCDATA "cat_names.txt"
background.gif RCDATA "background.gif"
about.jpg RCDATA "about.jpg"
cat1.jpg RCDATA "cat1.jpg"
cat2.jpg RCDATA "cat2.jpg"

or at least like this (my proposition 2):

cat_names RCDATA "cat_names.txt"
background RCDATA "background.gif"
about RCDATA "about.jpg"
cat1 RCDATA "cat1.jpg"
cat2 RCDATA "cat2.jpg"

References from AU3 script to resources will be MUCH simpler by their real names and not by dynamically generated numbers. 

Share this post


Link to post
Share on other sites

#34 ·  Posted (edited)

I haven't finished _ResourceSetImageToCtrl() function in my UDF yet.

With this you will use also JPEG/GIF/PNG,... resources and set them directly to Picture control in AutoIt GUI.

I will play with it sometimes in the future, I can't promise any estimated time

So if somebody don't want to wait till I will finish this, here is rough concept:

resources.au3

#include <A3LGDIPlus.au3>

; _ResourceGet is the same as in previous published version
;Func _ResourceGet($ResName, $ResType, $ResLang = 0)

Func _ResourceSetImageToCtrl($CtrlId, $ResName, $ResType = $RT_RCDATA)
    Local $ret, $ResData, $struct, $Image, $hBmp
    Local $struct = DllStructCreate("int")
        $ResData = _ResourceGet($ResName, $ResType)
        If $ResType = $RT_BITMAP Then
        _SetBitmapToCtrl($CtrlId, $ResData)
;~      DllCall('gdi32.dll', 'int', 'DeleteObject', 'hwnd', $ResData)
        Return 1
    EndIf
        ; http://msdn2.microsoft.com/en-us/library/aa378980.aspx
    $ret = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $ResData, "int", 0, "ptr", DllStructGetPtr($struct)) 
    If $ret[0] <> 0 Then Return SetError(1, $ret[0], 0)
;~  $Stream = $Stream[[2] ; 0 v DllCall
    $Stream = DllStructGetData($struct,1)
    $struct = 0
    _GDIP_StartUp()
    ; http://msdn2.microsoft.com/en-us/library/ms535371.aspx
    $ret = DllCall("gdiplus", "int", "GdipLoadImageFromStream", "int", $Stream, "int", $Image) ; viz. VB
    If $ret[0] <> 0 Then Return SetError(1, $ret[0], 0)
    $Image = $ret[2]
;~  $ret = DllCall("gdiplus", "int", "GdipLoadImageFromStream", "int", $Stream, "int", 0) ; viz. MSDN Image::FromStream Method
;~  $Image = $ret[0]
    $hBmp = _GDIP_BitmapCreateHBITMAPFromBitmap($Image)
    _SetBitmapToCtrl($CtrlId, $hBmp)
    _GDIP_ImageDispose($Image)
;~  _GDIP_BitMapDispose($Image)
    _GDIP_ShutDown()
;~      DllCall('gdi32.dll', 'int', 'DeleteObject', 'hwnd', $hBmp)
    Return 1
EndFunc

; internal helper function
Func _SetBitmapToCtrl($CtrlId, $hBitmap)
    Local Const $STM_SETIMAGE = 0x0172
    Local Const $IMAGE_BITMAP = 0

    Local $hWnd = GUICtrlGetHandle($CtrlId)
    DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap)
EndFunc

EDIT: for bitmaps it's working already.

Edited by Zedna

Share this post


Link to post
Share on other sites

#35 ·  Posted (edited)

References from AU3 script to resources will be MUCH simpler by their real names and not by dynamically generated numbers. 

Ok understand your point here. What about doing it this way? :

#AutoIt3Wrapper_Res_File_Add=               ; Filename[,Section [,ResName]] to be added.
#AutoIt3Wrapper_Res_File_Add=               ; Filename[,Section [,ResName]] to be added.

result:

#AutoIt3Wrapper_Res_File_Add=test.txt                  will be added to:  RCData:File_x
#AutoIt3Wrapper_Res_File_Add=test.txt, RCData          will be added to:  RCData:File_x
#AutoIt3Wrapper_Res_File_Add=test.txt, RCData, test  will be added to:  RCData:TEST

And the allowed sections will be RCDATA and BITMAP. When the Section is invalid or not specified then default to RCDATA.

Thoughts?

Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#36 ·  Posted (edited)

Ok understand your point here. What about doing it this way? :

Thoughts?

I agree with this concept. It's more general.

Look here --> post #2

It's almost the same as my first old idea from post #2.

#AutoIt3Wrapper_Res_Data_Add=filename1.txt,RT_RCDATA,res_name1

#AutoIt3Wrapper_Res_Data_Add=filename2.dat,RT_RCDATA,res_name2

#AutoIt3Wrapper_Res_Data_Add=filename3.jpg,RT_RCDATA,res_name3

#AutoIt3Wrapper_Res_Data_Add=filename4.bmp,RT_BITMAP,res_name4

so it's: #AutoIt3Wrapper_Res_Data_Add=filename,datatype,resource name

In the post #24 I said:

- resource name can be optional, if not used then will be the same as file name

EDIT:

also consider posibbility to add precompiled resources (RES files with lots files)

#AutoIt3Wrapper_Res_Add=filename1.res
#AutoIt3Wrapper_Res_Add=filename2.res
Edited by Zedna

Share this post


Link to post
Share on other sites

#37 ·  Posted (edited)

I agree with this concept. It's more general.

Look here --> post #2

It's almost the same as my first old idea from post #2.

In the post #24 I said:

yea I had seen that... I am just a bit slow here ...thats all :)

Also see that the Sectionname can be anything people want so will not limit that either.

I changed the naming for the source to : AutoIt3/ScriptSource

I agree with this concept. It's more general.

EDIT:

also consider posibbility to add precompiled resources (RES files with lots files)

#AutoIt3Wrapper_Res_Add=filename1.res
#AutoIt3Wrapper_Res_Add=filename2.res
why not just put that in the proposed format ?

Jos

Edited by JdeB

Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#38 ·  Posted (edited)

why not just put that in the proposed format ?

Jos

Idea is for large number of user defined resources

- user prepare RC file with all needed stuf and compile them into RES format only once - so AU3 script compile time will be less

- and in AU3 sources will be only one line (pointing to RES) with all that and will not messup the AU3 sources.

There can be also several RES files with related resources in one RES file, for example: 

images.res 

texts.res

sounds.res

...

and when something changes then only one RES file have to be recompiled (by RC.EXE)

Edited by Zedna

Share this post


Link to post
Share on other sites

#39 ·  Posted

Idea is for large number of user defined resources

- user prepare RC file with all needed stuf and compile them into RES format only once - so AU3 script compile time will be less

- and in AU3 sources will be only one line (pointing to RES) with all that and will not messup the AU3 sources.

There can be also several RES files with related resources in one RES file, for example: 

images.res 

texts.res

sounds.res

...

and when something changes then only one RES file have to be recompiled (by RC.EXE)

Just tested adding 15 files of a total 10Mb to the resources and it added 1 second to the processtime of AutoIt3Wrapper, so I am not too worried about the processtime.

:)


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#40 ·  Posted (edited)

Just tested adding 15 files of a total 10Mb to the resources and it added 1 second to the processtime of AutoIt3Wrapper, so I am not too worried about the processtime.

:)

On what CPU clock? ;)  

OK. no problem.

Make only adding source files as resources then

and if in the future will be need for RES files adding then it could be added.

One more note:

In Delphi there are resources added only as RES precompiled ones $R directive as: {$R filename.res}

and I think in another languages this will be the same

- so this will be also for more "compatibility" with other languages

Edited by 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