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.
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).
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
Message_Monitor() ; This function will set the OnMessage commands to monitor mouse hover and mouse click (setting action if they happen inside the images area)
; The label definition below is for organization purposes only. The code in it sets the hex strings correponding to the image file binaries in variables, and than rewrites the files with these in-script binaries. The hex strings have been obtained by opening the image files using HexEdit (File->Export->Hex Text) and than proceding a simple substitution in a text editor to remove the whitespaces.
RESTORE_IMAGE_FILES_FROM_IN_SCRIPT_BINARY:
; The hex string below corresponds to the image file of an ordinary button.
FILE_DATA_ORDINARY_BUTTON_IMAGE := "89504E470D0A1A0A0000000D49484452000000570000005008060000006CCDE9D40000000467414D410000B18F0BFC6105000000097048597300000EC200000EC20115284A800000001974455874536F667477617265007061696E742E6E657420342E302E3137336E9F630000051249444154785EEDD64D4EDC4010866196AC58B1418AC42677C96972981C85AB708F2C922CA248480E0553EEF2D76FFB67DC9EF1D88EF44472E1EEAEFAC663B86B9AE6B0102C1EEAC0E2A10E2C1EEAC0E2A10E2CAEC1FB3FFBAF97AE591B2C5E920656839E712D585C92067109DAC3A56071093AF035684F4BC3624D3AE05A689F4BC0E25C3AC8543FBF7C1D8DD64FA1BDD784C539B4F93128B439E88C3E3A432D583C8736DC8702590A9D5FA233CD85C5A9B4C9121AFE52A81FA2B3CD81C529B43942C35E0BF5A774C67361710C6D88D0706B41FD2A9D792A2C0ED126140DB356D47FA4B34F81C53E7AB8A201D68EE6883483B1B0D8470F8EA8F15B41F3449AC318582CD1031D357BAB683EA3598C8145A28745D4E42DA3198D6632048B4A0F89A8B95B47733ACDA60F16951EE0A8B1ADA0799DE65382C5483776D4D0D6D0DC46332AC1A2D34D1D35B25534BFD1AC08169D6EE8A8892DA30C342B8245A39B393A7CEB2807A399292C1ADDC8D0C17B417968668A8BB289A343F782F2309A5DC445D9C0D0816BF4E7E57D84DF9FFE7DB7DA73F3F7F5AE79FBF19CDD3B15E5A2D9455C940D0C1DB63ADF1FDA60D567D0F3502E9A5D941764B1A3C3D6E6D78FFBA6797D6C7ED9750CFAE509EF9F8A72319AA1CB0BB2D0D0417B45F968862E2FC8424387441F4F4CF80A260FCD1FB8FFC3B7C7E60DD674DF8D4FCD3FB8A7EBBEF9FB2DEC7B7AC7FACF07DFB5A3FA48281FCDD0E5055968E89028FE12C9E9F043F7BFF3AFF6A870E503D4B0DABD72E3FB48281FCDD0752F6491891B97B44DC666C23BAFF314F4BC0BE337809E9CF69C9E77A8DFF3F6F2700A39FF703FCCE883728A39BAEE852C30BA31C170C353971A0C5FD9C213959EA6FC95321CAE9F6981A6B3F280E6F54139C51C5DF7421698B8690986DB3E19E1C9095F597A224C7A6A7A5E27A570FDCC531FED5E1AE0CC3E28A798A3EB5EC80213372D499FB292C6C250C5BF3BE94339190AD77FDE06D69E57B70FCA29E6E8BA17B2C0C44D4BCAE17ECA875D22DCF84AF05AE1D57093E1CAD72F857E7A6F85A1AABF16DA300A626F33FBA09C628EAE7B210B4CDCB4A4146E1AC21B0C7F5AE9BD1FFA7FD1F4859B3EC8B2F494CEEB83728A39BAEE852C3071D39252B869E0F41B373D11F9531303A2AF6B39DC1456BE2E0419D6CDE983728A39BAEE852C30BA3189CD906EF3E1A928C1776A39DC1454FE679349FDC59F9FDF07E5147374DD0B59606873159F82AEFC7DD5BFA67CBF29855BAAB7C2FB589FC473FAA09C628E2E2FC8224307EC15E5A319BABC200B0D1DB257948F66E8F2822C3474C85E513E9AA1CB0BB2D0D1417B43B918CDD07151161B3A6C6F2817CD2EE2A26C60E8B0BDA15C34BB888BB281A303F782F2309A5D8445A39B183A742F280FCD4C61D1E8468E0EDE3ACAC168660A8B4E3773D4C09651069A15C1A2D30D1D35B05534BFD1AC081623DDD451235B43731BCDA8048B916E1C51435B41F33ACDA8048B4A378FA8B12DA0598D66D3078B440F71D4D8ADA3398D6632048B257A98A3066F15CDE7348F21582CD1C314357B4B6826A7598C81C53E7AA8A2A6D78EE6883483B1B038440F5734C05A51FF91CE3E0516C7D026080DB316D4AFD299A7C2E214DA10A1E1AE85FA233AE739B03895365642C35E0AF54374B639B0780E6DB20F0DBF143ABF44679A0B8B7368C3432890B9E89C3E3A432D589C4B9B9F8A022BA1F55368EF3561B1161D644DB4D72560B1361DEC9AB4B7256171493AEC25680F9782C54BD2206AD033AE058BD7A661F5D1B56B82C5431D583CD481C5431D583CD481C5430DCDDD7FF2957802F31AA04F0000000049454E44AE426082"
; File writing is done through DllCall().
VarSetCapacity(FILE_BINARY_ORDINARY_BUTTON_IMAGE, StrLen(FILE_DATA_ORDINARY_BUTTON_IMAGE) / 2, 0) ; Prepares a recipient variable for DllCall()
Loop % StrLen(FILE_DATA_ORDINARY_BUTTON_IMAGE) / 2 ; Loop to insert the binaries of the file byte-by-byte into the recipient variable.
{
NumPut("0x" . SubStr(FILE_DATA_ORDINARY_BUTTON_IMAGE, A_Index * 2 - 1, 2), FILE_BINARY_ORDINARY_BUTTON_IMAGE, A_Index -1, "UChar") ; Inserts each byte.
}
HandleToFile := DllCall("CreateFile", Str,A_ScriptDir . "/OrdinaryButtonImage.png", Uint, 0xC0000000, Uint, 3, Ptr, 0, Uint, 2, Uint, 0, Ptr, 0, Ptr) ; Creates a file (overwriting previous files with the same path)
Result := DllCall("WriteFile", "Uint", HandleToFile, "Uint", &FILE_BINARY_ORDINARY_BUTTON_IMAGE, "Uint", StrLen(FILE_DATA_ORDINARY_BUTTON_IMAGE) / 2, "Uint", "NULL", "Int", "NULL") ; Writes to the file (overwriitng is set on).
DllCall("CloseHandle", "Uint", HandleToFile) ; Deletes the file handle (saves memory space and frees the file).
FILE_DATA_MOUSE_HOVERED_BUTTON_IMAGE := "89504E470D0A1A0A0000000D49484452000000570000005008060000006CCDE9D40000000467414D410000B18F0BFC6105000000097048597300000EC100000EC101B8916BED0000001974455874536F667477617265007061696E742E6E657420342E302E3137336E9F630000082249444154785EEDDBCB6B5D551406F0685FA1D1D847ECD3A6E9431DF9404114073AB282E0488482203A12A482A8883A10144110850A4E8A223855848038A81351D181A250ACF84F24695E4DD3A6D99EB59375CF3ADFF9F6B9E7B1CFBDB778859F7057CEDE7BED2FE7EEDC36A723CEB9A196D0E2501CB43814072D0EC5418B4371D0E22048FE93FF15C2318386167B09038B01D7E8175A6C1306D10BD843AFD0621B70C3FD803DB58D1663C20D0E0AECB30DB4D8146EA4AA993B4E96C6C65781BDC7448B4D60F365B0D09A606B14C13DC4428B7560C34558206D61EB87E09E9AA2C5AAB0C910B6F95E61FD30B8B72668B10A6C8E619BED17D61FC23DD6458B6560430CDBDCA060FD22DC7355B4D80D3681D8660615EBDFC2BD57418B45707184CDCF3D32E92EBFBD3B57EF97CBEFEE72F34F1ECED4D83E2CCCA02C5A2C820B5BB66131FFF421B7FED74DCEFD3BE2965FDF9BFB7AAF2DBFB9C7F7223DF522605A0CC105956DD25AF968DC6F462D3EB79F5ED70B4BAF4C647AB972F6567A1DDB9FC02CCAA0450617B35893DEE409B7FAD5CECE86D62F8EE4EE985E587A391BECEAB931DF1BBB56B03D0ACCA41B5A44B888C59ACB3879DC5D9BDED1D9D8F53F6EF6E730BDB6050BA70FF86F6A27D82F7716062BD83E1566538416112EA05863CCEC3D536EEDC7AD69C03F6FF135766D4C18ECD5AF47FD379B5D8BD87E15E613428B164EAC584345E46E95BB56377AEDBBEDA5375A87FF615A3358C5F62D30A3105A5438A9628D9421E76DE62D9A9CC7DDDEA275F875363FA588B5F3DBDCECDDC7E8B5DDB0FD0BCC8AA14585132AD64459F256D54D8B954FC6E97575D1601B1E412C03CC8AA145819329B67855CBAFEECD04BCFCD61E7A5D55FEE8F9754B1A6C72CEC738DB590E023343B4287022C116AE6BE5C3DB7C00EBFF243FE07EBFD92D3C73905E57D6DC8347DDDA0FDBFC7C32AF841CF35309CB033343BC089328B6686DF219F8F3311FECD56F46DDE57776D73E1767A64EB8E5D7F6FA7964BEEBBFC40D56B03C046667F1224C20D8828D253FBD573E1EF7C15E7AFC889BB9ABE6A7873B8FFBF132CFDA9FC91666120BC90FCC33F2F5A36EE54272449C3D9A1F5711CB05B3B3781126106CB12892402F3D96049B043473A4E62707192701BF3FE6DC6CB2852458B41174332C17CCCECA1760B0628B45231FC7EA06AB92F1F39F267F12BC30E1E6E5F599F134DCE966E7B962B908CC50E50B3050B085FEAF583E98A1CA1760A0608B58F36747336FC1D4B85B24D77BA726DC1A19933D1B0FBA55724DD6A85B3965E6DD3C63F5EB5DCFDA527DA4583E98A1CA1760A0608B588BD3C950D2E006DC7CB7EB13FAD62E152E7C0331ACCE5C79E5FB48B17C3043957D0183849D38A4D3A46DC69C7999BBA0E02CB4EF0076E774D6293843F59AB5E9F1CD90F3DF5CAF411F2C279BA3CABE800102276668B8E6AE4B1B346FD9C01D95DE4DF923A57BB8BAA6049AAE950FA8591F2C279BA3CABE8001C24E1A42C3EDDC19E6CE316F59764788F4AE29384E42E1EA9A9B7D74E6C2001BF6C172B239AAEC0B1820ECA421E9771941636653C1CF9DEC9BB2A95BB8FAF54E609DF5E2F6C172B239AAEC0B1820ECA421E17037E437DB46B8F648D05AE068B821C385B75F1AFAE6B9653615FD58E88411607B6BD807CBC9E6A8B22F6080B0938684C24D37A10D9A8F5678AD57FC83A628DCF41B1996DEA5CDFA6039D91C55F6050C1076D29050B8E986D39FB8E91D91BF6B6C40ECED1A0E370D2B3FCE0469C635E983E5647354D9173040E0C48C6D86C9366FEE8A107AA686C34D83CA7F6C12697FF6EBF5FB6039D91C55F6050C106C7264EF82ACFC79151C335F7CBD08851BAA7798F318EF44DE7B711F2C279BA3CA176090600BC4347BEF949B7B20B9BB8FD5FC9B311957776C452C1FCC50E50B3050B04562997B68D25DF9EC16B7F4D2ED6EEEE1C924A40A7F612E7F4D79E2B81FB7F8C23E377B7FFBCF42B07C3043952FC040C11689417E15B3F6D356FF9088FC9A7DE9CC840F8B5D4BC9DFE13E71D82DBFB1C78F976713DA7ED884E58319AA7C01062AB65013F20B45FD4DEDFADF23EEDAF7DB7D8D5D5B64F6BE291FEAF5DFB66CCCF3ED8ED61E3661B908CC50F1220C166CB1BAFCE34DE7B7757E052ECF195C7AF408BDB68CF9A70EB9F50BE9B30AAB5F143F685717CB05B3B3781126106CB13A58B0319E7C5C7C7E7F674E21BFBA67D735C172C1EC2C5E8409145BB092E4ED6A9F788C15ACD2879B55CC07AE591E02B3B36851E024822D5A5A12AC9C8D9D602F8EB885670FF06B1B90C7A36CC0B11EB8667960668816054EA4D8C25D251FAF72C19E8E1FAC270F9B447EE09AE5203033448B0A2753AC8120D9ECB9B1CE66859C8FF4DA58E0F869FAC035CB00B3626851E1848A35409160E5DF26D06B23F33F38233C70CDF62F302B86162D9C54B146109E7FBD0A56F9A71E1B3C70CDF62D30A3105AB470628B35A4563ED8788A515D7E6F17BDAE6DFE79DD1A0F5CB3FD2ACC288416114E6EB1C6E41FD2D9602568765DAFD479E09AED556036456891C145146BCC3EDD1DFBC9F1BAF4816BB98B175FDC47AF516C9F0233E98616437031C51A9480FD3FA46BE18FA175F97F9A9AFC51997D4DB1FD29CCA31B5A0CC1C5106BF646C2F6A4308B3268B1082E8A58D3838EEDC3C20CCAA2C56E7071C43630A858FF16EEBD0A5A2C039B60D8660605EB17E19EABA2C52AB021866DAE5F587F0CEEB30E5AAC0A1B0B619BED15D60F837B6B8216EBC0268BB0CDB785AD1F827B6A8A169BC086BB618134C5D629827B8885169BC2E6AB628185B0F15560EF31D1622CB8914182BDB6811663C38DF513F6D6265A6C136EB617B0875EA1C55EC22062C035FA8516FB0DC32A826307092D0EC5418B4371D0E2501CB43814072D0EC5E046FE03CC0CF56CF1DCBD380000000049454E44AE426082"
VarSetCapacity(FILE_BINARY_HOVERED_BUTTON_IMAGE, StrLen(FILE_DATA_MOUSE_HOVERED_BUTTON_IMAGE) / 2, 0)
Loop % StrLen(FILE_DATA_MOUSE_HOVERED_BUTTON_IMAGE) / 2
{
NumPut("0x" . SubStr(FILE_DATA_MOUSE_HOVERED_BUTTON_IMAGE, A_Index * 2 - 1, 2), FILE_BINARY_HOVERED_BUTTON_IMAGE, A_Index -1, "UChar")
}
HandleToFile := DllCall("CreateFile", Str,A_ScriptDir . "/HoveredButtonImage.png", Uint, 0xC0000000, Uint, 3, Ptr, 0, Uint, 2, Uint, 0, Ptr, 0, Ptr)
Result := DllCall("WriteFile", "Uint", HandleToFile, "Uint", &FILE_BINARY_HOVERED_BUTTON_IMAGE, "Uint", StrLen(FILE_DATA_MOUSE_HOVERED_BUTTON_IMAGE) / 2, "Uint", "NULL", "Int", "NULL")
DllCall("CloseHandle", "Uint", HandleToFile)
FILE_DATA_PRESSED_BUTTON_IMAGE := "89504E470D0A1A0A0000000D49484452000000570000005008060000006CCDE9D40000000467414D410000B18F0BFC6105000000097048597300000EC100000EC101B8916BED0000001974455874536F667477617265007061696E742E6E657420342E302E3137336E9F63000014FF49444154785EED9D097456C515C747129240484848202B0471DFF75D1454D0AA48F5504BF7D6D3A3566B7BBAEFB6B655BBB877B3ADAD756D553697AAB5D65A5BB55A4545AB62B182A2028A065104ADDEDEDFBC7793F93EE6255F42421260CEB9E790EFCDDCB9F7FFDDF9DF3BF3DEF7707DD936DB6C332F83060D72454545AEB8B8D80D1E3CD8959494B8D2D252575656E6860C19E2860E1DEACACBCB7384CFB8461FFA3286B1E840173A4DFF46D54240010470006AD8B061AEB2B2D2555555B9112346B8DADA5A3772E448376AD4282F7575755EEC6FAED187BE8C612C3AD0854E7487406FB0CDA2C80025E2884000011C80AAAFAF778D8D8D6EF4E8D1AEA5A5C58D1D3BD68D1B37CE6DB1C5165EB6DC724B2FF637D7E8435FC630161DE84227BA9983B90C68B3638368386251CAD265391BA0441F808C1933C66DBEF9E61EB86DB6D9C66DBFFDF66EC71D77743BEFBCB3DB65975DDCAEBBEEEA76DB6D37B7FBEEBB7BE1DF7CC635FAD097318C4507BAD0896EE630A0991B1B067C345B8418A844104B9765DCD0D0E09D27F20064871D76F02001DC5E7BEDE5F6D9671FB7FFFEFBBB030F3CD08D1F3FDE1D7CF0C15E264C98E0C5FEE61A7DE8CB18C6A2035DE8443773301773323736608B816C760E9816824AB4E0104BB5A9A9C92FE3ADB6DACA471A91B7E79E7BBA7DF7DDD7830470871E7AA89B3C79326AA43339FAE8A3DD91471EE98E38E2083F86B1E840173AD1CD1CCCC59CCC8D0DD8824D6124F77B803190E546C626A9B01489161C62A912492C61A28B4823F2B445815B170170C09E3871A29F83B99893B9B1015BB009DBB0115BB1B9DF524518AD646C788EA548B2D97AEBADDD4E3BEDE4F6D8630FBA4601E94D99346992A791FDF6DBCFDB802DD8846DD888ADD8DC2FA3D880252B13092C3BB237C905EE236AB4451D5F9F4234431B808C4DD8868DD88ACDD88E0FFD06608C301AA8AEAEF6A510DCB6EDB6DB7ABED31675B4AFE5A0830EF274818DD88ACDD88E0F46137D0A301C45FD48F6656951FA909DB5451D2A54BE33B452BE3B74B87C5FE5CCF2E172767995971FA4627F732D36BE2B72C0010778AA208AB11D1FF0059FF00D1FD77B0B81ADA9A971CDCDCD7E89698B3AD1919C3E240113B000EFC7C3AAE4DC61D572BECA851523E422959FE4099F718D3EF4650C63BB033851BCF7DE7B7B2EC6077CC1A73E013804968C0B67698B1A1E932F950D936F0CA9F0110A183F545000E8021580FB79458D5C5C5923BF52F97565AD5CA2F29BE1B9C2675CA30F7D19C35874A00B9D5D059AF20D9A20D9E113BEAD57808D63BB03EC1715D4AFA7A09EA58E136D441EA0FCC2839900F7BBE123E572952BAB46CA5555A3E46A95DFE7099F718D3EF4650C63D1812E74A29B39982B664F4C4876ECFEF201EE750E366029BE8D0AB4458D0CE573A5E5F2D5B20ABFFC89A61F695411613F53007EA94000CA65299800774DF528B9AEBA4E66AACC52993DA25EE6E4099F718D3EF4650C63D1812E74A29B39988B390B8D64767C06B051043EF71AC028A544B1AA405BD4B0504E2D1D2A5F4829004E8513CF53477F9A82FA5B0580A8230AAF4D8102B41B546E1AD1207FAC69909B556E51B9D54B632AC9675CA30F7D19C35874A00B9DE8660EE6624EE6C6066C89D99B2F50043B3B361C5645F44A9906E7708CC7B6515BD418934F960C91D31458B8F55B1AAD64FD1FAB632421F891A8C271228DA89B95020A5080F62705F0CFB58DF217953B6A9BE4AF2A77E6099F718D3EF4650C63D1812E74A29B39988B39991B1BB0059BB02D667F289C537002C76603DFC1A047F9976F0A52AFA8A8E0CFA8112609B0E5F26505161A80EF4830440E7C0837C29544179176A30A110838B7A760FE6D6493DCA5F28F91CD72B7CA3DC8A866B93715FECD675CA30F7D19C35874A00B9DE8660EE6624EE6C6066CC1266CC3C6981FA1B06D66CBCC59321880458F44AFD1019C03B96B8B1A8084C07E5B9316B52849854C4E76BF5CF9F00FEA244B97E80280DB1408A28F68FC7B0A1800DE376AB4DCAFF22F950790BAD1F260DD182FFC9BCFB8461FFA3286B1E840173AD1CD1CCCC59CCC8D0DD8824DD8868DD81AF32794EDB6DBCE9FAE810158F4083D144207D38B4BE5849232F9B452413EB0646E788F4463D10A47125D1E548D3800211A0109C00070AECA432A0FAB3CA232AFAE2547F88C6BF4A12F63188B0E7479905537733017735A14630B36615B0830B6C7FC43384326C1C1BF3D420F7C3364480E35B44527453E3EB84C4E516029B55866F9C0B224E1BFEBD3688523E14C0FAA0A80108980046080F7687D8B3CA6F26F95C75379A27EAC17FB9B6BF4A12F63188B0E747990553773301773323736600B36E5038CEDF810F3116193C12E0E7A009375AA1EF86638C8D0169D0CF988027BB2D2C1E7D5A86F6A5540B9435666D919B033D419962609074E841F59C2FF5400883600211201C9C07C52419CDF90C853A9FC2715FBDBAED3D7C04607BAD0896EE6602EE6646E6CC0166C3280B1159BB11D1F627E9A400FD4BF6C91C1A65BD1CB37D25912FBC0E052CFB39F559EFD9A1AF53DCDC0E7A891D49664678B589CA17C6289927C8828B892A54CB419A844A58109880B1A3697A755FE6BD2984AFA37D7E8638033161D0632BA9983B99893B9B1015BB0C922185BB119DBF1015F62FE9A503D70C8D3EDE4D659D4BEAFB8C4D301B52C5CC5AE8B429D9D11DBD22B94D78C0A88160396C413462BCBDA400D017D46414416AA2C6A1C1715AE59BF10680319DD611433B7018C4D4611D88ACDD88E0FF8D211FF726783E4D6ADE835AED51655FEDEE2C1F2218DDA933C1D94EB524A78969D10053B3B24764CECA462C09284E6A9E344184B9AA80318A23104F45995E702599C4AF8197D42A0D1812E74A29B39988B3963006323B66233B6E303BEE013BEC5FC47C2E8ED12F7F24D900DB545151FAF51FB098D5A360A6C6B594AD48D70D7A5BAC428DC29E229E84924F01D19DC8065C9C29116AD16A90B53B0DA806C1A27CFA7F242D31639629FD3C700672C3A2C922D8A998B390D606CC1266CC3466CC5666CC7077CC1277CC3C71806C6BDECDC0AAE1CF806A8E1B445954E0DA296AD2D19962D253B1F9616650EC982029E3A939A938402EF59C4B6039B449A45AA811A82F9622712826D205B24A39B390C608B606CC1266CC3466CC5666CC7077CC1277CC3C7180E089503B7EE39D829A8EEA50324AD6D2D65471415CBB48CA8A5A4610714D2013B2676509445F01EE592016B34000816AD06AA01B72495A51962D743A0D1D11EC5ED34D106B0DA802DD8846DD818D2033EE04B21D14BDDCBE13AB7870A4A6C697847954D291AEC2B8413356A3FA77CC4DEDCA2F612FDC6C9BCEC846E4AE9C078961D1589C573AC8FD8B139C086D16AA086202ECB90B08F811C4671083073323736600B3619FF622B36633B3EE08B452F3EE26B0C0FA44B892D8B122669D41EAB51FBD174C340363D43BF59CA1778CAA2960C4CA943E11ED2815505C6B1F9C0E647AA07B03991979AB78C8A5D37A019FBCA4C27AB5F72F2E63227AF7E0A8047CBD27B9CBC7C76B39FDBAA88901EB0159BB1DDA2179FF00D1FF1159F63B81835D89638B311D65955C27B346A29BFD8E67E46EB5A0EBD29BAC9AEDC0DA09C81B7D8665AD452C05367867460C92B06AC456116A02FA712BBC698A5A756CA5BAF3859B35C017E3901F88D254E56BEE0E4A513932417D203B661635BF4AAEDF8802FF8846FF888AFF81CC3056AE0C4ACD3AA21BD105572744009ECC6207B6EA570C2C42E876CCBDEDDB8363F6A298B3C1D28B096BC8C0AF2A3D50033303B13EBFFCAF965F2F643B5B21C9DA754F8085EA500BF7E4D9D9F93B93D3D44A2D7B8171FF0059FF00D1FF1159F63B8201CA873DEC0730F99E066F1ED21838A7D6DFB6105F75325C939AD5102E44F8DC88108BB1EB22F650E7C16462D75670E1D041CBB2EC09AD8B890268C8399CBF8171BB0258C5E6CC5666CC7077CC1277C336AC0677C8FE1C3C325DCADE890773BE2DBE394123EA67CCBC9D757759970D8CC8107CBE7EA138AE4B6394EEEBAD5C9BFEE7432EF5E274F3EE8E4BF8F96CBFCACA83DAC4656E9D27D4B97F0DBBA94FFF7AA93775AF5EF0B5A02D01A64F50A27F25A5CDED56BEFAE289355878700B7C8EB0F273AD1BDEADC317E85588916462FB5EFDCF155F2B8DA8ACDD88E0FF832EB04CE9F93431D7CC5677C8FE103EFF2504926EF12CE59E0528219DF728EC06D1B763156255CFB0D27B7DFE0E4EE3F3B79F02E278FDDE7E4A9879C2C7CCCC9F3F34BE4D90949E96551BBECDA24E9C08D21B08807EC915A6955A0962BB86B22A0E64AA5BCD6F66528B8936BE52DD5834E74AF79B0C6477218BD569A3D75696223B66233B6E303BEDC708D933FFC6888A7067CC5677C8FE1C3ED784ECA32EBDD2CBE1D3FA8488E54BE7D7F717248C3CD46CA93906F677CD3C91D3739B9F78A0AF9BB72173BA0073E3254163DEEE485FF38597266734A091A412757F844B39AA89D599F93C05A2F284BA351C1B9B045C105E07659797D0AE8F50D6B5D33705FD3A8E34B5A33BB5256FBE82D931593DAEB5F6CF0D4F0C961DE366C5C7071ADB7994D05F7E86E3CB558FE789D936B2F73F29BE9C9AD7F5F92A9EF6010C3A9C3A49605EE410A6E98CCD8B170B0CC01C7CFD2126CE6B79CDC79B3937F5E59A185B95509B5F2F4134E5E5CE064E959CD29258C96E5F76B16276A35A2483C4495F1A581F36E1A912BF5EF10C08EC0458C46DE692D9337262B3D6844523D400D9E7B15D8841A9A65B14629B63D775B95AF7BB139E45D7C9A718593CB7E3958CE535FF119DFC120861387E8999B892C702728B86C1E3E986E79394CE6D4284C66B34F77F2B75B9CDC77558566DE04DCB91F2D97E79ED4A85D5022CF4F4CCBAF4347C8CAA50925AC3A6F4C4ED45AE4B55E58962EF7327953B93404AF53704FABF451FF8ED2CAABFAB7AF1E22D4F0CC212364D9426CD3C83DA3D1EFD8C2928CEDF0CC938A65E6954E2EFF55915CB475B5F719DFC120861315C3F0E1C3BB06EE44AD148E5170394F3839A814D81E7237953BAB73BE9D2482FBD364365F13C4338F3A59FC64892C4AF93601B7A60DDCD74FCDAD690D5C00EA2EB8AFE975C07D5B93223A9729FF1A35B42A35E480BB4857D4D36AE72792928CED30772D3850A7DEBD6E4AA9CCBACAC915BF2E929F28B8563180410C270E7132CBB18EC09DAAE05A19C66E85FBFE3170AD52983F578DD644B1787EE2C032A5059FCC0017BEED00DCE5DD0637497E563D7870B57258093568E27C23AD1A7C528B804BBD1B823B43C19D7DB5932B01779B6AEF33BE6795637642D67570831A772D707537D306EED515726FB07978EAB78903CB170D93E74370D93D65D0C28AEED242FAA5584224A959C500B8AB1FA8D1F9D606F7D9339AD60697CDC4C9C509B89714C94F7B15DC422357C1B55B3818FCD8C1D5F28207B754961E42195627AD69E4BE35374D6839E0B6C89BF35200E7D5CA8A103C958EC0E51A8930135C9DB3D59F355031D4C99214DCC5B757CBA36B45EE48B9F16297807BD610BF0DEE35700BE6DC145CF80B70E7E747AE3AB6E49CD2045C1C3E7F4C0EB8BE5250600070CD69B9E0198071708D1254A78E4357420B504FBDBC9E82BBEABA7A6F833F983F4BBF70C0D5A4BBE0F4C61CCEBDF54C27B7CED68D8472EEA5BADAF0B55738B74BD5C25F9D3C728FEDCEB4CCF1D542C2B96D87354DA3A5F501054F1DCED940A411E7C1CD485859E01A95BCBBA27D43D10E6EFB49D9AAA515F2620AEE82866659A4F66223B66233B6E303BEDC32CBC9CCAF54B46D817BA55A28A4CE9D71627152E7DEE1E4E1BB9D3CA1E03DADCBFBB9274A64A1560BE1D6975A939AF3A573CB7C0D9ABB3B4B9251085C2859E0B651C29C8636603DB83A0FE0BE788A6E5C145C4EC8969FD4BE05E6F8F1F1EF94785BB119DBF1E1CE9B8B65CEAEC9D1233EE2EB3AD7B959C78D9DEDD03845E2249FDD0DBB1CBF434B0FC8730F6DDA4FC3C263C6FCA48684E01522E1D8306A9983B9D6DAA1A94DD86607E7E10E0D5FF24FC66C8716C3A7D363473EE8EED9028F6B72932F3C6EE44620CF0D70F26FB775F24FC4C2A3468BB610A418883109C7981E8B5AE6C83F19B3B3056CC3466C0D8F1DF1059FEC8EC43A9F2DD0B2C0EDEC54CC0ECAB9934A422031D87D334E9EB2CE7263D19B0F30120314C9EFD7066C46D4464FC5D4C63099E1437860DE23A762B48EEE9F6D3ACFCD3E2C2FE83C9770A694D0B696828170272204D6E8202B6A7BEA4E04CF2F147427820B03FA1E5A3A3EA403E6602EE664EE3EBB8746CBE25D6420DCFD8D016B74C0DCDDBDFB1BC30329F8EE2F0DCEC87A006FD3730BB9C2AF2EBBF4DC02614D21AC2DAA709A46EFC6F6C44D0C07A4CB4FDCD081F0A666D31655BAE959B1E4573E5D7E568C46786F7ACAB1E3A8EDD6538E34BE01321F19505B54F9C6F07C6ECC6F845F5776FBF95C5A4789CD64437EB23CE6AFC93A3D594EE39B80A43B8A5E6463FB4D043F595DE7DF44D02C7AF986B44527DB987ECDC3ABB57AE4D73C34E35E7E73C5A98FB6E8A41BD2EFD062FE99F4E8EFD0687C336443F6CEDAA2939A0CF45F50C67C32E9F15F50D2F866A8E1D8DE75F6DB5F6420FEF637E64728BCFC0D3AE8F1DFFED25062C9AD237A301948BF5A8FD91F0A6F70EAB55FAD5B0BE98153206D516342E10C94BD3987CDFDED7D0B317BF38557B2F4FAFB1668460FF6A610B887B768688B1A164A7F7A5348CCBE98F02A96F5F6A6101A4AC990708EBDE30692D71635305FA009CA1D0A757642D496384E54B14322D11069EC98883A80EAA977DCC4EC89C961871DE6DF6ABA5EDF7163CD00E6B00272A7E6EB0AC0083B20F86E7DBC9D29367F96F016D33E7B3B9335380752CF079865A42D6A789610C9DC4A21C11061804226871FB91BC0B694EC0E70A1F019D7E8435FC630B62B516AC25B4B7963699FBF57CC5A08B05104B79829B4B5459D2854BAF246BCD8F8AEC8E1871FEEFAD51BF1AC8500B31DB477397242DF57AF732D548E3AEA28FF32E37EF92E476BC6C1564570A011BE85943A515BD4C1BE10DE16CDAB5EFBFD5B48AD6104250A0719DCF288BD3F9744C1BB6BB5459DEE4D39EEB8E39C813AA0DE9F6BCD00E6DE3D871A2C2D0AEFFC373FE3186F61E66DCC24126D5140D645A64F9FEEA64D9BE6A64E9DEAE718D06F7EB686517094D1049140C6A508CF7A6739599A880284638E39C61D7BECB1A88A821613803CFEF8E33D988C45C706F7CEF2B085514CF1CDB691658743705B216FDBE70DFA80C4729E32658A072D143EDBA8DEB61F368C0D4126FBE210D1C252E48489EC4C24C17D9BFE9F886E340C67B98591CC5284E7B82D4DE983F32C55920B8010692C614022F2D8316DFA1F4E3A6816213846FD485626820C68962AA5108090BD49362C63228F532904E010FB9B6BF4A12F63188B0E7419A0CCC15CCC39E023B590867316CD38CD311E49858C0D202C5DC061190314D187709E8AD8DF5CA30F7D19C35874A00B9D0668DF44A973FF072EE9BC87558CB9B50000000049454E44AE426082"
VarSetCapacity(FILE_BINARY_PRESSED_BUTTON_IMAGE, StrLen(FILE_DATA_PRESSED_BUTTON_IMAGE) / 2, 0)
Loop % StrLen(FILE_DATA_PRESSED_BUTTON_IMAGE) / 2
{
NumPut("0x" . SubStr(FILE_DATA_PRESSED_BUTTON_IMAGE, A_Index * 2 - 1, 2), FILE_BINARY_PRESSED_BUTTON_IMAGE, A_Index -1, "UChar")
}
HandleToFile := DllCall("CreateFile", Str,A_ScriptDir . "/PressedButtonImage.png", Uint, 0xC0000000, Uint, 3, Ptr, 0, Uint, 2, Uint, 0, Ptr, 0, Ptr)
Result := DllCall("WriteFile", "Uint", HandleToFile, "Uint", &FILE_BINARY_PRESSED_BUTTON_IMAGE, "Uint", StrLen(FILE_DATA_PRESSED_BUTTON_IMAGE) / 2, "Uint", "NULL", "Int", "NULL")
DllCall("CloseHandle", "Uint", HandleToFile)
CREATE_WINDOW:
Gui, add, text, x20 y20 w360 Center, Image below is a button
Gui, add, picture, BackGroundTrans x156 y50 Center, %A_ScriptDir%/OrdinaryButtonImage.png
gui, show, w400 h300, Image button example using Picture control
WinHwnd := WinExist()
HandCursor := DllCall("LoadCursor", "Uint", WinHwnd, "Uint", 32649)
Return
; Message monitor is checking for mouse movement and clicks. It triggers the functions below it accordingly.
Message_Monitor()
{
OnMessage(0x200, "CheckCursor")
OnMessage(0x201, "CheckClick")
}
Return
; Function below monitors the mouse cursors position. If the cursor is in the pictures area, it changes the cursor to a hand cursor.
CheckCursor(WParam, LParam, Msg)
{
Global
MouseGetPos, Xcoord, YCoord
If (A_Gui = 1 AND XCoord >= 156 AND XCoord <= 243 AND YCoord >= 70 AND YCoord <= 150) ; The math to determine if the cursor is hovering the images area.
{
DllCall("SetCursor", "Uint", HandCursor)
If (Botao_Aceso = 1)
{
Return
}
GuiControl,, Static2, %A_ScriptDir%/HoveredButtonImage.png
Botao_Aceso := 1
}
else
{
If (Botao_Aceso)
{
GuiControl,, Static2, %A_ScriptDir%/OrdinaryButtonImage.png
Botao_Aceso := 0
}
}
}
Return
; Function below monitors the clicks in the GUI. If a click is performed inside the picture controls area, it triggers an action (msgbox).
CheckClick(WParam, LParam, Msg)
{
Global
Gui +OwnDialogs
MouseGetPos, Xcoord, YCoord
If (A_Gui = 1 AND XCoord >= 156 AND XCoord <= 243 AND YCoord >= 70 AND YCoord <= 150) ; The math to determine if the click happened inside the images area.
{
GuiControl,, Static2, %A_ScriptDir%/PressedButtonImage.png
Msgbox % "You have clicked the button! `n(Assign corresponding action in place of this msgbox command)"
GuiControl,, Static2, %A_ScriptDir%/OrdinaryButtonImage.png
}
}
Return
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
EDIT: An example script on how to obtain the hex strings of an image file using only AutoHotkey:
Code: Select all
#Persistent
#SingleInstance, Force
FileSelectFile, IMAGE_TO_HEX,,, Select the image file you whant to retrieve a Hex String for, Image files (*.png;*.bmp;*.jpg)
If (ErrorLevel)
{
msgbox, 0x10, Error, Error reading the file. Close any applications that are using the file and try again.
ExitApp
}
RESULT_STRING := FILE_TO_HEX_STRING(IMAGE_TO_HEX)
Clipboard := RESULT_STRING
msgbox % "The Hex String has been copied to the clipboard."
Return
FILE_TO_HEX_STRING(FilePath)
{
STRING_OUT := ""
ObjFile := FileOpen(FilePath, "rw")
FILE_LENGTH := ObjFile.RawRead(FILE_CONTENTS, 999999)
SetFormat, IntegerFast, H
Loop % FILE_LENGTH
{
If (StrLen(NumGet(FILE_CONTENTS, A_Index - 1, "UChar")) = 4)
{
STRING_OUT := STRING_OUT . SubStr(NumGet(FILE_CONTENTS, A_Index - 1, "UChar"), 3, 2)
}
Else If (StrLen(NumGet(FILE_CONTENTS, A_Index - 1, "UChar")) = 3)
{
STRING_OUT := STRING_OUT . "0" . SubStr(NumGet(FILE_CONTENTS, A_Index - 1, "UChar"), 3, 1)
}
}
SetFormat, IntegerFast, D
Return STRING_OUT
}