Storing images in the script itself and than displaying them in an animated button (picture control)

Put simple Tips and Tricks that are not entire Tutorials in this forum
User avatar
Gio
Posts: 450
Joined: 30 Sep 2013, 10:54
Location: Brazil

Storing images in the script itself and than displaying them in an animated button (picture control)

12 Sep 2018, 18:18

Hello there :angel:

If you are a beginner AutoHotkey programmer and have set yourself to learn how to program GUIs, you may have noticed what may seem like "limitations" of the standard GUI controls and their options. For the picture control, in example, a shallow look takes us to conclude that it relies on an image file path for the picture, which means that any user can change the images in the GUIs of your program at any time by simply altering the image in that path. Another example: the button control seems to lack some form of texture or color adding routine, which is upsetting to those who would like to develop some GUI aesthethics.

Both of these situations are not flaws. The standards of the GUI Controls are exactly what they are: standards. What this means is that it is still possible to do the things you want to do, it just means you will have to go beyond the standard options (and this basically means coding a little bit more). To illustrate this paradigm, it suffices to say that over the years, users have already provided added functionalities that allow not only for images in buttons and pictures without files, but also many other implementations.

:arrow: For this reason, this tip/trick topic is yet another demonstration on how to overcome standard GUI options, and in this example we will basically: stop a user from disrupting (deleting, altering) the picture controls associated image (by restoring the original images the programmer choose right before the scripts uses them with in-script data) and also, how to simulate an animated button with images (by using a picture control that responds to mouse hover and mouse clicks, altering its image accordingly).

:arrow: Working around a standard option may have some implications which the developer has to fully understand in order to judge wether the method presented is really a valid solution to his problem. That is one of the reasons for why these methods have not become standard options themselves. Nevertheless, if the method works for your design, and the implications are not affecting your idea, you are free to use and benefit from these non-standard ways.

First the sample code for testing (explanations below it):

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



:arrow: The first trick here is simple. We are storing hex strings which correspond to the image file binaries inside the script. Using these strings, we than rewrite the image files right before assigning them to a GUI. This solves 2 possible problems: First, the script can now be distributed alone and the GUI will still display the images. Second, if the user has deleted or changed the image files, they will still be restored (overwritten) before usage, which means disrupting the scripts GUI from using the intended image is now a little harder.

As a second trick, the script is using OnMessage() to monitor mouse movement and clicks ir order to correctly animate the image. This transforms the picture control into some form of rudimentary button control. Mouse cursor is set to a hand if the movement takes the mouse to an area inside the image and the pictures image is changed if the mouse clicks inside the same area.

Final Thoughts:

The routine sample is just a proof of concept and can be improved in many ways. It is possible, in example, to add some form of integrity checks to the overwritten image files before assigning the images to the GUI. It must be noted also, that even though the image binaries are stored inside the script, the script still makes use of image files. There are many ways to overcome this situation too if needed. The math that determines whether the mouse position or click is inside the image is a simplified and a bit flawed: It is currently considering a retangular area, which goes beyong the image borders a little bit. Finally, It is a known-limitation of this method that some functionalities of real button controls are not present in this simple picture control version of a button.

Regards,
Gio

:arrow: EDIT: An example script on how to obtain the hex strings of an image file using only AutoHotkey:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



KEYWORDS: Picture Control Image Button Texture GUI Color Colour coloring File Change Changing Alter Altering Hover Mouse pointer cursor.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
User avatar
Alguimist
Posts: 290
Joined: 05 Oct 2015, 16:41
Contact:

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

13 Sep 2018, 04:53

A modified version:

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus


What should be noticed in your script:
• The files are created without checking if they already exist, which may overwrite a user file with the same name.
• The code that creates the files is repeated three times. Why not writing a function for it?
• Unnecessary use of DllCalls: CreateFile, WriteFile and CloseHandle. Why not FileOpen, File.RawWrite and File.Close?
• The first parameter of LoadCursor is hInstance (which should be 0 in this case), not the hWnd of the window.
• There is no need for WM_LBUTTONDOWN, simply assign a g-Label to the picture control.
• There is no need to check the coordinates of the picture in WM_MOUSEMOVE: identify the control by its global hWnd.
• The cursor should be set in WM_SETCURSOR (the style SS_NOTIFY (0x100) is needed in this case).
• The picture button can stay in pressed state when clicked and changed back to hovered state in WM_LBUTTONUP.
• Why including the picture data in the script, instead of providing everything in a compressed file?

When it comes to custom buttons, Class_ImageButton should necessarily be mentioned.
User avatar
Flipeador
Posts: 1004
Joined: 15 Nov 2014, 21:31
GitHub: Flipeador
Location: Argentina
Contact:

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

13 Sep 2018, 05:01

Also, why do you use UINT with handles and memory addresses? Both are of type UPTR.


Edit: What is "uint", "NULL" :shock:
Windws 1♂ Pro 64-Bits I make scripts for AHKv2 (my v2 compiler) & WIN_7+ Spanish Argentina SublimeText 3 & AHKv2 My GDI+ Library
User avatar
Gio
Posts: 450
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

13 Sep 2018, 09:04

Thank you both for the suggestions.

The files are created without checking if they already exist, which may overwrite a user file with the same name.


This is intended behaviour. If the user (not the programmer) tries to change the image files in the scripts folder (so as to change the corresponding image in the GUI) it will not work precisely because the script will overwrite the newly added files with the old ones as soon as it is executed. The original images (the ones the developer choose) are restored on each execution through overwriting of the image files using in-script data. There is also no need to worry about a possibility of overwriting legitimate files: the routine will only overwrite files with those precise names and only if they are located in the same folder as the script. Any files that meet such exclusive criteria were probably set there on purpose (as an attempt to change the GUIs image).

Why including the picture data in the script, instead of providing everything in a compressed file?


The idea is that the script works as a standalone file. Also, it prevents messing with the image data without accessing the source.

All the other suggestions are valid :thumbup:

Also, why do you use UINT with handles and memory addresses? Both are of type UPTR.


Old basic code which i recycled. Changed only what had to be changed.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
DRocks
Posts: 92
Joined: 08 May 2018, 10:20

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

16 Sep 2018, 18:17

Been wondering about this for long time thanks to you and Alguimist


How do you acheive this:
We are storing hex strings which correspond to the image file binaries inside the script

How do you extract this data from an image?
User avatar
SpeedMaster
Posts: 212
Joined: 12 Nov 2016, 16:09

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

16 Sep 2018, 19:02

DRocks wrote:How do you extract this data from an image?


The storage of images in base 64 takes less space than in Hex (base 16)

You can find an encoder\decoder for base 64 here
https://autohotkey.com/boards/viewtopic.php?t=35964
DRocks
Posts: 92
Joined: 08 May 2018, 10:20

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

16 Sep 2018, 19:25

Ty! :)
So far its one of the coolest things I've tried in AHK. I'm creating a MouseOver Lock icon that move its so fun.
User avatar
Gio
Posts: 450
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

16 Sep 2018, 21:44

DRocks wrote:How do you extract this data from an image?


I commented it on the code. I used a third party program called HexEdit. There is a menu option in the program that allows you to export the hex strings (File -> Export -> Hex Text). I then used the SciTE4AutoHotkey text editor to substitute the empty spaces between the hex bytes (A sequence of 2 hex digits is used for each byte, and the sequences come separated by whitespaces when you export the hex from HexEdit).

As a side note, it is also possible to create a routine that obtains hex strings from files directly in AutoHotkey. Might do one when i get the time.

EDIT: Done below.
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
DRocks
Posts: 92
Joined: 08 May 2018, 10:20

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

17 Sep 2018, 03:51

Thank you Gio and sorry for missing that info from your OP.

Nice for the in Autohotkey solution!
User avatar
Gio
Posts: 450
Joined: 30 Sep 2013, 10:54
Location: Brazil

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

18 Sep 2018, 10:16

As promissed, here is a routine that retrieves the Hex String of a chosen image file (PNG, JPG or BMP) and copies it to the clipboard (so that you can paste it in the source code of the script in which you whant to include the images).

Code: [Select all] [Expand] [Download] GeSHi © Codebox Plus



:arrow: Use the script above only to obtain the hex string (it is stored in the clipboard once the routine finishes) for pasting in the script whose source should contain the image (In example, you can substitue the string that generates the button images in the example on top of this topic in order to change the button images).
"What is suitable automation? Whatever saves your day for the greater matters."
Barcoder - Create QR Codes and other Barcodes using only Autohotkey !!
burque505
Posts: 546
Joined: 22 Jan 2017, 19:37

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

18 Sep 2018, 14:18

@SpeedMaster, I use that SKAN enc/dec script you linked to also. @Gio, that's a nice couple of scripts!
Regards,
burque505
DRocks
Posts: 92
Joined: 08 May 2018, 10:20

Re: Storing images in the script itself and than displaying them in an animated button (picture control)

19 Sep 2018, 22:10

Thanks man Ill need this when compiling my script! Awesome tips.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 1 guest