Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 07/10/2025 in all areas

  1. As the title says an UDF to extract the frames from an animated PNG (APNG) file. UDF: #include-once ; #FUNCTION# ==================================================================================================================== ; Name ..........: ExtractAPNG ; Version .......: build 2025-07-31 ; Description ...: Extracts the frames from an animated PNG file. ; Syntax ........: ExtractAPNG($sAPNGfile[, $sExtractedPath = @ScriptDir & "\ExtractedFrames"[, $iDefaultDelay = 50[, ; $sPath2DLL = ""]]]) ; Parameters ....: $sAPNGfile - a string value. ; $sExtractedPath - [optional] folder to save frames to. Default is @ScriptDir & "\ExtractedFrames". ; $iDefaultDelay - [optional] an integer value. Default is 50 ms. ; $sPath2DLL - [optional] a string value. Default is "". Path to the DLL. ; Return values .: number of extracted frames. If < 2 then error. ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func ExtractAPNG($sAPNGfile, $sExtractedPath = @ScriptDir & "\ExtractedFrames", $iDefaultDelay = 50, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then If @AutoItX64 Then _Extract_APNG_Frames_x64dll(True) Else _Extract_APNG_Frames_x86dll(True) EndIf EndIf Local $hDLL = DllOpen($sDLL) Local $iReturn = DllCall($hDLL, "int", "ExtractAPNG", "str", $sAPNGfile, "str", $sExtractedPath, "ushort", $iDefaultDelay)[0] DllClose($hDLL) If $iReturn < 2 Then Return SetError(1, 0, $iReturn) Return $iReturn EndFunc ;==>ExtractAPNG ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: Path2DLL ; Description ...: Return the path to the Extract_APNG_Frames_x??.dll ; Author ........: UEZ ; Modified.......: ; Remarks .......: This function is used internally by Extract APNG Frames.au3 ; =============================================================================================================================== Func Path2DLL($sPath2DLL = "") Return $sPath2DLL ? $sPath2DLL : @ScriptDir & (@AutoItX64 ? "\Extract_APNG_Frames_x64.dll" : "\Extract_APNG_Frames_x86.dll") EndFunc ;==>Path2DLL ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2020-06-05 Func _Extract_APNG_Frames_x64dll($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Extract_APNG_Frames_x64dll $Extract_APNG_Frames_x64dll &= 'DboATVqQAAMAAACCBAAw//8AALgAOC0BAEAEOBkAgAAMDh8Aug4AtAnNIbgAAUzNIVRoaXMAIHByb2dyYW0AIGNhbm5vdCAAYmUgcnVuIGkAbiBET1MgbW+AZGUuDQ0KJASGAFBFAABkhgsAEOXIi2gFV/AALoAiCwICIgCcAAyqzgADjgAnEwAHEAIebQcFAgO3AQAFAQwBANAiAQIUH7YBAtcAAD4gBCEFBwM+BQYGCoABBABagQOQAQCkD2EIctAAAKAELQIAwAgBAIiZicIAACjBkAvUkwEAcANIEgAgLnRleHSAAxiaDwRIgX0FbgQAYABQYGAuZGF0YYFmAHMAErCDgQCgixNAAGDIwC5yAxQQDoFZhCnioo4TQC5wwwnCOMA6hcIcss0JMEAueMMJKkzBCeDECbbQCWJzunPCKowCctSNwCdlwxPXwlzAXsIxutATacMJwmQLwGbCMbzOCcAuQ1KqVMECWAEBoMQTzM0JYEDALnRswifCfLAHxAnBmM0JcmVsb2O+AMN6wHzCCcFHyx1CoMkHPwA/ABYASI0N+d8AAADptCkAAA8AH0AAQVVBVFUAV1ZTSIPsKEkAicxNicWF0nUQeosV7IAEMcCFANJ+XoPqAUiLhB0UYD9FMeS/wVAIiRXOoANIiy3TAIQBAOsMDx9EEAAAueiAXf/VTACJ4PBID7E7SACJxkiFwHXpSACLPeq1AACLB0CD+AIPhO+AB7lSH4AA6C3AD7hhCUgAg8QoW15fXUEAXEFdww8fAIMg+gEPha8AA2VIEIsEJTAhBIsdl4FACEiLcAgx/4AOQl6BDhgPH4TjGTkwxg+Et+EKAxBIiSr4ARAzoQ/j4QU1aiHhDwaD+AHjD4sG4IXAD4SlIgGCAoFQIIX/D4SCYg0F2wq0wQAA4Ad0DU2JBOi64UBMieH/0ICDBdfeAAABsRZb4B/PAmbiAuAticAG6JJUAB7HByIWhzOCBUDpAf///5ACKukG' $Extract_APNG_Frames_x64dll &= 'VUAB4wUxwEiHA4TpdOYBSIsV6SISJA3SwADHBsEF6OeqJ2AGPWEEkOADqeMDkpLAAOjNIAPHBmEWrOko4gPDLb4BBgzhDaxBViE+4j0ggCMtgAYASYnNiRZBidQITInDYD9eiwXwAt0gIsB0Nei/hQGhA9gx0kyJ6ehEcpOCAUSJ4qEBVAGpAUGJxuiz/f8C/2AuA0Ux9kSJKPDHBoAN/+AhIFuSXqEhQV7kIehrYApgQY1EJP+mB6Awd0hw6HPiB3TARwzxEpIgBYnGgAJqQYOA/AF1cOjff4IOlrqBICEE3yUEdYzGFFbLYAKGAa6JAREgDOlmYMAS4V7oo2MHIAsDyA+FSqAC6R/iIyANyA+FN0AB68ZBDcM/SOnodMMF6SChKmYqLsVPkOAoSKBGdbMn4C4iAgBYdAoAH0jpBJH+4AlMiUQkOACJVCQ0SIlMJIgo6D0gGOgYiWAKaovgAovhAovgAuIFYZHhBUiJykBGVtzgNURBJuELjQ0JoTnkCeQWw5ALAOmrOAByAAgS6evgAegD4XpFoYBKjRVC5KJRU2AA2McFMVAAoiRckCEAMSCUwA+2wOErw0FGVyMiQkGB7NhAAkQQiYQkMNACSInTAkyQG3RIjVQkcPDHRCRwAQfQI6AAoWwIAOg/wARBicAxZMBFIAWFVCBjoQJ8gEiNTCR4MfZgAtZ4YQJwAHziAgDgAtAP4HxIx4QksYXSMbAAwfV2SYnO6OyAgzACQHhEifJJicAhxKzo0mARwBN4YAQ0UQIE/8ggFkhIjYQkRqjxA8AAQItscBWNCBXiq/AAa+1oTQCNdCxASYsO6Az/RzBngWxIidmJkMfocEoBChXPYQIoicFJEAHeAAIx0gCF/0yJ+Q+UwoT32pUR99ghwkAcCDjoHSADg3wkOHAAD4U88EZABQAEqAqqwAyjuQVEJEzoWhLTBaHAAdQFgCsCYGjo70kiAogjAqELaBToW0ECBUYCZOjKRUMCbUcC' $Extract_APNG_Frames_x64dll &= 'WOg2SQLHFOinIwJWJwJQ6BMVIAJEACZkASZQQYlIwzHAgAtgAAAN9yDYRYXSQQAORQ8AttJB99pECdAmRVEPIQEx/wABQQkAwkWF20APlMeA999BCfox/5ADBEwA8wCJ+kSJ11Ah1+gTMAdMoAVYYEyJyegGwgDgC0wgicHo+UghM/noQvFwAIX/dV1DEsXSqUASfkYKGO8QAqABdr6gASQSXQAC4hfBBkAgD7b/9984GMfoYp0yBQ+E16EucUC4gmRiW3wkQIO8QipIZLkKEAEPRiMrTBCNvCSQklnK/0HmufAmEAEFWPAGJC1ROJzzq6Ak0qJRCzs58QRejFIDsCgxJYIyQ/AUSGiNlCQxmEnQbYAOyMGwKUyJ8egIAQ+gEMJAgEJIidpI4l1RDuBNjQQsSJAG8ZgBKpFDNIQkyAEF8iMCBwHQT0CA3v/o80GXIWEAAuMS3IAH6E/AsmU6Jb5CCBXVwAEEEyxrIQKXIJ0DAr4DApEgOEToCSAChf9EoA5MhbEgOK8V99gJx0M7b8EhYBbxJcEQLnAAIBxUtTMJdDEJu0BcKBwsAwdibRUJxuiaAAIhHPELfwayBdoiHnQZRTHKyfMR2vFV5CKANaMQBv+APQAdNDl8JEggD4Mw/P/ABOHoAusQGkCE9g+ewBhIgcRRSYV2QV5BFF/DaIxIoGxIic7CuZFbRInNSMAdArrATIniRInD4QBRhcfwFxAHIgvF6NegADAGoEiJx/OkwQi/8QB1kE4og2PYkQJiWtBMMATogeYAiwH/UBAFEQKeJAEw/8NIiQjIdSWBAjhBieiX0QbwWNAGRBUC6CqSAIdwAUFf1oKAPYHWcAICdYA4Qbkgg7jtBXAqkBABSInQuQgBIifCSNHoQYPiAAFNhdJ0A0wxAMhI/8l16UmJAATQSP/CSIH6QVEqddHGBTpAAwEGwwOdEH1JictIiSjW6J3gY7gief/LUeBgTDHYQBswoAJCAA+2DAZJ/8BI' $Extract_APNG_Frames_x64dll &= 'EDHBSMGQLMHhAwiB4fiAikgzBArATDnDc965YgPwBgXCjcNwBXgx0osJekjwESRCEjAO0t3RJijdQQAwYg8yIoAAQJKRgABSSIUAUDGEAFg1AmBHo18ARCHT6DcrEDy2AWAFD7ZUJCdIwSDgGEgJ0LEAJUioweIQtAAmsAAIsAAJcAl4w6MfQDH2SASJ1+KBSInL6HATkGJwnHgRFAHZ6F4REQGNcAEEAfnoTUMAAYAoQYPI//ABSDwB8JMBNSPWDOLX6F8WJbAvpQMSoAMx0kgAiw9EigQRSI0EDDJxGAMLRIgBoEg50HPnYAlA0B0Ww9p0gdS+AwTXSIkizbIETYnE4ARMjQBsJEhMjXQkRwTouVgGSInD6LnxkC9I/8MiAbAKEixhEvhIKcNxC4Er9gqmCvEmEEmLBCTxSMHqGAyIEIAA8QAHuQBIweoQiFABSECJ2kmLBCQA0AgIiFACAVCIWAPHEEQkSAAAAEyJbCQkUAEQWEgASGAEUwBIASBoAQQgcAUQeGIxAhCEJIAADgNMhKwkiAGEBBaQAA4DARYQifJBuAJqienoIGk+AAC6AwzB6ADsMAAAQYgENgBI/8ZIg/4FdRDVSI1UAXzh6CkA/v//SIXbdAsoSIn6AQ8ZAA8xyQRBuAFnTInq6BkS/QAficEBIg5Ii0AXSYnY6AYEEo0ARCRMiEwkT0hQjZQkmAJohAYHoBWCA8iBTqiFWsHoGDaIABkEC7AACQJPwei6EAALTQALgD+BDLiHDFoIgQfAgAUFgcgIgdCNCIHYBIGAJE7oVQBQIJBIgcTgAAhbXgBfXUFcQV1BXgDDQVdBVkFVQQBUVVdWU0iB7ARoBgAr7Uj/wU1Aic9JidRMgFrAEQAJ6DA3gHyNtCRi4IBBTI2sgq6BoVhCPIEHXCR4uYASAAmFkN9JgYQV+6IAAACJ6POrTInZiQHZIP8AAOiGNEAOMIuUJNAADEEQlj0AAABJg8n/SINgyv9MifHB' $Extract_APNG_Frames_x64dll &= 'CcEvSWCJwOgrMoAIgAVIoIuMJAAHgBe5QUCQTI0FpgAW6M1ABwBMifmFwInDD0SF6wAG6Is2gRTFIOizQQAAwiNMjVQNfIAKTMBiIIAOSACJwkyJ14nYSaiDyP9BJdFCJQiBDhTwM4MJOIAJTYnx30EIRQtCEocLAjHBgAtFGKoiRBhQVhgCQRiORBhRgbJJieldGF+EC4AngAvCBwUL6eZBE6A1H4QFwRHBCQGUwAdIicMcieiBV8FLgBSNDXt2oQEGiDoFRBZBkIs66O0RItaAWYU6N8ESgA4BllvFDJA6o0FmgAnwwnHZ9V0YdMQFCEwdIEdCBwEFF6AZoRhgELWgaEyNvGQk+KAF6DlAB4dH6emJR+4vQwNN4CGgA0UDGSBG6NNAA6AF6Ps4CYBdwLnAgABFMclVIXbQ4BdBYA7GII2JxWESoAACSInXYoaAAkxxUGIXIAFyTuESMDvhEgEBKGNugAwkBXNHSYAAdA2AAHUKgAB2chqAAHcKoXJBCiV0qPVoAbBoAbhgASOd4G/oAibIYAGCOOAcQReKTAwEcIE9QQqIDAJIAP/ASIP4CHXovEiN4J8gf0Ib4RrAgAGIQbkFojisJJgiVUhEJEAgGzHAIRrvn+Mu4CShAeYoQG1Nn8SpowGJogm0JICgfEjgCHZwAAphA5hlA6EbaAGoa2ABpRiw6AK4YAGiGCqKLmAMiwARTIniwA4ITI2kQhnoQ/n/K8E5YRWwwTxSoI9Ii8JU4QTh6Iz4IK1gGv6woBCkN+AYYRcjHILC4ZDnJE1jG0AZh54DAsYbQsa3JAViHGgBmGABZReg6AJmqGABYhduLeOYwaNJXInw4UkhE8QWyMEWmyXikfKBFtf3gRZEJMpXRjKggSeJ12QW4KwuWEFNoZ1gAWBgATHAWWAW2J2JGGBIV08YaNWIRXBoAXhoAYABCkUedegCkIhLmGgBQTtlAXh1aAGAaAGIYAHmCOgCmDNgAUIkSyxDHSEb' $Extract_APNG_Frames_x64dll &= 'SYla6EEkaXAQcQCA8EtIBInqoRG89v//gwi8JNgBDnU+6OaDcA3QOEUxwDHShTUYQYnFcDsQKyDohwAjAABEielNiUDgMdLoKiTCAOjAEh8AAOn3sAhyOp1BBfDwMWFj4SRBuUABAv8ABY1QAehO9AD//0mJxUiFwBgPhJtxMEAZaEG56AogJlAHwBI8cgzABsoo0B3oUWqNfOCIQG5aXAAF4AABQAJY9T5gLYUAaIEAcABccQDo4CIW8QdMJGgxhWDojongAFCC4oTp6JPQAFjzDxCwAiECYBCF8+APKpwk+KAFgABwUy2CABEQCFICWLIAIOhKZDIFjJNPLzkEBkEMuFUjUyELSOi47gMAFnABSInHTInJBOjoYAJAhP8PhWK9YieEJEAAEYFNEGNwADIlTYn5QGPgAjFQwEG4KTQz1/NAjWgViZvuWsVQHapnKOshBaFnwuBZgQADM0UjAxlhP+iSIANlWkiJ2RlpWicqQw1xCehyExGRDNnoYiBq6w5IUI0N3ppQAVRQAesSHIETahVDD2DoaLGUAGjoVpEAsAG+cgCI8ei2lAFA6KyQAMWxIKRyAPnoDIFvEAKeBHAAkZCxjpeQQV+9kEL4YU6JlCRI8CxJAInNRInG6Bke1RCNw7Ej+HENOuAAdEvZMZgx7aA7g3jnIWqhACBIjZwkEEAQ6K73EC91LXCPi5MCFS6xlTGcPTIuo9ARIBHjA6OfMdJ+TJAA4TbhQXIARKHTKoS70nMxARBwANE3sQAYsAC3FTqBabUAKIAA1UAw+AKb0Y9VPECwANFt6CVADtPyHmEd6bMCoKTCCnKVRXck6WAPQbgRgyN8bpmZJPcg0jGCQB81hVC/gAICKUASUyTtkyIkTyADZZd+4Skk5CcjJCEJ6AYv8AfwAUmDzP/oIhswDun7ENMfv/EI///HQmgx0k2JgvD1FYnHSImcogO9cQAIcQBBFHAAFbUYmGC6ILgAKPFnRRT4AjjYYg5A' $Extract_APNG_Frames_x64dll &= 'sADiC/F6D7ZDAzK5wQEPtuMOETsgRBAPtksCQABDAejuW4AMPw4yDgAxDiZuwAFlsGEqcMXox4ABtAyDAPgBg9UA6JUiQdgjVAcE6HTnJOjQyBoAAOEr6hDNNQGE1BmwA/0BfkpBFMnBLjHSlrY8l7cpIS134R6FyqIcR4EJNC6BBS8pgAPrIKA7kZAD6JkSD9MYx8TwBv/oipmAl+lqMAGVBuiYsp/t8wS6UH4iwdMACcMOVAgktpaDAdomQgaFyluBAiUEVVHCwAFd0Hb/FcABrSEe9uMlifdBvLgSgADweeQCoCkTkAnc86sEAnImEFDf1ynxJA3VKbKQB/SrifDzq5vASScpvOoamstRJSgpdJwOc0eM0Y7CEKDY/2TofeAA6V2wAcBL0eNAQMNRwei1cAEBPYHt5IusYgDo0RARgEbkRbzoYnAnv0S1RDJEXwAn3wQeMAIQFuG+kRZINERyAK+E5DVEIswwAVg4QWB4Q/exy5aGOER4+AIByxaCNUQC4REdFLkAjZQkUAIAADEAwLkwAAAASMcYhCQgAHABAEiJ19JIAOhAAwNYKAVYACyqMAgsOAAWAQQWQAguykgAFggAFvOrAJADuGkAmjAEAzoQAKoFUhi1CAsgCAsoAAsFWTAIF244AAsMWQAVAABZBSEItQgLEAgLGAALBVEgCBcGKIAFgyjo3Ob//wCFwHU4i4wkqAGACOhMFgAATIkQ8ej0DoGI2ejsQYADTIn56OSCA+EAScfE/P///+gARSwAAOklDAAgAMdEJHwBK0UxAO0x20Ux5EiNFoQCJIALdIELQb4yEYKthCSQgAMPt8algAScgQhjxQBEmINJFYEWcIQDaIEDxkQkWnsCGogABgVNkQBNiQBEJGyFwA+FKQ4LACEADAEq6Gns/wL/BBJIicboKR2BhhlIicXoCh6AAwApxUg59Q+CBxeAhoUGACqswAEx0kwdQAKQAAYCKcABTI28/CTIASMDCMOG' $Extract_APNG_Frames_x64dll &= 'wCqBCMAEbqDAAcFSwQKowAIFWLBVyAK4AAIxxALAyAvIGwEIxALQwAJBeehJF6EARraEJK8AA7lBCggPtpRCHkQPtoxEJK4DAoQkrcIhRAAkIOi4IQAASYCDyf9Ig8r/wGYFAE0gARVJicDoXWOABoEFQbkFQAQAB0wQjQUPkgAZJCIASgABThdAHek3QjmkTCTYgUNAVLkGAgvnJPOrxVrVHAEbwehcvSXAJEIHALPgwXO4UcEaSYnBwQ1MgcwVAlrAF/OrTInRSENBIkCH/+gmI4YNDSz0kUMPg1jCxA1Jg2zI/wcNwkHxgCiHNeEdiTWGQAKBewEs6NEJJYWi+8EauimHiI4T5QF2jALH6DGApwEDwd7M6CQEA0H76BeEAaE8ZOh64AfpWmAKZCaNTAVWIBZkK+jsIA+JEsUgJ4SEgAPrXEhA/85FMclBoBe6wYI9iXQkMEgARoEMNUEZKMNF+cIaIQTougIN5hMx0kmJ+OgkWRUHFm0bIRFQBIzpb6AlCDeNBV5AWy0BEGsAEAE3YUAa6bIBwYmD/hp1UjHSBA++gGRNhe0PnwDC99r32IXCD4SEyQAOSY1F/ysUxkQhFGMiQf/NhxQmFAIYIBTrU0iNDbBrYA7AKvrBKmMAhKUUN9ISyCraCsgqzYQBwiqWwIABQRYo4AvpCOAHAEE57XwdSIuUg8IDIH7/xYoMAuEBQQEJiAwC696gQXAASGPbi1QkdEwEjaziO0hjTCRoAEg5ww+VwA+2QMD32Eg50UJJDwCVwg+20vfaCQDQdVtMie9Mi09grmAlgSbgHfOr5UVMEInp6FZgfkyJbFwkUGGwARWAA0gEjEA95AA45AABquEAgiLrXhwxwIgLCgtDQuno+bfhi2OXbQwooV8ALkjgGqp84ABA4AB04AA44RyPAjEAB2Ga4FdNifEhjxFBIUn/xCN78+r/uUIM5ibDxyFuQNUaRIZm6MAjYgGJ10EHoiWJcpTiAPOqRp7A' $Extract_APNG_Frames_x64dll &= 'BsGP0tUhBvCIkvhoAQBh4KXHq2ABJQwQKNoYYAEZwT8mqMA/RUG8GCioUAQE6JyAsg+2nCTkUeKWhCTl5JfpAQTBAOAQSMHjGAnDpSED5yIC4hCjAebjA4oIowHoowEYCdBhB1broAEjAepjBgijAe1roAHAJGghBuykCacG71WmBu6qBvGjBnyhBvCVrgbzVgPyVgOAfNBnHInaMV/hZ6AbD0TDJSAEcNEcD0QQCMH6GhjwAHTRHJEfiBCJAtq1AMH6EIhQAU2WAXjwLqQAWANgLmgR5QBAinRyBIhQBItpAeIDBRkBiHAGNgMoiHAHYQz0QhaMJAL2RBRJicZIicoVkQH1lAH3xAxECfAwCdF1BxAbQneYSBRjybF1AeB6SGnAQuhBS5lI9/kABOmYlfj/olcWSLyM4zxC6TBKhcB0OYYByFqL91HMwAHzUb63degCllAhSI1UBgTp+pehKMACPFRJcS0hJyEm/5Er4ia1PzABwSv0mANMhC8XZSkvLSctEWOSjUb/uEiJ6ehYkTfmTimXTQBJiegx0ujID5fzDCVhhg66gA7o6rAxASVOg/gBSBntgxDlBCnukFdMY/7AdC9LjUQ9D1dfVgToItBR6yxJjUcD3wLfAuiEBwAA/wDOO3QkbHwmSCBjVCRs/3BzSI0QDCpIA2NwTAHqBEgDk1WKAYgC64LUJA1NAf3oFxdmLUI69/Rb4nMawA3pqJL2JpPo2dAB6ZcAAfnBZI7PYRgkGoAKkhuqGvyJ11IcmBoBk9UblRqmG3/vGu0aEWugJLFpzxDCEHffQAi/ZLRkkQe6ZEyzZLFTgZETaEhjtCSAwQBgOcNIjZyCNLdlyt29ZVPrX3Ehu2X64JpyX7c/ZT9lMmVWP2U9ZaVABS85Zb9kv2SxhyCDZE2JEPhIidpgZOix5O0TZKTgBfE5LNAOhB5BEXHhLUyNtEIUYRtCfFihQXyLDTm/sABUgAEQSYP8AeV+fh/oFumxAqAE' $Extract_APNG_Frames_x64dll &= '4XIA8ejZEXIA6ehBIAbrJOhWyuMBcIP5cYO7VAKzBVQCG4II4EiBxPgB4ARbXl9dQVxBgF1BXkFfw5AAAED/JSZdAQBxABapdADeXHMArnQADnQABLZbcQBIhcl0GkAxwEjHQRAzIkEngcxwAHInw7hBE8NmEGYuDx/xmgAAVQBXVlNIg+woSASJywHehckPhKQTcbZRA+hXQSuDOwAAdGlIi0MISIuAUxBIOcJ0JDAzAggCAkiJUwhIiQg46CdCTEiDxCgh8QvDDx9A8BILSAwpyPCsEMdIwfoDwcBWBEiJ1ehyaVABCQBTRkggOokDSI1CBKAaUxDrqHEDuqVxBbmxH+jJogIDoQKQG0iNkJExSIlgCJmwAul0YAyyDOuJowozQQtgN+l3MAHoDZBBQlTyDSBIic6DAoMBER6LJkiLXghItMdGRBJGQhIzDccBL0gA6FOxQoXk0A6DAOsISTncdxNIIouyCO//0CQBdu1B0CXocv7//8IPIDBbXkFcQhsIAP8lVm5yGfAaWnMAlnQAZll0AL5Y9AF0AJ50AI5VdAB+dABudABedABOVXQAPnQALnQAHnQADmV0AP5QHJCQBRHwAllVcwHW9AHGdAC2cgAHugD/JaZYAQCQkBAPH4QAAQD/JR4iWwF4/yUOAjhBVABJicxIg+wgSACLSQhIhcl0EABB9kQkKCB0FgBMieHovigAAABIg8QgMclBXADpgQUAAJDoU0j9//8BNMMECDRmAwE0AgBMjUL/uAEBANBIhdJ0IjHAAEiDOQB0Gk2FAMB4FUw5QSB2AA9LjQRASItEAME4ww8fRAAABsMDNgYAVUiJ5UEAV0FWQVVBVFcAVlNIg+TwSIEE7KABUItBKEyJAE0oTItlMEyLAFU4g+AgdWxIAInXSItRIEiJAMtFicVMOeJ0AgUAd3VVTI1DMABMjXwkYEyNdAAkIE2F5HUq6wJlgjdJidNIg8AAAUmJSAhJg8AAGEkpy0mJ' $Extract_APNG_Frames_x64dll &= 'UPgASYPDAU2JWOgASTnEdD1JiwoISYtSAA/CEEmJAAzGSYkUx0g5kNF+xbkBa+h7gXsAjWXIW15fQVwAQV1BXkFfXcMEZi6Fr02J+EyJEvIBkMIniAZIicYE6PEACEmJ90gPAK/HTA+v/0mJAMZFhe10PkiDQH0oAHU3uoEuTBCJ+eiiALBIiUMACEmJxUiFwHQAVk0B7kyJexAAMclMiTNIiXsAGEyJYyDo9QMgAADpdf8BxfnoFLj7ihgkgih0x0gAhfZ0wkyJ6UkAAf3/VShIg+4AAXXxTItrCOsgrQ8fALmAMQDoKq6BES6AEWbFL0FVCEmJ1QKFVlNEiQLDQIZISI20JJhBAWCJdCQ4RYCIOwzoZsGFgAMoQYnYCEyJ6gE4i4QkkAEACUUxyUiJRCQQIOgz/gAlg8RInFtegUkAe8MX6IuAN0brR33Fe0WJxoF8SaSJ1EF9icsEfsACfhJ9QIxBIAF/SItVEEhIOfiBecB1RQBIi3Mog+YgdQA8McBMjawkgANBUEB9QEiF/3UPIOtEDx9AgKjAAQBIOcd0N0yLAiBIi0oISEB1TYkABMdJiUzFAEmQOch+3oN1pAKQdQHASU2J6EyJ+kjpQFnyJcFn+gAEQAPBOFA46B8mgUHCgLMkoDhJD6/UwADEAF8iMAAFVCQowQgwdEAfSInZ6FYBCosAVCQ4SDnQdg0YSYnQAAWAMjj/VSAwSItLCIEGMOgioYBxSYnAQDYPhArLwltDQwZIi0MQCQAOc0UCdkmNDAAID4SUAQgpwkiJgtBAtDHSSff0wJNgTTnjciCAcsC5SDiJTCSAFwBM4ABMAcThScE/6kyLQQrAEgxMA4B8IEkYSIPDkDBMiUMAEkPgoEsS8EAndC/gHkmLVAL1gAAM90iDxgEFgAQYIA1IiUvwSEApyEiJU/jCKokAQ+hIOfd11DFIyehlgCjpvEA+RRmATp1MQQyAEinA6EAUZwAA64ijTUA1gQSXgARm' $Extract_APNG_Frames_x64dll &= '52UATFhIiIN5CAA3lCSIQmAgVCRIdEjgTEG5gwEE4QE4SI0Fs8AvgEkPRMFMi5wCPWxIxyAYAwRcQCRiTq/xQWeDxFjoceFS4kIhMmWGU5ZALevV4U8BS0gAg2EoPzHSSINAwTBIx0HQwgbHjEHYgguhlcdB4GEBgEnB4APpRGYlnbHknYsBSECeoZ0kIDdEeC9AnXQqSEGdJEpIRJ1A6BExwAEEEKfBDsBL4FPHwMBv/wZiI+AhwBTAujBhBcnoQC0fAACLQKBWxBIo46VBVKADQYnMEwQEIbfoCIAERIlggaEEIESJ4EFc6R9p6wndHuEJDOcJ7AO9IeADSItAEAQEQACuU4ADwHHJDZlgBExhBASJWOEEIFtMicC75nvsCW3jCcBM9wlJ4wkdIExY4QTjCeYhhckPnISXgAWDguHUQTihnFB2/1AIwAAPIgbDGeaXSMdAmkILx0MIqQMCQxDkABjkACDkAK/CR+AAYRHhADjkAEDkAGZIAxrgC+mFoFbkJcSiICKGW+lxYAKQYgEc6WaBWuIDwKNcg/lA/3Q3jUH/QB09Av7AA3cbSGPJSBCLFZCCYYxEiQUASMHgBEyNhBCCEIAHTInB6RcgQEwPH8FUgCUFacAETOiNgGCEA/phC+Y54w3O9gBd5HzgLejHwGuBKTDEKOncIAPpU1NMA0Jc0HBEJCzovjEBEANjVCQsSIkTUeACMFvDIX8jNRUaREiLcHvAdBIQOTCAAHUD/+CQMaEdpXAGuFIqZpDgAizxDZZf8A3DDW3DDbOByA1ISI2Mwg3rDvAMma2SAYjxAIUGOYQGMYMGGAr/4PcxdCmLBWHzcwNxEOvG9QFzCPcN8Q8gSI0VBX3wRQBjY/FnAVR1CESAVDEnSFCJwegQcAFBggPrKuhwBQlwBUEzigXoFcEFFPBOQQFNg8BQMEGB+AAwAXElOAB8delgBPMIcAWxAPEGSABIY9JNi0gQTauAOeAQNeEQaOIe0hMR' $Extract_APNG_Frames_x64dll &= 'xjEREaIQiw2cUB3jHhSUCBIRFHQbiwWBcaABTI2QUQGwTEIoTDyJ0WFNsgmAAIIq6AmKMmInSPNCiwVJcwNXcxHxCMgIMMEIY8kILBXICA/NCA/wTwX5f2N/CH8IAOiBwSN4CMFHcwP7GfEITInIKxI6IVEJZUSNWWEJQYEK+4IJM4AJTIsVexFQBEiNTHEj4QROKI2UEYIJFvdbDVndcgaR/wnzCQJd5WABsgnt8AIp8wJyCc70CP4azAgSLsMI7n7PCADrEbvwIXAF0cABfwh7CF11CN34C5lzA/casBMVMApFBKuyhBBzeHAAKHAAcJIEfKMclATIcnEI8idAAkQAi1wkeESNUP+oQYH6IgxV8Asu8gsQRIAFROB/IEWJ1sHRHnUGQRF8ylANojm1QAiQ0AJE0HOAgNEDjY4uRgf6RiEB6YL5kUV98Ac4wB3Fd8EhEQL1Fej+7EBU4ALRvfNM8ALPAsQCnr/FAvc8Mr9RXj1iID0Qi4dgUTBVwHRLkEiNn7BRC423EQHWx3IB8xVDEkUGEJUQYYGQilBIOfN16HFaCEiNjzEDQbiwT0WARdKgnemFXhRdXhZfQwfxTzxlSTNIg2DqAYM5ARB/EhN0NhGycJABGfA/QUoATFhjQQRBAaCe0IFG50kDWWX49WFj0hAFOZUxJlQpYDVoOIh8ZTi2hGI4UV50ImByNWngAZvwX5UBWuG5+IwFSfMB3fVhOvoB4QzBB1fJBxAbZcYHC88H6ffSbfVn6dp7+gfa+mfwAcnzAfUH5rphcAYAQVTRZkZD4RUOfOEVAMWjWXRaSINgeBAAdFNigfAASiRIjaCZ/9DAFDpJG5G0UDm40LjABeH/UHoQYAEjYgFhAjDAMAEYv/MAoLGhhmMCIaeAnMTArP7AAZD1CkEHVgHwG/8R9RGwixXwev95Ig4n+nnWyWAC+BEK/Rmp8wH1EXbq+hEBEVu0jIC9cydCNbUQObcQLnG6UNv4/wHweStD' $Extract_APNG_Frames_x64dll &= 'MIM7AXUACUhjSwRImUgs9/kxDTG4W3c2xDAwMcBbw/BzCENmkBC6AIXJdDyD+f90AFeNQf9FMcA9AP4AAAB3OEhjAMlIixUAegAAAEiNRIkFSMHgAARMjYQQEAEAAABMicHpV///EP8PH4AAqABIi0gF2XkAKo2ABTg6wQA4Zi4PH4QBPAE+qrkDPmAEPhoAPpAGAACLBdqrAACDwBABiQXRAQj4AXQABMMPHwBIg+wAKDHSSI0N290AAABBuHBRAABI6OhaAASLNQAENgIVAZkVP3UAALmCAgFlg8Qo6cEAHhCQgy2JAEYBdAcgw2YPH0QBGewoAOjH+///McnoJuAAOgBRmd4AQVQmSQAEnxQBID2fADEAhHQlgiT/FdpjgVoMDYsACgErSInC6U6/gCyFdwAJw2aHb4nEDToBFIkVOwADAJUQkC4BAIkPQVRBVInMAEIgAIR4gA1IAIXAdAL/0ESJyOHooYFXQVQCDgDDAEVMiwFFMeRNMQAQJUi4AJIBAH9IACNBCEEPlMFIADnQD5zAQQjBgHUFSIXSfyiAFAjogAuCRyBEieA8QVyEd4ALBwmAo0UPQLZkEP/r04W3QQBWQVVNicVBVABJicxVV1ZMiYTOUwUgZEiJ00EfxHxJAIQPhJJAL8BrQE2J7uhPWYE4xyhIg/vABZVBQYX/AHRfSIn9SIXbCA+F6QAESYnoTAiJ8kxANfsKAAAYi4QkAUvAEhBIKSLvAAsPj+TAAw8fKkDAK/7AEKZDUiBMAIngW15fXUFcsEFdQV6AK8EH+sAHIs5BTsYEJEAd3zEo7euvyJO/RUZNiyAwSSN4CAIlhWuzQATBGYSUQhbBGNpAAhCLlCSIASLSD4UGK4Cfh1VJI0QkCEBIOfgPhZtBL4sgDCRJifhAMOg8E4Avwg+FXMGxkEyJAOnomAkAAOlNA8K8wAbrAUg530gID0/7wT+J3+kBIcq7SY0MLIASMdJo6DpYQA0NQg3AZUQD' $Extract_APNG_Frames_x64dll &= 'wESBIkWFwA+Ej70BCseAN8IBQCIFAhABAjjp2P4BDcMTwORIiVL6AVZyB4AGUsUTSYCDfQgAD4kbwAMEi4wDOcl0WkmLQEUQTYk0JEAtSUCJfCQISYnAFEmkx0WDJsdFBBpFwhlo6GAGQBR1gg0gPeG06IDhHFvjAYQOnUEElt1AAoEBYOAD65yIW0HjdDiLRCRggBcogeJhRCQg6Jf9oDHAg8Q4w2aQ6QMhL0XiA3flA5CQVsFPOEBIiVQkWExgA2AATIlMJGiFyX5AZ0hj8YnLoI8kgFgxyUiJ8kiAAxgo6P5gICFoSUiLgEwkKESNU/9ghEiDwQhHEkyLQC1JAviBAkWIDBBJiQDQSIPCAU050AB15UiLEMYEMtnhTjhbgU3llxmgiIMCcEiDwBBgEgkA7GVIMInWU0zgEkNmD4RWBaBKYWZ441a+wSohglZgAonmSInFA2YixAJp6egJ4AJMiRLqAWk5/cJN8UwPEE7F6CngAkGJxhCFwHUSAAN0DUEID5/GwHb2R410mjbAJP5BbQAJdDgDey7wKGbgK6EQf4Je+v+gdCHopFVhRvaAJJBBD5XG4QZ1yIEP8tQAOeu+4AVGYKIEgYsUlcaBO7MBBJeQSAK95QNMizFII2kN5Gs84WtGb0mLVQDASSN9COkzYV/kjoD2TYXtD4RMAQUVoRUeoQ4WqhFB994c6SwCWOB8SHFFCOsC2uYtV0FWTYnOYEFVSYnVhS4gLsMj4bgAnw+E+yFYg/gF4CqZoR6J0U2J7wjorlQClE2F9g9EhJyCIbwkkKG5D4aEAY8hLYn26IiiBODFSI0UOEIJAUBBH4yoBQGY4DH6SItAZjjE6I8ABSCawU4BxyBIifnofgACxgSWL+AKIBtapgt0YsHBOYqYQV8gS+HOhiVMiyA6SCN6CGEThWSBoSOJ+jH2Me0gEMR1guGL4egIQC8iNZqmYSYqoBEmDHWeYBek6BdAAuuU4gpNwHxgy0Ux/zGg' $Extract_APNG_Frames_x64dll &= 'LGUchQYcwQoGN0kjbghJAIs2SI1UPQDpRhOq7eArVboMgauJCM0xyWLPKOipBGVDNUSgD0G48E9wbOlBwDL/FatBAbJR6EROUwERwEi4MjYAxACA8lNMCcABRiAiS0IQARDD8DTJcWNyTHiNYBBlAUAi9HD/BynL/wf0B1P1B85S/wf/B930B0n/B0c98AcY8mr4D84D/QdgGPIHm0D1D/8Hu/8H9g9w/wf5D/0HKf8H9fQHS/UHzuCP/wf/B/MPh/8H9w9yNIM9nMohj4oy0JB7kADo1jIjCPAcSMdAsmGRULAA8mIXNwGgj7ADULEDdcRBZLkAwE9BuGFfsJgzKqLClSzhBCfgBOujAXMwjVHwSI0F7QLJoAA5wndASC2E2CeiAHI1U0gBXkwN+qEB8FTogUEIx0nAEAAAQG/HQ8QHQ1nFByBb8E5iQ8P3XlcASI16H1ZIg+cm4KFZEgVPAeIEwuIFsTYDYQ0TSIl7EEBIidhIiXPBEiAB4DrDSI1OAUiJyPfom2YCddnGBsQHBOvS8ZmNQh9VSBCD4OBXEEZWSMEc/wOSBoFBc2CLKUgAhe10DUiLQRCJUZqNiREcjWcBoH5AdEBMieJIQD3lYuNVBg+Eh3JLAAm6IdUcSCNTCOEJCdaHGAoARfFdidno6JKzUOHo8OGmCr/hC+gq3wcBWL4LuPMXicKASMH6A0gp0NCODH6MdAmTSOuiSI0qVkAQ6XEQQxcKhV4RYkor6XJyAPfpTtn3vkFVUysBoyvAiRBaBujximEWU0kPumxAJAg/TYnlIynog7IndAhUJEjofoF/TouQAOAC0C50IeKNwbTolhAESZBZgAy7kQ5SxnAC67txYkXgn7K5KIfpeyFn+KBwCHJyHwGhGIN5CAB4TEgkjVMxJ6GfgyZMSJIFNCd3QfAmiscQKpwVML8mvSZyC+hrsRQGrfY78ifr3YPI/6NzDf8I0nQzBGsgkIE4fw7GQL8CBfMEM04hwRDB' $Extract_APNG_Frames_x64dll &= 'SAHZiAFAAJfAAEI68Qw79gyLCfEA8Bzo/t9wE+MKzwrEClfzB+yL+MUVEoIf8QJB8FzpfE3zuPTCckLxwgRJvHZrI2EI6B1n4nz1AfSQQVRBmyEgD5SEjMJMzJQKNEnAHTAIQbggUQGXhCHqJOi0ABdNI9AhSYkB4IbrSSsEJEgpUsPww38lIEuWUBZMxI1o4Erh6CrRJOMjdluGwSAT2hDc8SNzInQrAOqwBNgxu4gQA+vEv/Te8E/ABAEE0AMzBehCBEf1X1KFRc8PhIsyFDkwAA+EgZEAitd0cQfgHOCY0tedwUGEyQR0X9GeWkwPSMAISI1awDHCSCnaATC/GEg5yEwPTEDCMclMicKBrFBI6NL8tgoqTCCwUDBJAxwkQAuQDOgumkxBx0XQqnABQsYAcKTrEfYLiWrHEB2TsrvwF8MQw/ELMrPjF33UCyEgDXQYSL7HC3EIJaALfrDi9nVABwU1DTgFyYAJBRZe2roAQVxBXcMPHwAASDnWSInTSA8ATt4xyUiJ2ugAFPz//0mJxUgAhcB0wEgp3kgAiwhJAzQkSYkA2EiJ8ugX/f8A/+u0Dx9EAAAgSIsF2WkADIPEAChbXkyNaBBBUFxMiegAppADAFYQSInOUwGyg+woIOh/+f//AaIaSECJMEiJWAgABhCzAzkAgoQAAQAAT4kGTwBIg8AQw2ZmLqMFHACnVjH2AE7LAU4ASIXJdAjos0ohAC2JxugjBFsWSKCJGEiJcABbcAdbGkABVzELVwOfQVVJQInVQVRWU4UofgBJicxIhdJ1JhEBBnHoLAEvhcAP4JXAD7bAgx4EmQNJBOgLABBMielIiRjD6AAABYCQTInqIEyJ4Ug5AJXGTAAPTsDo4EkAAACFwHXBSDnedBi8D5wCI4AmW16NGEQA/4ImB3ExwE2Qhe10loAo6LEAG3MDPQYY99gCF4StAQBVlleDsIBeTYAVhIyAIQBMicNIjWoBSKCJ10mJ6AHmz4Mk' $Extract_APNG_Frames_x64dll &= 'AHgiSDnFdQxFADHASI1H/2ZEKIkEfoNoX8czSI0EDH6AeEg5znNWSEG4P0AE6xXBT0EED0iAIcICZolCAP5IOdF2Cw+2AANIg8MBhMB1AORIidBIKfBIgNH4MclmiQqIFEHAh0UxyTHAgBoJIYYFMcDr18c7QVUUQVRBLyCBW0pIiYbKAHcAKDHJ6BoALQFDoHhKdDBIjUygAALo7tpBpcTBeQIOQ1pIicHo+P4BgH6DxCBMieBbY8azwANFMeSIBMQ3iXDZ6IBIwTnAE4AX6AKbhxTLSo0MaEiAicJIOchzKwQ/cBgPH4DCKdg/ADiJjgIKIMdngTUL6T4AGY5mwkPJbsQHD4SHABgTBXKEyrRHwSrHSIUI2348wSY3SDnDAEgPT9hIjWwbpAJIQIfj2cEtwcEGkBtJicAACn8jACJEQYnCuEyJyAJbkBsBA8BgWwAExAPtAkgMKd+ATcGGjRR+6AaiIA0ACUyNBCjrHL6QYAVABacUVboECgEhEeUENeTwSIGE7DBAAkyNbCQAHgjp6FqhKoXAfx0JQGzOZSErZehbTHiNYBCgIYEhYS/gb4lCwgGLw+g7+OYtziGgikyNQwHAOOgcj+EdIAdFKGUoSYnIInMAidFMicL/FbEkMwHiG4nA5ndBVAMhdmEEiwn/FQg10gHgX+FBIDthIA1hBQZE4JGGMldIjT2oSL8AAAB+Y9niTovcBN/iSQE4YCbD4zRgPYwIucAcgAnG6C/AN+VhBNzhloPAYItgBsUFA8mT4GRUVkiNNUYTIAwHDAzeoUAfSItAQfhMjWH4IQkCRP/QoBToJtgAC8dMBN4iUwIKQVwpCmZwkFMx24EIgBIjAokC2YBO6Jb///+D8PsGdfGCBmlKASHgZ6S6CGAFuQUBlApgBSRIi6Imw2biA7oYF+ACgATjA+qhZ41QCNBIx0AQI2QQQAHhBx4AIAJBIEIH5GCLAUEAidCLEUQJwokOEeEORKfAInk4AHQC' $Extract_APNG_Frames_x64dll &= 'IUIm6Hff//9B4WA8g8QwROA5gRrouwSpY4EMy8eAYFGEAADhBYuEJIhBAwTHQaIOiUEIi0SwJHBIx2EDoAEcoAFCeCCIQYPpAWAEIFHCCMdBKOQAMOQAOD3kAEDkAIB84gCCGsdBBBgEggkgQYP5AhgPh8XDDkEahcC4KcEAD0/DAYnEAEEEIEiDvCSQ4jqEJVFhKMdDEMAA/yCI/06UAgNAHECuhZnCGnNBoM3+/w+FB0IFRAIkwxOLQzhMi0gEEE3gP2VMi0AYAWC0dFyLA4P4AggPj8GCD3hNMdKIQbgCQ5NB/9EAxUI9wQZIjVQkwF7ZWP9QGMEBYaLSwgEQgEiLdCQo6xjjVMTHQeEaAOlPwA7hTwAx9kiJcxDpgfOAOuNYxwPhA8Aw4BfCK1/hGOQA4UBxACQVQyQVQ9UkFUMkFUMkFUMjFVAdgyQd8AWD+AR1i7UKyEH/0MIJ6XjQCPMJKlWhQ1ZRds2BOtRXAESJz1ZEicZTLEi7wRQAAH/gI1BIQCNaCEiNQzAU4BDw6BgtkRMSSCkCxDFejXQkUEyJQPHoovT//5E9xiAEHgDohcAASIsARUiJfCQgQYkK8bJg8mJ4RCRAi4RFQGAAOItFOGAAEDCLRTBgACjoUptAixBG0EA74UBBXhJBUEyLSQjRGSeBMUwAi0EQMdJMicko6H1CoHjJgS/pqsbcsAz3ecnpmQAB9jYATYsQTCsSSYMAwgFIg/kBdikGQRIw9wJLiwTISkArBMpJg8EQAsAAAUwPr9BMOcngdedMidBxarB40AcCSUR87gF0RkyLMBpFMdL1A5EFTIkA20+LDNBOixyA0kgB2E0p2cEEAEkPr8FJOfJ1AN5IA0TK+FtItPfYgY4AdTpQdubyIIXyBRHgOQgAdAogSOEADkj3cRh3AhJq8wE2BPEBG2pXUIQVhiDoIq7BLY0UQIBcSIsCRhAbdNDoSDn7BHYk9klIgz4AdKEAUvHoMvPhV+tQD+Tu' $Extract_APNG_Frames_x64dll &= 'GDACdeUfU/BNggfhoF10BuuU8Qr9VIMJoAkx0ulyMSWQ/XMR1V8g6NLwAU2F5BB0CEH24B4gdA0P8QbhVPRc4XnhQVzphCrV6BuQQbkA0C8J0jXpeHAuVUmNQAAQSMHoBEjB4BoEZG9WMGBEpyDoe4IqwAQpxEyNZOFvGOHoY0ADYyk0AOgkrhZRbAXnAYaJQ0I4gT4DD4TwICEPzI/aEA1xP4VZAXXFRNiNFY4AdIEEYoAE8464D4SiIAKYCWF22+CIkESLQwgCeum6AUMc6B8APXAGUDP4/3Skak0BfRVM5AT78AK95QRT4ASCBDMFMZOM7wQI6JAHcRJ7EP91snehAYsTwyzRB7WhAcmUBnVZ9QjpkjEc8xUQjRXLWeJAD4V811RGAQ6hCIioCMijZ6UIDZEEAeABYgd0iYtDIBxMiWtAMFAHx2xDHJFLcAV9cAVgBP+wFTQtAXG0oAEYcQk9MKIOQJAwPSJmMYNmkNCFwHkcQ2jysXW5ARdyChAGIAUaogoBdBU7ABngAAfgAGAbYgAPRJLQuQvMPrYLhUQwAYvwAyBcMXAddCy5UhOmin8G8xC4WBAS9IJYsXAsjRWu8AAhBXkoBaLx4AGLUxzwxrIQAsqDFAJXFgJ0m3AQ4Qwc6ceQAvEqsFRBVFWYTInFkjliOU2L0bMID4TgEmdxQEiLDB0V4JRiEP/TSDlwxg+EpeGA4Qr0AJUD8QCyfYX2dHNJgQD8AAAQAA+GjgEQAU2J5kmJ/TGI2+sfcQtJge6hAWxJgRBzYQD+gwLxA0lQifFBuOEAulUij0I9AAUBw0g9MA8AAHfESTncdBFNAZBnjQwfMdJJKcjY6CYBAoldo1XBQCJdo1jpRdf0ajHJYRAKicbpX/RsED11ChvACMn1Ssn/FThyRiLf6UUwAqAKAAsxgtv2UonxTYnwFgnk/TwSCelxoALzrDQ9o9ITcj2D7DjSExJhOQCLWUBMiyXXRRHUEUH/1HC3D4Su' $Extract_APNG_Frames_x64dll &= 'C+UTBQGdohPbD4TsAYEGiwZJjUgBSZCB+P9/kD6HoHEIEWhE6EcmN0NJidkx1Anh6F/QCfERiflN4EMEMbIRsinyoCeLEC5Jgf3hBHdFSYA53XQTSSndYBQAXzHST41ELQAo6N07IRAeIDAL1k3iJ9hkbfUnMcmhComYw+lWghTiBrjNYPsCsfMBTIlFyOifAM3/MLsA/0yLRchIhcAASYnED4Vg//8A/7kEAAAA6LUA1f//66gPHwAA/xXKRAAASIkIw+kWAHBmkLkBJQF4lgF4iZAAAOmzADsAAGZmLg8fAoQAMAAAVUiJ5RBBV0G/AUxBVkEAVUFUSYnUV78AAAIAAFZIic4AMclTTInDSINA5PBIgexgACjoAksASkyNdCRgSICF20jHRCRIAUUAiUQkPEiNBZ8BAHJMiXQkQEgPlETYARxQARwPHwCRAIn6TInwg/8IAHIQwe8DMcCJAPlMiffzSKtIAIn49sIEdArHAQKMSIPABPbCAhB0CjHJAAoCZokASP6D4gF0A8ZAAABJifC6AZRMEInx/9OAfw+E4kkAGLj+gFvrEYB7SACD6AFIg/j/DwSEwYFkD7YUBkgAjXgBgPoNdHxAgPoKD4STAAuEANJ010iJ+kUxAO1IiVQkSEyNAEQkQEyJ4UnHCsEAXP+BCVBIx8ILgQWAXSCBSEWF/3QAHOjH4v//RYUA7XUcRTH/6TIjgauGn+g7HIES7XQE5IuCgWXIW15fAEFcQV1BXkFfCF3DkIA9dBtIiQDCxkQEYABBvZkBs+l/gCCFHzHSAGYAdOGAfARfDUgAjVD/ddNIidBQ684x0oA0VANEPIoRBESdgFXoi+uAcgSTZsUPQVVJidUAQVRTSIPsIEwAi2FASIsdyUIEAACCff/TSTnEGHQtuYBNxAIhTYUA5HQoSIPEIEyEiepAE0UxwFsBK5jp9f2BJMBpMclACuSJxMAJddjBCQISwwggUdP//5DEi1ZNjInGhx5A' $Extract_APNG_Frames_x64dll &= 'h4PsQIQfXkqFHwGAAlEBAigFAjArAQJDI1NIJkdBJk5MGI18JIAmwSVMifrE6F9AJUGJxABIgHYAEXRDTIn56IsC6kBqjWXYRIngL4Ilw1nGQ8gvssO+mtIZAhHrysI3xHpNifgATInyTInp6EsZwG/rpoHGAgBIi0lAQEiFyXQnQDQoAOhONgAAhcCJGMG4A8GxAN6DxCic6UkAFMYbwhjpNoAEBcMPQcChQYP4AncCFsDDf1IAAEqLZBTAgDPpA4ASwKlFEcAWCzHSQQTxNQAgAJAxwMNI42aQCUPgzFYBdCiD+gKAfh6D+gR1HQEeZFtegmEKN+AEJgaFGNJ5FOFZ4ANMiegFQwTD4AxEicMx0gRBuAEsRInO6IWhYA2FwHU/IUjJIBEASYnFhfZ0yURYjUP/wAThFQvgFc9mUeMVIzDoUIAGCwtJNMfFoSfrxiXmJR9TyEiJ04FQ6GrAC+B3hIkDwUdb6RvRIUtd5CQOgAFnBwEATYA7E2GFCArprQ3kheMF3kLQ7QVBVFVXgiMgCEiLaYAG7Q+EiQcgBYCW4JRMicYx/wBJgfgAABAAd0gc61vhgoHuoQFJRIHEwQBIgf7BAHZAcUmJ6UG4QQG6C+EMoSJrwBZIAcdIQj3AFQB3yLkhPkgMOfuAd8EYXl9dQYhc6U/AEQ8fgOEuSeAWdStBAzHJhAMyWYADZpBnZqMCHEIGQO9BDGAOoZiCUv1AK0MMQA7AOft1muuz4xviawpURhxxQBz2D4SuCSEFiddAHEmNSAEBIBz/fwAAd1tJAI1AEEjB6ARIQMHgBOiSH2AEKQDESYnQSInaTCSNZAJp6BzAW0mJ0PFJidgmHYHBOiAlAMlIOfMPlcGNoAxJ6HbPgmrgYpfB4kfoM8f//wBpoZMQP0mJ+GAKSInBOOjNG8IJohkjCugyJ8AJ4AEgCugHYAbrp0nnN+ge4ArrpkPUEhVhAZrAGjhgno1MJFAs6BAQwAIrgABIQIsV' $Extract_APNG_Frames_x64dll &= 'RFMAAEBniQyCNAAHQKksiYI4myABwCk4CWTgTQUZQAUQSIO4SCEMdAfrXq3iDWAW4jLCdpdgVLoiFKVz6CDIoBuLFULhoHFIiYJQwwooNyAG4AbAVstDLUNQDejEQsagBcdDQKMJYD+T6g/kMh2UgQmDu4MQZgrjBOE8SLiBHSI7x0yDEKEDQjeDKKEOx0SDGCUCx4MgRwEw90cBgR5EAUBHAcIMQwHhC52kAFikAIMGQhb9/oEceAW2rEIHYQOjCfYzU4a6EQZyEUyNBT4CAglAO5Xs8W/DSIuIAbEI/xUxIQEAx+9RDCUQ9oJQAwggAmIEtGCPMUsSK1KC8hWJTRCzF2I8gAVMjWzAKKBdSEEhBo1wLOsT9gSLAEME99BEhfB0MGdIi4uxB4Bp/xUSwsARicfgfHRuSCHAIChEi3ThLPpIIInxQbgEUAJJiSD0SIlDEMEBMESoiXMIwAAYwQA4gAAD4BlwfYlDKOg3MkFQT/90m+gGACFEAItzCEUx5EiLJHUQ4IHGifCBZcgGTFBk+XpIjXsQiTmgi0MINBZxG2MQ5/gIKfiN4hExwMHpAgPAi+unZpCLAS2AQAr3EfckiZMU5x+fnBTHJPEi9XQwFInVQhUx8l9XSL+BVgAAf1a7UE21FWDwAZBHMBiEAYsF8IssoJbwSCN5CK3jFs3RcUAWhYCQ0eEVQBCF0g+F/xFSiwAMJEiNVCQw/8QVXCAJSInH45JRCgGSE0SLfCQwTI10cyxRAlhjFtCWZRZAuESJe2YWgBxjFlBhFgLQMH1EiehIibsJwQQNAKAJQfbFEKR1CEABDSDQAIlDHhD4D4Wtw5nHiQbExwPzSPHooeADAWOiwoAL6EzhYUfFYUcwdEiLCFBGcHroVqkAmOsb8RKLYWxCUEAUE0+ALwZhFEyNaPoQcU2hoAMzHeBqOB1yPuToA7CE6ffgMaAaErKI8egwIAFJicaxBhiu6XJCmaAQBblOWTMF66rxAHAC' $Extract_APNG_Frames_x64dll &= 'CHcChvzpRIIXXyJfIlQi9D2xHEPCA/xsV0mJ1+EfTSyJxZIf4W1MMiRISDCLtCSwUQWgegdII8MOgI0PhEcRMIN8QCQ4AA+EOyIh/xgPiDIxB2AU3+ioAslBIFwkOEGJxjmhAYW3MQLhHdEAhJ5B4aSLTCQISXA5LBEAiQ+ExrEejQQ/IESLlCTAUQY5x6BND0bHRcEjOjCEETAnD4SR4rfpSIkQ6EG5LHW9D7cQgaG6SIPBAYhRwL8AykgpwkwB4kxgAcJ15EnROZIGTQCJx0wp+E0B/UJJkMIwSYnAEbyFQqASJvhI0ehACExgD0X4TClwC2ANRVCF9nU9MCx0QCmELwIJoQRgAUADi/IqQCAXMsDBAFG8OOOs/9BMBgPgA2APQYM8JAEEdDKREwNMiT5ExVAcklFgg8RIg3nDIcrD9NF2sAHr4vEloQdQyYuMJMCBAOBgvkpFkEcEQAF0tCIISCiDeBBAF1YBGGPOAEUx9kg5y3QSCZJ86DFABEljTCQWBPAHdBRLMBWF0kkoD0THMG/3sDTISMwp0KMAoBWEXeAgQhJASDnCD4cJkQ0pctAiEulC4ihxg4DT4WzoJcBzEhxIQAB1HYRy1OAs6TExLTZF9RI5jRAr+DEcQCt7McACHILgEaZBD75UBWAAEIlURCyQGwFMOQDAdepJKcdJAVrFQLFN4BfwGcfyAm0hkAVKjVQ9QDDpRICJTCQo6B4tkD4xAB0o6USwAfJui0DaKMIcdQABwxQpUIAQCiTpeBABkEiBGelM0TANKOjoUCNM4VyKIZzp4uA19lMgFelGQWykKcICF0G4ZItJtsPwUBDpJHY8MAsgBnHZ9lfy7pEAtcLM8wRxNHAcADiD+f90a41BIP9FMdI9MKAAdxA0SGPJAFSJBUgwiw3HSoACMJRMjWSUCKF06xf2CPBAqbHQAUyNkIEBEAlwdQiYTInRFs7iDTH8AyYxc4CLBXFzAzFb68ZR+QhIY9IgCTUh' $Extract_APNG_Frames_x64dll &= 'CWhVKQkxKAk0LQkU8w75uQBIiwUZSgAATACNkBABAADHRIgkMAAAAEyJ0QBQUigAiABIACAgAUzoAKH7//9Ig8RIIMMPH0AAANzhSQUC3GAASuvGDx+EAQFIAEiD7EiFyQB0OIP5/3RrjYBB/0Ux0j3+AC4AdzRIY8lIjURAiQVIiw2nAHJIgMHgBEyNlAgBdojrF2YGP4sFiQNXFR6PEQyPURWPSGPSVQCSNQGSaAmSMQiSFJUNSRQASUSCR/lIhkegSItEJHARSokAStjogPoGSIEbwYMbsI+Wh4Acl49ppUfw+YpHCjGJR5AEAFNIicshwCQg6GspgA2FwAB0H0iJ2UgB2AHFG4A5L3UDxgEAXEiDwQFIOcFEde8AFCBbw4UPkFBWTInGwBDTwBA4AP8VQhcBAInBCP8VWsABQYnxRVAxwInaxWtIAQZpABYBADHJg/gBCA+VwUASOFuNDABJXulHw///D2wfgEEJyxPygAuBDQqF1ROB0hP3wv//xCcAQVdBVkFVQVQQVVdWU8EURIu8BCSgQA9Ei7QkqCHAAYusJLABE4XJRA+EQlSDeTiAFssID4QCQANJidRIIIXSD4j2gAgxyUGAJkyJz+iZQBdIBMdDwlxBicVNhRDkD4XlwAJFhe0gdCBEienCIV5fAF1BXEFdQV5BGF/paAAMx29DOIWQ7Q+E/MICQDiAXIEDA0mJ+EiJ8gBfAP/QQYnERYXkAEEPlMGDOwEPBIQJACJFhfYPhKrwARmEACrngj/5wBsYHOmjwALAdw+2RAAO/0iNUf88CgB0EzwNdA9IiRLRADV158RVSYnYAEiLW0hIhdt1IPSJ+CnIwQYGQQCLQCQB+EGLSCAoQYlAJEEgPf8A//8x0vfxQYlQUCTpMIABucFJ6UYpIAHjYUyJ4mAU6DDlyP//YB9AHg+FMgmAA+kkgADhcA+3CERO/uEQZoP4CkR0iaAADXSDZBHjLOl25ghgHzBhH4UEEYUM' $Extract_APNG_Frames_x64dll &= '6EHBYQrE6QADgwTjJUWJ5emo/gHnJ0WF/w+VwEQgIMgPhOjAAkhjBEsEwGlxSItTOABIg3oQAHRmSEA5z3R5uQMhCu8awCQEwOAK4SmF7UgAjQQ/SA9ExzEA0kj38UiJyEjMKdBDAcA8hJYhCgA0gESITCQvQbgjaYDZ/1AQRA+2IAJc6XYCEeIpAjIP4AHpEnOAAGYu5RNBicFgRTHk65b/feh9l7sBIvZ9ecEu433AfXjIfc2gfCghgKJ9Ev2mfeOW9kHjBu6POOChAYXBAYFpzYIvVIAuAVfDZmcZ4qpL4AWOBSeFBZCQ4AMoELoAAwPAY/8VK8QTAeCzBaT5wgdBAaqhRwGeRwGbRwGYRwGqlUcBkkcBj0cBjEcBoolFAYPEKEkWkCeT0wMA4CA5Q8EhgME2AZzIBf/g4GXpI6EF4gMSGeIDQGiBAwj/4AnjU+nj4wNWSInOieWR6P9CrgXYQmAjALdQPGY5UDh0AAoPt0g+ZjlISDp1NOAjLFDjJCgiGaIN9nQG4DMsicYG4G5CASiJA8ODoDQB4khMjUwkKEyNAYAEMdIxyejtAgWANcfoF1VIieVICIPk8OAPQEiNVGAkIP8VpSBB4RgPIL9EJCTJCzYAVcQxySgG6P0MwBDBBs2ipWsrB+U76MfxHIAIkCxFMckwVjHSACX4LOjBMDTRC5Qe9AjyBSxBVMBUJAaaIAZMjeJkIAaLHQoABpAGQEIQ/9OFwKASrUEAAAB0UzHSZolQQDgPt1QkLIAAOqGBACCD6gGwADyxAGowgAA+wA9QkQTxRcEJ0QN0LNFtKkiJBQTAnEEMZfBbQVxCXXUTSMdAOHEA637H9ETwI2ACogGnAnKBKTEwCMcFb9ABwSuLQOZAcR51BOkr0UYnFPF+gkBVAgLDkOkL+wEIiwUqgASFwHUGnOuk8QX9MvEaQVTCZhXyEVBQEagBBVNAhYDSdW6LBeub4gMIBehioVbJ6FsLJRMaMBIayQ4S' $Extract_APNG_Frames_x64dll &= 'GllIAItUJDqJ0EiJAFQkKMHoEGY5BAW9cAN0U0iLPQReDzAWjXMgTI2EJacwAUiLSxARRiAKTYngugEO/9cASIPDCEg583X65JAQ4JBosxD0DcU8IAUCauADda0PtwVlAYAAZjlEJC51n0zry/sk8S8xyRQwKCjorQqEd0iAConBIMH5EA+/sF32dBQQZkBWuNEvQQ9EBMCYEy8NZoXJuMGRMA9E0IkTsTqALwH8KkiJzVdIidcFcn9MsogoiwXGmkVEEj0SWQVmP8ACvxBIOA+/UTfRdFEgRA+/QDowAD5mQEE5wHRCSKBwCCEwAclEiU1gN/90AAdFD7/IRIkPAaEJBynKg8IBiQIWEQkIRCnAg8A2AVI4wAhf9yQQBAfHxkUzEgAEBscHowAgPITHBqMA23TJx3FlG1JHwgNm8Tn9CziLBQoG9Qt9QVmLBaY+ZRhDWBVDdE7wNrEfLGXBNyiQN+jt8Q6gCApBsUKD6AEBRdIICftxOOEABwEJ0QDCAUIWtgGflEVhCScW/wnxCWaZ9Al03fzyCQb/Cf8J8QlNVfwJKfsJKfoJKfoJKYP3CftNzVdMicfwCZF1Vijop4J3XRjBBAAyTI1O/0iJ2iQxwPAHZpCghE2JAMJIAfpJOcFMkA9H0kjQHEjHcS9FoENRYC/Gddy4HQCEQVTRrUyLYRhwmih0EUnACAgyRkEYBOhgoxwgTIngQSxcw3NE8C7WNLEo6AJvA5sYSIlGCEg4iXMYFCz6ZbMHSMdUQQh0ABB0ABhxAMMISItB4DnAdBdIhIlQMAQCSMdCggIAgwEBSIlREMMRQAAI6+f3GkyLAiBIi0IITSADJEn4iUAIwQDxA0AKQAWzA4xIx1BiIAQpAcPwEAJB8QF14EyJQRAI692Q0a5NicVBoFRJicxVgBXPYq9OIPKtga6ABQ+E8xXWAklBiR5MicHobiodAQHDwqiQUQKJ7jTrHHNVu2BKAQB/TQCLMEkjWAgPhIKJ' $Extract_APNG_Frames_x64dll &= 'YhP+/w+En1IXCOHoL+IDxUmNDAIEIBt+e0iD7gEATInySYnwSSkAwEk52EkPTtgBAKjo387//4uEDiQBN/ENsQIfSAHrqEgp3qEAFPADHDADYDHS6P4cAEnzB4Nw//90GlQaV7X2TEyQienoeGAF69zzArNgBpAH6HUhAXLPvvULiEkjdKEf4UG44QAASI0UHugfzP8w/0kDNIAWQQNIiSjx6D1xA4v4HTHABcFVJuChfh5MjQwyESCj6wxxBXAnTDkAyHQMD74QRDlownTvkBzI8EDRAjMF0QIuwJ0R/0j32UNzCWAChNJ0BaACdQwcSNAw8AcISIP6+P915vSa0APyZPyL1xy2VuVRIQYv4BsxIkAyHJJqMRyqG3Eb6EjQMRSNRkA69rAOSA9FENDo2dHRmvv/dB4j8StiFEEUcweNuwBFMcAx0uvNZhAPH4QAAQBMiekA6CjN//9Ig8QAKEyJ4FteQVwgQV3DZi4FfEi6Av8DAH9NiwBJIyBVCOuRZgc6ZpAAQVVBVEmJzFcAVlNIg+wgSIUAyXRJSInTTIkAxkSJz02FwHSAT0yJwejXGgCQwIP7/w+EzQGkABYAPkiF23RbSIMA6wFJifBMieEASIna6LEBAAAAhf90CUg5ww+sjyQADACTIAKTXwKUCA8fRAET+v90WgUAJgUAQX9BQcYERiQSJwRWjRSFAafojlUPTgCBghPYMdKAFAToe4BR642Qi1SAJHCF0g+E1IAajEnHAC6CA0QkCAUEchABBOlhgIiDRwBmy0hMjSwCM4tEAB7AKA+Fh4FyuAWcSSMBAB9MOeh1O0mLRAwkAkzq6MQBJ4mIwEi4gqMAAICDErAJwEmJgAOOaACA2wMAGwFUWsn//+u1AYbPKcNJjUwEAUQx0oBk6LYZgE3FGP7//4jvAhrFyP+Y/+l9gEYBBojLAAOun0AJwBVAbThANSBCSXYvwASAHjjJf8QHQTLoCg/FB5AGAFVXVkgUic4B' $Extract_APNG_Frames_x64dll &= 'fyiAew+EpAHCHMNIjWoBSImQ10mJ6EF2xxgCSgB4Gkg5xXUIxsAEPgBIjUeCnEA4AYE3QABMjQQ+TCA5xg+DkQEdifIE6xXDZ0iJy0iDAMIBiEL/STnQAHQxD7cDSI1LBAJmQF1VZoP4fwB232YFAChmPUD/A3cduD/CK8IgAUiDwwQDDHXPIEiJ+Os0wTmJy0nCB+uxwxXGAcGDKAwxwEIgyDuJ0EmJwNBIKfBBxkKMQyjhAG0xwOvswBHBu4a6MBhIicoAFsHUyegU4hdBdMXAOXUaSBCLBbM2Q5xbTI0MYBDAcsOckEiJwkXACibAcEmJxAGP1NhIiwiAbsGEsINXQn4bggvAV1MCQIAbi0lAEYEcBehSAVPHQ0ABQ2fEIDHJW+n2GLH//8NjQycoTIuAYUBNheR0FIAPAYB8gzsBdh3oEHtADkAcNMEaolOgDIAvgAliP/MWwAk7QxAPgJ3DD7bbidiBBBz32CME4CWACDHb6AJ+YByD+P+JwQ8AlMN020yJ4uiyDCAC69HnQeUUN6EQjOiWoAPgIRIxycEJTOlPwBTkDbkDwxcoLOk6gALnL7kAdQDpFibmGWGIE4UKCul9Zu3kbuME/rDlBAUAV4JWo1EwiwWBkCAMEIsdGjWiHi6F9qB0EkiLA2AOMGA6AeUeSGNDMEiLRATDEO0Ciz1lAwGIALn2wCTHBTJACSEBDv/XufUAAkiJAAP/10iLC0iJBEMI4RITSI1UJEAs/xXzAgHBHRtESIvgAsdDMANKQ1gQ64PmceCLLCAHgyjKAYlCBniADOvPYecfxwXGjyOCg2xREFBIPQBgjkiNTIAkGHIZSIHpogFggwkASC0iAaIDd5DnSCnBgQJYWWhzJ+IxwDCgUcUeQRoQSBCF0nQh5KjACEhIiQWt4AL/0gAEpHkGBHXkwTLlIOK6IAgNVJMzAQQR4q86wQiJANCD6gFIjRzBAEgp0EiNdMH4CeIK/xOAughIOfPAdfVI' $Extract_APNG_Frames_x64dll &= 'jQ1+gSWCaEjpI4HijTHA5XrCA0AQQHU8wQB18uuiruYjBdqO4jUG40734CHgAYI9cYAJ4FsgjgI8BUA7L4EWuDKi3y0cmSuBYuSYAMh0F0jA99NIiR0dIQQjOw5dQFngb+AoIP8VkVIB4H+LdEEBXkABicLF5ADH/xV+QQOgBIAoQYnE/xWwoQFwM3QkKCCZROEgCjGg8In+SDFg3OBAAQBIIdBIOdh0JUlBGvfSgCqYHeEbFQ6hwQBoD+MeusxdIEjSZtTgIrgzBBfrSsvnP1WAG4nl4BtwIQF/jQ3sjWAqFToJwhU110AhSI1V2IEAjkiJ8f8VK8ACiEmJwcCID4SgAR+AjUXgSItV2MGVNMlIAMkwIAIgsEQkYChIjQWhQAlhJDizYylBXRXxoBXQH36ABQkRAx39MQKJBWaSYYEVCQQAwJEXAAFFIQEBiwW+HNEARfCFoADDowD4/xXFMQRQjQ3yLZEK2MAA/xQVAlAAuuEDSInBiP8VtNAA6KsTEQRSRSBTBRBiDEXxJ6UZ8Abpe4Ed+CqD+gPkdBcgJhO40gfRKPYzoOgLDAAAdwGQ9SkEBePQNoM4AnQGCMcAAtABg/oCdEATg/oBdE7GAlsiXvIfHUkL8Qo1QuFhADnedN9zGZBBUCcYAv/Q0GPwK9517fOKA/YHiwv4B5EBtxtxbCwxwAs481g4IJJIjVBEJFi5sQlIoD9YAkwAGGBMiUwkaInyGegT8BFBuBvgAWK60gWNDREAFdAd6EQREuEJXCQowgPonurgAJBXkBURf4QRIAEaTyABkPMl9jFQSGNMPVPAdJEHidYgeYUQ/w+OhmGQiwU/E3ABIVnAGPBaEEk5ANRyFEyLQAhFETAATAHC8AAPgosFMRTB8DnAKDn5dSrZYYOhkBdIAm4PhAp3gwT2IVaNPL9IAMHnA0gB+EiJSGggx2MSpA2wPE0iDIFRIEG4kVBIAQrBEAPEEQOJTDgYxXAj/lKBD4Q5wASg' $Extract_APNG_Frames_x64dll &= 'kwBEjVDAg+K/dAAMg+gEg+D7D0KFoAIAgwWNsVeDAPsIcyz2wwQPDIXLQAGwoxAPtgYAQYgEJPbDAg80hdfjGFCUNnEYSIsGBnCRkZTh+EmJBCIkAG2LVAagAFQEAPhJKcxEAeNMICnmg+P4gAVyxCFwADHAicIgUUyLAAQWTIkEETnYbHLvGAX4gYvwQ6AEJAg4QbgheEgDPfERAFtIiU9QfPlIiUBXEP8V5P0RTA9khUDRQhUW0ADQHLvBgD6Jwujs/WFQcCII/+mo4H6QiwaJBNtB8AmLRB78QcCJRBz86TNAA/cGAInbD7dEHv5mUbEB/ukXEpzi4AQUWeAE6J/ABDAVcAAIixRVCFABHlABTItEUDgY6ISgAZDwVlUwQVdBVkGLUyE4SIiNrCSBXYs1MlADQTBxFkiNZbiEpkFsXkHimHJXDvABkSjoAjkQL0iYSI0EgAkwAMUPshbg8OhiYvmwCIsli1AqoFiUsWAAxwXekD1TqcThLpogED7TIAEAjUgpEIUg+Ad+kYsAYvgLaA+PS9G+0vAcwR9DRgTxEsFGi1MIUDsPDIUcsC6QOAxMjX2gqEyLLXWxML6hBQExFUw543I/6UMBYUNED7YBTIn/QE2JwkmBysEBRQCEwE0PSMJJKQDQTIn6TQHITBCJRahBAjvo4PwD0WgwBTnjc3eLEyiLSwTQA0MgL+pMAAHpTIsKQYP4kCAPhAqwAg+H8b8R8AAIdJ5QABAPhWJ1UAFED7e4BsAGZrxFhcIGQQUMB6I6bwAHPbEKk/ccMFQgT9AOjoTT4B/wE7f7sDjb9kXgHEFyWgHYRIsA4AV0AA5Ii1AQSItIQeElQf/Ug8bhrSgIOzV3UAJ80ek+DWK8QKIUch1DBInHQAt7CA+FqpABi2RTDLEJ6ZMjwfFBgyD4QA+Fp5IGAUEeuGHNIA0gfMALTAHIoRBdqOi4+/DB0/PBRosRD4DKTAnw0AhJwA9JwEG4BBIeGQMahhED' $Extract_APNG_Frames_x64dll &= 'ofEs4A4Pg6mhwCdJg+wBgBu8gXkBMBxJKdxJwewDYE6NZOMI8QrAF4syA6QEifoxVzAYAwENwQQ5wARgBHXc6c+FEAVEUHWNDd0osWskRaiyRaj6cByNDTKRMAHonLAA/Y6LAQA9lgAAwA+HLwVAGz2QTMB2WAVzAP//P4P4CXc6EEiNFcfRBGMEggBIAdD/4DHSuUlREOhi4U2D+LAnpQtFWIMBSYAB6FQKAE0x2EQg2/poPQWRBoRSlaAAdkYAAj0gA8DYdNg9sH8QLa5gAfAFaVEO6AL1BYQx34JPn3MxBsEB/9C4BVEE4COA2EEPlTYBRQq9sThCBO6TASqDaKEEY6AvIgKiBBzpVPXpgAMgAwDohAGEA1m5AHR+SIXAdCm5AAsAAAD/0EUxAMDpKf///2YuCA8fhACIAABBuBIBABTpFABQDx9EVQE8BAE8BAU8ugE8uZkBJugxAIYBgOj+AICrBX4DPggBPhEEPsgPPlEBfejxCgMfqAkfQQBUVVdWU0iD7AAg6GEHAABIiQDGiwWwigAAhQDAdSVIhfZ0IABIjQ0wJwAAx4wFlgAVAUzoaQUAJwUA1BQCukiDxCBbAF5fXUFcww8fgEAASI0diYsAcQIwABpFMeRIjRUCeoAbSInfSI0tAND9///zSKu5giABG4nXSCn1gAYJAATrN4eHxgcJSQCDxAFIg8MMiQBvBItQDIlT9AADUAhIifhIgwDHCEgp8IlT+ACJQ/xJg/wgdIAjTInh6DsGgkYAdcZNheQPhGnBgJtEieLrDYZ/ATYoSYnwAGPxAET/FbRX9wCvQoHBg7dUgX0ASIsRiwJJicwQicGB4QANIIH5gENDRyAPhM4AHgA9lgAAwA+HqgMBBYBswHZUBXP/gP8/g/gJdzoAbwQbJoA/YwSCSAEg0P/gMdIDxYYJQQGM+AEPhbfLaG2pAAboeABauIAZ/8FOhcRNPQBVwA+EpQAJCHY7PcAKwHTcPXIdgAF1' $Extract_APNG_Frames_x64dll &= 'NAAVw38FFYSWpwFQQGAZAgb/0AITBOuxwhECAACAdEChSIsF4ogDCR0DQEkDGkj/4JD2QkoEQCUowAvpeQABkGwxwAQhhS7LQAFBGXSaZQEPtwIFRBjpTEKlroDBVYALApWchQtPgQu2iMS5gwsdAAHIr3GACmCDyP/pBgNfzq9RW0ABAw7kQKgIrjgEDs2pgAVBVIOrKAB0wAJ0ROb0QCCLHZOBmYUA23QySIs9u/UJgQQ1DIABiwv/16BJicT/1oCIDoCIQHQJSItDCIBE/yDQSItbEEAMddzFgBJ1QQ+DxChAssFJHCUZgA7ChwTHiwU7oUAIic9IiQESCgS9YMNmkLoYgSnDxZuJQHSJw8FBPIk4ABWCIEK+cAj/FUJiFIgF74nAAI0NCOICBB3hoQGJQxD/FZ6rwAMDMYEKQB3rnuUjpaQPvWAFictADw/kBBeARuIwwAm5YAP/Fd8S80EMDYyBCoXJdIAqMdLrDg8fAAwCygESG0iJwYsBADnYSItBEHXrAEiF0nQmSIlCEBDoBZlgFo0Ndh1CCCTHEMAL4w9IiQUyOYAD69XkDeIRg/qQAg+EwqABdyggCTBMiwUeQASgDDLHfAUQIAGhIWeDQAngKIOA+gN164sF9YBSEQAF4eg0YDnr2maKkIAP+WAC/xWf4BdA67+QiwXSQwQFxOgRQASLBcPAAeBLFHWuYDyvQlrbdBsR54VIidnhOOg8mCsAGYA57wAKqMEExwVGfcAAAQDHBXskAf9oFbHyoH9gwljjB+gE6wOKFUhjQTxIAI0UCDHAgTpQAEUAAHULMcBmAIF6GAsCD5TAAeA9ZoE5TVp1CXzr1+VggAKnEeAZ4QcBAMEPt0EUSI1EQAEYD7dJBsAxLQCD6QFIjQyJTBCNTMgo4XREi0AADEyJwUk50HcACANICEg50XcAC0iDwChMOcgcdeOACuezA1BIicsE6CgBr4P4CHd6GQA90yMCrOMRV+hEi2AaoCZO' $Extract_APNG_Frames_x64dll &= '6A9MjWThD0RBBuACSIPo4A8EAIBJjXTEKOsTAycWgK0oSTn0dCdEQbiBcEiJ2oGqtsMAdoBN4kyJ4KNSAIQX46VADokCkEFxTIsVAkWiEcBmQYE6TQBaSYnJdWBMiRjR6K8gOIAPVEljAEI8TInJTCnRAEkBwkEPt0IUYE2NRAIYIQGBEzFhhBNNjUzAgCPiKkERQL9IidDgInIJQYQDQAAkwXIMSQAkSk0AJOJADUyJIVUoh6kv4s9Bg4sNtSJBM1GDIxLoJ+MQCYEjD/C3RAgGIgfiGeEFoAkbQBagBn+gBmMGTOjzu4DVYAZDCioCOgIqKAYqAkRhFgBB9kAnIMh0CU1gPRBJgD1BFWBJOcB156gK+AkVR5AG8RLCBgvohsIGTDgPRcG3AvQt8hUN5Qoh8gxB8QJJich1klfgFOhQIwpLSSAKgbAkTCnJSQHBQBUkQRRAAFEGoAkBGJHwOSmD6qAKFJKwJ6TQKHMnwkzgFAhxdQ3wFRR4J3YKi0Ak9zDQwegfPRbzCB1VEfAIRTHJAAk7TVoCQQAJX0yJ2ei/AvwCCVNJY0s8TGAB2YuBkBADAAFCU+AI4DBUEeUwMeYwVEbK0BNwGESLSnAJyatgCHAJSnAJyHEJwnAJiNJ145AGTInIoghgTAHY6wvxFvEXgwDAFItIBIXJdQYH0CKQDtdFhcB/AOVEi0gMTQHZ5RUDkAoA2+MLAaI/KAEp/QBBVOE3SLCBSIkU00GBbi1QAAJ0R4GgBnVmSIlUJJBem0AAUTPgsAMgB0hbMn3H9BLBAWECKOjx4AFAA1BDSAFcIAGLIAHrsMmQ6ONQAcEDU4B7sInB6FRgAMAaGJcFEOuk6EdAAccAFmthVZJ+mmMAk3AQw3AxINuJzugxogMVzoFQg4kwSI1K/LIMBOsSdC7DAYM82gD/dCaLBNk5xhB17+jy0QqNFZuB4AKLVNoEiRDzbwF0Po1G7YP4EXYQOIHuvEAEg/4OkHcV6MAQ' $Extract_APNG_Frames_x64dll &= 'A8cAYkJzowLwB+irQgGxCfoD6HqTcgENdwHzFNAKYg0oBOjisiF1DkiLRJQkKDACOPMxx8CyDQLu9Bf/JdbvAABVcQDGdAC2dACmdACWVXQAhnQAdnQAZnQAVlV0AEZ0ADZ0AA50AP6q7nMA7nQA3nQAznQAqrZ0AKZ0AJZ0AIZ0AKpudABedABOdAA+dAAqLnQAHnQADnQA/u2rdAd0ANZ0AL50AK50AKqedACOdAB2dABedACqTnQAPnQALnQAHnQAsg50AP7s9AZ0AN50AG6+cgD6hrBmFLAAoHWNwBRJSMHiBMCt43Gr8Q90A3Z0AGZ0AFZ0AKpGdAA2dAAmdAAOdACs/ut0CHQA3nQAznQAqr50AK50AJ50AI50AKp+dABudAA+dAAudADKHnQADnQA/ur0BnQAqt50AM50AL50AK50AGqedACOdAB+cgD1Eeke2yDG+EPBKgEA0BMAchDxAdCpcwAFAPUB4P/0AQ8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAB8PAA8ADwAPAAcA8bSEAQALANA6ABABODTwOQM4wAQcFQDgjyUDPrAEDmBvAw6QcFUELmkEnmoEjnEDDuApBA6wkAMH0AQvEG5tAweABAcFAGAEJw0ACFqqCxf/BAAFDwIML7ACqAsvMqLfLZkrgYcHzV0g0mbUhx8DfwBbAGkAbQBhAABnAGUALwBqAGpwwAFnQAUuwgJHAmWrSAJFBWbADmZMEGfEBAIuRgJ7MUQ1QkUANEI1LUZBNEEALTQ1MkQtOUMAREQtNURCMzUAMTA1RTdFQn19SxF0wg7DEcMCRwJNHHBcAG5EJEUCSQdiwAJwA0IHRQIwMDAAAFwARnJhbWVfAF8AAG1zLnBuZwAASUhEUgBJREEAVABJRU5EAEUAcnJvcjogZmEAaWxlZCB0byAAY3JlYXRlIGkAbWFnZSBmcm8AbSBtZW1vcnkE' $Extract_APNG_Frames_x64dll &= 'IQ3FCnNhdmluAGcgcmUtZW5jRG9kgA1QTkdEECEAIC0+IAANCgACRkADIG5vdCBmAG91bmQ6IABmAGNUTABObyBhAm6AFnRpb24gYyBodW5rcwMILg1gAFVuYWLADIcgAIBJbnZhbGlkAwoAIHNpemUgYXTgIHBvc2nCD8YHgRZTCAnAEmZkwDdy3INyACtiAHJiAHdiDABhoACBAXQAQ08qTuYDA+xqBOwHgCaSAeJroCHjANCU+4eUALDjBAjkACwn4wAsMKDjAB0ATaAudy0AdzY0IHJ1bnQMaW3AM2AudXJlOgIK4gNBZGRyZXMAcyAlcCBoYXNDgC+DOC1zZWPhJQAAICBWaXJ0dWFAbFF1ZXJ5RT5mAG9yICVkIGJ56HRlc8ErYaYI5Q7mBjBQcm90YAklB3dpCHRoIAFAIDB4JQJ44QRVbmtub3cAbiBwc2V1ZG9RIERsb2NjPXBAB28AY29sIHZlcnMxAQIlZC6jFvsGYmkOdAM/6AUFAELX//9VbQBs5ADnZAGiYAAuAHBkYXRhAADuSNn//20AGNrjAKm74ABhAUNgAPUv4ccW5EGvYQDhQ+EA4UIYYAAFYACqDWAABmAACWAAB2AAfgzhPeQAYQLhAOEYYQML72gD4QphB+EAD+QKgUJhAloRYAASZADhAiHkAjVV5AFB5AFD5AFQZAZSVeQCU+QAV+QLWWQPbN3kAm1hMGAAAT4c4WJkFavhGOEFgGQWgeQAguQDqoPkA4TkCJFgAClgAKqe5AGh5BGk5A2n5AKqt+QTzuQD1+QDGIAil2EhZdvu77Dra+Cp6wGkEM77AWDC/Dl8ezesgCp+OPoA1PwHWPwDqlD8AAB8PQj8ABD8AEog/QFn+waAZvsAMAP0QwUAR0NDOiAoIVBCR1ctV1BCeDggNl82NC3xUngtAHNqbGosIGJ1CGlsdLA+IEJyZQBjaHQgU2FuZIEAOSkgOS4zLtBi/woA/wT/BP8E/wT/BP8E' $Extract_APNG_Frames_x64dll &= '/wT//wT/BP8E/wT/BP8E/wT/BP//BP8E/wT/BP8E/wT/BP8E//8E/wT/BP8E/wT/BP8E/wT//wT/BP8E/wT/BP8E/wT/BP//BP8E/wT/BP8E/wT/BP8E//8E/wT/BP8E/wT/BP8E/wT//wT/BP8E/wT/BP8E/wT/BP//BP8E/wT/BP8E/wT/BP8E//8E/wT/BP8E/wT/BP8E/wT//wT/BP8E/wT/BP8E/wT/BP//BP8E/wT/BP8E/wT/BP8EA/8E/QSxtYQwAPwBEAAADMAADADggALAAf8RAAACBMACABIAAEQTqAAAGMACUMABn8AAqijAAqDAAa/AADDAAqqwwAG8wAA0wALAwAEqwcAAOMAC8MABIRSYAAA8wALBAdcYwBKDwALBAZgZAABcwAI1wQHnwABwwALBAUEaWAAAdMACwQHXwACAg8ELwAFxGwAAiMACwcEBlR0AAJTAAsEBYKEmAACswALBAYywOQAAxMEgwAHlwAC23MEgwQQ6gDXAAtDAAQxBO8AEwQWRAAApUJIAAPzAAjDAAZhZwAAE4cA1wAG/wAAQBcACwMABlpMAABSDwQXAAZiUAAAkwQJVwAHPwAA0wALQwAFRVpXAOMACYMABY8AASFXAAnDAAdrAAEzAAuBBwAHtlwAAWMAC8MHAAdWaAABowQXAAZyXnMA4wRTAAZqdwDhzwQLAAVCfwBvAAsEBu83AAKDBI8ABOKDAW8ACakDAAcnAALzBIMEEodfAOcACwQHOwADMwQXAARrjwADQwR3AATiiAKwA1MEOwAHfwADYwSDBwAFhowAA5GEW4AAam2AA7GEQ4AAMpABUAPRgARDgADhgAPzLYQfgAMVgAATi4ArgAKyCpeAEYAGQ4ACTYACqFGABoOAApmAAGGABqrDgALZgABxgAcDgAKBdpgAAIGABYOAAoAqnAAAsYAEQ4ABqOWAAOOEFqGArYABA7eELqWAlYABIYAEfAB8A/x8AHwAfAB8A' $Extract_APNG_Frames_x64dll &= 'HwAfAB8AHwAFCQABYQAMBwAMQgAIMAdgBnAFUBAEwALQYQIGAAwCMmICwATQAuAB4AQBAASC5AVlAGECAkLgABMKABMBGwAADDALYApwCQBQCMAG0ATgAhrw4gqC7ArhBgYDAMAGQgIwAWBkCOA8AAEHBAAHcgMwAAJgAXABEQkAABEBHAAKMAlgsAhwB1AjEOUMze8MDeICn+8CYQ0IBQAIAEIEMANgAnABQlDhAQQACDLiAcAH5hfpEWEGCgYAClIABjAFYARwA1AB4AQKBQUK0gYDB6ITYQj1BgcDAAdiFaAEwGQIkmgIGAqFEBgDEGJkFMAH0MAF4APwAVBmCeEFgjLoBQYCAAYy4AAACQUACUIFMARYYANw4grhJDLkJAXAAgAFMgEw5gBpM9/xHP8AcwB5BDENgjQNfRv+YnAAuAcPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAA8PAA8ADwAFAOXIi2hRcQAygAG6HyjwACwtMAAwMABxdk5wAAAAAEV4dHJhY3RfAEFQTkdfRnJhAG1lc194NjQu+GRsbLUBoQFvBg8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8Anw8ADwAPAA8ABgBkkJc7wPydAQDUkzAAOAEAlJ4BAESUAQAE9JE3AYSfAQBksJUBALywAgUAmDABrCyXX0ABAER0AWB0AKp+dACcdACydADGdABK2nQA8nQACphzACbVdABEdABadABsdAAFAKp+9ACWdACudADAdABK3nQA9nQACplzACBVdAA2dABUdABkdAB0VXQAjnQAnnQArHQAulV0AMh0ANh0APR0AAyqmnMAGHQAMnQASHQAqlx0AHZ0AIp0AJx0AKq0dADSdADadADudADa/PUFm/QSdAA4dAAFAKpI9ABWdABkdABydACqgHQAinQAnHQApnQAqrR0AMR0ANJ0AOR0AMrudAD6' $Extract_APNG_Frames_x64dll &= 'dAACnHQWdACqFHQAIHQALHQANnQAqkB0AEh0AFJ0AFp0AKpkdABsdAB2dACAdACqiHQAkHQAmHQAoHQAqqh0ALJ0ALx0AMZ0AKrOdADYdADkdADudAC6+HQAAvAych10ABZ0AKoedAAodAA0dAA+dACqSHQAUnQAXHQAZnQAqnB0AHx0AIZ0AJB0APUFAJz0AK58Af82/zb1Nu62IgAAANqXAQFgAPKpBHAKmAM4JgQ4RAQcWloEHGwEHAUAfgQellUEDq4EDsAEDt4EDvapBA4KmQMOIAQONgQHqlQEB2QEB3QEB44EB6qeBAesBAe6BAfIBAdK2AQH9AQHDJoDBxhVBAcyBAdIBAdcBAd2VYQDioQDnIQDtIQD0lWEA9qEA+6EA/yFL5tbhJeEAziEAwUASIQHVlWEA2SEA3KEA4CEA4pVhAOchAOmhAO0hAPEVYQD0oQD5IQD7oQD+lmEAwKchLOEAxSEAyBVhAMshAM2hANAxAFIVcQBUsQBWsQBZMQBbFXEAXbEAYDEAYjEAZBVxAGYxAGgxAGoxAGyVcQBvMQBxsQBzsQB2FXEAeTEAe7EAfjEAQJWncR1xAEWxAEexAEoVcQBNMQBPsQBSMQBUlXEAVzEAWbEAXDEAXy1xAGGxAGQxAEFAJzEAwKuzAVRAEdkaXAAQ3JlYXRlQmkAdG1hcEZyb22AU2NhbjAAUtMGQnQABG0AAGBIB0jAQklUTUFQgQcDCgQAkUIHRGVsZXQAZUdyYXBoaWMQcwAAmUMFaXNwAG9zZUltYWdliAAAuMMEcmF3AgSAUmVjdAAeAcEECEdldIIERGltZYBuc2lvbgAfygWARW5jb2RlcuAKoiDyAlNpeuALImoDAWURQ29udGV4dEQA8aIDU2F2wxFUAG9GaWxlAHUCAaECbHVzU2h1dEBkb3duAHYmAnQAYXJ0dXAAABsCAaMbQ3JpdGljGGFsUwAXYRQ/AUXFQAtyzQIADQJgEMAOIHNv' $Extract_APNG_Frames_x64dll &= 'bGVN4BMAAAITKAJTY3JlZW4AQnVmZmVySW4gZm8AACGiA3VygHJlbnREaXLACDBvcnlBIEXoAlBygG9jZXNzAClvApBJZAAtqAJUaAA1BmSAAmEbZXRMYXKIZ2VzhQ9XaW6AHAfCJeAcoQNzdEVyciBvcgAA6uEBU3QgZEhhbmQAIwABAgPhAXlzdGVtVJnAMkFz4SUhAQAfIQMAVGlja0NvdW4AdAAARwNHbG8AYmFsQWxsb2N0AE6kAUbAHKBZpAFMQG9jawAAWaQBVYZuIAXgAXwDSW6AJwxhbAASzSjYA0xlM4A1riv2A2EJgjcAawAEUXVlcnlQZQByZm9ybWFuYwJlQhJlcgDGBFIAdGxBZGRGdW5R4gZUYWIABsehAkNgYXB0dXIgBeNCzoFhAkxvb2t1cIUFQcA6cnkAANUhA1YWaYBAIRZ3QCcAAP3kBFNsOwkFJwLDK6M6InLhAlVuaMIpZEVweGNlcGELABfhE4IgBVNsZWWgZwVUYGVybWluQGtFPAAgpQVUbHNALFZhQGx1ZQCzBZYIAM60YAMhKaMh1AWEFSAJMnSBawDWJQLCJAAAIFAAX19kAHJycgpuIBRUoAFpb2JfAmbAHgAAewBfYYBtc2dfZXhpIAcQngBfYwAkcm9sImYgYMsAX2QG5gAEX2aADWxlbmd0gGhpNjQAAOcjAoWAA+ohAW5kY2wgDAgAAOyjAWZpcnNqdOEE8uMBbmAuwAEmAAFfZ2V0X29zJmZjG6BIAV/gCXRvOGEATSABwEIgHG0ARqdgAWECugFfIiNbQAJfbWtkabAP4gACX3N0cmljbSHwCSUDX3XEAwApNbAAbJIANJAAgyYNBABhYm9ydAAgBCOQJEEqAC0Ecw4xBAJm9AoyBGZlb2ZRUAMEZmbQP2iQZwQmZjAKAEwAN5IAcwAAPgRmb3BlbgAgQwRmcHXwAEYEsmbBNgBHcQAwBEhxACESAk4EZnOzA1MEzGZ3MCzQAVYE' $Extract_APNG_Frames_x64dll &= 'QASwBwiCBG1UCIUEbWIQc3RvdxFTiQRtVGVt0gyKkgBw8BqLgZEAbW92ZQCMkQABEAUAAJMEcHJpJG50kAqXBEIIAJ5mBEAIAgWmBCACgABhBQAVp7EAdmJ1ZgAAqARzaWduYWzwAAC9BCATsBpQj5EAGm7hBsGTAOAG3gR1Qm4TCuAEdmZVBvU2BOAJMgP4kQAyAwUFCZAAdG/ACwAAEQAgQ0xTSUQEY2luMGcAoACzYvNjT25+SEM/wmowaT8APwA4AGeB01guZGxsABTwAP8/AD8APwA/AD8APwA/ADcAAEtFUk5FTDMy/4IJcX0wAT8APwA/AD8APwD/PwA/AD8APwA/AD8APwAxAEBtc3ZjcnTTDjz/8AAxACBPBxAPAA8ADwAPADcPAA8ABQAQEAAPAADQ+pRzAaB0AA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8AAw8AAwCTsAAAoAAAEAAAAEDoqfCpCKoAgLAIAAAsADAQoBigACCgQKBIoFCgAFigYKBooHCgAHiggKCIoJCgAJigqKDAoPCgIADAAAA8AFZQogBYomCigKKIogCQopiiwKXQpQDgpfClAKYQpgAgpjCmQKZQpgBgpnCmgKaQpgCgprCmwKbQpgkAaKABAu4YoDCgDjgAg/8AcwA=' $Extract_APNG_Frames_x64dll = _WinAPI_Base64Decode($Extract_APNG_Frames_x64dll) If @error Then Return SetError(1, 0, 0) Local $tSource = DllStructCreate('byte[' & BinaryLen($Extract_APNG_Frames_x64dll) & ']') DllStructSetData($tSource, 1, $Extract_APNG_Frames_x64dll) Local $tDecompress _WinAPI_LZNTDecompress($tSource, $tDecompress, 53760) If @error Then Return SetError(3, 0, 0) $tSource = 0 Local Const $bString = Binary(DllStructGetData($tDecompress, 1)) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\Extract_APNG_Frames_x64.dll", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Extract_APNG_Frames_x64dll Func _Extract_APNG_Frames_x86dll($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Extract_APNG_Frames_x86dll $Extract_APNG_Frames_x86dll &= 'SrkATVqQAAMAAACCBAAw//8AALgAOC0BAEAEOBkAgAAMDh8Aug4AtAnNIbgAAUzNIVRoaXMAIHByb2dyYW0AIGNhbm5vdCAAYmUgcnVuIGkAbiBET1MgbW+AZGUuDQ0KJASGAFBFAABMAQkAENHIi2gFV+AADoAjCwECIgCaAAyCwAADXgAAsBMAB6oQAAOwAiIQAgsCA7ceAQS/A5QADQAMGogBHwLXAzQEAwEGBA0AMAGEAFoC6AEAYAsYcjBwAQDIBi4PACjCCAAAGBEMQgEAnIMBTBQALnRleHSAAxz8mQRIgXWMM2AAUEBgLmRhdGGABXwnAQiBfYB5AJ6LE0AAkGDALnIDFIAKhJkKDIABoI4TQC5ic9JzgQXcXQAC0JXrwBNeZcMTwkjASsIdrM0TMHhALmnDCcJQwFLCHa5BzgnALkNSVMECLEsCfcQTutAJdGzCJwgLAkDECbzQCXJlbG9MYwDDZsBoAAbAAb59zglCoLE/AD8APwA0AIMg7BzHBCQgQRDoBHEtwAHEHMONtBImIQONtqEAV1ZTAIPsEItEJCSFQMB1cosVDCAFhQDSfleD6gEx/8q+AVyJYgLrFuMFgAkC6OBu/xWYQgEQAIPsBIn48A+xgDXULQEQicMgCAjgodhAAYP4Ag+UhOKjBR/AAOjqwEICuIEJg8QQW15fCMIMAIQQkIP4AUgPhacgAWShwWyLAj3hCotYBDH26wAYjXQmADnDD1SEyOgO12EO8GAOHSNhDiAO3jHbZA4BDwyEDmAMogGFwA+EFrHABkcDy6ABhdsPJISLoQIkwqAcwHQAHItUJCjHRCRCBIFQiVQkCOABIACJFCT/0IPsDHSDBeEeASAWIhfDFpApywFmkIUrBIArxwUboQ3BGoeiEwIF6Qn/RP//RS52ALtiAkpnYQLiKSMF6WoBAsAdkKGhERBQARDgCgjBAKNCCmEG6J4rAAcs6QTGBOMEwG0Q6ICgA4MFWWEZ6RLm' $Extract_APNG_Frames_x86dll &= 'BCQwaKEH7gb+RxHkL1VXic9WIInGU4nTIEWJFURosME/dWmh4kDAIHRI6AuMQCN8JAYIAQ4hBok0JOinCpQBSwzBAolcJAQVQQKERALFiQKf/f8G/4ACoDQCMe3HBUuBC+AS/4BQiegAKF0gw2aQ6KsAMo1Dpv/IBsE1h6SBFl/lB7R0wMkKGGUNoTyboUrK+4BInSEG/YWnFYJXycAF+ZPHBYV24A/NGZbYBATMArHTAsr8ghILQjHgF5ulC4P7Aw+khReAAunkxyyQQhNy/wAC67cFCYJNAAlhGSUH6eEHBgACxwVwBuxj2MBRFIP6AXQgGotMJBhgdBDoIk0gBYPEDAdo6HtyhuME69viPaA4AAUgRcRSicAN6Kkpcz+QgQEAVYnlg+wY4AHUMBRQK87gCskGQfEDY1MCBwDpqz/GIgEC6c778AD4AfQERCQCXeENqEDUAFEpUGEABcEACdIrdCqyDYXAyQ/AlMAPtsDDgAOwR2CNRZyB7GFnkQqLIEUIjVWgcTjHRaqc4gRFEm6JsD9k8AMkicMQBDHAUDyFvwngGMdFQSIAjUWoEcEDjUWkcALHRaiFUhEl4AKNVbi5URsAiddQUInYi10AqPOriRwk6EYmKCABkSRFjHADCIsJcgPo/EASi0WMxgBFkwCJRZRrRZSkTLAGAyAChXQwEgFxDdLAABCLRZQIi0Aw8QIUTwAAgFKJxotFDFKiOAFkCk1RAABRicMaUTEB5gADMQHpTgAAADHShfYPlMLA99pXhcBXExCwCAD32CHCiVWI6AT3UMARfYgAUA98hZZATlAGAicBB9MGpnEgBImFfJAIAQcaB9tRsANRiccSBxYUB3el4gJw4wJTU+kCrOACFFZWEQEgwwKJRYRU6EfyAnjpBQX0AnyL4QXCBSr1AoDoF/ACLlPCD7IFtQJQsAJSiUrD8gM2pAjsTeEJwlhRi43hCDAPhQMgyEAxwPfZg70xBwDhAAH32AnBkB0w' $Extract_APNG_Frames_x86dll &= 'EqIABIXSwBIPtvL33jAJ8YO9cQ9BAg+2gPD33iHO6MiwF1CLRYBT8QW8sABQKItFhLEAsLEAiTyD8EmAAIX2UHVzlBS6QpcUXPAIMAp9G5UQA6hRicaCDlakCzGgAgGwJpTDD7bbidpFqhs0oxvT6D2RBttQUA+EylFX2aAugyB9EGS4ZHEpXcgCuUExD0ZFEInfBIlFwCOI86uNfZ6sEApgBgI+cAAMJ3MAnAhgYAfhBxFS6EXwuUCLRazHRchSc+waFAEJAGAXMCeNRcxLAAiiPY7AA1FRwUS0JbABjYAGReQxD0XcUWEDx0Xg8Q1WYy4M7UAvDGQ20QTyMD2gf9BWAQAJgF2T/+jQSFnwgOk/oANxCIj6LiTSTIASRYjuJ1xwB4UT0p6EE/hL4CFTQhbpIUIxoAJXV4nHMQGoDaQCzaACNRb321KFoMBSi1WIRBY8QBYECcOkINL32iHTLOjO0iTgDsWyGVZ1amoUHrQXHnogBR8e6NazogODCsjUB0/YBx8exRMeW5IGUHQrkwbhr2fBSgIVxxSlJcUUkRSDKEWUTOACO7JDD4WUvvuBNYxxAtEj4LcAfZMAD57AjWWO9DFwoFyjUIPsLGBTU8FhcRNF3AJgdaBQ4HEkBwTov1AGATaRBKODsABwP4tNDPOkYU3ii/AAjUXcwh7manABWmNyAeCBZuIK3MEDPiNAAaAAV1eLcRD/UhQIUKECWEEMfRD/QfA04HUvi1VBJ8eMReSSBEBZjVXkYAD4BOj5sN0QAhEF8UfQAAUAA+TlDBAAgD0gAaBnAHU6VTHSiRDlU4nQYjCJw9EA6IPjAYXbdAUANSCDuO1Jde0QiQSVQJACQoH6QSHeddZbxgWRAwGEXcPRYVNR6LISSQAIMcmLXRD30ABLi1UMD7YUCgBBMcLB4gLB6JAIgeL80FIzgkEEADnLc+Ba99BbEfQUg+xIRRCNRdCAiUXUiUXYjVAAf4IbMBWS0UAWEQIQFtMy' $Extract_APNG_Frames_x86dll &= '5KVhAIuAAOgx8gDs0wEi8DRox0X0EefoCQHQAQ+2RdAPtlWg08HgGAmBANHQEAjB4hCyANLJweIgCAnQwgSEHTHbGIPsPAWJEB2LfQxNISxiIGoBL3gVyYpMwVABU1ONWAFGAfBMYjehAgHYUuALoXYUP6RDknU1KSFEoUPJBA8pAACWuAAAx0QkBAEAAAAAiTwk6O8pAAAAUVGJReQxwACLF4oMAo0UGABAAxY5ReSICgBz7o1l9FteXwBdwggAVYnlV2BWU4HsjADYBfiLoH0Mi3UQAYiqAYgQicNRQwmyhSMAIABSKcNSACYYA20DbBQADAEOEAEjAAcMGQQPCP8AAAY7NCToBHklAF4GidrB6gAYiBCJ2osGwUDqEIhQAboCdgYIiHgCAARYA41FEJjHRZgBQ4lFoICJRaTHRagEAVAkRawCX0WwAwa0MZUCBrgDG7wCc0XAAUmAiVQkBItFCIFAAYI8VZSJBCToPMBFAACD7AyGRwAJBLk3gGVSi1WUiABEFZdCg/oFdRrEAFONgDoAEugo/gD//4XbUVF0DlCJfCQEgV8WgAhSHlKBTwAtgTuBE8cEJEGBPegz/f//gC+FANt0FYlcJAiLJheAMIFE6BoDDIhlAJ6NVZyJVcSJgFXIicKIRZ+BgjUACMICOcQBJQCHx0WqzANo0INy1AMD2AN2KtyDDeADduQBdohVSJ3ofoAwUFCFdQwNhnVMAAgAQot1FEBBgTuaPQAAVwECcRBDAAC5AQ9SicMAjZX0/P//McAQidfzq8AtDI2d4qhAE4kUJAF0BHDCOgEBTvDAABDo0zvBQBVVGIPsFIE3wRPcsURBmwEMRH4MAQ5ANAXBYATCAhwk6Fs5nUEjMMANQQjEigj0gBSLRgnAEtVACYmF1MAkIIPsEIXAAEcPhQIhAAvo3DwAAFYIiYXQQAboYEgAMACNlUgAKoIxidfYicaLwgzAMHTAJEMvmggEI/WDGIKj6BVAL/iN' $Extract_APNG_Frames_x86dll &= 'lVSPDsAlQ0DMPgImUQAV6Ns6QQ5gSA7Dq0sOxR0CxB39yR2dQg/6bFQPi8I1yBAEUIGrww86XcIPeMkPQA6DEOn4FQGguyIbDKE311GJksbCBDHAYAtNMBAirIlMQFeFCwCCCxiHC0+BO4AywQdUIujMADWNvJUkCRLBBSEHXCGSIgeuMDsHxC4HIFyiBjwMIIkiFBQkAQeNnQCAA21hBwelUKkOHOAHwxoInI2FJQXpValQrzaADbyFtCJ3oRIBWZYFgoAFQcEEHCSNnQhAhOgkcT8hL7kY4AXGhSLsATvGhe3AAFDGhIXuwABOxoXvwAAQR8aF8MAADVKNRJUgoAbGhfGgAQof4XBhq2QYf6thIRwkxoSF8qAHGsaF84EITMeF4RBCBYUMJgEQTSYBFCABAgqFGGYCHCMgAQFE6NMfoReKjBIFIReLlSEJiAwCAECD+Ah16o2VDpjAAaGFohvzq42dIoQlMseFgIQJjbVpIQGJ30AzHII5JScFiYQXBsGHfseFhGYQqogmAYwmFJBmApQlFLTRNCGJDIRUoEQI4YssL/nirMIwkIAS6Ooz4p1Ad421gRghuFT4MP//jZWBS+IXx4WC+KQLidfHhfwmDX4AAAQjAUEU4xAhLmECUNpQYk7fYh4AIL1BCPQcrgvqHAFH4hcR4hcQ5RdafOMXb2AT5Rec4RcqJeAXUGXPmvcgF1WIbYRK20AzYhbsAAXjE/D1lgD0lgD4kACRY8BhIgPIiYXk4UGF6HEBUAzHkzRwGs8LJAgQyAvxDVSF/HYFAJYSBJYAcFU2E3SWAHiWAHx1FEXKgMNrhJIQBzNxNqEDb6Y5EgphESARXEAPIxHoPh3gX1AMoQLSASARh/YJ0AF9HNANdWDoHb4n+jJ2MnQAEWzhehAQb8dyPfJ/AI6D7BgEJFUCGOgiKpKCUQf3IgAYAOmFUExpjJIgANAAU0BTYQiLgjb0BieyUXIGsAUR9BVsww+MhN+gAyUW' $Extract_APNG_Frames_x86dll &= 'jYXgkRiBoAqLRSSNteTAAAHxAwogJgCNvegz0wBTC4XcUR5khotF/CDHkgOjAWEDkwAhA0UH/FgZ8QVhA2EN8gnCBqABsvWAI1BQ0nH0JvsQATqLwgLZQgQhD2BU2Vw0JBQAA9kiBsAAENuERSxgAAzbRShgAFgI6MxiA6NRGJEFU7HQTlKJxucGAQxVFAms/+3QQ3RuDMET9dACAooCAYTAUQ+FAxGQEY212PIojZXA9dZd9yA21yU2AxuPceAbJYIZQZAq6DyhJJXMzz9sE2KxA/SqDGqTLXNhPgRwAzOJ34vVL3ALXTBPYQ+BCnEFkA3gFdMghFFwZVDrPmCgFWEIwddgAWQqQAIHUReNUkbhAKz4F8EBwVFS4QDp4ABSUTAE613xGHvQAFDbAxnBAXTjAPUbXaIDcQVaU+EAruIAcQVW4QCfa4YFAp6QsQONsinhAIFz4wBlL9I4wQJhnlIIw1XgAFHFoyzGo7xQLw/gt0UQiYVBi2CksQICd9C/UYXAD4TqBYEyqdAAMduJhazFBwKWQIhSi5URAd04T9CiUhcaOSADMyaBG7jxwQnYiZVhTJAfgYORH/3iAJURTdNMIoycSJEA8y78CIuyCNUF40mis7IQwQMnEAc9caF26B2wDI2VisjohdghiQzpKKAIzI2dgReCAY2Vtm31KW8QpMAPIyZlRxFjO+LGbWVxIZ3wI42VARvrKYl28O8p6SllcAPvKc61vk4t4SmFVFAVQRNygehi5cCJx4WkcA0BAFA06Q9wAY1SElACjbXxAQ/otfDiFUYRYVsiv2tpW2MAhNEUifIE4ydSnonDLlJf9lmNGEWIk8sTgeYiGEWQ0Q7opyHxQCa2hfuABPFBQA7QALr6IVUEkgMhFBAB+SEX71AFoACiNOHZTBAPsDOPmeNEEeAC6Kgsk5liAoZtMn6IbehlYARwWoP4kgEjC4PTQilOKIAuDIuNcQ6gTdcx0okAyIPABIPSAAFm8INO' $Extract_APNG_Frames_x86dll &= 'sQIR+jAtYi8PrzAsAAxjAQEB3kCUV4EyE+GLZwGnHHAC+wFWHH468Itv0EYxx4WwGxAD0mjEMgyAZA+EfKnQAusqoBGDESVXMCYMjYUBHJEF/RK4ADQAAMeFpP3/AP/+////V+knABEAAItFDIkEACToAjgAAI2VArAAaFaJVCQIx4BEJAQ3AAAAAWiAlx0AAIPsDABIDAwBACQADgj0wACWEAFEAIr/AURELAFEwBCFwA+F/ABEBKYKrgCCUgEQdTsAACBRQA+F4AA2jZ0CcAA0McCLdQyNJJWAAIe5AwFn3/MYq4nXAgoACHQkDGiJFCQAYBAADwJwEgEDBwSfwQAQ6HYKLQGr+AY714nGMcDA86uD7BQANQA87gQBOQEZAbJqADEBQQGq3Og8gBwAE4gsDAJhgA9BBmccJOiVKoBhhTeBU4EpAGAYABcBDLwz2YA8hciCkgALrQAHg6eTAAGAp9cPAhONtQEdWOhPLgB/iZK+ABdREFGJhYCAFuiRHomAFYWsAAWLRQiBDhSANgA6lQEIU42ddwFugMOBXBSFVIWFhAMEU4EDARwXIQGHwAAcMRDAiZUUgRzXuQJJgqSNhQIHlRiAAseMhRyAAkEPx4UgQAKJwnKFJEQCg+wYQUFGi0IkRRfHhSiABzGNQgIsBA9AHMeFMAADlQMINEACB0AC6AHAM4iNlZjBC8DHhQF2UcIn17kYwgmEBASNRJUQQEPHhYhGEIz1xiKQxgSUBBuAncKFwxCDAUXCEFWIx4X8Bgv+AAAUQwJBWoMSgXvDBAF4r4ESyBFBZwMHdEYCeEYCknwFEUWAAgRFhIMPAOgf5f//hcB1Fk7DSEFe/cATV4k0q8C/wIdQAYg7AQKNgj/dAQgsgwMBjIEDfYBSw4vC/AAZUOmnDYIewAOrhB5GAoxGApBGAqBGAqqYRgKcRgKIQAIyQgJjwRfBBMaFh0EChytuChuBnJSgAYXAUw8UhZogSo2GA9Xq/xD/' $Extract_APNG_Frames_x86dll &= 'UYnDpwWQIgBQAFaJxgQC10ECXZIjAAidcCFEhXSkDABRKcYZ1zneiYD4g9gAD4waICeRpUeNhbQhB4U4gCHkjbViIIU8YQEiAqhNG+IEoxhAIAOBB8eFRKvEQuJNSGZETAZSUEYFmlRGQVggAQF/6HNAHXAPtoW3AAtgSGANELWgAbaBDQSCEyACDCACPrWBEgARQAFiFSAX6BhOJ0IYCoSmeDQkwQXopHQm5YgMBaRyBuOMWcUE6DHACESiS0AX6YpzgACLgi+NnVzJnq0nLv4AeaGvBIEB8WCQ2I2V1EADIgVXITGhB5hXidcqpMQTCCCkgvKxIaRUKIEHwSwmpKMHn4AWoAcjBzGkoafoFqAHcb+k6G8lIRphGaSk8ioKo6SWAJ9QxxrXFX+CYKFuYqmAXsABIpzAAQnbwwElZvqAUihmS0AJI1pi+8AHUul1QAypLn5NrC67YBKjLoSkQATrgnIFqEuJXCQY46o/4RoE2WaqhTwiTkAY8w6bYRsiGFyjHqWtGRklAwsBSwACSCAvUYPABGCD0gDpKUChyRMLJcwTHMYThZ4gCukXAQAFg/sadWQxwEgPvpXBdYO9wnwPAJ/A99r32IXQmA+E+0NqohiLnaEDL2Mp3RgiHgEUJ2AZMcCU62BAX9HBIUMJtg0t0AE5gAUDBVfhAHoLbdoZa+MA1Rlc4QCBDLMrAH9zGfqSTN0wUjnDSHwViyJ9i43xBIoAFAKIFAFA6+cki7VhSjHAsig5tRkRTYu9MUyTMA+VwEAx0vfYOb1BTw8AlcL32gnQdVx9ojFFUYdGKIVvxSiBGuqjUErhJ1wkKKABJCQCu8EwcQAcdABxX0YU69AW198F3wXQBYzQBYsCWjEGLfAFizJa1AYUpAIgizPyWpAAHIvyWpAAGIv7Yn6RR4uyWRFHRDDABRQWTeAGi1IUwRVq6GEGLEFxB1QrAAD/ggFTLzNAkX2xEjBsGtFoqo2jgjcve4mVYLJ+ZFAA' $Extract_APNG_Frames_x86dll &= 'q5EC4lNo5lNslgBwhlRudKQCkGiGVHyQAIAuAOjoKhbsLlnQoOQu4wsvgiQgo/JuY1fYgRy2lQLZYADB4BjB4hC0CdDgANtDBLIA2qEBdOIIsgDdkmEhIqAD3G2CARBgA7IB3+AAggDeXQgD4QIDASQAA+ALA+N1BQPiCAPlAgORGwAD5JULA+cFA+YFA4uVsQg0gL3Sc4nSH2MdD0Q9UgqJwgAzHyABcQjB+pQYifIAi3IdiBAzBIHTAMH6EIhQAbMAGVd8i40RAjN6AYuVYVEEiGgCilIBdQMYYIhIA4uNoQF0BVAWBJMCiAUFpAFoBoqpmQJIB6AO6HMY6WIALI3q4hgTEeuxAOEIQAnRD0SNbLAAaYTA6MA5mff5icIqWOnH9yIlhkzrjExTUxA2gkx0V2kCEGwCLMFlAonDD4QqMKl3Ry4RoCJwQhELnbGEg8EABIPTAFYByBHI2uniICqNlXEpsaS3gS60pCJrhREuAoa1oQG/sy5jK48ugy5wztGwQwR8zhhotT9UOFTo63BNNAvydHtgEROlwLTRrxKDDgQoHzIQg/gBGfYgg+YEKfMkXo17eP90RoZdciHvCOsIjSxEA7JFB1k7AFnrOjyJfDUBjw2fBFSV6A9JsA07vVGBfCzTgYtSlVEAA5WxCP8SAQMR8lwB8ANSGIoAiGgC68zzEAGiaHEER82AQlcfQRNBGhdhEkOChfJDGXASUOln9dVPzckC7cBGYALpSdABhXD8jvPxb0YgYyGPILJRryDfryCjIPYW3xLYEki0IiMTmfAs3AahGiERihQQXkFRB4gUGEM7shB14uWPbv+LtYNuQVyFbu61j26vaK1oAbBsj26PbgOPbtgF+bnAAMdEJAwAAAAAcAQE/wAAiUQkCIkAHCTooxsAAIsAhXj9//+D7BQhAFAki4V8ADCJXBQkKACoFASoIIuFAowBKkQkHIuFkCEDEhiLhYADEhCLBIWIAxIMjYVc/hEDuI2F' $Extract_APNG_Frames_x86dll &= '+AMSBIuFgqQBOgQk6IHhAWZCLAF3ayQAAAMs/wUCHlEBH/YCAABTiIuFrAAPjZ3IAQVktYAAIY29AkoAIIUACwAAUKFQ1ACKEAENLwAujYVwAEIkg70BQwFSABV+IwTorwAXUIk8JOjCpgIINCTonQIIADuE9CMABOsr6IwFEaqDAARSARF6AARRARHq0QARx4JJ+YAsAEcBBQCNZfRbXl9dwgAMAJCQ/yVgQ1QBEIEDXIQDSIQDNKmEA+RCgwO8ggNmgAACi4CDhcB0F8dAMgiCwkAEAgMBAgAxCMDDuIGzw420JgGBB410JgBXVlMAg+wQi1wkIIWQ2w+EloEVBCQBHSjoKgEA2AOAJVyLAEMEi1MIOcJ0ACKNUASJUwSLoFQkJIkQhRP6giwIg8QQgFvDkIsLACnIiQwkicKJgMfB+gKNNNUBGkCJdCQE6MIBAsIBwBM7AfKJA40EwDiJUwjrroGJgSg1QBMgQROkQQlBHRWNFJCAwQJDQBwI64IpAi7rmQUdhQABg8gY/+uIwy+EBYt8JAgg6HIBAjeLXwTUx0eDQEeDQAdCAcQPAkUAAYX2dB6D6yAEOd53D8I58//S0IIDdvGBaZdAggA1jDHAgjUGAP8lZMReqgzEAQTEAfDEYjDEAaosxAEoxAEkxAEgxAGqHMQBGMQBFMQBEMQBqgzEAQjEAQTEAQDEAaqUxB2QxAF4xAV0xAG6cMQBbMaGQQBASxhBewPAdIA8EfZDFCB0kiNBo3MsQFTsBMBjAcFhAIPEGFvpr24GAInDioHBhEHXgArIUgWCCuvTwENTAIMMCriAigBAFQiF0nQAG4sLMcCFyXQAE41K/4XJeAwAOUsQdgeNBEmAi0SDHFvCCMBahQoAVQI4bIuEJKE9UIusJJTBAEAhhBiAg+AgdWmLvCMDQFcQO5QkkCABdKAEhdJ1UsUCtGICEI1fGI1gP4X2dQgm61XBWpCJ1okASwSDwAGDwwwAKc6JU/yD' $Extract_APNG_Frames_x86dll &= 'xgEgiXP0OYRDCDGLAEzFAItUxQSJAAyHiVSEQDnRTH7OQEPBGOi6oxuDDMRsAXFmZUQkQIl4fCQEIY6AFaEIQSJ9tivgAMECwwIEiwOggANgD6+EJIQDFcIAjAQkiMAAD6/zicdBgCRxi5QkjEFR0lx1ZiFhARCBT54hLcUBhCKJaASF7Q+EhqrBByMCAe+JOAAggQEKiXAIiXgMgAHNgg54IWHBFej0gF6vGCRmkKELtPutC3RQA6ABAhHAdJuF23QKl2AaGCUMdCQciQ7uIDPhA+EHAf7/1eCD6wF19IU2YQWABOCLaATpW6B04i/gEMnBbuhs4xDprcGrAAMVoT0kgJQ8wEUwjXQQJESFwEBKdEDorsOAJQAFQANAIA4UgAIxAr5EJDglyqIrRCQSNEG96MQBycQkW1Bew422Ah4jIssEFOu+/Euc4ksQO4TEJJiDScB1VKUDwE4Cw6ALFIPjIHU/U0AzIQQxwKAUQKJL0kR0RcDVFIucAgPrhgvhGUBMOcN0KelJlBSGwEnnxUlrAwox3cAeFMANAQjAHAhiR0BFvDUp5AHBMoIDBANcAAMdZkiMozxB4iMCD6/F2+EVIEk2xTlgBqhgBkAOMDnodiCgAgFqiWz3QAsh5IYE/4Np4ClBbQUDFItAgg4XAUTBhcBYD4QhgcBkA1RABUgABItACDnQc1wEg7ziQQCNLAEPhITDAAEpwolUAEXw0DHS96Qu4AAgO6EAFHItcBMcMDJ2AIlmLKEHoQMDrLIBkSTqmyUGUAKLIAYADgHI0A5BsgoBiciLTDAZwDAYiUjwQAEyKUj0U5AAchJI+NAPLvYtiwAMnossn4PADACDwwGJyolo+AAp6olI/IPCAZCJUPQ5gxt120UyFs/QDbkZlMI5hdIPPIR5cCxRB0E5sicsJAApwYlMJAjoM8JkFxFIBOlQgAK1LmKA4ARS6RKRLkRDdoXgBSyAEDCLSgRgCspagS+58gQUJFGPoQCA' $Extract_APNG_Frames_x86dll &= 'hcC4wG0AEFUugA9EwY1MJESwBt4cAAghRUIw8AAYCjDyLlTELPhJRIgyFHI0FDM2NKoDiPqgdDRtg+wCHHABIItQEINgRBQ/QBbHQOjyBBQQUsdA7JEAweICiMdA8HIFVCQIBhGJYCIoY3FiHMIESF1F8WAIgAsMixoADyGAjUH/hcB4KiBFACY5QhB2IY0E4ECLRIIggWBzO7BiQNt08ItCECIBdvoAc37f9gTwCSAHg3ygB6YcM3zSG7Eh0RsMMCu/QAh1EPFtBQNxbk0DfEMD4IlYBInYMW7ACxUU1/II/wamA0H1Bgj4Bv8CNfYCEfUCDP8C/wIA6CbhgHfxAlAM8BMgifBIDInQ0xXomv8Q9wMyofQDQBD/Bv8CAOhqcfUGEPMGEPUG+VNXBQAVFOOhdFOLQzQlAGJMsFn/UOGDCoMgxBRbX8OBCY17DATHkE4QBef8x0MCPJEAKfuNS0DB0OkC86sVB18xlfE291ID8hZlUkSqAQcP9CnABgA1uojtABCD+AD/dBqNSP/B4IgGjZABAYH5/6ACkriiM0PQIC/oSXG6NYMTdkEPIAEGAAHp4LEiYhzoaKCgJQnMY2PnERPzK/QjkEkiOdIJNQrEQB9wL8OLgAEFMSS5UFQV0NCVhA/QJMPwZhyJxxFnUhdPBADo+zIegCkd2GADIQTFjRBwCOsPcAqLRQQAi1UI99CF0HSyNOGyi4VRBiEG07APCOHoZAFJVQgxwOSB4vEOiRcQC5l9YwF4jUUcmAHxIvaeEK515/AaMApyAYuD9QUtDMUXg2MA83Msi2wkQDB+YkhgRhyLfVGiwg2FIvblDQ9E8BQOgecxoAp/6BNwDhEOw4VQ/w+E1tE4EIBVhar8oQVDw2hF8wfU8AdGieIIwB0PhIJjaUQUDQBwBPaAABAPhE+hIiDIwMAREnVS1A57YByJFscDQpMQ1nEGXmYd4QWJxugfFa0xCAgwCKBskih3i/JLJCAWIgrrHnFp' $Extract_APNG_Frames_x86dll &= '8OhqQbHfx2ASrHEjoK8AEAC7yOwQ4Cwk6G51kAQAQ4EiLPTZ8yuLFSGT0tADA9QDdMXpjm9BkOMT8dhEDSAAAYTpPEAAZpDomwAnnOn6MWLyAxIG65z2Nov02wBZNPCGGYsSUAAQE4tAMGAJBP/i3GaQMNzyG4PcZvVbIAMCJaExSI1Q/4H6cv6ABXdFJjIAJvZouhJIAAGLQnE8JIsIBSBaHrDbejAAdQWZoDP/0XYzwjbr1nMGnOvo+VjxBmEf8MHT8VRhXWBc0gAKCwBEYLkAxBzCBACNdgAAiQQk6HBdAABEuv8AAOvmkAUAuAABAAAA6xONtAImABwAZpCDwAEEPQAATHQWicLBAOIGi5K87QAQgIXSdefDjbYBQhgxwMMGdgEAVblIAQBAV1ZTg+wsiwBEJEiLbCRAiyBwCItYBAAaRJlAhe10JLmIACGDAP3/dBqNff/BEOUGjY0BEIH//wUATr8BUw9Dz4l0ACQQiVwkDMdEbCQcARIABxgBmQAHFAEBD4lEJASJVCQACIkMJOg5MAAAAIPELFteX12YwgwABLkEBpBVBoqCTAKKTCREi1wAS7EASVAEuIFVAUm4DUkqhQ5JxwRJCBZJVCSYDIlMAEuArKYvB0myEAZJdCaAR42PXABKUHgIi3CEj9uFj/uBAUZr/8HjBrkBHhSBw4JI/YFID0LLUQAbTIl8AEh0ADpcbCQUDUqJjxkSRtBHVFfIR4Ikw0fSxUf6gSRqqv+AgbiCJMKJJMKADy5QiCTOSYAjFMVHhi5ZhyQUAMmPwyJEAQ9wWG4AEAEPxHsUwAVAVcABEMABPMABDMABOLXAAQjAATTBO8ABMAEXNqmAHQAXw8JbwxNAjSBQ/4H6/gASd06hwClEweAGRRgFATG3hhnAKMAHPIARgAIQgAK2OIF1wAE0QVPAATDAAQgE6EaDGMIYAMcEBCQBN+gk9///2IPsBAMFzjM4BRgBi5HBC4tQCAIYQAREMjFC' $Extract_APNG_Frames_x86dll &= 'MMH4HwQ0AjIwN9NDGQe1dgDDEzzXE8Isp8UUQYBIRt82AxQQJxQAoYgtARCFwHQQUFO7yGE87BjHRgVBAgVWi0M0oAMGAIkcJP9QBIPDSECB+6EDdegADwiUwD8CEAQCEQQk4QeI6LRYQQwYW8PEgh3lS0xgS+A6oBNIhclID4SGYRZZNMBdf2CDwP/HQUB44AbSUP+DOQEAFhgAFxygdDSLWwgABF7gBioY4AYcQA0MgjQMJCnFW//TpEjD5VmLaTEhIByLdGAGAQnvDwSv1eAIwf8fD69g9wHW9+VBC0EMAYB0JByF23WiBTjsY/UFOOoJVuJ1QBjBTyokQGMgbXRzYXSNi1ViYf5hYbsDhstpcPUC/qALxBRbXsIIG4Y54qdWYmziC1QkICvAJGEMKGxucmFujYK1Rwy6QwzC4WxlapJGDNYMCFDCLyBgCjDAJ6I6QeWVhdsPhJ7BMFMgNDH2Mf9ADn6LhEIIgD13i0IMwAAocI1U4CccAWEE/2DQhcB1V2BBYTACP4MIwz7AQGIy4UOAB3UyC4AEAAcQBQdQDItLMjQiMRwkijglOFEIAWA1EIt8JBSDxOAgifCJ+sAvpS/hXdzEIKETBQPgaRwiJqEltawkSqgk+aokoCP0oiMvgd/K1egjwDpqo11ji2pAASBcDSBLIkthGdEAIcGD+f90OosAczAx/ynwGfqAgzsBdRqLSwExQ8EFYDIIwfkfwAAMCOiaRSBbwAGD0o9hGYIb4pLgGsAx0okdN+JB/xvzGzTA+PEboWAi1OAHwAGj4gD4AYx0BnVRoRgI2EAqPCTA7CA88VTgMNQzTUAA74Ai0QH0wSBSBHIkgR/ou9ABgAZVC4NiLYEFAXQH9IBwBegwqPv//+AC4QDovEdwBLAAIQ3oACgAATtZMAWh1HAGEBYeRAX/4BVwsAAQISGSAfEMZqRkBuAWBKNhCYAACMSjxIMADKOMQEhwLiHwiewcoZAjTAL/6tCwASDR' $Extract_APNG_Frames_x86dll &= 'A57QA/MP0B0FgUAg8AFUiwgx25CFyXQhkH+B4vASAH8PlMM7VCQkQA+cwgjTddFdJECF0n8dMdshBJPKC0Aq2BJBGFtXO0ECgA+2XBH/69pyFOQx2/ABidgRAvpOsYYKfPBOdPBO7XRphRD2D4SB4RF8JEwQ/w+EjhEwNCToBF5TcADxicOD/wVAAY1COXRmidiFsP8PhetDMuM9LBFPSBzoDzAJg+yhXRwj0XbwIRApw3A8j9YL9yMDBpGhAMQsiehdInYY1QvwEpEGx6AAxoFgKYn7McDrtXIMgIteBIsOgeNREVkhAoVzkAARQpw3BelR4Q98JFTRCTUwU4sIRQQl8QI52A+FJqXRCsRIi0XSpWIKM8IKwwOFb5ACEQ/MCR2AAuiHVrEJ8ijvATkA+4n7D0/H6QZzoAL2CgHotIQiKnEFUmBSAADpFTECcgtE4QAJwA+ElAEsIA1iAOXjLEWSSenqkD/3RAZLylxjFUxgFZgHYxWwAETpN4QFi0YEYAWJBgzgACMGdGGLRggAiU0AiV0EiUWoCMcGIgZGkwZGIwXN4A2NcAHADemAQQfxCdkwBuiIMA9BAWBAAXkHasDCAghyB7+xAXQBWPPzAnEB64r8mvSMeLD/kKn8kGn9kW0YgX8U9IMv8gORv/8D/wMp+QNXuA7IMDgxLjFbIIX/fmo2QJ8E5T7dohRRZCYAjUwkKDHSD7YAWfyLMIPBBIgAHBaDwgE513VA7YsQxgQ60CkQv8FPYAASBcJd+DNhsWywMwDbD5XChe0PlUDAIMIPhJ/DKETA/4nWD4QCICjQWZjoGlAUKqAVGIlQAhYDgQGgFO+hfuj7TwdCOzF/IXwUOcIPThjCicEQCkKCVlfzEKZ0CbkhgHcC9wjZX17QiZTAicYBAWk5+nQRifCEAMB0CzHJOfoPQJ/BjUwJ//IHdNJsEgd0NjE2yJW18R6lMTOYZQp0OQEKeRAIJDHJ0CSVwVIDdcrxgx4U6L/T' $Extract_APNG_Frames_x86dll &= 'IoAewG/gMASJyIYEMcn3QwRZMkqVwTFo4QKQ5wLpwnx1KlMEiwPTTEMQMeBpD4X90CTgOYt9JgASOrEP6f8wAWaQsYAI7Q+EUS4TDB8BKoTXThYK99npGvk3uUU+69/7nLGcMxpM4TcL8UAABUjBMkQPhK5ttDp+gAVQFkTwFlAHsd1zEVCwRBHBVRBZQQKAAMSJbDAAwo0E0CNzRwtxD2OCHIACGOiABRHzMjiJw/ACGFFWAFHB6QLzpVmDQOED86ReWXSfFAyJ0Z0BkgnGBwB00lviB3RqYRvY1MdzU5SLMLG4wZESgeEBDykAC4VPETLItTYx0rmACYVn0RHw84AdsPIIsgTSBXWlkQ8xD+owQaFTAVD/dZbhFdgQAa+kZCXP9hXAYbQAjslzEXSF6IEbVSFUMx3xCI2wBArp6XAB82y70TJvYbqQEZGUlTdjYgeRNzbMicNRTuBXAItyllRxAP8V7EIBj7kAEIsDiQQk6OUATAAAicKLQwQAJQAAAIAJ0IkAQwSDxBiJ2FtAwgQAjbQmAFAABI22ARRTu8jsAAAQg+wYx0QkBCIMAEDHBCQBLujzAAMAAIPsCIXAkHQ2icMAOAgKACoIiwCJAEyLRCQgQQDI/xUAQwEE3nUlGN6QCQBXVgVxEIuAdCQgi3wkJAF5KhgIeXkMeQwEeTQkAQB8CIl8JAT/FaTgQgV5+0sQeRCAPKBeX8IIAKE3CaA3CvyGN4ubN4PsHIsAFYzoABCF0nQKM4AwgAAF6BcxAEIAAC8Yx0AIgTiDYMAIx0AEgQQFCMQkHMOEyqGEgR3AdbLEAUQAAQARgEEUARUhgFqA1AAQhSljMEAAAOuekFMA3YsAXCQgjUP4PWyRgAt3Pj1BCXI3AWoVxQrHwArHQDkAADGowMdDQx5DRB4YiYSQdgC4/wAA6+gEBB5mwU+BToBNQhl3H4Mg5uCNRgFBQu3eEP//iQPANRGJc2AIidiJewFCg0GNUEcBif7B' $Extract_APNG_Frames_x86dll &= 'CMnECHWm3AQchB/r1EQYVQIYCizAZkQAGECNRh8AiyuD4OCJx8EA/wMBx4XtdAsAi0MIOfAPjYuxAWVUJEiAFoBWOIE3QIksJOjs3wMYD0SEhgAIiXsIRmbwQUBmidiDxCyAJF0kwgzEu4kcQXUc6FLUgFaD7IGyHMEpIVXFKb0ENxAFBFQMLq4BxBHCwfoDKdA5iPh+jkYlD4VmAU9CnIEQLCSJ98Eo6BJLBSiFXwAHiSvp4mqBAffpUYABwFtBP8IUgVaF23QzQCNBpwPCGwMqBOjb/v//iIPsDIBZVIFLgSAAgIneg8QUifBEW17Bm+iL/YATw5WABzVRD52jB4nGIBkywIAC6MzABeAe67wh5C8x9uuxpT90JvAAkOlr4RIHAuVLwBPCXEArhcB4RUFNYkzKSyNORElNXC5fTQQULOhQoQJgEa7mTtuQzOuOhQ/DAFdWQEPhTwAMi0wkFIX2dAAUhcl+EFFWUQDB6QLzpVmD4QAD86ReWcYHAM3gTgxAjegVIouBU8I78Erc//+jEnIS6JPiBxPgmyAHJIOgXv90LckBCJVHggWJw0Ga4Fs55mUx2+ScgALhJ4tYEgTgBYHjoBl/6C+dQT3YQBziDKA1kJDjXQIcQBQwhdsPhI2roVrBFDMhNyChAVMCCJLiAQiJVEA4Si+AAkBzBInFKwMgOYEC5gEDKcaF9n8klr8BmwEpV6A8ifjiDMYcol3GLJCJdGIzAp2ikGI/CInH4A3DAANoCIlsgLkA4hvjROvGsSAIwgpbifgDCaq3Be4XlSEWO4X/D4RH4nNgb8ETD4R9oQF0ACQ0hfYPn8E7AEQkNA+dwoTRBHRpgDg4hcl0YSVgZjjhA4nHhBOD7gEBaEl8JDiJwokA8SnyAfk5yA8MTdchIGAAOOjU/EVjF8VgFyOLOOEIA1AzUVZX6UBfAEEEUA8A6wjgMr1lIzu94WPoaCOhRPYZ4hYTAIwWFUAu4EA04y2FwH6gBIX2' $Extract_APNG_Frames_x86dll &= 'dSImLuXAERcqLsA/4oI7gRr1D0+YbCQ0JBuBLOgVxBcFQS+6IAIIKe4DMwthM8MvFiIzDOukkC/sL2JGCQCAFQiAFRToUJP5//+ACRcgKRACiYBOWAiJEIPEdggFUaAAuHIE2CrxKVZeUxArEEewcMA0CkBu6ES5REAKw+hCAwUW/Ikw4wRARiBGkCRyDdAAX/MEIQH/E/ETQDo0YDdtUIX/dSFwAGVxEj2DsAWwT5XAD7bAqBIKdvI/IIEHPCSJxgzoFpEAgHY58InFRInwsAEPTsXBd+gE9UPxA3XEOfV0GMAPnCEEgARbXo0IRAD/0xExwIX/5HSlUATo0qICoAZFAmz32A8U9gp08Cc1C/bgdHmNbwHRGJEZkQkC1rIEeBo5xXUJADH2jUf/Zok0Cnv0C8NyFI0Me4mA2jnLc06/P1FhAhb1Ng9Ix4PCAgBmiUL+OdF2CgAPtgaDxgGEwAB16InQKdjR+CAxyWaJCnoEMf8gMcBmiTs1ATHAXOvb+pn0dxNNUuZdXA1XPSqwCnEleER0MmVwEQLxJFLX4CkwX3TuEJACIoxRAQCgLLGKoGPOX4Ed8QfwADH2FgFzGSyoQhEFtQQGtQTUjQAMeInCOchzI40zDxIBBP0OA4PD8g69UQ0CyAb1F7EX41UIwQW0sdYhCRwHAvUZTLAZUfFDyXRt8AIwsQLxQkFxKoX2flvQA1cAOcYPT/CNbDZaAlGAYmAEQAFCcBD2gH8UMdJmiRfYJgFyWVQkMCnzjU2Q/o00Wt1j6873XB1gAzGwI5Yj4AiB7CChwIKNdCQcMZgEsAAFUTNj8AKFwH8XgdbE0QGDQfiAA8P0gfGJEsM1Gqb45z/OiwDvMBLSJrEZgA1YgA1jBBME1/kq9BJktyRit0jAqNAEp1Gj8DzUPIsGsgH0sAHxkavD6LIwB8Rngzz3bSHQJIsEnaCSpnQNZ8Jp9ZFChAQksAhgqgRVMoSRwxXYIBQoMQFQfPyJwwOF' $Extract_APNG_Frames_x86dll &= 'A/kq9owHBiJAi1D8jXD8QFUF9SEK0jJH1AB5EwLURSIKdGaQ4kkY9xjwKNAS6IaloSugDPsGde1hB182EvARRTHSGXO9BUEXEX0yAwzgFue1/QIUz/IC4ZEzcI1QBNS5iRDwuQeSEAcE8BEEiwiLEMQLVLAbEInIyhr2K1IssayLS+ErHtQU6ObiMIggDInGIKlSMRBAAHYAjWsEjXsIQbCSBYgtARDCBucI/InpZIop+cdFEjgCEsE8ISurx0MZ8hLHQyHBwQhMx0MqGEIPQ8NmAzABXIlEQwhgAFCJQ7EjVAiJQyCBAoPoAYMg+AIPh/qDtFi4AoARLNIPT0QkWK1wHljgsmACYKG0SZAT/bAASNAGYZnQBmEAAVlQAUJEtKX/VCRgcUEPhIXIEQV7FItrEDAAIeiD+P8PhRi5EQRDNCAWkdahFhwCCyRQCBAHhIehAEgMYIXJD4R8ApCBCY/SsRI1eG2RzwL0GcQDKTWt/9LAYFCABY1UjCQYcQjggf9QDJMGB7EcTwNAA1AIi2wkohigXhzrFIQV6cEhQYFBMe0x/4mAC3uIFOlk8B+Qie/VqxFwGMdDPFIY+41LDkDiF6gb9ST4BHW7Vo1gDlUR0bYGqPEFVQSJ5RIhPIt9DIsEXwSDoY1DHIPg0PDocCywBcRRQMBFwDOLB4Pm8GJD8DGABfX//8YEHuCxkgyxbeb04BRFJOEjMcBAi0UgokNAFYtFRhySRAAIi0UYYADZuQAUi0UUiUQkEAiLRRAAYAyLRQgAiQQk6Gb9//8AjWX0W15fXcMCkAoAg+wci1QkACCLQgSFwHQXAItSCMdEJAQAAwAAAGyJVCQI6MMoPAAAACYgASaDxEAc6Rva//8IflcAVlOLdCQUi3wQJBiLXADsDysOAIPBAYP7AXYYBLoBADKLBJcrBACWg8IBg8ABDwCvyDnTde1biYDIXl/DjbQmAVKCVQBAg+wEi0QAP4B8JByLbCQgAIgiSQEP' $Extract_APNG_Frames_x86dll &= 'g+gBAIR0TUCLNzHAMdsEL4MAwwGJ8YtUnQCAizSfAcgp8gBZAA+vwjscJHXlAQCHGANEt/yDxJAEW/fYAXWNdgBZSAQxwIJ7jbaBHzEIwOvXBCWNdCYAEJCLTCQAEIXJdAAPi1EEhdJ0CACLQQgx0vdxDIzCBAIQAEQEMdIASRAKi0gEABMDi1AYCInQAA6Ff4nXVpSJxgBhEIGzrv+As4AUQInDi0YEgGoAjXSQ9Dn7dh4JgEOLBoAhC4k0JCDoWvP//4ANg+sAAYPuDDn7deV4g8QQAFCET4E3AMgMMYM2CeufBFaFl4PsIgwAERCLUAFWBzHI0uh7ADmDxAFXgkcDgEQBYiCJHCTo0AGBBuwEhdt0BvYAQxQgdAuDxBgaW8Q1icAIgQPpa9HPynPBg0B7QHwMAMB8wAFGCIEdSIXokTpCgsMRwk9VieVCcByLdQAQi10IjUYcwQDoBMHgBOiTKQAAACnEi0UMjQB8JB+JdCQIgwTn8ECkBIk8JOhCZ0AQxgQ3AMECewIUAD0Dx0M0ILAAABCD+AMPhGFAAgAAD48rQI+DIPgCD4XKAALHQ8IQwDL/x0MUggGAEVD8wQAQgQ9kgBKJwMaFwA+ED4ANli3ZwF3aOcQHQVlDwrlADEoAwCQIgQdTCcACUwAUIcKJQxCD+nD/D4SWAQfALQEKCdrCQxvewBBDG6FBJRhJCmxbG4UADItDFCNBwBr4/w+Fn0MPDMlCzEMIQQmLA8AJAUxM6LnACkgmdXUBEJSZwBfps0Gxw4W6AoAowIP4BA+FnmEJ6iVr4HjCLjimF+PkDXUlrhI4yROEYYAIi0McAIlzOIXAdQfHKEMcA+QFDOMi/xVQ+EIBEGMDGGEYx8QEJEEJ6O7VIlBFj2HgYIXAeRygA4EE6EbQrAPicVMcuGE7g4j6AXSAAAK4+IABxLr/gAAPRMLMGqRJZmGAFcIahSnjFCBtMJkgSXQrAA2BLuhnDw1xQgrp1P7gdeJu' $Extract_APNG_Frames_x86dll &= 'oRkFNaQ8EAYK2OADIBKF0iR1tIlO7zcDBHSec2AhQRnprwAF4mfjmSxFQHhI4GhAizrBLReBYASLcDiLHXBgXAGkH//TOcYPhL0XgyWhFAMCrCABhfYPBIT84ACB/wAAEJAAD4bQoTL5icOjAESJ9zHbic7rkhrjFoHuYQSBxaIAUv6hAHZ8IAUMozoQg+IawQ2JLCToKMAWAAHDPf//DwB3IsehrTnfdKF9RCmC34Y/fCQIAdgBWETLNoKRSIkYhTkhMtQDl8Qs6KmEA//TEInG6USBMvGJ/mNBCyBnDIlMo2flD6ghQAoBw+uJ4S+F/0B1LTHb653lBxU7QSNgCAghqOADZUSs06mCDuuJQh/5QAal6tep549FCEEtNEEteE4tsMcPhMpKLQACuUEtBaBbGUEGRRCLGI1AQwGB+/9/oI+HUeApAI1DZZnHYBQpAMSNVCQfg+LwPInW4Svgp2cbIGbMNeFBmgYAicPBUsCeQYcZ4SiL8UBIoAs4gf8JQQt3XoAuIItNDASJ+GUuKdgBwI2EFFlCgxQk6FIgCTOh9+YuqdKrV+wux+kWN2Emw4CQYRFcyf/Y/+uYcwIhCETwAPMsSkLRMwRiB+hSYAVSjOuphAN7GMfp65ExZXgYJEMI6XYQBPkX6UzrNDZI8QJVveECVwS/AHAWVonuU4Fs7ExxWaQM3sBm0X6UDCRoUAEQDyy4cHRAABCNXCRAABU04IXSD0WEogGwEUA4D3IA8IegAmMBg/8EDwSDwVdPZpCF/3RAD8YDAPfHcR0PRIVHsRyEJGAjBAS3UQiQcKEV/zMHMSL1oAIEuf6QAusNkIPpKAGD+UAg2OEDtgQAC415ATwND4SCneAAPAoPhK1wAACEwHTZifgx7QVQBDgwADyNRCQ0URJahCRkcwYQpAoMA9Vp4kkEJIX2dDcI6CriMQ8Uhe11SDcx9gEMgkjxGk8NgAI7UT4giYnfwekwAvOr6eEZlA3o4yYZwX5g' $Extract_APNG_Frames_x86dll &= 'A3TJYDgsgQbEcRR3UjwKdBSJQMjGRAxAABIX6RpesQN2wARgg+iAfAAMPw2NQf913BCJwevY4JP/6TzJowksEQJGdKvUC/EhDMjqUxlrBjHAZolgRDv+6a2RIAQedmIAsTYUizVRInGCiwRYOEU21jnDdDGrBTbBACSAhy9AAiQQGAtFZgJt2NCog8QUWxBew2aQdSfWicOQhdt10eUmtc+0RtdRAvkm8Qck9gcwcAXwg43CFxiidvAIRCQcFC2VdglJeQk8cAlHjUCrNXkJdHAJQHAJYAjAdEBKg/gRdEWhNK0q6SAB2JIIJP8Kdbkl9QoF8wqJw3ACidj/kAL1OEAKEQmSISJB0UEBJIlwFwAaIR4Q65b4DSPym4EVTCQkcJwoi9JAMHd0OfBkLCFHIFXKBOB8DOEDIS9gf5F4STAtRcIRAX/OVBMYtlsFCAUKZKgB+RRT0qQbgL4ABxQQtyCXdyuLyAyFELBwMdvlFWAHhRFPEBHBW+moLgY4opDQJgwxyWBZ1PW1V6YH86H6cEQgDUCQXEwlgAQcoAZ+GCCLdRc5JGXpvxANxANwghQxBPYxcCIsifCJ+r+GL7EUkRzFUwYc8K4QcAkVQIhNsQB0oASJxokq1/AzvAAHHDAw0oMA7QGD/QJ3CYv0BK3iDdLhDEMgcprCKazLLdGtRwe+kRu/QQBc6XDytPKxYxkqQRcKg5AG0RqJAYlRBIVOvPXM5BZgsvVachjchwG5+LYwC7A3cdgg2EKRBcPB2/C5HOkMCoMU9QPenPwD8xUyBLAVNKBvIW0jsavg0Dgx7TOBdyAU62b6gsP3gg+GiJeDfz+DcBTcMBUBxTODgMM5bCQ4dCWgCHlRJ+gRpgh4afEuMBgvuYUQ7MtKAvEzcgzUewHfwQryIrJ1VLc1CFgyCMEHMHWD66b76/l/i102EFCW0ZO+4nvUfHdrjZd8/aBBV8lcJARTyXoIUZ1REFdii6l9cAHZARAhicYxwDnz' $Extract_APNG_Frames_x86dll &= 'D6CVwI0EQEEfFeMLpzZ59lHBAdTBsD7HUByeS3GAQAZQBEEG6O8wSjEfBiTodxEGMALG6LKhoAPrlHAE9o/K84+KlWV7mwABUuuG99oKLPBoHPabmrkABCToOQwAAIMQ7AjoYQFw6AGjAGztABCLRCQcBKNwAECDxCzDjQi0JgAAAI10JgAIkKF8AFCFwHQHHOu1AjwGcAMMkIPsABzomP///8dECCQEFAAgxwQkAQEADOh8wv//o4AFAqAcCaBTg+wYi0BcJCCLQzgAVQ+SiQCPzcAAPkM4ASHQg8QYWwYttgEFBn8iwwMPV7pMABAxwCS5DwAMidcAx8cFCkgAEQQADvOrxwWiYAQLxwVkAAkDAYpKWQGeBQFHwOgBjwiIX8OQBgBVV1YASQo8gH9kAEtQi2wkoFSLfCRYgDgKgQkCx4E5AIXbD4RDAQBri0M0hcAPhII4AAWF/w+IMIADA4B3gRDoJMn//4MQ7ASJxoAaYIlEBCQsgAEQifgJ6EgPhaGBHHswgBiEApIAFYtDCI1LLECJTCQYhcAAEhQhABgQD4SsABKNLAIAAAZsOe8PRu8RgDOFiAKAM+0PhALogAOLTCRcjUMILL8shKMPtxCDAMACg8EBiFH/AIn6KcIB2gHqBHXqgC2LUzCJ7wGBKyn6AXwkXImAUzCF0g+F6YFBgGwkFIn40eiAFKBF+Cl8JAF9EIEqEIX2dT3AFxCFycB0NYtUJGyBOcAMSonBDEAAXw+EggJ0BUAgVAA2HCSJVCQACIl0JAT/0AMCfAAExoM7AXRGQUAOZIXSdAaBTYmAOIk0JOgQyMJEAIPEPFteX13DM8KPxYf0x8sGw3xmkBXAIrZAEGgAYK6LcyAEhfZ0p4Aji0AKCIEhn4AOifEx9sA5TCRgdBSAEsJ3IqmAEotLBENfbCQQbI0EP4A4RMcxgNL38YnIKdDBAQnAM4RbwIGLQzA5EMIPh10AEinQiTBDMOlGAAUBJol8EYA0' $Extract_APNG_Frames_x86dll &= 'bCQEQDfoSNE5AAp7MMJywnGBbtf+MP//6UAAAcOhOcdoD0bHwAYcQWzBJquVgXZMwANsgElTLIAFAFwBzYXJD4QiA0F2hLR2AGYPvggAg8ABg8ICZokASv456HXuifpFAJwcgBJcKfpAa3UyPYlm6WBBHMAni0CaFIGEd4ADhVCxxoScPOl8AQmDGMESAA8YATr4gA8EQQICa4DZCimgAADp+P3DCZBgSZvEDoEEXMIfgATtKAJU84FIQEjpuMEF4h3gBcAjrghCSyMGoAW/qwWKoAUQMfbp88AAi0s0YCnCx0MwQQdAgwxrARYAEQRgAQhhAsAs/xBRCOnI5gsx/+liBEAxkIn6IA2AAT5Z5DJWuKF7QHQk4EswFQAsNMB0OOBMJLiIAaGL+v90Go1y/5DB4ga4wQiBwqECiIH+/2ABD0LCYAagRIlcJAjADhzCDuhUJBhgAkDgAYGV4QGqEOABPKBxBGABDIEahOr7wCrEJFteAlYUVrnmD0RiDzCZhVDbdCS5gg/7gQ9zQP/B4waNi+cOu9EhCw9Dy4AFPAUP4AC6GGIgXAAOABgGEFyADkMgKoI0DCTobYUPwk4Q46//H+UfjYJHELp7QxDhH0DsH+IdxRHoIAzrYiDhH/pFEBTgcf8f4h96uYIvw4kv4R8BLe0fFP/hImIeZCFiH+Eg4R+ID/8fu/8/7z8U5D/DEfE/+UUQMBgAkJDl1eGCsCUB4LHAdBuJ2gHYAeXfgDovdQPGAgBcg8IBOcJ18bMC2KfLkJChy0EnMIAICjRAqDxADP8VzEJUARACAdwBAXQAD1xdYmMQZCVjZAEEhAAEgwDsFIP4AQ+VwEAPtsCNBECBFLV/wOvCp+JU6PX/Df8G+Qaou/8G8QZF+Qb5DfNzLLEeVfBERNBPSNFyHQFjSwo08U8S0XLtD4gKGdhy9sEhf9JBicaJguiQBQn4D4UAkQJo9nQcsWPUEAICByxL+2HQGlzzaYQZ8mkcY8FX' $Extract_APNG_Frames_x86dll &= 'ogBUJFC0aaAATCHRRv/QicWgB5TBUQBqD4QhQQJEsX0P1IQFsACEwAn9IVPQTBWAJVDwC0zgHR/psgH4jQ+2RA//jVEA/zwKdBQ8DXSAEInRhcl16vdcAInfi1s8hdt1ovdQBFApyMABB5EAAANHJItPKIlHGiQRECywTMJoVyTptiB0TUVc7MCPeA6QgFgGBIJW8CbAyv//iUDGhfYPherBZwFB8VEPt0RP/vAIZiCD+Ap0glAADQ+MhHiAAXIJ4ult5AWIkItA4IUPhef4YkKBowaJxeno92KJGO7pjdcA8BVEJFQBgAOVwCDID4TOUZABi1MEwRaEgRJLADSLaQiF7XR6YjmwFg+EiPOeQngkIcAFicWLQ2F4he0sicJAF/AUXLEQAcAl8HNEgACJ11AQ94kq+CJ591EFbQEGQzQwiEwkH19iU2JQCKQPtuAB6UJRCnYGHA7YkGMzAXQMwTHt676N8Er/Qv9C/0L3Qkj/Yj8wRPNBskPgMGZDIEPo+rb8+WKxMEQDVrQ1FFINa7A2cAE4cAAMgVTxT8G0+B9gAAjBOiE2QqAb72AggV/4PPMEQNAGMWM/BW+wBvJTeAUFBfHQEQEFFBtgTAYAV/BMsboAAwMR1Tj/FcBAP7qgLRABELkNoXjAideE86uQTF/DZpDKPlMAAPC+oQABw1QwvEwUJCQAMxTSERQk/xLQsL7CCHQLxBzpkiDxu/Ts87v/4HIBLOn7UTX9UXTzSuguIZCuD7cFxKAIZjmkBcBgAHQQ8ADG8wBSwmAAdS6xGVAkZRnFwbn2MqcciQaAaZEAqBiJA/NbCPAsjfAAW/IOAxMM8ABBjwiVSAyp0CvrvPkNPCACGnQUMcEe/xVEMlEQqHQF4A+/RCQeQKsFSfEC7aUE0cATALIaESx/A3QDvfAc6GCx8dLg1zIJHDIJTAQkVS/lCujwsAmDLuyy2WHZ9hI0FAeNdDAkGuhbUAexuIsdC+EGcQfTMwdlMcBm' $Extract_APNG_Frames_x86dll &= 'hqMhFCBDJCZmo9ETZaEAGjDfZqMhFtEAKmxmo9EVNQwN1AR4BD0D8AfBNCijBOkAEIiJFQhQAIPENPQunsdSGmILYhuRAOux91H8xwVRA/MBkQNT3tID893yyNEHBQCgATEtsRJyBTTpE5FMdvMB+N/p+4s3P3ECoZEDhcB1/+kT8xnyEosdUgTbD4XGgSEHJAMF6H+BGJQPbhPgGN8bEhBbFRDAGhJVQRMUQAIWACkGgAR0EFaLNZCgAosEnfaoowrxJghRD4EcgjrgBADWg+wMg8MBg7D7BHXV+Q8wAhJ0AKYWElhTBXWqYC8KgACEZjkALHWc68sEDVXidhAAMyAAMyTFC1YqC+R7WDEgwTBYwfkQEA+/0bAxDmaFDMC/8TIQ0ZiJBoe6AIXbdA1mhcm4ABkAAAAPRNCJABODxBBbXl/DCI20JgCIAJBVVwBWU4PsHIs9AADpABCLdCQwiwBcJDSLbCQ8hQD/dQXoTv7//wAPvw3ALQEQDwi/BcQADGY5wXQgWw+3FcYCJD3CAQEkiVQkDmY51wB0Q4X2dAUPvxjRiRYA6gAQ94kzAItUJDiF0nQLAQBVOCnIg8ABiYADhe10DQ+/ADIAKfqDwgGJVQAIg8QcAJFdw410iCYAkABCBscGAZqRAEMGxwMBCYtMAEQAyXQKi0QkOMfFARAAAEPJx0UCCgY9EwPQA88soQLObCRAUIt8JEQAa0gAQEykhcAAaXv9AGm3hGXyBYFsdGmAB4FngAeBZwB0WY1EJBzHRIQkDAEoiUQkBIAHChiABwiCBwQk6McHAIsAQQFIGIPoAQFARQCF/3QJgAYc3YEGB4BhAQYCDQYAY4YMEAODxCwBVsIQAFOLv5hXy/y/VxfLKylVyispySspySspyCuQCwQAxYt8RIp0JDyJkDwk6KVBGl8MQBIAK41u/4nYMdIEMf/Cc4nBifsDQcBtOdUPR9jAe8cCAQIlWQQ51nXjF8xuAQwAFxiAHyCL' $Extract_APNG_Frames_x86dll &= 'WAIMQCISi1MEiVCgDIlcJATBMV/Ce7AYidhbxq9BIxRAIgIgQCIkiRwkiXQQJATodwGNQwyJAEYEiXMMg8QUWFtew8UvwBYEw5DHTEAEgwGCScdAQk/DQ8EHAK0Ii0gIgJwZgIlRBIkKx0JCCgCDAAGJUAjDjVq2QjBQDwbBO1MAEAyBwCMIiwiLUASAEMYegBBBAtJ0GwAMxByBQ64rAVvDiVOABoB15YlLCOvix1cKLEAQQIGBhdsPhEK5Abz2D4SxwQx8ACRM/3QaiTQkBOgSgPSJx4XADwSEn8EjdCQY6xeAZpCLBot+BMCAABiB5////38PBISTowZE/w+EwEHhBBwk6NgYYmpEAI0UA4XJD46JBUNsRKAGHIkUJI1Aaf+J6SnBAUI5EPkPTvkBSol8JAAI6IHQ//+D7AIMAANQhcB0JoUI7X4iAUUBxyn9AWABFgHfiWwkCLfATkIcgUKY4AwDFhEASaugNkFJFMI8kCEYIAAKIInYg+wExUwUAJ3hMxihDQARAQ/oDIMOxOu3BD6LawQhW2AbEv9AGYHlgRyNRD1xwl7ov80lFGMIYAIDgCuJLCToxs8CA1zpbsAFJUEDAFOBPTEWwOAfoTYQwTSFyX4AGwHRidDrCo0EdgBAljnIdAcPAL4QOdp08lvCFAwAAAP4BVZ2AFMVIAcIZD4QwD0vhcAAfiuNRAH/99kD4hwAB4TSdAQ52gR1CyBqjRQIg/rY/3Xq4QjkSMhhAecRVeVrXOBrbOJrOGBtPAVgYSuAa0GD//90EmxhJxQXYAfxjVXF4HqJIBAPRcKBX4Eg7CrTYB3ABCWga2Quxo0AZpAxyTHA68hz5xdhCZjO5jDicekFiyBGBIsOJaEs65JbARrCExAFbkATKEATQKXAiU4hPl4WID7+QE0izWFWwHQ+YBZdg9zuAaIxIHOhT/oggIAuAixALQg5xg+PGj/gAYDSQhWhQyMPoAh0YwXACyxACwSF9n83BMYD' $Extract_APNG_Frames_x86dll &= 'sARmkMHgAsuCC4QfnYsJZpCgDmdS5aAPBCAU65DnH0HegWumzMFyos3HQ2N0Q+KCXOlhYB/gBIAZ1EA9MAiNNIUC0MkPhYGFoowEgiM58HU1hRyUiwNhlRMgEYnC4QPBwASACdCJQ8Ar7xdTxrSkI/zK412yJAQp4MaNRAMBJhigGYELvD4VIBOh0OEb4gZk4ga4COl3wRXgNGECAMJhOATpnoAC9VKxRUQk2jwABRDUYuEyOHAAUSzWNEEUcAAwQQYRYAPAVb/AOfhq+AMyOP8D9gPRkHaL9gP/LTjShnwkNDFOco3RGG8Bgl5QRFEpAgIUISR4FjnFdQeAxgQ+AI1H//ZiAHYAjSw+Oe5zoHuJ8usR80TLwGUAiEL/OdV0LQ9AtwONSwJmIBtJAGaD+H9242YFAAAoZj3/A3cZBLg/sSXCAYPDBIHCAnXTifjrKXEwksuiAeu5hA7GBpGFBDHA9QaJ0InVKUzwxjCHRQiJ9ZA07lH0MHwkIIAqHtYcfIlQZgQkoQDoOhPwAAbGsHyQEBC7yOwAXUQgBIJQAROVApAzHInaw5AL09YkEnzFsRjlI84E+ELyctE4QzhQA8IhYokAB8dDOEIslAV2drCSILBzW5ZwAwD3c3NCOMA6EYM7AcAXdlgY6DtQBBAFL+BzuAeRHjB08QroKxIAAAA7QxAbUxQPnRDDD7bbgEPEFPeHcAnzb8ADMdvorkACAIP4/w+Uw3TfyxIqYAlSMAHr0bEf4X1qQOEKOnEBynAB0BEW6bUKyq+0ChxxF1ABUTk86LRYAXEGcAGRhOicB3cB8gzzBTALRCQsQUBGIHQXi0KRBhDFcBYgQALpXOzzMfUDhlz8A+AQKIsVDNCYjfBJKqEE0AMKoaBwloCDxChbw6G4kAAwiwSFqAUBdWkdYChCARBQBfawEscF0wEE8QX/08AFo9EDoAEi9XEU04sV4QCjpDUBBOxxgR3hm/Ru/xVOQGAEQCAQESShMQLH' $Extract_APNG_Frames_x86dll &= 'bAW8UADCHAWxB5EAo5nRB+lfwWyimsgBsntH8AOCClAV/xWMcwTrPrq1TmMAowmijvIOUVCKPeEAjfBvchWBogEwgwkALXEAggF366QpwQABWFngAmYQAFihYLCAqsERJWBKZiCQg8AEoyEB/9LBlgF164PEDHURtp0D9EPyKh3gqQAQgzD7/3QpwGPzO/8UQp1CAesBdfSgElDAmAAQ6DB7QS8gKylwIDHA9HLDEHmLFEaFwQKgBvDrvQsGoSIQoRvAdAd0mscF0wEBoRjrhPtHNOFcBTsDMUzwIjyJDCSJ3YFRSIXbeRj32aWGSIPTAJAB99vySd0AidOF0nkN99gC96CDg9IA99qJANOJx4sEJIXbAHUQOe92VInqADH29/eJwesKAGaQOet2JDH2kDHJiciBgonyIIIYB/fYUgN6zw+98wCD9h91QDnrcgAHMck7PCR3zZq5UgvGcwzg2Au4AQEAMdL384nHMdK0ieggBsZQB5IGoPUVBLggQRLxifop8ADT44nB0+qJ8UAJ2tPnieuwAOsBgNoMifGLFCTTQuWhAQnVidpgBHQBQAHTicX35znTAHIgizwkifHTAOc5x3MEOdN0gBGJ6TH26UAxZdH0BY1N/xABLnaU9cs+dMAfRWVwALBbACRO5gBAu3QV99CjeF/QAUSedBkwL3MqZHIqBAHhkzNcJBT/FVBBAAGJxf8VVHEAx3j/FWhxAFBwMJ3xAogj9ALwADHYM2AvMegQMfgx8LMGIYnCyPfSo7EIiRU6B/Z+gLqwGb9EuE/AAkTr14EXVYnlED/HBAUAcFkJBADAiwBFBI1VBMcFBCPwAOEWiRXk8COj2EVBAAwwAYtFCIRKo4bMMAFyD4lF8KHRBsCJRfT/FZTzCUACJBzCYDEVpPMA/xVeTPFBIDpRBpIMnBM66BzpDXAVBQDzSySD+PgDdBRxSzIfkCIBo/JV3fPJKEFU4BwCX2jw8nkCA8QOchbAuQBWU4Ps' $Extract_APNG_Frames_x86dll &= 'FIM9bACwABACi0QkJBB0CscFAmAAAAAAg/gCdBeD+AGAdEqDxBS4AQBEAFtewgwAjXQmAACQuyhQARC+AQEQOd504I20JgEAOgCNdgCLA4UAwHQC/9CDwwQwOd518Q5wAMYoxwhEJAQBKIlEJAgBAB4giQQk6MQFhwBvCiwDUjHAw5AJACEArhjHBCQBno1cgCQk6PwMAAAATzQIGwNPDAVbACNAwjAAEOhMAR8DL+jQiQALi1QAb1wkCABzgIlUJATo1AsADAaHAAyEN1dWU4nDAIPsMIs1eOwAQBCF9g+O6oAKoQJ8AAYxyYPADIsAEDnadwqLeAQAA1cIOdNyf4MAwQGDwBQ58XWA5okcJOgOB4BCQMeFwA+E24UajQActsHjAgHYiYh4EMcBMADo+QASBIsVgQ0DRwyJREAaDI1UJBSBYRwHgWEASoBN/xWwQgFQEIPsDICmc4GZjQBQwIPiv3QIgwDoBIPg+3UOgwIFgU8Bg8QwW16UX8OAEBSBbAMdASvAiUMEiVMIgHKBhhQIQIkqrIIqEIXAYHW+/xVcAAaAjbADwEmATgTooP7//4Ax9ukz////gi6Yi0QYwCfAaEcIgAlafIUJeYAJABcEwARcDYFYacADRE9mkFWJguWAUIPsPKF0QSKERcwAMAuNZfRAKWRdw8CHxwXBBUFo6ARhBkBdBICNBIUBAW/B6ATB4AToYIz5///HwjbBEykAxI1EJB+D4PACo8EjuIDKABAtAQEBg/gHfqqLFaGDAgsPj5bACrtBAyCF0g+FjkAXi0NSBEBhhYOCAgjAsA8EhcTAAo17DIH/IcEJcibpZ4A5ZpAAK0XUAwOJxomI2OgCgTUzg8dECAgPg7EAFYsHi0+ABA+2VwiNsEADSBCNmUEBi4BBAYkAddSD+hB0ToMA+iB0uYP6CA9MhOBEWgBGDMMARlCo/f//AST4wYKEwBQgiccLPYjBFoUtKQEmFYzAArsBAelEEwAjwtUP' $Extract_APNG_Frames_x86dll &= 't4EdEIlNgNCJ8YHJAADAKBEAoUjxK0AbxwwBBQEqWYAVi03QZokTQgpEK4JSQRB2AKEhgq3AD46IgDOLHYHBe4t9zI115ERoAQOejQS/jQSCi4GAS3QaiXQkDKAWkAiLUAiBF4tAIkWC06BEg8cBOz3hCQR8ySU4kA+2E4kI1oHO4BL/hNIPAEjWK1XUjTQCCaASw/zAJ/CIA+lOusdB4BGiMoH7Iyr0AyAX5RBzBIs7g8MoCAO+4iqGoQDof4dhCAICIwZy2eksBCO54gjpKGE0YFAgLNhBT5Du+///yoOQVaJPihwABIgAF/8VPAEgBB2AYAGD7ASF26B0NIstoEECPYFfC+KVoR3VgAOJxv/XQeBiDIX2dAjAR4kANCT/0ItbCIUo23XbpgmAwmcEgyTEHOVZoYTiLXUH+MONtuEa4pMgFCCK4Y6pAl2AnaAWwwBhQqGduYQJiQPBrUB1YxShQRQyiQUViUMhbmcOMcABog4YW8ODyP/rHvbFK+Ai4Q1iEItcJAog4BAPoAQxwFvDHUQEkAohggzhIMB0J5AxyesL4BeJwWJABtDhmiBAde+FyXSIK4lR4aPoRJtgcZPTEOZ9iRVhCuvQ5Q1H4REBG2DHD4S/IAJ3CiWgDVHEJHQwxwUvIQHBIuAIo73D4RiD+IgDde2lBOToNQA9LOvd4YXlD3xDL+u+4+MsRQUF6ApABaIBoHwsdapjPQA9F+MEidgTYDiBGXeagHHbde98xwUBBEEDQxEiAYUMOBmDDOlgoU7iB+i7AwFJFZADQDyBOFAARQAAdRVmgXgAGAsBD5TAD7Y+wOYt4NWlM+IHYCEEZoCBOE1adQXr4UUp7QNWU+C2DIA3EAMAUjwPt0IUD7dAcgaNRAIYwFAbQDHJkItQDADOB6gDUAjAAAyizSigzZroYDxe4QnhXTHbIF4Ai3wkMIk8JOgCGwHp+Ah3YGaBpj0haSAPVbiia0GAGhEgJkehPKABD7eQChTC' $Extract_APNG_Frames_x86dll &= 'AKhQWBCNnBACGGAAhe10NzH2BOsNcAWDxgGDw6AoOe50JjFkCJEUhnwwZDBusgQAAIAmMt5AMInYYzDxG8QcjDHb9QDnKZAx0ncIxGNWgghT6LcgG5AIVk2SCLAPDNYIsNEIgQrrMkGUMwn2dCMxAsn2JotCDDnDcrAHA0IIYADyEMLzEIjSidAQEZCJ0PsVVDHA9wcacxA50wcMDXQQgCEH9xvSU4tMVCQIRwNHQwMEQwM5DcsTmMIThArbdBkxgMD2QicgdAdANBgPg+mwGuIJ2HXpV+IJ8h/4EBSjBalhYsDxsgAPRdAIDPIT+Av2E0J3EgN0TYsVBxSCpRMJsggUhAIEFCIGFI3yJNPwE/Ak03Ia/yQBxQeLQCRbXvfQyMHoH/wUyVcGCbArZXArdVMJ6OLAW0AJSDMSEuNyi4CQclE6Mw8Et1aQLX4GjVQWGBiF/xAdNUyLSgykOcjwCEoIYAASUSeFABP+8AjJW4nIkI1L0CzgRQ/2H4Pr8ZaLwEgEhcl1B8AM0EsA1IXbf+iLSAwpsCeBwcJzyDej2+Nf+6NyPOCl/wD5YyxAOUxBwA1Ai3QkRJA1SACD+gF0LIP6AkB0T4XSdXUgcxgQjWwkGCAxHIlsxWMx64AEg8QsdWHiAWQcJNEB6ADQpxAzUMoBYAMRIAPry/dxMALZoQLo5OADYQQEsALhSmFxAAHGEdehBmEG64iX6PkgAscAFnADoriQPP/rkWMAivxERdFABHALEOjQMQUwCRIO6xtUAoPDAYMYPN1E4IlQGIsE3QJAkAA5xnXo6JsFEYkUkgGJEIPEBAPhIAAojUbtg/gRIHY4ge680QP+DnB3FehwgggxQXcC6E5b1glEAfMG6ENyAQ3bdgHrepCwFiCeGEF9oFJaMKEP0bAC4BIV8AAYXXAYHFAV92YyD7qCD+eB8QP/JYhDARBxAKqEdACAdAB8dAB4dACqdHQAcHQAbHQAaHQAqlh0AFR0AFB0AEx0' $Extract_APNG_Frames_x86dll &= 'AKpEdABAdAA8dAA4dACqMHQALHQAKHQAJHQAqiB0ABx0ABh0ABR0AGoQdAAIdADMsGhxAMjVdADEdAC4cgBmFADxZcDB4AUDBehgAcAVGOk7aiqRkRJAFADYENCpo27xAFDwAKLIAwAAwSFwPgAQsD04ABCAMAB1AQUAIJYAABDglQAQwHcQABBgeTACcQAQzPByMACwAPB6MADwAfKwsABgdnACMABCRjABvfUD9HAHMQcBAEHYwPAAAE7mQLuxGb9E/70GDwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAD8PAA8ADwAPAA8ACQDmtQBpAG0AYQBnAIBlAC8AagBwAHBgZwAAAC4CWAdIZaMIJAVUZgBpAAwAAAoVB4JnBCYuBhJ7MUQANUJFNEI1LUYAQTRBLTQ1MkQALTlDREQtNUQAQjM1MTA1RTfoRUJ9C0V0AjsDRwML4wcJDXFwAG4EkQUJCR0aYgALcAIdBQkwMDAAAABcRnJhbWUAXwBfAG1zLnAAbmcASUhEUgAASURBVABJRU4ARABFcnJvcjoAIGZhaWxlZCAAdG8gY3JlYXQAZSBpbWFnZSAAZnJvbSBtZW0gb3J5IQ2FFXNhAHZpbmcgcmUtIGVuY29kABtQTgJHhCAhIC0+IAAQDQoARoAGIG5vAHQgZm91bmQ6ACAAZmNUTABOEG8gYW4ALXRpbwBuIGNodW5rcwEDEC4NAFVuYWIDgBkHQQBJbnZhbARpZAMUIHNpemUAIGF0IHBvc2mfgh+GDwEtCBKAJWZkgG8GcoCBAQByK2IAcsBiAHdiAGFAAQEDgHQAQ09OAAPABgoCwAAEAQnsABAgIOkAEACcwABgARQQBMAAbMAEGFABEhCEEQBNQD13LXcANjQgcnVudGkGbYBHwDx1cmU6CgAAQWRkcmVzc4AgJXAgaGFzAD4hA1Atc2VjwSoAIAAgVmlydHVhbCBRdWVyeYVbZm8AciAlZCBieXR0' $Extract_APNG_Frames_x86dll &= 'ZXOBNmFGEcEbxgxQGHJvdMARRQ13aXQEaCABXiAweCV4AcEJVW5rbm93boAgcHNldWRvQGYobG9jw1hwgA5vY4BvbCB2ZXJzAQQwJWQuCsIW1wxiaa50A1vECgUAAcAAFsRMq8EAyU8YwAAFwAANwACqBsAACcAAB8AADMAAvgjEAcEEwQHBFMEGC8gGd8EVwQ7BAQ/EFQFewQQRrcAAEsQAwQUhxAU1xAOqQcQDQ8QDUMQMUsQFqlPEAVfkC1lkD2zkAu5t4SFgAIEuHOFFZBXhGFXhBYBkFoHkAILkA4NV5AOE5AiRYAApYACeVeQBoeQRpOQNp+QCt9XkE87kA9fkAxiAImEhHQEA/wAASC8CAEdDQwg6ICigUEdXLVdBoFBpNjg2LaFheAAtc2psaiwgYhB1aWx0oEkgQnIAZWNodCBTYW4CZMA+KSA5LjMu/jD/B/8H/wf/B/8H/wf/B///B/8H/wf/B/8H/wf/B/8H//8H/wf/B/8H/wf/B/8H/wf//wP/A/8D/wP/A/8D/wP/A///A/8D/wP/A/8D/wP/A/8D//8D/wP/A/8D/wP/A/8D/wP//wP/A/8D/wP/A/8D/wP/A///A/8D/AMPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPACEHANHIi2hxADIwVgHyjDUAKPAALDAAMEEwAEgoAABOcAAAAABFeHRyYWN0FF9BAK5fgrRzX3jAODYuZGxstQGhAf9vBg8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAGAExkQDEdAwDUSbAAQggBAJw4AVxKAQASODABHEE3AUBLAVQAuDAB9DgBVDABkFZD9wAJAJxwAbgwANYFMAD0MAAKRAEAHlUwADIwAEowAGIwAH7VMACcMACyMADEMAABAArWcADuMAAGRQEAqhgwADYwAE4wAGIwAKp4MACOMACs' $Extract_APNG_Frames_x86dll &= 'MAC8MAAqzDAA5jAA9jAABEaoAQASMAAgMAAwMACqTDAAZDAAcDAAijAAqpwwALQwANIwANowAAruMAD8MAAYRwEAWiYwADgwAAEASHAAVlUwAGQwAHIwAHwwAI5VMACYMACmMAC0MADAVTAA0jAA3DAA6DAA8LUwAPjxA0hwDjAAFjAAqiIwACwwADYwAD4wAKpIMABQMABaMABiMACqbDAAdjAAfjAAhjAAqo4wAJYwAJ4wAKgwAKqyMAC8MADEMADOMACq2jAA5DAA7jAA+DAAqgJwGwowABQwACAwAKoqMAA0MAA+MABIMABqVDAAXjAAaPEdAAB0BXAAhrQAtLignEMBALgAMNYAMIL0ADAKRAEAHgAYqjIAGEoAGGIADH4ADGqcAAyyAAzEAAwBANYFABzuAAwGRQEAGFUABjYABk4ABmIABnhVAAaOAAasAAa8AAbMFQAG5gAG9gAGBEYBVAASAAYgAAYwAAZMVQADZAADcAADigADnFUAA7QAA9IAA9oAA+4FAAP8AAMYRwEAJq0AAzgAAwEASAAHVgADqmQAA3IAA3wAA44AA6qYAAOmAAO0AAPAAAOq0gAD3AAD6AAD8AADWvgBP0gA5wADFgADIlWAASyAATaAAT6AAUhVgAFQgAFagAFigAFsVYABdoABfoABhoABjlWAAZaAAZ6AAaiAAbJVgAG8gAHEgAHOgAHaVYAB5IAB7oAB+IABAlZJgDWAARSAASCAASpVgAE0gAE+gAFIgAFUtYABXoABaIABAQB0gAMChoQFSQBHZGlwAENyZWF0ZUJpAHRtYXBGcm9tgFNjYW4wAEqTDUJ0AAhtAABXiA5IwEJJVE1BUAEPAxQEAIeCDkRlbGV0AGVHcmFwaGljEHMAAI9DBWlzcABvc2VJbWFnZYgAAK3DBHJhdwIEgFJlY3QADwHBBAhHZXSCBERpbWWAbnNpb24AEMoFgEVuY29kZXLAFaIR0gVTaXrAFxPKBgHF' $Extract_APNG_Frames_x86dll &= 'IkNvbnRleHREAN1CB1NhdoMjVABvRmlsZQBgAgFBBWx1c1NodXRAZG93bgBhRgR0AGFydHVwAAAVAgFDN0NyaXRpYxhhbFMALsEoNgFFxYAWco0FAAQCwCCAHSBzb2xlTcAnAAACCkgEU2NyZWVuAEJ1ZmZlckluIGZvAAAYQgd1coByZW50RGlygBGAb3J5QQAAH8gFAFByb2Nlc3MAQiDPBElkACRIBVRKaABqZAAFAGhBBUwgYXJnZXMFH1dpFm4AOYJLaUMHc3RFgHJyb3IAANzBA4BTdGRIYW5kAEYEAPPCA3lzdGVtMlSAZUFzwUtBAgASAgNABlRpY2tDbwB1bnQAADcDRwBsb2JhbEFsbFBvYwA+pAFGwBwABABCpAFMb2NrAGQASqQBVW4gBeABbcgDSW6AJ2FsABLNKDDNA0xlgDWuK+kDA2EJgjcAXgRRdWUAcnlQZXJmb3IgbWFuY2VCEmVy0ADlBFNsMPEoAsMgiaMvWgXgAlVuaMIewGRFeGNlcAENAAwB4QhqBVNsZWVwAAB5BVRlcm1pBm5AYEUxAI0FVGwCc0AhVmFsdWUA5JsFlggAnGADIR6jFpC9BVZpIEthbCAJMnSBYADAJQLCGQAAIDgAX19kAGdycgJuIBSQAF9hbXMgZ19leGlgBbQAhF9jQFpyb2xmYFMI3QBfpAQAAV9mAcALbGVuZ3RoaVw2NAACIwKAAwIhAW6IZGNsYAoAAAajAVBmaXJz4AkMowFuAWFkOQFfZ2V0Xwhvc2YjGQAAXAGCX2AJdG9hAGAgASOANeAZbQBkYAFvYhgAALzgAGED0QFfAQI6bAJfbWtkaQEgHvMCX3N0cmmEY21gFDsDX3WECNQAP2ABbCIBTCABw0AAJARhYm9ydACMMQTgPEFIAD0EYx0IQARmZBZBBGZlAG9mAABDBGZmgWBzaAAARQRmYBUJwIsARiIBcwBLBABmb3BlbgBSBIhmcHXgAVUEZkFhbABW' $Extract_APNG_Frames_x86dll &= '4QBgCFfhACIEXAgEZnNjB2AEZnczIEygA2UEgAhgD48EAm2kEJIEbWJzdARvd+GZlQRtZW2RYAYAAJkhAWNwoDQCmiEBbW92ZQCfQARwcmludOATo2IEQg8AqgRAD8IIsVYEwAYAAWHAKbJhAXbAYnVmAMUEwCNgMygAAMghAW4BJecEhHVuYxDpBHZmJQrM/wQAECIFAgUgASIFEg8hAXRvwBMAAAlAAENMU0lEBLZpYG5nAIkAY7Xjt0/sbkiDboHAQGDBfwBqAAJno6EuZGxsABR/4AF/AD8APwA/AD8AOwBLgEVSTkVMMzKCCP0AACgwAT8APwA/AD8APwB/PwA/AD8APwA/AD8ANwBtoHN2Y3J0Ew488AD/MQDgSkcPDwAPAA8ADwAPAN8PAA8ADwAPAAcAEBAABQDgnAAQsJv4AA8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwCfDwAPAA8ADwA7PwB4YAAABjAwMEQwWTAAZjBxMLEw2jAA5TDzMAAxFjEAPDFjMW4xeDEAojG0MbsxwTEA3DHjMe4xLzIAODKMMrUz+jMAGTRyNHk0fzQASjV7Nbs17TUAGjZKNng2BTcAMzeqNzo4bDgAlzjnOBU5dToAnzqvOuQ6ZD5Atz4aP5I/AAcgCAAALGAAKzCdMAATMawylDNRNAD7Nis3gjeaOQDKOSo7vjvsO0BIPME88zxAAjAoAABYYABbsAcVMgDRMnAzADQ5OABgOGQ5zTxOPQBWPV49Zj1uPQB2PeI+6j7yPgD6PgI/Cj8SPwAaPyI/Kj8yPwA6P0I/Sj9SPwBaP2I/aj9yP6B6P4I/ijMIQKDgAWAANTVcOG04yAA48DgNOSc5swA56jkzOs86MQA7kDuhO8k76wA7' $Extract_APNG_Frames_x86dll &= 'QTxiPIQ8lQA8Dj0XPSg9ggA9pD26PS4+N0A+TT6rPg2QBgAGUJC7cAQRMBswJAAwQjBbMDIxSAAxWTGSMasxvAQxxBAL4jKkM7EAM8Iz8TP5Mx4ANDU0UjR3NIYANJc0oDS1NL4ANMc01DRCOJQAOMI7/TsyPG0APKQ85zwUPVcAPYU9kD3BPd0APeQ9/D0DPhAgPgBgAABAogBnADBuMHsw7TFEADIJM18zxDMMADRcNHg35DcAADgrOGg4jDiuADi6Obo+6D5WMD/5PwDQnGAOAG4AMHcwxDDRMNYEMCkwHV0xnjG5AdADQTQcswCxNGc25zZIOAAnORM8HDwxPABtPLE8wjzUPADgPOo8+Tz9PAAAgAAAnAAAAACyMMsw4TAyMQBIMVkxsjHLMQDcMTIySDJeMgCyMssy4TKGMwCPM7Az9jP/MwAgNOI2+zYRNwAVOBo4RDhxOAClOKw4tTi8OAA0OWw52znvOQD6OQg6Ezo8OgBCOlI6XDpyOgB8OpE6lzqxOgDROvc6BDsqOwBNO1U7XDtoOwCjO6w73zspPABFPEw8WDxfPAD4PBg9Hz0oPQAvPag9yD3PPQDYPd89AJAAAALAAJuQNTY3RzcAUTdYN2o3dzcAhTeUN5k3sTcAvTfDN8031jcA8Df5NxI4UTgAZDhrOJY4qzgAtzjYOPE4AjkAaDqGOqE6sjoIujrCgD70Ovo6ACg7ODtCO0c7IEw7WztggEFxOwB7O4E7ijubOwAHPBQ8OTw+PADbPBo9Jz1dPQB5PZk9uj3QPQDvPfw9Az4YPgAqPj4+Wj5yPgCWPqg+rT6yPgC9Pss+8z4VPwAqPzA/Nj9XPwBpP3E/fT+CPwCTP70/wz/RPxDfP/I/AFygAAAC+AADITBhMGcwAIIwiDCTMJkwAKkwuTDaMOAwAOYw8zD5MCgxAC4xQTF1MYQxAIkxjzGcMaIxAMUx4zHpMe4xACMyKTJCMmgyAHIyjjKjMqkyALky' $Extract_APNG_Frames_x86dll &= 'xzLSMvMyAP0yCDMOM90zAOYz9DP7MwI0AAk0ZTRvNH40AIk0kDSWNJ00AOU07jT8NAM1ABo1IzUxNTg1AD81RjV1NX41AIo1pTWvNb81AMo10TXXNd41ADY2RTZTNlk2AF82oTbQNvY3AAA4EDjCOMo4ANI42jjiOOo4CPI4+kBRCjkSOQAaOSI5KjkyOQA6OUI5SjlSOQBaOWI5ajlyOQB6OYI5ijmSOQCaOaI5qjmyOQDJOeQ56Dn0OSAAsAAALMA9BDAACDAMMCAwJDAAKDAsMDAwNDAAODA8MEAwRDAASDBMMFQwYDAUcDABeBjAChwyIAAyJDIoMiwyMAgyNDIABFABABCBgAEMMBgwHDAAAh8/AD8APwA/ACwA' $Extract_APNG_Frames_x86dll = _WinAPI_Base64Decode($Extract_APNG_Frames_x86dll) If @error Then Return SetError(1, 0, 0) Local $tSource = DllStructCreate('byte[' & BinaryLen($Extract_APNG_Frames_x86dll) & ']') DllStructSetData($tSource, 1, $Extract_APNG_Frames_x86dll) Local $tDecompress _WinAPI_LZNTDecompress($tSource, $tDecompress, 50176) If @error Then Return SetError(3, 0, 0) $tSource = 0 Local Const $bString = Binary(DllStructGetData($tDecompress, 1)) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\Extract_APNG_Frames_x86.dll", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Extract_APNG_Frames_x86dll Func _WinAPI_Base64Decode($sB64String) Local $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(1, 0, "") Local $bBuffer = DllStructCreate("byte[" & $aCrypt[5] & "]") $aCrypt = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $bBuffer, "dword*", $aCrypt[5], "ptr", 0, "ptr", 0) If @error Or Not $aCrypt[0] Then Return SetError(2, 0, "") Return DllStructGetData($bBuffer, 1) EndFunc ;==>_WinAPI_Base64Decode Func _WinAPI_LZNTDecompress(ByRef $tInput, ByRef $tOutput, $iBufferSize) $tOutput = DllStructCreate("byte[" & $iBufferSize & "]") If @error Then Return SetError(1, 0, 0) Local $aRet = DllCall("ntdll.dll", "uint", "RtlDecompressBuffer", "ushort", 0x0002, "struct*", $tOutput, "ulong", $iBufferSize, "struct*", $tInput, "ulong", DllStructGetSize($tInput), "ulong*", 0) If @error Then Return SetError(2, 0, 0) If $aRet[0] Then Return SetError(3, $aRet[0], 0) Return $aRet[6] EndFunc ;==>_WinAPI_LZNTDecompress Example: #AutoIt3Wrapper_UseX64=n #include <InetConstants.au3> #include <MsgBoxConstants.au3> #include "Extract APNG Frames.au3" Global $sExampleFile = @ScriptDir & "\Animated_PNG_example_bouncing_beach_ball.png" Global $sDestPath = @ScriptDir & "\ExtractedFrames" If Not FileExists($sExampleFile) Then InetGet("https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png", $sExampleFile, $INET_BINARYTRANSFER) EndIf Global $iResult = ExtractAPNG($sExampleFile, $sDestPath) If $iResult > 1 Then MsgBox($MB_ICONNONE, "APNG Extraction", $iResult & " frames were extracted to " & $sDestPath, 30) Else MsgBox($MB_ICONERROR, "APNG Extraction", "Extraction of frames has failed: " & $iResult, 30) EndIf The needed DLLs are in the UDF and will be extracted to script dir on first usage. DLL is written in Freebasic by me. 😉 History: 2025-07-29: first releas 2025-07-30: bug fixed when $sExtractedPath is empty. If empty current dir will be used to save frames. You must delete old DLLs.
    9 points
  2. ioa747

    🕑 Analog Clock

    I played around a bit, and ended up with this analog clock. ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: AnalogClockGdi.au3 ; Description.....: A simple AutoIt script creating a digital analog clock GUI. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.1 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <StaticConstants.au3> Global $hGUI, $hGraphic ; main GUI Global $hGUIBack, $hGraphicBack ; background GUI Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter _GDIPlus_Startup() _CreateClock(600) Func _DrawClock($iWidth, $iX = -1, $iY = -1) Local $iHeight = $iWidth $hGUI = GUICreate("Analog Clock", $iWidth, $iHeight, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED, $hGUIBack) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUI, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hPenSeconds = _GDIPlus_PenCreate(0xFFFF0000, 2) $hPenMinutes = _GDIPlus_PenCreate(0xFF0000FF, 8) $hPenHours = _GDIPlus_PenCreate(0xFF00FF00, 12) $hBrushCenter = _GDIPlus_BrushCreateSolid(0xFF000000) Local $sTime, $Tick = -1 While True If $Tick <> @SEC Then $sTime = @HOUR & ":" & @MIN & ":" & @SEC ConsoleWrite("- " & $sTime & @CRLF) $Tick = @SEC _RedrawClock($iWidth) EndIf Switch GUIGetMsg() Case -3 ; $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GDIPlus_GraphicsDispose($hGraphicBack) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() EndFunc ;==>_DrawClock Func _RedrawClock($iWidth) Local $iHeight = $iWidth Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.5 Local $hTransparentBrush = _GDIPlus_BrushCreateSolid(0xFF00FFFF) _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iWidth, $iHeight, $hTransparentBrush) _GDIPlus_BrushDispose($hTransparentBrush) Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) - 90 _DrawHand($hGraphic, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) - 90 _DrawHand($hGraphic, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 _DrawHand($hGraphic, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphic, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) EndFunc ;==>_RedrawClock Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand Func _CreateClock($iWidth, $iX = -1, $iY = -1) Local $iHeight = $iWidth $hGUIBack = GUICreate("Clock Background", $iWidth, $iHeight, $iX, $iY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUIBack, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) ; Get the graphic context for the background GUI $hGraphicBack = _GDIPlus_GraphicsCreateFromHWND($hGUIBack) _GDIPlus_GraphicsSetSmoothingMode($hGraphicBack, $GDIP_SMOOTHINGMODE_HIGHQUALITY) Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.5 Local $iTextRadius = $iClockRadius * 0.90 ; Adjust this value for number placement (closer to edge) For $i = 1 To 12 Local $sDigit = $i Local $fAngleDegrees = ($i * 30) - 90 Local $fAngleRadians = _Radian($fAngleDegrees) Local $iTextX = $iCenterX + ($iTextRadius * Cos($fAngleRadians)) Local $iTextY = $iCenterY + ($iTextRadius * Sin($fAngleRadians)) Local $iDigitWidth = 36 ; Estimate based on font size 30 Local $iDigitHeight = 30 ; Estimate based on font size 30 ; Draw the number - 0xFFFFFFFF = White color for numbers (ARGB) _GDIPlus_GraphicsDrawString($hGraphicBack, $sDigit, $iTextX - ($iDigitWidth / 2), $iTextY - ($iDigitHeight / 2), "Arial", 30, Default, 0xFFFFFFFF) Next _DrawClock($iWidth, $iX, $iY) EndFunc ;==>_DrawStaticClockBackground Which I "tweaked" a bit, and ended up with this ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: Analog_Clock.au3 ; Description.....: A simple AutoIt script creating a digital analog clock GUI with alarm functionality. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.1 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <StaticConstants.au3> #include <TrayConstants.au3> #include <Misc.au3> Opt("TrayMenuMode", 3) ; 0=append, 1=no default menu, 2=no automatic check, 4=menuitemID not return Global $hGuiParent, $hGUIBack, $idBackTheme ; Parent GUI & background GUI Global $hGUI, $hGraphic ; main clock GUI Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter Global $mAlarm = _GetClockSetting(StringTrimRight(@ScriptFullPath, 4) & ".ini") _GDIPlus_Startup() _CreateClock($mAlarm.width, $mAlarm.x, $mAlarm.y) ;--------------------------------------------------------------------------------------- Func _DrawClock($iWidth, $iX = -1, $iY = -1) Local $hDLL = DllOpen("user32.dll") ; for _IsPressed ; Tray Menou Local $idMove = TrayCreateItem("Move") Local $idSetAlarm = TrayCreateItem("Alarm Setting") Local $idAlarmActive = TrayCreateItem("Alarm Enable/Disable") TrayItemSetState($idAlarmActive, ($mAlarm.active = "1" ? $TRAY_CHECKED : $TRAY_UNCHECKED)) Local $idClockSetting = TrayCreateItem("Clock Setting") TrayCreateItem("") ; separator ----------------------- Local $idClose = TrayCreateItem("Close") TraySetClick($TRAY_CLICK_SECONDARYUP) TraySetIcon("mmcndmgr.dll", -15) TraySetToolTip("Analog Clock") TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu. ; Clock GUI $hGUI = GUICreate("Analog Clock", $iWidth, $iWidth, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED, $hGuiParent) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUI, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hPenSeconds = _GDIPlus_PenCreate(0xFFFF0000, 2) ; 0xFFFF0000 $hPenMinutes = _GDIPlus_PenCreate(0xFF0000FF, 8) ; 0xFF0000FF $hPenHours = _GDIPlus_PenCreate(0xFF008000, 12) ; 0xFF00FF00 $hBrushCenter = _GDIPlus_BrushCreateSolid(0xFF000000) ; 0xFF000000 Local $Tick = -1, $Tack = -1 While True If $Tick <> @SEC Then $Tick = @SEC _RedrawClock($iWidth) EndIf If $Tack <> @MIN Then $Tack = @MIN _CheckAlarm() EndIf Switch TrayGetMsg() Case $idClose ExitLoop Case $idMove WinActivate($hGuiParent) While 1 Local $aMpos = MouseGetPos() WinMove($hGuiParent, '', $aMpos[0], $aMpos[1]) ToolTip("click to drop it", $aMpos[0] + 30, $aMpos[1] - 10) If _IsPressed("01", $hDLL) Then ExitLoop ; 01 Left mouse button Sleep(10) WEnd ToolTip("") $mAlarm.x = $aMpos[0] $mAlarm.y = $aMpos[1] IniWrite($mAlarm.file, "ClockSetting", "x", $aMpos[0]) IniWrite($mAlarm.file, "ClockSetting", "y", $aMpos[1]) Case $idAlarmActive If BitAND(TrayItemGetState($idAlarmActive), $TRAY_CHECKED) Then ; If $TRAY_CHECKED TrayItemSetState($idAlarmActive, $TRAY_UNCHECKED) IniWrite($mAlarm.file, "ClockSetting", "active", "0") $mAlarm.active = "0" Else ; If $TRAY_UNCHECKED TrayItemSetState($idAlarmActive, $TRAY_CHECKED) IniWrite($mAlarm.file, "ClockSetting", "active", "1") $mAlarm.active = "1" EndIf Case $idSetAlarm _SetAlarm() Case $idClockSetting ShellExecute($mAlarm.file) Case $TRAY_EVENT_PRIMARYDOUBLE WinActivate($hGuiParent) EndSwitch WEnd DllClose($hDLL) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() EndFunc ;==>_DrawClock ;--------------------------------------------------------------------------------------- Func _RedrawClock($iWidth) Local $iHeight = $iWidth Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.45 Local $hTransparentBrush = _GDIPlus_BrushCreateSolid(0xFF00FFFF) ;0xFF00FFFF _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iWidth, $iHeight, $hTransparentBrush) _GDIPlus_BrushDispose($hTransparentBrush) Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) - 90 _DrawHand($hGraphic, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) - 90 _DrawHand($hGraphic, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 _DrawHand($hGraphic, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphic, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) EndFunc ;==>_RedrawClock ;--------------------------------------------------------------------------------------- Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand ;--------------------------------------------------------------------------------------- Func _CreateClock($iWidth, $iX = -1, $iY = -1) $hGuiParent = GUICreate("GuiParent", 10, 10, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TRANSPARENT)) $hGUIBack = GUICreate("GUIBack", $iWidth, $iWidth, 10 - ($iWidth / 2), 10 - ($iWidth / 2), $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hGuiParent) $idBackTheme = GUICtrlCreatePic(@ScriptDir & "\Clock-600.gif", 0, 0, $iWidth, $iWidth) GUISetState(@SW_SHOW, $hGUIBack) GUISetState(@SW_SHOW, $hGuiParent) Local $aPos = WinGetPos($hGuiParent) _DrawClock($iWidth, $aPos[0] - ($iWidth / 2) + 5, $aPos[1] - ($iWidth / 2) + 5) EndFunc ;==>_CreateClock ;--------------------------------------------------------------------------------------- Func _GetClockSetting($sIniPath) If Not FileExists($sIniPath) Then ; make one Local $sTxt = "" ; Write Example data to the ini file $sTxt &= "[ClockSetting]" & @CRLF $sTxt &= "file=" & $sIniPath & @CRLF $sTxt &= "width=600" & @CRLF $sTxt &= "x=-1" & @CRLF $sTxt &= "y=-1" & @CRLF $sTxt &= "sound=C:\Windows\Media\ringout.wav" & @CRLF $sTxt &= "day=1,2,3,4,5" & @CRLF $sTxt &= "active=1" & @CRLF $sTxt &= "time=17:30" & @CRLF FileWrite($sIniPath, $sTxt) EndIf ; Read the INI section labelled 'ClockSetting'. This will return a 2 dimensional array. Local $aArray = IniReadSection($sIniPath, "ClockSetting") Local $mMap[] If Not @error Then For $i = 1 To $aArray[0][0] $mMap[$aArray[$i][0]] = $aArray[$i][1] Next EndIf Return $mMap EndFunc ;==>_GetClockSetting ;--------------------------------------------------------------------------------------- Func _CheckAlarm() If $mAlarm.active <> "1" Then Return Local $iPos = StringInStr($mAlarm.day, @WDAY) If Not @error And $iPos > 0 Then If $mAlarm.time = @HOUR & ":" & @MIN Then ShellExecute($mAlarm.sound) EndIf EndFunc ;==>_CheckAlarm ;--------------------------------------------------------------------------------------- Func _SetAlarm() Local Const $MARGIN = 10 Local $hGUI = GUICreate("Set Alarm", 300, 260, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) GUICtrlCreateLabel("Select Days:", $MARGIN, $MARGIN, 100, 20) GUICtrlSetFont(-1, 9, 800) Local $a_idDays[7] Local $aDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Local $iY = $MARGIN + 25 For $i = 0 To UBound($aDays) - 1 $a_idDays[$i] = GUICtrlCreateCheckbox($aDays[$i], 10, $iY, 90, 20) Local $iPos = StringInStr($mAlarm.day, $i + 1) If Not @error And $iPos > 0 Then GUICtrlSetState(-1, $GUI_CHECKED) $iY += (20 + 2) Next GUICtrlCreateLabel("Set Time (HH:MM):", 170, $MARGIN, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputTime = GUICtrlCreateInput($mAlarm.time, 180, 35, 80, 20) GUICtrlSetFont(-1, 10) Local $idInfo = GUICtrlCreateLabel("", 100, 65, 190, 100) GUICtrlSetFont(-1, 10) $iY += $MARGIN GUICtrlCreateLabel("Select Sound File:", $MARGIN, $iY, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputSoundFile = GUICtrlCreateInput($mAlarm.sound, $MARGIN, $iY + 25, 240, 20) Local $idBtnBrowse = GUICtrlCreateButton("...", 260, $iY + 25, 30, 20) Local $idBtnSetAlarm = GUICtrlCreateButton("Set Alarm", 190, 170, 100, 20 + 5) GUICtrlSetFont(-1, 10, 800) GUISetState(@SW_SHOW) While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idBtnBrowse Local $sSoundFile = FileOpenDialog("Select Alarm Sound", @WorkingDir, "Sound Files (*.mp3;*.wav)|All Files (*.*)") If Not @error Then GUICtrlSetData($idInputSoundFile, $sSoundFile) Case $idBtnSetAlarm Local $sTime , $sSoundPath, $sDays = "", $sInfo = "" GUICtrlSetData($idInfo, "") For $i = 0 To UBound($a_idDays) - 1 If GUICtrlRead($a_idDays[$i]) = $GUI_CHECKED Then $sDays &= $i + 1 & "," Next $sDays = StringTrimRight($sDays, 1) ; remove last "," If $sDays = "" Then $sInfo &= "⚠ Please select at least one day." & @CRLF $sTime = GUICtrlRead($idInputTime) If Not StringRegExp($sTime, "^\d{2}:\d{2}$") Then $sInfo &= "⚠ Please enter time in HH:MM format (e.g., 07:30)." & @CRLF $sSoundPath = GUICtrlRead($idInputSoundFile) If $sSoundPath = "" Then $sInfo &= "⚠ Please select an sound file." GUICtrlSetData($idInfo, $sInfo) If $sInfo <> "" Then ContinueCase ; checks if everything is valid $mAlarm.day = $sDays $mAlarm.time = $sTime $mAlarm.sound = $sSoundPath IniWrite($mAlarm.file, "ClockSetting", "day", $sDays) IniWrite($mAlarm.file, "ClockSetting", "time", $sTime) IniWrite($mAlarm.file, "ClockSetting", "sound", $sSoundPath) ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>_SetAlarm ...but I didn't stop there and ended up with this Release 0.12 ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: Analog_Clock.au3 ; Description.....: Analog clock GUI with alarm functionality. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.12 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <GUIConstantsEx.au3> #include <TrayConstants.au3> #include <Misc.au3> #include <Timers.au3> Opt("TrayMenuMode", 3) ; 0=append, 1=no default menu, 2=no automatic check, 4=menuitemID not return ; Global Constants Global Const $AC_SRC_ALPHA = 0x01 Global Const $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT = 5 Global Const $GDIP_STRINGFORMAT_ALIGNMENT_CENTER = 1 Global Const $GDIP_STRINGFORMAT_LINEALIGNMENT_CENTER = 1 ; Global Variables Global $hGUIClock Global $hImageBuffer, $hGraphicBuffer Global $hClockImage = 0 Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter Global $iClockWidth = 600, $iClockHeight = 600 Global $mClock = _GetClockSetting(StringTrimRight(@ScriptFullPath, 4) & ".ini") _GDIPlus_Startup() ; Try to load a clock background image _GetClockImage($mClock.Image) ; Start the Clock GUI _CreateClock($mClock.Width, $mClock.X, $mClock.Y) Exit ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; Try to load the clock background image Func _GetClockImage($sImagePath = Default) ; The Default clock background image If $sImagePath = Default Or $sImagePath = "Default" Then $sImagePath = StringTrimRight(@ScriptFullPath, 4) & ".png" If Not FileExists($sImagePath) Then ConsoleWrite("WARNING: ClockImage not found or could not be loaded initially. fallback to Default" & @CRLF) ; Set $sImagePath to Default $sImagePath = StringTrimRight(@ScriptFullPath, 4) & ".png" EndIf ; If there isn't one, make one. If Not FileExists($sImagePath) Then ConsoleWrite("WARNING: Default Image not found or could not be loaded initially. Generating new image..." & @CRLF) Local $bOk = _CreateAndSaveClockImage($iClockWidth, $sImagePath) If $bOk Then ConsoleWrite("INFO: Default Image generated successfully. Attempting to load it now." & @CRLF) Else ConsoleWrite("ERROR: Failed to generate Default Image Will go to exit." & @CRLF) Exit EndIf EndIf $hClockImage = _GDIPlus_ImageLoadFromFile($sImagePath) ; Check if loaded image is a valid pointer and file has content If IsPtr($hClockImage) And FileGetSize($sImagePath) > 0 Then ConsoleWrite("INFO: Loaded ClockImage." & @CRLF) Else ConsoleWrite("ERROR: Failed to Loaded the ClockImage. Will go to exit." & @CRLF) Exit EndIf EndFunc ;==>_GetClockImage ; Clock GUI - Initialization and Main Loop Func _CreateClock($iWidth, $iX = -1, $iY = -1) ; Tray Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $idMove = TrayCreateItem("Move") Local $idAlarmActive = TrayCreateItem("Alarm Enable/Disable") TrayItemSetState($idAlarmActive, ($mClock.Alarm = "1" ? $TRAY_CHECKED : $TRAY_UNCHECKED)) Local $iSettings = TrayCreateMenu("Settings") Local $idSetAlarm = TrayCreateItem("Alarm Setting", $iSettings) Local $idSetColors = TrayCreateItem("Colors Setting", $iSettings) Local $idIniFile = TrayCreateItem("Ini file", $iSettings) Local $idRestart = TrayCreateItem("Restart", $iSettings) TrayCreateItem("") ; separator ----------------------- Local $idClose = TrayCreateItem("Close") TraySetClick($TRAY_CLICK_SECONDARYUP) TraySetIcon("mmcndmgr.dll", -15) TraySetToolTip("Analog Clock") TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $hDLL = DllOpen("user32.dll") ; for _IsPressed $iClockWidth = $iWidth $iClockHeight = $iWidth ; The clock GUI $hGUIClock = GUICreate("Analog Clock", $iClockWidth, $iClockHeight, $iX, $iY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) Local $idMouseLab = GUICtrlCreateLabel("", $iWidth / 2 - 5, $iWidth / 2 - 5, 10, 10) GUISetState(@SW_SHOW) $hImageBuffer = _GDIPlus_BitmapCreateFromScan0($iClockWidth, $iClockHeight) $hGraphicBuffer = _GDIPlus_ImageGetGraphicsContext($hImageBuffer) _GDIPlus_GraphicsSetSmoothingMode($hGraphicBuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ; Colors from inifile RGB to ARGB Local $sColorSeconds = "0xFF" & StringTrimLeft($mClock.ColorSeconds, 2) Local $sColorMinutes = "0xFF" & StringTrimLeft($mClock.ColorMinutes, 2) Local $sColorHours = "0xFF" & StringTrimLeft($mClock.ColorHours, 2) Local $sColorCenter = "0xFF" & StringTrimLeft($mClock.ColorCenter, 2) ; hands Width Local $iWSeconds = ($iWidth * 0.005 < 2 ? 2 : $iWidth * 0.005) Local $iWMinutes = ($iWidth * 0.015 < 4 ? 4 : $iWidth * 0.015) Local $iWHours = ($iWidth * 0.020 < 6 ? 6 : $iWidth * 0.020) ; Initialize pens and brush for drawing hands and center circle $hPenSeconds = _GDIPlus_PenCreate($sColorSeconds, $iWSeconds) ; 0xFFFF0000 $hPenMinutes = _GDIPlus_PenCreate($sColorMinutes, $iWMinutes) ; 0xFF40C880 $hPenHours = _GDIPlus_PenCreate($sColorHours, $iWHours) ; 0xFF0080C0 $hBrushCenter = _GDIPlus_BrushCreateSolid($sColorCenter) ; 0xFF000000 ; SetTimer so it doesn't freeze with the tray menu _Timer_SetTimer($hGUIClock, 250, "_RedrawClock") Local $bRestart, $aMpos, $iCnt = 0, $Tick = -1 ;******************************************** While 1 ; Check Alarm If $Tick <> @MIN Then $Tick = @MIN _CheckAlarm() _ActivityTimeout($mClock.ActivityTimeout) EndIf ; GUI Msg $idMouseLab Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYDOWN ; long press Left mouse button in bullet, to move the clock Local $a = GUIGetCursorInfo() If $a[4] = $idMouseLab Then While _IsPressed("01", $hDLL) ; 01 Left mouse button $iCnt += 1 If $iCnt > 60 Then $aMpos = MouseGetPos() WinMove($hGUIClock, '', $aMpos[0] - $iWidth / 2, $aMpos[1] - $iWidth / 2) ToolTip("Move it", $aMpos[0] + 30, $aMpos[1] - 10) EndIf Sleep(10) WEnd If $iCnt > 60 Then ToolTip("") $mClock.X = $aMpos[0] - $iWidth / 2 $mClock.Y = $aMpos[1] - $iWidth / 2 IniWrite($mClock.IniFile, "ClockSetting", "X", $mClock.X) IniWrite($mClock.IniFile, "ClockSetting", "Y", $mClock.Y) EndIf $iCnt = 0 EndIf EndSwitch ; Tray Msg Switch TrayGetMsg() Case $idClose ExitLoop Case $idMove ; move the clock WinActivate($hGUIClock) While 1 $aMpos = MouseGetPos() WinMove($hGUIClock, '', $aMpos[0] - $iWidth / 2, $aMpos[1] - $iWidth / 2) ToolTip("click to drop it", $aMpos[0] + 30, $aMpos[1] - 10) If _IsPressed("01", $hDLL) Then ExitLoop ; 01 Left mouse button Sleep(10) WEnd ToolTip("") $mClock.X = $aMpos[0] - $iWidth / 2 $mClock.Y = $aMpos[1] - $iWidth / 2 IniWrite($mClock.IniFile, "ClockSetting", "X", $mClock.X) IniWrite($mClock.IniFile, "ClockSetting", "Y", $mClock.Y) Case $idAlarmActive ; Alarm Enable/Disable If BitAND(TrayItemGetState($idAlarmActive), $TRAY_CHECKED) Then ; If $TRAY_CHECKED TrayItemSetState($idAlarmActive, $TRAY_UNCHECKED) IniWrite($mClock.IniFile, "ClockSetting", "Alarm", "0") $mClock.Alarm = "0" Else ; If $TRAY_UNCHECKED TrayItemSetState($idAlarmActive, $TRAY_CHECKED) IniWrite($mClock.IniFile, "ClockSetting", "Alarm", "1") $mClock.Alarm = "1" EndIf Case $idSetAlarm ; Alarm Setting _SetAlarm() Case $idSetColors ; Colors Setting _SetColors() Case $idIniFile ; Ini File (open ini file) ShellExecute($mClock.IniFile) Case $idRestart ; Restart the clock $bRestart = True ExitLoop Case $TRAY_EVENT_PRIMARYDOUBLE ; double click activate clock WinActivate($hGUIClock) EndSwitch WEnd ;******************************************** ; Clean up resources _Timer_KillAllTimers($hGUIClock) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphicBuffer) _GDIPlus_ImageDispose($hImageBuffer) _GDIPlus_ImageDispose($hClockImage) _GDIPlus_Shutdown() DllClose($hDLL) GUIDelete($hGUIClock) If $bRestart Then Local $Cmd = StringRight(@ScriptFullPath, 4) = ".exe" ? '"' & @ScriptFullPath & '"' : '"' & @AutoItExe & '" "' & @ScriptFullPath & '"' Exit Run($Cmd) EndIf EndFunc ;==>_CreateClock ; Helper Function to Draw a Hand Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand ; Redraw Clock Function (CallBack by timer) Func _RedrawClock($hWnd, $iMsg, $iIDTimer, $iTime) #forceref $hWnd, $iMsg, $iIDTimer, $iTime Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iCenterX = $iClockWidth / 2 Local $iCenterY = $iClockHeight / 2 Local $iClockRadius = $iClockWidth / 2 _GDIPlus_GraphicsClear($hGraphicBuffer, 0x00000000) _GDIPlus_GraphicsDrawImageRect($hGraphicBuffer, $hClockImage, 0, 0, $iClockWidth, $iClockHeight) ; Calculate angles for smooth hand movement Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) + ($iCurrentMinute * 0.5) - 90 _DrawHand($hGraphicBuffer, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) + ($iCurrentSecond * 0.1) - 90 _DrawHand($hGraphicBuffer, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 ; + ($iCurrentMillisecond * 0.006) ; - 90 _DrawHand($hGraphicBuffer, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) ; Draw center bullet Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphicBuffer, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) ; Create HBITMAP and display Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImageBuffer) If IsPtr($hHBitmap) Then _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hWnd) EndFunc ;==>_RedrawClock ; Custom _WinAPI_BitmapDisplayTransparentInGUI Function (by UEZ) Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $bReleaseGDI = True) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) Then Return SetError(1, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0) Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) Local Const $hOldBitmap = _WinAPI_SelectObject($hMemDC, $hHBitmap) Local $tBitmapInfo = DllStructCreate($tagBITMAP) _WinAPI_GetObject($hHBitmap, DllStructGetSize($tBitmapInfo), DllStructGetPtr($tBitmapInfo)) $tSize.X = $tBitmapInfo.bmWidth $tSize.Y = $tBitmapInfo.bmHeight $tBlend.Alpha = 0xFF $tBlend.Format = $AC_SRC_ALPHA _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA) _WinAPI_SelectObject($hMemDC, $hOldBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_ReleaseDC(0, $hScrDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI ; This function draws a clock dial and saves it as a PNG. Func _CreateAndSaveClockImage($iWidth, $sFilePath) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iWidth) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) Local $iCenterX = $iWidth / 2 Local $iCenterY = $iWidth / 2 Local $iRadius = $iWidth / 2 ; Clear with transparent background (ARGB: A=00) _GDIPlus_GraphicsClear($hGraphics, 0x00000000) ; Colors from inifile RGB to ARGB Local $sColorOutline = "0xFF" & StringTrimLeft($mClock.ColorOutline, 2) Local $sColorTextHour = "0xFF" & StringTrimLeft($mClock.ColorTextHour, 2) Local $sColorTextMin = "0xFF" & StringTrimLeft($mClock.ColorTextMin, 2) ; Colors and Pens/Brushes Local $hPenOutline = _GDIPlus_PenCreate($sColorOutline, 5) ; 0xFFEEEEEE Local $hPenHourMark = _GDIPlus_PenCreate($sColorOutline, 5) Local $hPenMinuteMark = _GDIPlus_PenCreate($sColorOutline, 2) Local $hBrushTextMin = _GDIPlus_BrushCreateSolid($sColorTextMin) Local $hBrushTextHour = _GDIPlus_BrushCreateSolid($sColorTextHour) ; String Format for drawing and measuring text (centered) Local $hStringFormatCenter = _GDIPlus_StringFormatCreate() ; Check if string format object was successfully created If Not IsPtr($hStringFormatCenter) Or $hStringFormatCenter = 0 Then ConsoleWrite("ERROR: Failed to create GDI+ StringFormat object." & @CRLF) ; Clean up other resources before returning failure _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return False EndIf _GDIPlus_StringFormatSetAlign($hStringFormatCenter, $GDIP_STRINGFORMAT_ALIGNMENT_CENTER) _GDIPlus_StringFormatSetLineAlign($hStringFormatCenter, $GDIP_STRINGFORMAT_LINEALIGNMENT_CENTER) ; Draw outer circle Local $iOutlinePadding = 5 _GDIPlus_GraphicsDrawEllipse($hGraphics, $iOutlinePadding, $iOutlinePadding, $iWidth - (2 * $iOutlinePadding), $iWidth - (2 * $iOutlinePadding), $hPenOutline) ; Draw hour and minute marks For $i = 0 To 59 Local $fAngleDegrees = ($i * 6) - 90 Local $fAngleRadians = _Radian($fAngleDegrees) Local $iStartX, $iStartY, $iEndX, $iEndY Local $iMarkLength If Mod($i, 5) = 0 Then ; Hour marks (every 5 minutes) $iMarkLength = $iRadius * 0.06 $iStartX = $iCenterX + (($iRadius - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iStartY = $iCenterY + (($iRadius - ($iRadius * 0.02)) * Sin($fAngleRadians)) $iEndX = $iCenterX + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iEndY = $iCenterY + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphics, $iStartX, $iStartY, $iEndX, $iEndY, $hPenHourMark) Else ; Minute marks $iMarkLength = $iRadius * 0.04 $iStartX = $iCenterX + (($iRadius - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iStartY = $iCenterY + (($iRadius - ($iRadius * 0.02)) * Sin($fAngleRadians)) $iEndX = $iCenterX + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iEndY = $iCenterY + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphics, $iStartX, $iStartY, $iEndX, $iEndY, $hPenMinuteMark) EndIf Next ; Draw numbers (Hours and Minutes) Local $iHourTextRadius = $iRadius * 0.66 ; Radius for hour numbers (adjust this to move them closer/further from center) Local $iMinuteTextRadius = $iRadius * 0.86 ; Radius for minute numbers ; Define font families Local $sFontName = "Times New Roman" Local $hFontFamily = _GDIPlus_FontFamilyCreate($sFontName) ; Critical check for font family handle If Not IsPtr($hFontFamily) Or $hFontFamily = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontFamilyCreate returned an invalid handle for '" & $sFontName & "'. @error is: " & @error & @CRLF) ; Clean up current resources before returning failure _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_StringFormatDispose($hStringFormatCenter) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return False EndIf For $i = 1 To 12 ; Hour Numbers (1-12) Local $sHourDigit = $i Local $fHourAngleDegrees = ($i * 30) - 90 Local $fHourAngleRadians = _Radian($fHourAngleDegrees) Local $iHourFontSize = 50 Local $hHourFont = _GDIPlus_FontCreate($hFontFamily, $iHourFontSize, 1) ; 1 = Bold typeface ; Check for font handle If Not IsPtr($hHourFont) Or $hHourFont = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontCreate failed for hour font. Skipping text drawing." & @CRLF) ContinueLoop ; Skip drawing this text if font creation failed EndIf ; Calculate the approximate position for the text bounding box (large enough to contain text) Local $fApproxTextSize = $iHourFontSize * 1.5 Local $tHourLayoutRect = _GDIPlus_RectFCreate($iCenterX - $fApproxTextSize, $iCenterY - $fApproxTextSize, $fApproxTextSize * 2, $fApproxTextSize * 2) ; Measure text to get its exact dimensions Local $aHourMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, $sHourDigit, $hHourFont, $tHourLayoutRect, $hStringFormatCenter) Local $fHourTextWidth = 0, $fHourTextHeight = 0 If Not @error And IsArray($aHourMeasure) And DllStructGetData($aHourMeasure[0], "Width") > 0 And DllStructGetData($aHourMeasure[0], "Height") > 0 Then $fHourTextWidth = DllStructGetData($aHourMeasure[0], "Width") $fHourTextHeight = DllStructGetData($aHourMeasure[0], "Height") Else ; Fallback: Simple estimation if measurement fails $fHourTextWidth = $iHourFontSize * 0.6 * StringLen($sHourDigit) $fHourTextHeight = $iHourFontSize * 1.0 ConsoleWrite("WARNING: Failed to measure hour text '" & $sHourDigit & "'. Fallback: Using estimation." & @CRLF) EndIf ; Calculate the FINAL position for the text, taking into account text dimensions and desired radius Local $iHourTextX = $iCenterX + ($iHourTextRadius * Cos($fHourAngleRadians)) - ($fHourTextWidth / 2) Local $iHourTextY = $iCenterY + ($iHourTextRadius * Sin($fHourAngleRadians)) - ($fHourTextHeight / 2) ; Create a layout rectangle specific for drawing the text at the calculated position Local $tDrawHourLayout = _GDIPlus_RectFCreate($iHourTextX, $iHourTextY, $fHourTextWidth, $fHourTextHeight) ; Draw the string using _GDIPlus_GraphicsDrawStringEx _GDIPlus_GraphicsDrawStringEx($hGraphics, $sHourDigit, $hHourFont, $tDrawHourLayout, $hStringFormatCenter, $hBrushTextHour) _GDIPlus_FontDispose($hHourFont) ; Minute Numbers (5, 10, ..., 60) Local $sMinuteDigit = $i * 5 If $sMinuteDigit = 60 Then $sMinuteDigit = "00" Local $fMinuteAngleDegrees = ($i * 30) - 90 Local $fMinuteAngleRadians = _Radian($fMinuteAngleDegrees) Local $iMinuteFontSize = 20 Local $hMinuteFont = _GDIPlus_FontCreate($hFontFamily, $iMinuteFontSize, 1) ; 1 = Bold typeface ; Check for font handle If Not IsPtr($hMinuteFont) Or $hMinuteFont = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontCreate failed for minute font. Skipping text drawing." & @CRLF) ContinueLoop ; Skip drawing this text if font creation failed EndIf Local $fApproxMinuteTextSize = $iMinuteFontSize * 1.5 Local $tMinuteLayoutRect = _GDIPlus_RectFCreate($iCenterX - $fApproxMinuteTextSize, $iCenterY - $fApproxMinuteTextSize, $fApproxMinuteTextSize * 2, $fApproxMinuteTextSize * 2) ; Measure text Local $aMinuteMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, $sMinuteDigit, $hMinuteFont, $tMinuteLayoutRect, $hStringFormatCenter) Local $fMinuteTextWidth = 0, $fMinuteTextHeight = 0 If Not @error And IsArray($aMinuteMeasure) And DllStructGetData($aMinuteMeasure[0], "Width") > 0 And DllStructGetData($aMinuteMeasure[0], "Height") > 0 Then $fMinuteTextWidth = DllStructGetData($aMinuteMeasure[0], "Width") $fMinuteTextHeight = DllStructGetData($aMinuteMeasure[0], "Height") Else ; Fallback: Simple estimation if measurement fails $fMinuteTextWidth = $iMinuteFontSize * 0.6 * StringLen($sMinuteDigit) $fMinuteTextHeight = $iMinuteFontSize * 1.0 ConsoleWrite("WARNING: Failed to measure minute text '" & $sMinuteDigit & "'. Fallback: Using estimation." & @CRLF) EndIf Local $iMinuteTextX = $iCenterX + ($iMinuteTextRadius * Cos($fMinuteAngleRadians)) - ($fMinuteTextWidth / 2) Local $iMinuteTextY = $iCenterY + ($iMinuteTextRadius * Sin($fMinuteAngleRadians)) - ($fMinuteTextHeight / 2) Local $tDrawMinuteLayout = _GDIPlus_RectFCreate($iMinuteTextX, $iMinuteTextY, $fMinuteTextWidth, $fMinuteTextHeight) ; Draw the string using _GDIPlus_GraphicsDrawStringEx _GDIPlus_GraphicsDrawStringEx($hGraphics, $sMinuteDigit, $hMinuteFont, $tDrawMinuteLayout, $hStringFormatCenter, $hBrushTextMin) _GDIPlus_FontDispose($hMinuteFont) Next _GDIPlus_FontFamilyDispose($hFontFamily) ; Dispose font family after the loop ; Save the bitmap to a PNG file Local $bSuccess = _GDIPlus_ImageSaveToFile($hBitmap, $sFilePath) ConsoleWrite("DEBUG: _GDIPlus_ImageSaveToFile $bSuccess=" & $bSuccess & ", @error=" & @error & @CRLF) ; Add check for file exist and size after saving If FileExists($sFilePath) And FileGetSize($sFilePath) > 0 Then Sleep(200) ; Give some time for file system to release the file Else ConsoleWrite("ERROR: File save verification failed for '" & $sFilePath & "'. Success: " & $bSuccess & ", Exists: " & FileExists($sFilePath) & ", Size: " & FileGetSize($sFilePath) & @CRLF) $bSuccess = False EndIf ; Clean up resources _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_StringFormatDispose($hStringFormatCenter) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return $bSuccess EndFunc ;==>_CreateAndSaveClockImage ; Make, and read ini to map Func _GetClockSetting($sIniPath) If Not FileExists($sIniPath) Then ; make one Local $sTxt = "" ; Write Example data to the ini file $sTxt &= "[ClockSetting]" & @CRLF $sTxt &= "IniFile=" & $sIniPath & @CRLF $sTxt &= "Image=Default" & @CRLF $sTxt &= "Width=600" & @CRLF $sTxt &= "X=-1" & @CRLF $sTxt &= "Y=-1" & @CRLF $sTxt &= "ColorSeconds=0xFF0000" & @CRLF $sTxt &= "ColorMinutes=0x40C880" & @CRLF $sTxt &= "ColorHours=0x0080C0" & @CRLF $sTxt &= "ColorCenter=0x000000" & @CRLF $sTxt &= "ColorTextHour=0xFFFFFF" & @CRLF $sTxt &= "ColorTextMin=0xFFFFFF" & @CRLF $sTxt &= "ColorOutline=0xFFFFFF" & @CRLF $sTxt &= "Alarm=1" & @CRLF $sTxt &= "AlarmSound=C:\Windows\Media\ringout.wav" & @CRLF $sTxt &= "AlarmDays=2,3,4,5,6" & @CRLF $sTxt &= "AlarmTime=17:30" & @CRLF $sTxt &= "ActivityTimeout=3" & @CRLF FileWrite($sIniPath, $sTxt) EndIf ; Read the INI section labelled 'ClockSetting'. This will return a 2 dimensional array. Local $aArray = IniReadSection($sIniPath, "ClockSetting") Local $mMap[] If Not @error Then For $i = 1 To $aArray[0][0] $mMap[$aArray[$i][0]] = $aArray[$i][1] Next EndIf ; Default colors If $mMap.ColorSeconds = "" Then $mMap.ColorSeconds = "0xFF0000" If $mMap.ColorMinutes = "" Then $mMap.ColorMinutes = "0x40C880" If $mMap.ColorHours = "" Then $mMap.ColorHours = "0x0080C0" If $mMap.ColorCenter = "" Then $mMap.ColorCenter = "0x000000" If $mMap.ColorTextHour = "" Then $mMap.ColorTextHour = "0xFFFFFF" If $mMap.ColorTextMin = "" Then $mMap.ColorTextMin = "0xFFFFFF" If $mMap.ColorOutline = "" Then $mMap.ColorOutline = "0xFFFFFF" Return $mMap EndFunc ;==>_GetClockSetting ; Check Alarm time Func _CheckAlarm() If $mClock.Alarm <> "1" Then Return Local $iPos = StringInStr($mClock.AlarmDays, @WDAY) If Not @error And $iPos > 0 Then If $mClock.AlarmTime = @HOUR & ":" & @MIN Then ShellExecute($mClock.AlarmSound) EndIf EndFunc ;==>_CheckAlarm ; Set Alarm GUI Func _SetAlarm() Local Const $MARGIN = 10 Local $hGUIAlarm = GUICreate("Set Alarm", 300, 260, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) GUICtrlCreateLabel("Select Days:", $MARGIN, $MARGIN, 100, 20) GUICtrlSetFont(-1, 9, 800) Local $a_idDays[7] Local $aDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Local $iY = $MARGIN + 25 For $i = 0 To UBound($aDays) - 1 $a_idDays[$i] = GUICtrlCreateCheckbox($aDays[$i], 10, $iY, 90, 20) Local $iPos = StringInStr($mClock.AlarmDays, $i + 1) If Not @error And $iPos > 0 Then GUICtrlSetState(-1, $GUI_CHECKED) $iY += (20 + 2) Next GUICtrlCreateLabel("Set Time (HH:MM):", 170, $MARGIN, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputTime = GUICtrlCreateInput($mClock.AlarmTime, 180, 35, 80, 20) GUICtrlSetFont(-1, 10) Local $idInfo = GUICtrlCreateLabel("", 100, 65, 190, 100) GUICtrlSetFont(-1, 10) $iY += $MARGIN GUICtrlCreateLabel("Select Sound File:", $MARGIN, $iY, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputSoundFile = GUICtrlCreateInput($mClock.AlarmSound, $MARGIN, $iY + 25, 240, 20) Local $idBtnBrowse = GUICtrlCreateButton("...", 260, $iY + 25, 30, 20) Local $idBtnSetAlarm = GUICtrlCreateButton("Set Alarm", 190, 170, 100, 20 + 5) GUICtrlSetFont(-1, 10, 800) GUISetState(@SW_SHOW) While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idBtnBrowse Local $sSoundFile = FileOpenDialog("Select Alarm Sound", @WorkingDir, "Sound Files (*.mp3;*.wav)|All Files (*.*)") If Not @error Then GUICtrlSetData($idInputSoundFile, $sSoundFile) Case $idBtnSetAlarm Local $sTime, $sSoundPath, $sDays = "", $sInfo = "" GUICtrlSetData($idInfo, "") For $i = 0 To UBound($a_idDays) - 1 If GUICtrlRead($a_idDays[$i]) = $GUI_CHECKED Then $sDays &= $i + 1 & "," Next $sDays = StringTrimRight($sDays, 1) ; remove last "," If $sDays = "" Then $sInfo &= "⚠ Please select at least one day." & @CRLF $sTime = GUICtrlRead($idInputTime) If Not StringRegExp($sTime, "^\d{2}:\d{2}$") Then $sInfo &= "⚠ Please enter time in HH:MM format (e.g., 07:30)." & @CRLF $sSoundPath = "" & GUICtrlRead($idInputSoundFile) If $sSoundPath = "" Then $sInfo &= "⚠ Please select an sound file." GUICtrlSetData($idInfo, $sInfo) If $sInfo <> "" Then ContinueCase ; checks if everything is valid $mClock.AlarmDays = $sDays $mClock.AlarmTime = $sTime $mClock.AlarmSound = $sSoundPath IniWrite($mClock.IniFile, "ClockSetting", "AlarmDays", $sDays) IniWrite($mClock.IniFile, "ClockSetting", "AlarmTime", $sTime) IniWrite($mClock.IniFile, "ClockSetting", "AlarmSound", $sSoundPath) ExitLoop EndSwitch WEnd GUIDelete($hGUIAlarm) EndFunc ;==>_SetAlarm ; Set Colors GUI Func _SetColors() Local $hGUIColors = GUICreate("Set Colors", 180, 250, -1, -1, -1, $WS_EX_TOOLWINDOW) GUISetFont(10) GUICtrlCreateLabel("Seconds hand", 10, 10, 101, 17, 0x0002) GUICtrlCreateLabel("Minutes hand", 10, 40, 101, 17, 0x0002) GUICtrlCreateLabel("Hours hand", 10, 70, 101, 17, 0x0002) GUICtrlCreateLabel("Center Pin", 10, 100, 101, 17, 0x0002) GUICtrlCreateLabel("Hours Didits", 10, 130, 101, 17, 0x0002) GUICtrlCreateLabel("Minutes Didits", 10, 160, 101, 17, 0x0002) GUICtrlCreateLabel("Image Outline", 10, 190, 101, 17, 0x0002) Local $aNames[8] = [7, "ColorSeconds", "ColorMinutes", "ColorHours", "ColorCenter", "ColorTextHour", "ColorTextMin", "ColorOutline"] Local $iY = 5 Local $aColors[8][3] $aColors[0][0] = 7 For $i = 1 To $aColors[0][0] $aColors[$i][0] = GUICtrlCreateButton("", 120, $iY, 50, 25, 0x8000) $aColors[$i][1] = $mClock[$aNames[$i]] GUICtrlSetBkColor(-1, $aColors[$i][1]) If $i < 5 Then GUICtrlSetTip(-1, "This will be in effect after restart the clock") If $i > 4 Then GUICtrlSetTip(-1, "This will be in effect after deleting the existing clock image") $iY += 30 Next Local $idSetColors = GUICtrlCreateButton("Set Colors", 70, $iY, 100, 25) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") GUISetState(@SW_SHOW) Local $nMsg, $iChooseColor While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aColors[1][0] To $aColors[7][0] ;ConsoleWrite("$nMsg=" & $nMsg & @CRLF) Local $id = $nMsg - 10 $iChooseColor = _ChooseColor(2, $aColors[$id][1], 2, $hGUIColors) If $iChooseColor <> -1 Then $aColors[$id][1] = $iChooseColor GUICtrlSetBkColor($aColors[$id][0], $aColors[$id][1]) EndIf Case $idSetColors For $i = 1 To $aColors[0][0] $mClock[$aNames[$i]] = $aColors[$i][1] IniWrite($mClock.IniFile, "ClockSetting", $aNames[$i], $aColors[$i][1]) Next ExitLoop EndSwitch WEnd GUIDelete($hGUIColors) EndFunc ;==>_SetColors Func _ActivityTimeout($iTimeout = 3) Local Static $iMinute, $iMouseX Local $aMpos = MouseGetPos() If $iMouseX <> $aMpos[0] Then $iMouseX = $aMpos[0] $iMinute = 0 Return EndIf $iMinute +=1 If $iMinute = $iTimeout Then $iMinute = 0 WinActivate($hGUIClock) ConsoleWrite("INFO: Activity Timeout triggered." & @CRLF) EndIf EndFunc Extra background image Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
    5 points
  3. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) HotKeySet("{ESC}", Terminate) ;;; https://www.autoitscript.com/forum/topic/212981-move-window-behind-desktop-icons/page/2/#findComment-1544435 Example() Func Example() Local $hWorkerW = 0, $hProgman = _WinAPI_GetShellWindow() ; WinGetHandle("[CLASS:Progman]") ;~ _SendMessage($hProgman, 0x052C) ; <<<<<< force the creation of a WorkerW handle under Progman ; https://stackoverflow.com/questions/56132584/draw-on-windows-10-wallpaper-in-c ; https://stackoverflow.com/questions/34952967/drawing-to-the-desktop-via-injection ; https://github.com/rocksdanister/lively/issues/2074 _WinAPI_SendMessageTimeout($hProgman, 0x052C, 0, 0, 3000, $SMTO_NORMAL) ; same as _SendMessage() If Not $hWorkerW Then ; dah Local $aEnumWindows = _WinAPI_EnumWindows(False) For $n = 1 To UBound($aEnumWindows) - 1 If $aEnumWindows[$n][1] <> "WorkerW" Then ContinueLoop If _WinAPI_GetParent($aEnumWindows[$n][0]) = $hProgman Then $hWorkerW = $aEnumWindows[$n][0] ExitLoop ; but is likely one at the end of the Z-order EndIf Next EndIf ConsoleWrite("WorkerW = " & $hWorkerW & @CRLF) If Not $hWorkerW Then $hWorkerW = $hProgman Local $hGUI = GUICreate("Overlay", 400, 300, 10, 10) ; , $WS_POPUP, $WS_EX_TOOLWINDOW) GUICtrlCreatePic(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1)) & "Examples\GUI\msoobe.jpg", 0, 0, 400, 300) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 180) GUISetState(@SW_SHOWNOACTIVATE) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd EndFunc ;==>Example Func Terminate() Exit EndFunc ;==>Terminate My take on the problem is creating "WorkerW". Finding it with _WinAPI_EnumWindows() works best. Reading this github.com/rocksdanister/lively/issues/2074 ( and the projects ) look interesting.
    5 points
  4. Hey, got it working on Win10. Never expected it. Found some code about forcing the creation of a WorkerW handle. Let's see if it does the job for your too. #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> Opt("MustDeclareVars", True) HotKeySet("{ESC}", Terminate) Example() Func Example() Local $hProgman = WinGetHandle("[CLASS:Progman]") _SendMessage($hProgman, 0x052c) ; <<<<<< force the creation of a WorkerW handle under Progman Local $aList = WinList(), $hWorkerW For $i = 1 To $aList[0][0] If _WinAPI_GetParent($aList[$i][1]) = $hProgman And _WinAPI_GetClassName($aList[$i][1]) = "WorkerW" Then $hWorkerW = $aList[$i][1] ExitLoop EndIf Next ConsoleWrite("WorkerW " & $hWorkerW & @CRLF) Local $hGUI = GUICreate("Overlay", 400, 300, 10, 10, $WS_POPUP, $WS_EX_TOOLWINDOW) GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\msoobe.jpg", 0, 0, 400, 300) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 180) GUISetState(@SW_SHOWNOACTIVATE) While Sleep(100) WEnd EndFunc ;==>Example Func Terminate() Exit EndFunc ;==>Terminate
    5 points
  5. I’m thrilled to introduce my IStream UDF, a sophisticated library designed to handle the COM IStream interface in AutoIt. This UDF enables management of data streams, whether from files, memory, or other sources, leveraging Windows IStream APIs. It provides a reliable solution for reading, writing, and administering streams in your AutoIt scripts. Whether you need to process large files, manipulate in-memory data, or handle transactional streams, this UDF is crafted to be versatile, well-documented, and user-friendly.Key Features Full Implementation of the IStream Interface: Supports all methods of the IStream interface (Read, Write, Seek, SetSize, CopyTo, Commit, Revert, LockRegion, UnlockRegion, Stat, Clone). Support for File and Memory Streams: Create streams from files using _SHCreateStreamOnFileEx or from in-memory data with _StreamCreateFromData, _SHCreateMemStream, and _StreamCreateFromDataOnHGlobal. Advanced Error Handling: Includes a detailed HRESULT error table ($tagIStreamErrorTable) and a _IStream_GetErrorInfo function for clear, understandable error messages. Utility Functions: Functions like _StreamGetSize, _StreamGetName, _StreamGetType, and _StreamStatDisplay simplify access to stream metadata. Comprehensive Documentation: Each function comes with standard UDF-format documentation, including syntax, parameters, return values, remarks, MSDN links, and practical examples. Compatibility: Works with AutoIt 3.3+ and relies on standard libraries (AutoItObject, WinAPI, Memory, Date). Use Cases Reading and writing large files without loading their entire content into memory. Handling in-memory binary data for applications such as network stream processing or serialized data manipulation. Supporting transactional streams for secure operations (e.g., via StgCreateDocfile). Integration with other COM interfaces requiring IStream. you need: AutoItObject.au3 Example: copy data between streams #include "IStream.au3" ; Example demonstrating the use of _StreamCopyToEx to copy data between streams Func Example_StreamCopyToEx() ; Create a source stream with the content "Strong" using _StreamCreateFromDataOnHGlobal ConsoleWrite("Creating source stream with 'Strong'..." & @CRLF) Local $iSrcSize,$aError Local $oSrcStream = _StreamCreateFromDataOnHGlobal("Strong", $iSrcSize, True) If @error Or Not IsObj($oSrcStream) Then ; Handle errors by displaying the HRESULT code and details from $tagIStreamErrorTable ConsoleWrite("Error: Failed to create source stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf Return EndIf ConsoleWrite("Source stream created, size: " & $iSrcSize & " bytes" & @CRLF) ; Create a destination stream with the content "AutoIt is " using _StreamCreateFromDataOnHGlobal ConsoleWrite("Creating destination stream with 'AutoIt is '..." & @CRLF) Local $iDestSize Local $oDestStream = _StreamCreateFromDataOnHGlobal("AutoIt is ", $iDestSize, True) If @error Or Not IsObj($oDestStream) Then ; Handle errors for destination stream creation ConsoleWrite("Error: Failed to create destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release the source stream and COM resources before exiting _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Destination stream created, size: " & $iDestSize & " bytes" & @CRLF) ; Copy the content from the source stream to the destination stream using _StreamCopyToEx ConsoleWrite("Copying 'Strong' to destination stream..." & @CRLF) Local $iBytesRead, $iBytesWritten If Not _StreamCopyToEx($oSrcStream, $oDestStream, $iSrcSize, $iBytesRead, $iBytesWritten) Then ; Handle errors during the copy operation ConsoleWrite("Error: _StreamCopyToEx failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release both streams and COM resources before exiting _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Copied " & $iBytesRead & " bytes read, " & $iBytesWritten & " bytes written." & @CRLF) ; Read and display the content of the destination stream ConsoleWrite("Reading destination stream content..." & @CRLF) Local $iNewDestSize = _StreamGetSize($oDestStream) If @error Then ; Handle errors when retrieving the destination stream size ConsoleWrite("Error: Failed to get destination stream size. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Release both streams and COM resources before exiting _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ConsoleWrite("Destination stream size after copy: " & $iNewDestSize & " bytes" & @CRLF) ; Position the stream pointer at the beginning for reading Local $pDestMem, $iDestRead _StreamSeek($oDestStream, 0, $STREAM_SEEK_SET) If @error Then ; Handle errors when seeking in the destination stream ConsoleWrite("Error: Failed to seek destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf _StreamRelease($oDestStream) _StreamRelease($oSrcStream) Return EndIf ; Read the content of the destination stream _StreamRead($oDestStream, $iNewDestSize, $pDestMem, $iDestRead) If @error Then ; Handle errors when reading the destination stream ConsoleWrite("Error: Failed to read destination stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) $aError = _IStream_GetErrorInfo(@extended) If IsArray($aError) Then ConsoleWrite("Name: " & $aError[0] & @CRLF) ConsoleWrite("Description: " & $aError[1] & @CRLF) ConsoleWrite("Affected methods: " & $aError[2] & @CRLF) EndIf ; Free the memory buffer if allocated, then release streams and COM resources If $pDestMem Then _MemGlobalFree($pDestMem) _StreamRelease($oDestStream) _StreamRelease($oSrcStream) _WinAPI_CoUninitialize() Return EndIf ; Convert the read data to a string and display it Local $bufSize Local $bDestData = _WinAPI_GetBufferData($pDestMem, $bufSize) ConsoleWrite("Destination stream content: " & BinaryToString($bDestData, 4) & @CRLF) ; Free the memory buffer If $pDestMem Then _MemGlobalFree($pDestMem) ; Release both streams to prevent memory leaks _StreamRelease($oDestStream) _StreamRelease($oSrcStream) ConsoleWrite("COM uninitialized, resources freed." & @CRLF) EndFunc ;==>Example_StreamCopyToEx ; Run the example Example_StreamCopyToEx() example demonstrating multiple IStream interface methods #include "IStream.au3" ; Example demonstrating multiple IStream interface methods Func Example_IStream() ; Initialize the COM object model (required for COM API calls) _WinAPI_CoInitialize() ConsoleWrite("=== Creating Stream with SHCreateMemStream ===" & @CRLF) ; Create a memory stream with initial content "Hello, IStream UDF!" Local $sData = "Hello, IStream UDF!" Local $iSize = 0 Local $oStream = _StreamCreateFromData($sData, $iSize) If @error Then ; Handle stream creation error and display details ConsoleWrite("Error: Failed to create stream. @error = " & @error & @CRLF) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Stream created successfully. Size: " & $iSize & " bytes" & @CRLF) ; Test IUnknown::QueryInterface to verify the IStream interface ConsoleWrite("Testing QueryInterface..." & @CRLF) Local $IID_IStream = "{0000000C-0000-0000-C000-000000000046}" Local $pQueriedStream = _StreamQueryInterface($oStream, $IID_IStream) If @error Then ; Handle QueryInterface error and release resources ConsoleWrite("Error: QueryInterface failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("QueryInterface succeeded." & @CRLF) ; Release the queried interface to prevent memory leaks DllCall("ole32.dll", "ulong", "Release", "ptr", $pQueriedStream) ; Test IStream::Write by appending additional data ConsoleWrite("Testing Write..." & @CRLF) Local $sNewData = " Additional data." ; 16 characters Local $iNewSize = 0 Local $pMemory = _StreamCreateMemoryBuffer($sNewData, $iNewSize) If @error Then ; Handle memory buffer creation error ConsoleWrite("Error: Failed to create memory buffer. @error = " & @error & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $iWrittenSize = 0 ; Set the stream size to accommodate new data If Not _StreamSetSize($oStream, $iSize + $iNewSize) Then ConsoleWrite("Error: SetSize failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Move the stream pointer to the end for appending If Not _StreamSeek($oStream, $iSize, $STREAM_SEEK_SET) Then ConsoleWrite("Error: Seek failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Write the new data to the stream If Not _StreamWrite($oStream, $pMemory, $iNewSize, $iWrittenSize) Then ConsoleWrite("Error: Write failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemory) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Wrote " & $iWrittenSize & " bytes." & @CRLF) ; Free the memory buffer _WinAPI_FreeMemory($pMemory) ; Test IStream::Seek to move the pointer to the beginning ConsoleWrite("Testing Seek..." & @CRLF) Local $iNewPosition = _StreamSeek($oStream, 0, $STREAM_SEEK_SET) If @error Then ConsoleWrite("Error: Seek failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Stream pointer moved to: " & $iNewPosition & @CRLF) ; Test IStream::Read to retrieve the entire stream content ConsoleWrite("Testing Read..." & @CRLF) Local $pMemoryRead = 0, $iReadSize = 0 If Not _StreamRead($oStream, $iSize + $iNewSize, $pMemoryRead, $iReadSize) Then ConsoleWrite("Error: Read failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pMemoryRead) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $bData = _WinAPI_GetBufferData($pMemoryRead, $iReadSize) ConsoleWrite("Read " & $iReadSize & " bytes: " & BinaryToString($bData) & @CRLF) _WinAPI_FreeMemory($pMemoryRead) ; Verify that the read data matches the expected content If $iReadSize <> $iSize + $iNewSize Or BinaryToString($bData) <> $sData & $sNewData Then ConsoleWrite("Error: Read data does not match expected: " & $sData & $sNewData & @CRLF) EndIf ; Test IStream::CopyTo by copying the stream to a new destination stream ConsoleWrite("Testing CopyTo..." & @CRLF) ; Create a destination stream Local $pDestStream = _WinAPI_CreateStreamOnHGlobal(0, True) If Not $pDestStream Then ConsoleWrite("Error: Failed to create destination stream." & @CRLF) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Move the source stream pointer to the beginning $iNewPosition = _StreamSeek($oStream, 0, $STREAM_SEEK_SET) If @error Then ConsoleWrite("Error: Seek failed on source stream. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Copy the content to the destination stream Local $iBytesRead = 0, $iBytesWritten = 0 If Not _StreamCopyTo($oStream, $pDestStream, $iSize + $iNewSize, $iBytesRead, $iBytesWritten) Then ConsoleWrite("Error: CopyTo failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Copied " & $iBytesRead & " bytes read, " & $iBytesWritten & " bytes written." & @CRLF) ; Create an IStream object from the destination stream pointer Local $oDestStream = _AutoItObject_WrapperCreate($pDestStream, $tagIStream) If @error Then ConsoleWrite("Error: Failed to create destination stream object. @error = " & @error & @CRLF) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ; Read and verify the destination stream content _StreamSeek($oDestStream, 0, $STREAM_SEEK_SET) Local $pDestMemory, $iDestReadSize If Not _StreamRead($oDestStream, $iSize + $iNewSize, $pDestMemory, $iDestReadSize) Then ConsoleWrite("Error: Reading destination stream failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _WinAPI_FreeMemory($pDestMemory) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf Local $bDestData = _WinAPI_GetBufferData($pDestMemory, $iDestReadSize) ConsoleWrite("Destination stream content: " & BinaryToString($bDestData, $SB_UTF8) & @CRLF) _WinAPI_FreeMemory($pDestMemory) ; Verify that the copied data matches the expected content ; Test IStream::Commit ConsoleWrite("Testing Commit..." & @CRLF) If Not _StreamCommit($oDestStream, $STGC_DEFAULT) Then ConsoleWrite("Error: Commit failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Commit succeeded." & @CRLF) EndIf ; Test IStream::Revert ConsoleWrite("Testing Revert..." & @CRLF) If Not _StreamRevert($oDestStream) Then ; Note that Revert may not be supported by memory streams ConsoleWrite("Note: Revert may not be supported. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Revert succeeded (unexpected for memory stream)." & @CRLF) EndIf ; Test IStream::LockRegion and UnlockRegion ConsoleWrite("Testing LockRegion..." & @CRLF) If Not _StreamLockRegion($oStream, 0, 10, 0) Then ; Note that LockRegion may not be supported by memory streams ConsoleWrite("Note: LockRegion may not be supported. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) __IStreamErrorInfo(@extended) Else ConsoleWrite("LockRegion succeeded." & @CRLF) ConsoleWrite("Testing UnlockRegion..." & @CRLF) If Not _StreamUnlockRegion($oStream, 0, 10, 0) Then ConsoleWrite("Error: UnlockRegion failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("UnlockRegion succeeded." & @CRLF) EndIf EndIf ; Test IStream::Stat to retrieve stream metadata ConsoleWrite("Testing GetStat..." & @CRLF) Local $pStatFlag = 0 If Not _StreamGetStat($oStream, $pStatFlag) Then ConsoleWrite("Error: GetStat failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Displaying stream metadata:" & @CRLF) _StreamStatDisplay($pStatFlag) _WinAPI_CoTaskMemFree($pStatFlag) ; Test IStream::GetType and GetName ConsoleWrite("Testing GetType and GetName..." & @CRLF) Local $sType = _StreamGetType($oStream) If @error Then ConsoleWrite("Error: GetType failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Stream type: " & $sType & @CRLF) EndIf Local $sName = _StreamGetName($oStream) If @error Then ConsoleWrite("Error: GetName failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) Else ConsoleWrite("Stream name: " & $sName & @CRLF) EndIf ; Test IStream::Clone ConsoleWrite("Testing Clone..." & @CRLF) Local $pCloned Local $oCloneStream = _StreamClone($oStream, $pCloned) If @error Then ConsoleWrite("Error: Clone failed. @error = " & @error & ", @extended = 0x" & Hex(@extended, 8) & @CRLF) _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() Return EndIf ConsoleWrite("Clone stream created successfully." & @CRLF) _StreamRelease($oCloneStream) DllCall("ole32.dll", "ulong", "Release", "ptr", $pCloned) ; Clean up all resources _StreamRelease($oDestStream) _StreamRelease($oStream) _WinAPI_CoUninitialize() ConsoleWrite("All streams released and COM uninitialized." & @CRLF) EndFunc ;==>Example_IStream ; Run the example Example_IStream() The help file is included with the UDF IStream.zip
    4 points
  6. Helper App: ; ================================================================================================= ; Title .........: AutoIt Embedded File Generator ; Author(s) .....: Dao Van Trong - TRONG.PRO ; Version .......: 2.5 (Fixed syntax and delimiter logic in generated code) ; Description ...: A professional tool to convert binary files into self-contained AutoIt hex functions. ; Features architecture detection, GUI and CLI modes, and robust code generation. ; ================================================================================================= #Region ; *** INCLUDES *** #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <Clipboard.au3> #include <File.au3> #include <Array.au3> #include <ListViewConstants.au3> #EndRegion ; *** INCLUDES *** #Region ; *** GLOBAL VARIABLES *** ; Global variables for GUI controls Global $g_hGUI, $g_hListView, $g_hEditOutput, $g_hInputChunkSize Global $g_hBtnAddFiles, $g_hBtnRemoveSelected, $g_hBtnClearAll, $g_hCheckAddHelpers, $g_hBtnGenerate, $g_hBtnPreview, $g_hBtnCopy, $g_hBtnSaveAll, $g_hBtnSaveSeparate, $g_hBtnExit ; Global 2D array to store file information. ; Index [x][0]: Full Path ; Index [x][1]: File Name ; Index [x][2]: Formatted File Size ; Index [x][3]: Architecture ; Index [x][4]: Generated Function Name Global $g_aSelectedFiles[0][5] #EndRegion ; *** GLOBAL VARIABLES *** #Region ; *** SCRIPT ENTRY POINT *** ; Check if command-line arguments were provided to determine execution mode. If $CmdLine[0] > 0 Then _RunCommandLineMode() Else _RunGuiMode() EndIf #EndRegion ; *** SCRIPT ENTRY POINT *** #Region ; *** GUI MODE FUNCTIONS *** ; ------------------------------------------------------------------------------------------------- ; Function: _RunGuiMode() ; Purpose: Creates and manages the main Graphical User Interface (GUI). ; ------------------------------------------------------------------------------------------------- Func _RunGuiMode() $g_hGUI = GUICreate("AutoIt Embedded File Generator by Dao Van Trong - TRONG.PRO", 800, 650) GUISetBkColor(0xF0F0F0) _CreateGUI_Controls() GUISetState(@SW_SHOW, $g_hGUI) Local $nMsg While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE, $g_hBtnExit ExitLoop Case $g_hBtnAddFiles _GUI_HandleAddFiles() Case $g_hBtnRemoveSelected _GUI_HandleRemoveSelected() Case $g_hBtnClearAll _GUI_HandleClearAll() Case $g_hBtnGenerate _GUI_HandleGenerateAll() Case $g_hBtnPreview _GUI_HandlePreviewSingle() Case $g_hBtnCopy _GUI_HandleCopyToClipboard() Case $g_hBtnSaveAll _GUI_HandleSaveAll() Case $g_hBtnSaveSeparate _GUI_HandleSaveSeparate() EndSwitch WEnd GUIDelete($g_hGUI) EndFunc ;==>_RunGuiMode ; ------------------------------------------------------------------------------------------------- ; Function: _CreateGUI_Controls() ; Purpose: Creates all controls for the main GUI window. ; ------------------------------------------------------------------------------------------------- Func _CreateGUI_Controls() GUICtrlCreateLabel("1. File Selection:", 10, 15, 150, 20) GUICtrlSetFont(-1, 9, 600) $g_hBtnAddFiles = GUICtrlCreateButton("Add Files...", 10, 35, 100, 25) $g_hBtnRemoveSelected = GUICtrlCreateButton("Remove Selected", 120, 35, 120, 25) $g_hBtnClearAll = GUICtrlCreateButton("Clear All", 250, 35, 80, 25) $g_hListView = GUICtrlCreateListView("File Name|Size|Architecture|Function Name", 10, 70, 780, 150) GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 0, 250) GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 1, 100) GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 2, 100) GUICtrlSendMsg($g_hListView, $LVM_SETCOLUMNWIDTH, 3, 320) GUICtrlCreateLabel("2. Generation Options:", 10, 235, 150, 20) GUICtrlSetFont(-1, 9, 600) GUICtrlCreateLabel("Line Length (chars):", 20, 260, 120, 20) $g_hInputChunkSize = GUICtrlCreateInput("4000", 150, 257, 100, 22) $g_hCheckAddHelpers = GUICtrlCreateCheckbox("Include helper functions", 270, 257, 150, 22) GUICtrlSetState($g_hCheckAddHelpers, $GUI_CHECKED) $g_hBtnGenerate = GUICtrlCreateButton("3. Generate All Functions", 10, 290, 200, 35) GUICtrlSetFont(-1, 10, 700) GUICtrlSetBkColor($g_hBtnGenerate, 0x90EE90) $g_hBtnPreview = GUICtrlCreateButton("Preview Single", 220, 290, 100, 35) GUICtrlCreateLabel("Generated Code:", 10, 340, 150, 20) GUICtrlSetFont(-1, 9, 600) $g_hEditOutput = GUICtrlCreateEdit("", 10, 360, 780, 220, $WS_VSCROLL + $WS_HSCROLL) GUICtrlSetFont(-1, 9, 400, 0, "Consolas") $g_hBtnCopy = GUICtrlCreateButton("Copy to Clipboard", 10, 590, 130, 30) $g_hBtnSaveAll = GUICtrlCreateButton("Save All to File", 150, 590, 130, 30) $g_hBtnSaveSeparate = GUICtrlCreateButton("Save Separate Files", 290, 590, 130, 30) $g_hBtnExit = GUICtrlCreateButton("Exit", 660, 590, 130, 30) GUICtrlSetBkColor($g_hBtnExit, 0xFFB6C1) EndFunc ;==>_CreateGUI_Controls ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleAddFiles() ; Purpose: Opens a file dialog and adds selected files to the list. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleAddFiles() Local $sFiles = FileOpenDialog("Select Files", @ScriptDir, "All Files (*.*)", 4) If @error Then Return Local $aNewFiles = StringSplit($sFiles, "|") If $aNewFiles[0] = 1 Then _AddFileToList($aNewFiles[1]) Else Local $sBasePath = $aNewFiles[1] For $i = 2 To $aNewFiles[0] _AddFileToList($sBasePath & "\" & $aNewFiles[$i]) Next EndIf EndFunc ;==>_GUI_HandleAddFiles ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleRemoveSelected() ; Purpose: Removes the selected file from the list. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleRemoveSelected() Local $iIndex = GUICtrlSendMsg($g_hListView, $LVM_GETNEXTITEM, -1, $LVNI_SELECTED) If $iIndex = -1 Then Return _ArrayDelete($g_aSelectedFiles, $iIndex) GUICtrlSendMsg($g_hListView, $LVM_DELETEITEM, $iIndex, 0) EndFunc ;==>_GUI_HandleRemoveSelected ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleClearAll() ; Purpose: Clears all files from the list and resets the UI. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleClearAll() ReDim $g_aSelectedFiles[0][5] GUICtrlSendMsg($g_hListView, $LVM_DELETEALLITEMS, 0, 0) GUICtrlSetData($g_hEditOutput, "") EndFunc ;==>_GUI_HandleClearAll ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleGenerateAll() ; Purpose: Generates the complete code for all files in the list. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleGenerateAll() If UBound($g_aSelectedFiles) = 0 Then Return MsgBox(48, "Warning", "Please add at least one file first.") GUICtrlSetData($g_hEditOutput, "Generating code, please wait...") Sleep(10) Local $bAddHelpers = (GUICtrlRead($g_hCheckAddHelpers) = $GUI_CHECKED) Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize)) Local $sCode = _GenerateCodeBundle($g_aSelectedFiles, $bAddHelpers, $iChunkSize) GUICtrlSetData($g_hEditOutput, $sCode) EndFunc ;==>_GUI_HandleGenerateAll ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandlePreviewSingle() ; Purpose: Generates code for only the selected file. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandlePreviewSingle() Local $iIndex = GUICtrlSendMsg($g_hListView, $LVM_GETNEXTITEM, -1, $LVNI_SELECTED) If $iIndex = -1 Then Return MsgBox(48, "Warning", "Please select a file from the list first.") GUICtrlSetData($g_hEditOutput, "Generating preview...") Sleep(10) Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize)) Local $sOutput = "; Preview for: " & $g_aSelectedFiles[$iIndex][1] & @CRLF $sOutput &= "; Architecture: " & $g_aSelectedFiles[$iIndex][3] & @CRLF & @CRLF $sOutput &= _GenerateHexFunction($g_aSelectedFiles[$iIndex][0], $g_aSelectedFiles[$iIndex][4], $g_aSelectedFiles[$iIndex][1], $g_aSelectedFiles[$iIndex][3], "$sHexData", $iChunkSize) GUICtrlSetData($g_hEditOutput, $sOutput) EndFunc ;==>_GUI_HandlePreviewSingle ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleCopyToClipboard() ; Purpose: Copies the output text to the clipboard. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleCopyToClipboard() Local $sCode = GUICtrlRead($g_hEditOutput) If StringStripWS($sCode, 8) = "" Then Return MsgBox(48, "Warning", "No code to copy. Please generate code first.") _ClipBoard_SetData($sCode) ToolTip("Code copied to clipboard!", @DesktopWidth / 2, @DesktopHeight / 2, "Success", 1, 1) Sleep(1500) ToolTip("") EndFunc ;==>_GUI_HandleCopyToClipboard ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleSaveAll() ; Purpose: Saves the generated code for all files into a single .au3 file. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleSaveAll() Local $sCode = GUICtrlRead($g_hEditOutput) If StringStripWS($sCode, 8) = "" Then Return MsgBox(48, "Warning", "No code to save. Please generate code first.") Local $sSaveFile = FileSaveDialog("Save Combined Code", @ScriptDir, "AutoIt Scripts (*.au3)", 16, "All_Embedded.au3") If @error Then Return If Not _SaveStringToFile($sSaveFile, $sCode) Then MsgBox(16, "Error", "Could not create file: " & $sSaveFile) Else MsgBox(64, "Success", "All functions saved to: " & @CRLF & $sSaveFile) EndIf EndFunc ;==>_GUI_HandleSaveAll ; ------------------------------------------------------------------------------------------------- ; Function: _GUI_HandleSaveSeparate() ; Purpose: Saves the generated code for each file into its own separate .au3 file. ; ------------------------------------------------------------------------------------------------- Func _GUI_HandleSaveSeparate() If UBound($g_aSelectedFiles) = 0 Then Return MsgBox(48, "Warning", "No files to process.") Local $sSaveDir = FileSelectFolder("Select folder to save separate files", @ScriptDir) If @error Then Return Local $iChunkSize = _ValidateChunkSize(GUICtrlRead($g_hInputChunkSize)) Local $bAddHelpers = (GUICtrlRead($g_hCheckAddHelpers) = $GUI_CHECKED) Local $iSaved = 0 For $i = 0 To UBound($g_aSelectedFiles) - 1 Local $sFilePath = $g_aSelectedFiles[$i][0] Local $sFileName = $g_aSelectedFiles[$i][1] Local $sArch = $g_aSelectedFiles[$i][3] Local $sFuncName = $g_aSelectedFiles[$i][4] Local $sDrive, $sDir, $sNameOnly, $sExt _PathSplit($sFilePath, $sDrive, $sDir, $sNameOnly, $sExt) Local $sSaveFile = $sSaveDir & "\" & $sNameOnly & "_Embedded.au3" Local $sCode = "; Generated from: " & $sFileName & @CRLF $sCode &= "; Architecture: " & $sArch & @CRLF & @CRLF $sCode &= _GenerateHexFunction($sFilePath, $sFuncName, $sFileName, $sArch, "$sHexData", $iChunkSize) If $bAddHelpers Then $sCode &= _GenerateHelperFunction($sFuncName, $sFileName) EndIf If _SaveStringToFile($sSaveFile, $sCode) Then $iSaved += 1 Next MsgBox(64, "Success", "Saved " & $iSaved & " of " & UBound($g_aSelectedFiles) & " files to:" & @CRLF & $sSaveDir) EndFunc ;==>_GUI_HandleSaveSeparate #EndRegion ; *** GUI MODE FUNCTIONS *** #Region ; *** COMMAND-LINE MODE FUNCTIONS *** ; ------------------------------------------------------------------------------------------------- ; Function: _RunCommandLineMode() ; Purpose: Handles the script's execution when run from the command line. ; ------------------------------------------------------------------------------------------------- Func _RunCommandLineMode() Local $aFilePaths[0] For $i = 1 To $CmdLine[0] If FileExists($CmdLine[$i]) Then _ArrayAdd($aFilePaths, $CmdLine[$i]) Else ConsoleWrite("! Warning: File not found - " & $CmdLine[$i] & @CRLF) EndIf Next If UBound($aFilePaths) = 0 Then ConsoleWrite("! Error: No valid files provided." & @CRLF & " Usage: " & @ScriptName & " <file1> [file2] ..." & @CRLF) Exit 1 EndIf Local $aFilesData[UBound($aFilePaths)][5] For $i = 0 To UBound($aFilePaths) - 1 _PopulateFileInfo($aFilesData, $i, $aFilePaths[$i]) Next ConsoleWrite("+ Generating code for " & UBound($aFilesData) & " file(s)..." & @CRLF) Local $sCode = _GenerateCodeBundle($aFilesData, True, 4000) Local $sOutputFile If UBound($aFilesData) = 1 Then Local $sDrive, $sDir, $sFileName, $sExtension _PathSplit($aFilePaths[0], $sDrive, $sDir, $sFileName, $sExtension) $sOutputFile = $sDrive & $sDir & $sFileName & "_Embedded.au3" Else $sOutputFile = @ScriptDir & "\All_Embedded.au3" EndIf If _SaveStringToFile($sOutputFile, $sCode) Then ConsoleWrite("+ Success: Output saved to - " & $sOutputFile & @CRLF) Else ConsoleWrite("! Error: Could not create output file - " & $sOutputFile & @CRLF) Exit 1 EndIf EndFunc ;==>_RunCommandLineMode #EndRegion ; *** COMMAND-LINE MODE FUNCTIONS *** #Region ; *** FILE AND DATA HANDLING *** ; ------------------------------------------------------------------------------------------------- ; Function: _AddFileToList($sFilePath) ; Purpose: Adds a file's information to the global array and updates the GUI list. ; ------------------------------------------------------------------------------------------------- Func _AddFileToList($sFilePath) If Not FileExists($sFilePath) Then Return For $i = 0 To UBound($g_aSelectedFiles) - 1 If $g_aSelectedFiles[$i][0] = $sFilePath Then Return Next Local $iUBound = UBound($g_aSelectedFiles) ReDim $g_aSelectedFiles[$iUBound + 1][5] _PopulateFileInfo($g_aSelectedFiles, $iUBound, $sFilePath) Local $sListViewItem = $g_aSelectedFiles[$iUBound][1] & "|" & $g_aSelectedFiles[$iUBound][2] & "|" & $g_aSelectedFiles[$iUBound][3] & "|" & $g_aSelectedFiles[$iUBound][4] GUICtrlCreateListViewItem($sListViewItem, $g_hListView) EndFunc ;==>_AddFileToList ; ------------------------------------------------------------------------------------------------- ; Function: _PopulateFileInfo(ByRef $aArray, $iIndex, $sFilePath) ; Purpose: Gathers file info and populates a row in the provided 2D array. ; ------------------------------------------------------------------------------------------------- Func _PopulateFileInfo(ByRef $aArray, $iIndex, $sFilePath) Local $sFileName = _GetFileName($sFilePath) Local $sArch = _DetectArchitecture($sFilePath) $aArray[$iIndex][0] = $sFilePath $aArray[$iIndex][1] = $sFileName $aArray[$iIndex][2] = _FormatFileSize(FileGetSize($sFilePath)) $aArray[$iIndex][3] = $sArch $aArray[$iIndex][4] = "_GetBinData_" & _SanitizeName($sFileName) & "_" & $sArch EndFunc ;==>_PopulateFileInfo #EndRegion ; *** FILE AND DATA HANDLING *** #Region ; *** CORE CODE GENERATION *** ; ------------------------------------------------------------------------------------------------- ; Function: _GenerateCodeBundle(ByRef $aFiles, $bAddHelpers, $iChunkSize) ; Purpose: The main code generation engine. Creates the full script content. ; ------------------------------------------------------------------------------------------------- Func _GenerateCodeBundle(ByRef $aFiles, $bAddHelpers, $iChunkSize) Local $sOutput = "; Generated by AutoIt Embedded File Generator - TRONG.PRO" & @CRLF $sOutput &= "; Total files: " & UBound($aFiles) & @CRLF $sOutput &= "; Generated on: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF & @CRLF For $i = 0 To UBound($aFiles) - 1 $sOutput &= _GenerateHexFunction($aFiles[$i][0], $aFiles[$i][4], $aFiles[$i][1], $aFiles[$i][3], "$sHexData", $iChunkSize) & @CRLF & @CRLF Next If $bAddHelpers Then If UBound($aFiles) = 1 Then $sOutput &= _GenerateHelperFunction($aFiles[0][4], $aFiles[0][1]) Else $sOutput &= _GenerateMasterHelperFunctionFromArray($aFiles) EndIf EndIf Return $sOutput EndFunc ;==>_GenerateCodeBundle ; ------------------------------------------------------------------------------------------------- ; Function: _GenerateHexFunction($sFilePath, $sFuncName, $sFileName, $sArch, $sVarName, $iChunkSize) ; Purpose: Reads a binary file and wraps its hex content in an AutoIt function. ; ------------------------------------------------------------------------------------------------- Func _GenerateHexFunction($sFilePath, $sFuncName, $sFileName, $sArch, $sVarName = "$sHexData", $iChunkSize = 4000) Local $hFile = FileOpen($sFilePath, 16) If $hFile = -1 Then ConsoleWrite("! Error: Unable to open file in binary mode: " & $sFilePath & @CRLF) Return "" EndIf Local $bData = FileRead($hFile) FileClose($hFile) If @error Or $bData = "" Then ConsoleWrite("! Error reading binary data from file: " & $sFilePath & @CRLF) Return "" EndIf Local $sHexWithPrefix = StringToBinary($bData) If StringLeft($sVarName, 1) <> "$" Then $sVarName = "$" & $sVarName Local $sOutput = "Func " & $sFuncName & "()" & @CRLF $sOutput &= @TAB & '; This function holds the hex data for ' & $sFileName & @CRLF $sOutput &= @TAB & '; File size: ' & _FormatFileSize(FileGetSize($sFilePath)) & @CRLF $sOutput &= @TAB & '; Architecture: ' & $sArch & @CRLF $sOutput &= @TAB & '; Generated by AutoIt Embedded File Generator' & @CRLF Local $iHexLen = StringLen($sHexWithPrefix) $sOutput &= @TAB & "Local " & $sVarName & " = '" & StringMid($sHexWithPrefix, 1, $iChunkSize) & "'" & @CRLF For $i = $iChunkSize + 1 To $iHexLen Step $iChunkSize $sOutput &= @TAB & $sVarName & " &= '" & StringMid($sHexWithPrefix, $i, $iChunkSize) & "'" & @CRLF Next $sOutput &= @CRLF & @TAB & "Return " & $sVarName & @CRLF $sOutput &= "EndFunc ;==>" & $sFuncName Return $sOutput EndFunc ;==>_GenerateHexFunction ; ------------------------------------------------------------------------------------------------- ; Function: _GenerateHelperFunction($sFuncName, $sOriginalFileName) ; Purpose: Generates a helper function to deploy a single embedded file. ; ------------------------------------------------------------------------------------------------- Func _GenerateHelperFunction($sFuncName, $sOriginalFileName) Local $sHelperFunc = @CRLF & @CRLF $sHelperFunc &= '; =================================================================' & @CRLF $sHelperFunc &= '; Helper function to deploy the file from hex data.' & @CRLF $sHelperFunc &= '; =================================================================' & @CRLF $sHelperFunc &= 'Func _DeployFileFromHex()' & @CRLF $sHelperFunc &= @TAB & 'Local $sHexData = ' & $sFuncName & '()' & @CRLF $sHelperFunc &= @TAB & 'Local $Deploy_Dir = @TempDir' & @CRLF $sHelperFunc &= @TAB & 'If $sHexData = "" Then Return SetError(1, 0, MsgBox(16, "Error", "Hex data is empty."))' & @CRLF $sHelperFunc &= @CRLF $sHelperFunc &= @TAB & 'Local $sOutputFilename = "' & $sOriginalFileName & '"' & @CRLF $sHelperFunc &= @TAB & 'Local $sTempFilePath = $Deploy_Dir & "\" & $sOutputFilename' & @CRLF $sHelperFunc &= @TAB & 'Local $hFile = FileOpen($sTempFilePath, 18)' & @CRLF $sHelperFunc &= @TAB & 'If $hFile = -1 Then Return SetError(2, 0, MsgBox(16, "Error", "Failed to open file for writing at: " & $sTempFilePath))' & @CRLF $sHelperFunc &= @CRLF $sHelperFunc &= @TAB & 'FileWrite($hFile, BinaryToString($sHexData))' & @CRLF $sHelperFunc &= @TAB & 'FileClose($hFile)' & @CRLF $sHelperFunc &= @CRLF $sHelperFunc &= @TAB & 'If Not FileExists($sTempFilePath) Then Return SetError(3, 0, MsgBox(16, "Error", "Failed to write file to: " & $sTempFilePath))' & @CRLF $sHelperFunc &= @CRLF $sHelperFunc &= @TAB & 'MsgBox(64, "Success", "File deployed successfully to:" & @CRLF & $sTempFilePath)' & @CRLF $sHelperFunc &= @TAB & 'Return $sTempFilePath' & @CRLF $sHelperFunc &= 'EndFunc ;==>_DeployFileFromHex' & @CRLF & @CRLF $sHelperFunc &= '; Example usage: _DeployFileFromHex()' & @CRLF Return $sHelperFunc EndFunc ;==>_GenerateHelperFunction ; ------------------------------------------------------------------------------------------------- ; Function: _GenerateMasterHelperFunctionFromArray(ByRef $aFiles) ; Purpose: Generates a master helper function to deploy all embedded files. ; ------------------------------------------------------------------------------------------------- Func _GenerateMasterHelperFunctionFromArray(ByRef $aFiles) Local $sDelimiter = '"/"' Local $sHelperFunc = "#include <Array.au3>" & @CRLF & @CRLF $sHelperFunc &= '; =================================================================' & @CRLF $sHelperFunc &= '; Master helper function to deploy all embedded files.' & @CRLF $sHelperFunc &= '; =================================================================' & @CRLF $sHelperFunc &= 'Func _DeployAllFiles()' & @CRLF $sHelperFunc &= @TAB & 'Local $aResults[0]' & @CRLF $sHelperFunc &= @TAB & 'Local $Deploy_Dir = @TempDir' & @CRLF $sHelperFunc &= @CRLF For $i = 0 To UBound($aFiles) - 1 Local $sFileName = $aFiles[$i][1] Local $sFuncName = $aFiles[$i][4] Local $sArch = $aFiles[$i][3] $sHelperFunc &= @TAB & '; Deploy ' & $sFileName & ' (' & $sArch & ')' & @CRLF $sHelperFunc &= @TAB & 'Local $sHexData' & $i & ' = ' & $sFuncName & '()' & @CRLF $sHelperFunc &= @TAB & 'If $sHexData' & $i & ' <> "" Then' & @CRLF $sHelperFunc &= @TAB & @TAB & 'Local $sOutputPath' & $i & ' = $Deploy_Dir & "\' & $sFileName & '"' & @CRLF $sHelperFunc &= @TAB & @TAB & 'Local $hFile' & $i & ' = FileOpen($sOutputPath' & $i & ', 18)' & @CRLF $sHelperFunc &= @TAB & @TAB & 'If $hFile' & $i & ' <> -1 Then' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'FileWrite($hFile' & $i & ', BinaryToString($sHexData' & $i & '))' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'FileClose($hFile' & $i & ')' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'If FileExists($sOutputPath' & $i & ') Then' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & @TAB & '_ArrayAdd($aResults, "' & $sFileName & '" & ' & $sDelimiter & ' & $sOutputPath' & $i & ' & ' & $sDelimiter & ' & "Success")' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'Else' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & @TAB & '_ArrayAdd($aResults, "' & $sFileName & '" & ' & $sDelimiter & ' & "' & $sArch & '" & ' & $sDelimiter & ' & "Write failed")' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'EndIf' & @CRLF $sHelperFunc &= @TAB & @TAB & 'Else' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & '_ArrayAdd($aResults, "' & $sFileName & '" & ' & $sDelimiter & ' & "' & $sArch & '" & ' & $sDelimiter & ' & "Cannot create file")' & @CRLF $sHelperFunc &= @TAB & @TAB & 'EndIf' & @CRLF $sHelperFunc &= @TAB & 'Else' & @CRLF $sHelperFunc &= @TAB & @TAB & '_ArrayAdd($aResults, "' & $sFileName & '" & ' & $sDelimiter & ' & "' & $sArch & '" & ' & $sDelimiter & ' & "No hex data")' & @CRLF $sHelperFunc &= @TAB & 'EndIf' & @CRLF $sHelperFunc &= @CRLF Next $sHelperFunc &= @TAB & '; Display results' & @CRLF $sHelperFunc &= @TAB & 'Local $sReport = "Deployment Results (" & UBound($aResults) & " files):" & @CRLF & @CRLF' & @CRLF $sHelperFunc &= @TAB & 'For $i = 0 To UBound($aResults) - 1' & @CRLF $sHelperFunc &= @TAB & @TAB & 'Local $aParts = StringSplit($aResults[$i], ' & $sDelimiter & ')' & @CRLF $sHelperFunc &= @TAB & @TAB & 'If $aParts[0] = 3 Then' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & '$sReport &= "• " & $aParts[1] & ": " & $aParts[3]' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'If $aParts[3] = "Success" Then' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & @TAB & '$sReport &= " → " & $aParts[2]' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'Else' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & @TAB & '$sReport &= " (" & $aParts[2] & ")"' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & 'EndIf' & @CRLF $sHelperFunc &= @TAB & @TAB & @TAB & '$sReport &= @CRLF' & @CRLF $sHelperFunc &= @TAB & @TAB & 'EndIf' & @CRLF $sHelperFunc &= @TAB & 'Next' & @CRLF $sHelperFunc &= @CRLF $sHelperFunc &= @TAB & 'MsgBox(64, "Deployment Complete", $sReport)' & @CRLF $sHelperFunc &= @TAB & 'Return $aResults' & @CRLF $sHelperFunc &= 'EndFunc ;==>_DeployAllFiles' & @CRLF & @CRLF $sHelperFunc &= '; Example usage: _DeployAllFiles()' & @CRLF Return $sHelperFunc EndFunc ;==>_GenerateMasterHelperFunctionFromArray #EndRegion ; *** CORE CODE GENERATION *** #Region ; *** PE HEADER AND ARCHITECTURE DETECTION *** ; ------------------------------------------------------------------------------------------------- ; Function: _DetectArchitecture($sFilePath) ; Purpose: A wrapper that returns the architecture string for a file. ; ------------------------------------------------------------------------------------------------- Func _DetectArchitecture($sFilePath) Local $sArch = _DetectArchitecture_File($sFilePath) If @error Then Return "N/A" Return $sArch EndFunc ;==>_DetectArchitecture ; ------------------------------------------------------------------------------------------------- ; Function: _DetectArchitecture_File($sFilePath) ; Purpose: Reads a file's PE headers to identify the target CPU architecture. ; ------------------------------------------------------------------------------------------------- Func _DetectArchitecture_File($sFilePath) If Not FileExists($sFilePath) Then Return SetError(1, 0, "FILE_NOT_FOUND") Local $hFile = FileOpen($sFilePath, 16) If $hFile = -1 Then Return SetError(2, 0, "CANNOT_OPEN_FILE") Local $bDOSHeader = FileRead($hFile, 64) If @error Then FileClose($hFile) Return SetError(3, 0, "CANNOT_READ_DOS_HEADER") EndIf If BinaryMid($bDOSHeader, 1, 2) <> "0x4D5A" Then FileClose($hFile) Return "Not PE" EndIf Local $iPEOffset = _BinaryToInt(BinaryMid($bDOSHeader, 61, 4)) FileSetPos($hFile, $iPEOffset, $FILE_BEGIN) Local $bPESig = FileRead($hFile, 4) If @error Or $bPESig <> "0x50450000" Then FileClose($hFile) Return SetError(5, 0, "INVALID_PE_SIGNATURE") EndIf Local $bCOFF = FileRead($hFile, 2) FileClose($hFile) If @error Then Return SetError(6, 0, "CANNOT_READ_COFF_HEADER") Local $iMachine = _BinaryToInt($bCOFF) Switch $iMachine Case 0x014c Return "x86" Case 0x8664 Return "x64" Case 0x01c0, 0x01c4 Return "ARM" Case 0xAA64 Return "ARM64" Case 0x0200 Return "IA64" Case Else Return "UNKNOWN_0x" & Hex($iMachine, 4) EndSwitch EndFunc ;==>_DetectArchitecture_File ; ------------------------------------------------------------------------------------------------- ; Function: _BinaryToInt($bData) ; Purpose: Converts a little-endian binary string to an integer value. ; ------------------------------------------------------------------------------------------------- Func _BinaryToInt($bData) Local $iResult = 0 For $i = 1 To BinaryLen($bData) $iResult += Number(BinaryMid($bData, $i, 1)) * (256 ^ ($i - 1)) Next Return $iResult EndFunc ;==>_BinaryToInt #EndRegion ; *** PE HEADER AND ARCHITECTURE DETECTION *** #Region ; *** UTILITY FUNCTIONS *** ; ------------------------------------------------------------------------------------------------- ; Function: _SanitizeName($sInput) ; Purpose: Removes illegal characters from a string to make it a valid function name. ; ------------------------------------------------------------------------------------------------- Func _SanitizeName($sInput) Local $sCleaned = StringRegExpReplace($sInput, "[^a-zA-Z0-9_]", "") If StringLeft($sCleaned, 1) = "$" Then $sCleaned = StringTrimLeft($sCleaned, 1) Return $sCleaned EndFunc ;==>_SanitizeName ; ------------------------------------------------------------------------------------------------- ; Function: _GetFileName($sFilePath) ; Purpose: Extracts the filename and extension from a full path. ; ------------------------------------------------------------------------------------------------- Func _GetFileName($sFilePath) Return StringRegExpReplace($sFilePath, "^.*\\", "") EndFunc ;==>_GetFileName ; ------------------------------------------------------------------------------------------------- ; Function: _FormatFileSize($iBytes) ; Purpose: Converts a file size in bytes into a human-readable string (KB, MB, GB). ; ------------------------------------------------------------------------------------------------- Func _FormatFileSize($iBytes) If $iBytes < 1024 Then Return $iBytes & " B" ElseIf $iBytes < 1048576 Then Return Round($iBytes / 1024, 1) & " KB" ElseIf $iBytes < 1073741824 Then Return Round($iBytes / 1048576, 2) & " MB" Else Return Round($iBytes / 1073741824, 2) & " GB" EndIf EndFunc ;==>_FormatFileSize ; ------------------------------------------------------------------------------------------------- ; Function: _ValidateChunkSize($iChunkSize) ; Purpose: Ensures the chunk size is within a valid range. ; ------------------------------------------------------------------------------------------------- Func _ValidateChunkSize($iChunkSize) ; First, check if the input from the GUI is a string containing only digits. If Not StringIsDigit($iChunkSize) Then Return 4000 ; If not, it's invalid, return the default value. EndIf ; If it is a digit string, convert it to a real number. Local $nChunkSize = Number($iChunkSize) If ($iChunkSize < 100) Or ($iChunkSize > 4000) Then Return 4000 EndIf Return Int($iChunkSize) EndFunc ;==>_ValidateChunkSize ; ------------------------------------------------------------------------------------------------- ; Function: _SaveStringToFile($sFilePath, $sContent) ; Purpose: A robust function to save a string to a file. ; Returns: True on success, False on failure. ; ------------------------------------------------------------------------------------------------- Func _SaveStringToFile($sFilePath, $sContent) Local $hFile = FileOpen($sFilePath, 2) If $hFile = -1 Then Return False Local $bSuccess = FileWrite($hFile, $sContent) FileClose($hFile) Return $bSuccess EndFunc ;==>_SaveStringToFile #EndRegion ; *** UTILITY FUNCTIONS *** !
    4 points
  7. Updated to WebP v0.4.1 build 2025-07-10 beta. You can now play WebP animation in a separated thread. See WebP Example14 .1.au3 and WebP Example15.au3
    4 points
  8. ... Fun topic ... 🙂 just for fun, here are some tweaks to @argumentum's script above to simulate dragging the window and see the visual effect of the movement under the icons...nice effect. To make the window follow the mouse, press F9 once; to stop the movement, press F9 again. #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <WinAPISysWin.au3> Opt("MustDeclareVars", True) HotKeySet("{ESC}", Terminate) ;;; https://www.autoitscript.com/forum/topic/212981-move-window-behind-desktop-icons/page/2/#findComment-1544435 HotKeySet('{F9}', F9) ; <-- Global $bFlag = False ; <-- Example() Func Example() Local $hWorkerW = 0, $hProgman = _WinAPI_GetShellWindow() ; WinGetHandle("[CLASS:Progman]") ;~ _SendMessage($hProgman, 0x052C) ; <<<<<< force the creation of a WorkerW handle under Progman ; https://stackoverflow.com/questions/56132584/draw-on-windows-10-wallpaper-in-c ; https://stackoverflow.com/questions/34952967/drawing-to-the-desktop-via-injection ; https://github.com/rocksdanister/lively/issues/2074 _WinAPI_SendMessageTimeout($hProgman, 0x052C, 0, 0, 3000, $SMTO_NORMAL) ; same as _SendMessage() If Not $hWorkerW Then ; dah Local $aEnumWindows = _WinAPI_EnumWindows(False) For $n = 1 To UBound($aEnumWindows) - 1 If $aEnumWindows[$n][1] <> "WorkerW" Then ContinueLoop If _WinAPI_GetParent($aEnumWindows[$n][0]) = $hProgman Then $hWorkerW = $aEnumWindows[$n][0] ExitLoop ; but is likely one at the end of the Z-order EndIf Next EndIf ConsoleWrite("WorkerW = " & $hWorkerW & @CRLF) If Not $hWorkerW Then $hWorkerW = $hProgman Local $hGUI = GUICreate("Overlay", 400, 300, 10, 10) ; , $WS_POPUP, $WS_EX_TOOLWINDOW) GUICtrlCreatePic(StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1)) & "Examples\GUI\msoobe.jpg", 0, 0, 400, 300) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 180) GUISetState(@SW_SHOWNOACTIVATE) While GUIGetMsg() <> $GUI_EVENT_CLOSE If $bFlag Then WinMove($hGUI,'',MouseGetPos(0),MouseGetPos(1)) EndIf WEnd EndFunc ;==>Example Func Terminate() Exit EndFunc ;==>Terminate Func F9() $bFlag = Not $bFlag EndFunc
    4 points
  9. Thank you so much for everyone's kind help! Apologies in delay in replying, I don't know what I was doing wrong, but it was like beating my head against the wall somehow (my mom passed away 3 months ago, so suspect I was also just having trouble with details, who knows <sigh>). But I came back to this again. When I leave my apartment, I like to shut down all things running apps in the systray except what's there "automatically", as it were. Then when I come home, start up those extra things I like to have running when I'm around. Ultimately, pixelsearch kindly wrote up the code to include that TRUE statement which escaped me because of the presentation before as just describing what to do (and I see now I must still have been affected by mom's passing as I just couldn't make heads or tails of that). Here is the what worked just now, but I removed the suggested "_ArrayDisplay($array)" line as that created some havoc, too, and I find it's not really necessary, just an extra confusing step, it seems. #include <file.au3> #include <Array.au3> Local $array = _FileListToArray(@ScriptDir & "\Startup\", "0*.*", 1, TRUE) ;_ArrayDisplay($array) For $i = 1 To $array[0] ShellExecute($array[$i]) Next Thank you!
    3 points
  10. ; #FUNCTION# ==================================================================================================================== ; Name...........: HourAmPm ; Description....: Converts a time in 24-hour format to AM/PM format. ; Syntax.........: HourAmPm( $sDateTime [, $sAmPm = "AM|PM" [, $iTrimRight = 0]] ) ; Parameters.....: $sDateTime - The time (with date or not) string with "HH:" in it. ; $sAmPm - [optional] The AM/PM representation (default is "AM|PM"). ; $iTrimRight - [optional] The number of characters to trim from the right of the result (default is 0). ; $iNoDate - [optional] Whether to omit the date from the output. Defaults to False. ; Return values .: Success: Returns the formatted date and time in AM/PM format. ; Failure: None. ; Author ........: argumentum ; Modified ......: ; Remarks .......: This function takes a 24-hour time string, converts it to AM or PM format, and returns the result with optional trimming. ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/index.php?showtopic=213061 ; Example .......: MsgBox(64, "Converted Time", HourAmPm("12/31/1999 18:59:59")) ; =============================================================================================================================== Func HourAmPm($sDateTime, $sAmPm = Default, $iTrimRight = Default, $iNoDate = Default) Local $aAmPm = StringSplit((StringInStr($sAmPm, "|") ? $sAmPm : "AM|PM"), "|"), $sFormat = $aAmPm[2] Local $iHourPos = StringInStr($sDateTime, ":"), $sHour = StringMid($sDateTime, $iHourPos - 2, 2) Local $sDate = StringLeft($sDateTime, $iHourPos - 3), $sTime = StringTrimLeft($sDateTime, $iHourPos - 1) If $sHour < 12 Then $sFormat = $aAmPm[1] ; https://www.autoitscript.com/forum/index.php?showtopic=213061 $sHour = Mod($sHour, 12) If Not $sHour Then $sHour = 12 Return StringTrimRight((Int($iNoDate) ? "" : $sDate) & StringRight('0' & $sHour, 2) & $sTime, Int($iTrimRight)) & " " & $sFormat EndFunc ;==>HourAmPm ...am always looking for these ( because am disorganized ) and when I find them they are more than needed so, I decided to simplify it and flexibly-cate** it. All that's needed is the hour, the rest of the date-time string should be anything as long as there is a "HH:" in it. ; Examples: ConsoleWrite('- ' & HourAmPm("18:59") & @CRLF) ; - 06:59 PM ConsoleWrite('- ' & HourAmPm("18:59:59.999") & @CRLF) ; - 06:59:59.999 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999") & @CRLF) ; - 1999/12/31 06:59:59.999 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999", Default, 7) & @CRLF) ; - 1999/12/31 06:59 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59", Default, 3) & @CRLF) ; - 1999/12/31 06:59 PM ConsoleWrite('- ' & HourAmPm("12/31/1999 18:59", "a|p") & @CRLF) ; - 12/31/1999 06:59 p ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999", Default, 7, True) & @CRLF) ; - 06:59 PM Don't remember seeing this approach anywhere so I decided to share it **flexibly-cate [verb] To make it flexible
    3 points
  11. Absolutely. Please keep in mind that I am a complete AutoIt rookie. The examples show JSON code already in the example scripts as Global variables and parse/manipulate from there. The thing that would help a rookie like me the most would be to have an example script and an example .json file. The script would load the .json file from disk, parse json, modify some data and save those changes back to .json file on disk. That would have helped my rookie situation a lot. However, I also understand that some of that is outside of the responsibility for the UDF. But from an example perspective still would be beneficial. By the way, thank you all for your help. Cheers!
    3 points
  12. If you then want to write to the theme with _JSON_addChangeDelete() (which could make sense due to the nested structure), then you basically only need to determine the first free array index. Since you have an AutoIt data structure after _JSON_Parse(), you basically only need to make a Ubound to the themes array: #include "JSON.au3" ; your input JSON string Global $sJSONRAW = '{"workbench.startupEditor":"none","breadcrumbs.enabled":false,"window.controlsStyle":"custom","workbench.activityBar.location":"hidden","window.customTitleBarVisibility":"auto","window.titleBarStyle":"custom","workbench.colorCustomizations":{"editor.background":"#00000060","terminal.background":"#00000060"},"theme":"Existing Theme 1","themes":[{"name":"Existing Theme 1","tab":{"background":"#00000080","unfocusedBackground":"#00000000"},"tabRow":{"background":"#00000000","unfocusedBackground":"#00000000"},"window":{"applicationTheme":"light","useMica":true}},{"name":"Existing Theme 2","tab":{"background":"#00000080","unfocusedBackground":"#00000000"},"tabRow":{"background":"#00000000","unfocusedBackground":"#00000000"},"window":{"applicationTheme":"light","useMica":true}},{"name":"Existing Theme 3","tab":{"background":"#00000080","unfocusedBackground":"#00000000"},"tabRow":{"background":"#00000000","unfocusedBackground":"#00000000"},"window":{"applicationTheme":"light","useMica":true}},{"name":"Existing Theme 4","tab":{"background":"#00000080","unfocusedBackground":"#00000000"},"tabRow":{"background":"#00000000","unfocusedBackground":"#00000000"},"window":{"applicationTheme":"light","useMica":true}}]}' ; parse JSON string into nested AutoIt data structure: Global $vJSON = _JSON_Parse($sJSONRAW) If @error Then Exit MsgBox(0,"Erro", "Error " & @error & " during parsing the JSON string") ; print to console to check the structure of the input JSON string ConsoleWrite("------- Input --------- " & @CRLF & _JSON_Generate($vJSON) & @CRLF & @CRLF) ; determine the number of elements already in the array "themes" Global $iNewIdx = UBound($vJSON["themes"]) ; add the new theme at the first free index: _JSON_addChangeDelete($vJSON, "theme", "Default Theme Test") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].name", "Default Theme Test") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].tab.background", "#00000020") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].tab.unfocusedBackground", "#00000000") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].tabRow.background", "#00000000") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].tabRow.unfocusedBackground", "#00000000") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].window.applicationTheme", "dark") _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "].window.useMica", true) ; create JSON string out of the AutoIt datastructure and print it to the console ConsoleWrite("------- Output --------- " & @CRLF & _JSON_Generate($vJSON) & @CRLF & @CRLF) Exactly - after _JSON_Parse() the whole thing no longer has anything to do with JSON but you have completely normal AutoIt data structures. However, this data is heavily nested. In AutoIt you can easily read information from nested data structures. But changing them is extremely cumbersome. To simplify exactly this, there is the _JSON_addChangeDelete() which (contrary to its name) has nothing to do with JSON but takes care of nested AutoIt data structures. The "cleaner" way mentioned is therefore already the way that _JSON_addChangeDelete() takes, as it changes the data at AutoIt level - just with a simpler interface than building the nested array element manually. Btw:, here's a little trick: With structures as complex as your theme description, you don't have to add everything manually. If you already know the structure beforehand, then simply describe it directly in JSON, have the theme element created completely from it and add it as a whole. In other words, you can replace the entire _JSON_addChangeDelete() in the example with a single one (similar to the jq example above): _JSON_addChangeDelete($vJSON, "themes[" & $iNewIdx & "]", _JSON_Parse('{"name":"Default Theme Test","tab":{"background":"#00000020","unfocusedBackground":"#00000000"},"tabRow":{"background":"#00000000","unfocusedBackground":"#00000000"},"window":{"applicationTheme":"dark","useMica":true}}'))
    3 points
  13. smbape

    OpenCV v4 UDF

    Update OpenCV to 4.12.0
    3 points
  14. Hello everyone, I'm excited to share a new AutoIt UDF library: SafeArray UDF. This library simplifies working with COM SafeArrays and VARIANT structures, making it easier to interact with COM objects (like Excel, ADO, or other applications) in AutoIt scripts. Key Features Bidirectional Conversion: Convert AutoIt arrays to COM SafeArrays and vice versa (up to 5 dimensions). SafeArray Management: Create, modify, access, and destroy SafeArrays using functions like _SafeArrayCreate, _SafeArrayGetElement, _SafeArrayPutElement, and _SafeArrayDestroy. VARIANT Support: Convert AutoIt data (integers, strings, arrays, COM objects) to VARIANTs and back with _VariantSet and _VariantRead. BSTR Handling: Allocate, read, and free COM strings with _SysAllocString, _SysReadString, and _SysFreeString. 32/64-bit Compatibility: Works with AutoIt 3.3+ without external dependencies, except Date.au3 for $VT_DATE types. Error Handling: Uses @error to report issues (e.g., invalid pointers, incorrect dimensions). Why Use This UDF? SafeArrays are a standard for passing multi-dimensional arrays in COM interfaces. This UDF streamlines their use in AutoIt, eliminating the complexity of direct DLL calls. It’s perfect for working with COM applications like Excel or databases via ADO that rely on SafeArrays. Simple Example #include "SafeArray.au3" Func Example_VT_FILETIME() Local $tVar = DllStructCreate($tagVARIANT) Local $tSystemTime = _Date_Time_GetSystemTime() Local $tFileTime = _Date_Time_SystemTimeToFileTime($tSystemTime) ; Set the FILETIME into the VARIANT _VariantSet(DllStructGetPtr($tVar), $tFileTime, $VT_FILETIME) ; Read the FILETIME from the VARIANT Local $sDateTime = _VariantRead(DllStructGetPtr($tVar)) ConsoleWrite("VT_FILETIME: " & $sDateTime & @CRLF) ; Should display current date/time ; Clean up _VariantClear(DllStructGetPtr($tVar)) EndFunc ;==>Example_VT_FILETIME ; Run the example Example_VT_FILETIME() #include "SafeArray.au3" Func Example_VariantTypes1() Local $tVar = DllStructCreate($tagVARIANT) ; Test VT_DATE _VariantSet(DllStructGetPtr($tVar), "2025/08/03 12:34:56", $VT_DATE) ConsoleWrite("VT_DATE: " & _VariantRead(DllStructGetPtr($tVar)) & @CRLF) ; Devrait afficher 2025/08/03 12:34:56 ; Test VT_IDISPATCH Local $oObj = ObjCreate("Scripting.Dictionary") _VariantSet(DllStructGetPtr($tVar), $oObj, $VT_DISPATCH) Local $oRead = _VariantRead(DllStructGetPtr($tVar)) ConsoleWrite("VT_IDISPATCH IsObj: " & IsObj($oRead) & @CRLF) _VariantClear(DllStructGetPtr($tVar)) EndFunc ;==>Example_VariantTypes1 Example_VariantTypes1() #include "SafeArray.au3" #include<WinAPICom.au3> Func _VariantTypes() Local $tVar = DllStructCreate($tagVARIANT) ; Test VT_DATE _VariantSet(DllStructGetPtr($tVar), "2025/08/03 12:34:56", $VT_DATE) ConsoleWrite("VT_DATE: " & _VariantRead(DllStructGetPtr($tVar)) & @CRLF) ; Devrait afficher 2025/08/03 12:34:56 ;VT_CLSID Local $oGUID = _WinAPI_CreateGUID() _VariantSet(DllStructGetPtr($tVar), $oGUID, $VT_CLSID) Local $oGUIDRead = _VariantRead(DllStructGetPtr($tVar)) ConsoleWrite("VT_CLSID : " & $oGUIDRead & @CRLF) _VariantClear(DllStructGetPtr($tVar)) EndFunc ;==>Example_VariantTypes _VariantTypes() SafeArray.zip SafeArray.au3
    3 points
  15. Released v1.0.14 today! Changed Node package update. Sets editor.minimap.showRegionSectionHeaders to false for AutoIt scripts. Optimized editor command registrations. Enhancements to syntax definition file. Fixed Usage of wrong Au3Check encoding for the file path string. View and Rate on VSCode Marketplace View and Rate on OpenVSX Star, Submit Issues, and Contribute on GitHub
    3 points
  16. I want to share a framework that I am using in my "Taskbar Program" project. ; =============================================================================================================================== ; SCRIPT: Controller-Worker-Task Manager Framework ; AUTHOR: Dao Van Trong - TRONG.PRO ; VERSION: 4.0 (Optimized, INI-driven, Tray-Only) ; DESCRIPTION: This script implements a robust Controller-Worker-Task architecture for running background processes. ; It is designed to be a flexible framework for automation tasks. ; ; ARCHITECTURE: ; - Controller: The main process that runs persistently. It has no GUI and is controlled entirely via a system tray icon. ; Its responsibilities include: ; 1. Reading the configuration from 'Configs.ini'. ; 2. Creating and managing the tray menu. ; 3. Starting, stopping, and monitoring Worker processes. ; 4. Launching one-shot Task processes. ; 5. Automatically reloading the configuration when 'Configs.ini' is modified. ; ; - Workers: Long-running background processes that perform recurring tasks (e.g., monitoring, syncing). ; They are started and stopped by the Controller and run completely hidden. ; Each worker monitors the Controller and will self-terminate if the Controller exits. ; ; - Tasks: Short-lived background processes that perform a single, one-shot action (e.g., generate a report). ; They can be configured to run exclusively (locking all other tasks) or concurrently. ; They can also be configured to run as a separate sub-process or directly within the Controller's process. ; ; HOW IT WORKS: ; - IPC (Inter-Process Communication): Communication between the Controller and Workers is handled via the Windows Registry. ; The Controller writes a signal to a specific registry key to gracefully shut down a Worker. ; - Asynchronous Operations: All monitoring (process status, config file changes) and Worker functions are handled ; asynchronously using AdlibRegister, ensuring the Controller remains responsive. ; - Configuration: All Workers and Tasks are defined in the master arrays within this script, but they are enabled, ; disabled, and configured via an external 'Configs.ini' file. This allows for easy customization without ; modifying the source code. ; - Logging: The script generates a detailed log file ('manager.log') in the same directory, recording all major ; events like startup, shutdown, worker status changes, and errors. ; =============================================================================================================================== #include <TrayConstants.au3> #include <Array.au3> #include <File.au3> #include <FileConstants.au3> ; =============================================================================================================================== ; --- GLOBAL CONSTANTS AND VARIABLES ; =============================================================================================================================== ; --- Settings --- Global Const $g_sConfigFile = @ScriptDir & "\Configs.ini" Global Const $g_sLogFile = @ScriptDir & "\Manager.log" Global $g_sAppName = "Controller-Worker-Task Manager" Global $g_iCheckConfigInterval = 10000 Global $g_sLastConfigModDate = "" ; --- Registry & IPC --- Global Const $g_sRegBase = "HKCU\Software\ControllerWorkerApp" Global Const $g_iAdlibCheckInterval = 1000 Global Const $g_iGracefulShutdownTimeout = 3000 ; --- Status Constants for internal logic --- Global Const $STATUS_STOPPED = 0, $STATUS_RUNNING = 1, $STATUS_ERROR = 2 ; --- Task Execution Mode & Type Constants --- Global Const $TASK_MODE_EXCLUSIVE = 0, $TASK_MODE_CONCURRENT = 1 Global Const $TASK_RUN_TYPE_SUBAPP = 0, $TASK_RUN_TYPE_DIRECT = 1 ; --- Menu Type Constants --- Global Const $MENU_TYPE_MAIN = 0, $MENU_TYPE_SUB = 1 ; --- MASTER DATA STRUCTURES (Hard-coded definitions) --- ; [InternalName, DisplayName, FunctionName, MenuType] Global Const $g_aMasterWorkers[10][4] = [ _ ["CheckResources", "Check Resources", "Worker1Function", $MENU_TYPE_MAIN], _ ["SyncFiles", "Sync Files", "Worker2Function", $MENU_TYPE_MAIN], _ ["MonitorNetwork", "Monitor Network", "Worker3Function", $MENU_TYPE_MAIN], _ ["BackupDB", "Backup DB", "Worker4Function", $MENU_TYPE_SUB], _ ["CleanupLogs", "Cleanup Logs", "Worker5Function", $MENU_TYPE_SUB], _ ["ProcessEmails", "Process Emails", "Worker6Function", $MENU_TYPE_SUB], _ ["AutoScreenshot", "Auto Screenshot", "Worker7Function", $MENU_TYPE_SUB], _ ["MonitorTemp", "Monitor Temp", "Worker8Function", $MENU_TYPE_SUB], _ ["CheckUpdates", "Check Updates", "Worker9Function", $MENU_TYPE_SUB], _ ["SecurityScan", "Security Scan", "Worker10Function", $MENU_TYPE_SUB] _ ] ; [InternalName, DisplayName, FunctionName, MenuType, ExecutionMode, RunType] Global Const $g_aMasterTasks[10][6] = [ _ ["QuickCleanup", "Quick Cleanup", "TaskA_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_SUBAPP], _ ["GenerateReport", "Generate Report", "TaskB_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_SUBAPP], _ ["SendNotification", "Send Notification (Direct)", "TaskJ_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_DIRECT], _ ["TaskC", "Run Task C (Direct)", "TaskC_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_DIRECT], _ ["TaskD", "Run Task D", "TaskD_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP], _ ["TaskE", "Run Task E", "TaskE_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP], _ ["TaskF", "Run Task F", "TaskF_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP], _ ["TaskG", "Run Task G", "TaskG_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP], _ ["TaskH", "Run Task H", "TaskH_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP], _ ["TaskI", "Run Task I", "TaskI_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP] _ ] ; --- Dynamic Data Structures (Populated from Master based on INI) --- Global $g_aWorkers, $g_iNumWorkers Global $g_aTasks, $g_iNumTasks ; --- Tray Menu Control Variables --- Global $g_aWorkerTrayItems[1], $g_aTaskTrayItems[1], $g_iTrayExit ; --- Shared Global Variables for Worker processes --- Global $g_sWorkerInternalName, $g_iControllerPID, $g_sWorkerRegKey ; =============================================================================================================================== ; --- MAIN SCRIPT LOGIC ; =============================================================================================================================== _Main() ;/** ; * @brief Main entry point of the script. ; * ; * Determines whether to run as the Controller or as a sub-process (Worker/Task) ; * based on the command-line arguments. ; */ Func _Main() If $CmdLine[0] > 0 Then Local $aCmd = StringSplit($CmdLine[1], ":") If $aCmd[0] < 2 Then Exit Local $sType = $aCmd[1], $sInternalName = $aCmd[2], $iControllerPID = ($CmdLine[0] > 1 ? $CmdLine[2] : 0) Switch $sType Case "worker" _RunAsWorker($sInternalName, $iControllerPID) Case "task" _RunAsTask($sInternalName) EndSwitch Else _RunAsController() EndIf EndFunc ;==>_Main ; =============================================================================================================================== ; --- CONTROLLER FUNCTIONS ; =============================================================================================================================== ;/** ; * @brief Initializes the Controller process. ; * ; * This function sets up the entire Controller environment: ; * 1. Cleans up any leftover registry keys from previous runs. ; * 2. Loads the configuration from Configs.ini. ; * 3. Creates the tray menu. ; * 4. Registers Adlib functions for background monitoring. ; * 5. Starts the main event loop. ; */ Func _RunAsController() _CleanupAllRegistryKeys() _LoadConfiguration() _CreateTrayMenu() AdlibRegister("_CheckStatus_Adlib", $g_iAdlibCheckInterval) AdlibRegister("_CheckForConfigChanges_Adlib", $g_iCheckConfigInterval) _WriteLog("INFO: Controller started successfully.") _ControllerMainLoop() EndFunc ;==>_RunAsController ;/** ; * @brief Loads and parses the configuration from Configs.ini. ; * ; * If Configs.ini exists, it reads the settings and the disable lists. ; * If not, it uses the default configuration (all master items enabled). ; * It then populates the dynamic $g_aWorkers and $g_aTasks arrays with only the enabled items. ; * This function is optimized to count items first, then Dim the arrays once to avoid ReDim in a loop. ; */ Func _LoadConfiguration() Local $sDisabledWorkers = "", $sDisabledTasks = "" If FileExists($g_sConfigFile) Then $g_sLastConfigModDate = FileGetTime($g_sConfigFile, $FT_MODIFIED, $FT_STRING) $g_sAppName = IniRead($g_sConfigFile, "Settings", "AppName", "Controller Framework") $g_iCheckConfigInterval = IniRead($g_sConfigFile, "Settings", "CheckConfigInterval", 10000) $sDisabledWorkers = "," & IniRead($g_sConfigFile, "Workers", "Disable", "") & "," $sDisabledTasks = "," & IniRead($g_sConfigFile, "Tasks", "Disable", "") & "," Else $g_sLastConfigModDate = "" $sDisabledWorkers = "," $sDisabledTasks = "," EndIf Local $iWorkerCount = 0, $iTaskCount = 0 For $i = 0 To UBound($g_aMasterWorkers) - 1 If Not StringInStr($sDisabledWorkers, "," & $g_aMasterWorkers[$i][0] & ",") Then $iWorkerCount += 1 Next For $i = 0 To UBound($g_aMasterTasks) - 1 If Not StringInStr($sDisabledTasks, "," & $g_aMasterTasks[$i][0] & ",") Then $iTaskCount += 1 Next $g_iNumWorkers = $iWorkerCount $g_iNumTasks = $iTaskCount Dim $g_aWorkers[$g_iNumWorkers][7] Dim $g_aTasks[$g_iNumTasks][7] Local $iWorkerIdx = 0, $iTaskIdx = 0 For $i = 0 To UBound($g_aMasterWorkers) - 1 Local $sInternalName = $g_aMasterWorkers[$i][0] If StringInStr($sDisabledWorkers, "," & $sInternalName & ",") Then ContinueLoop $g_aWorkers[$iWorkerIdx][0] = $sInternalName $g_aWorkers[$iWorkerIdx][1] = $g_aMasterWorkers[$i][1] $g_aWorkers[$iWorkerIdx][2] = $g_aMasterWorkers[$i][2] $g_aWorkers[$iWorkerIdx][3] = 0 $g_aWorkers[$iWorkerIdx][4] = False $g_aWorkers[$iWorkerIdx][5] = $STATUS_STOPPED $g_aWorkers[$iWorkerIdx][6] = $g_aMasterWorkers[$i][3] $iWorkerIdx += 1 Next For $i = 0 To UBound($g_aMasterTasks) - 1 Local $sInternalName = $g_aMasterTasks[$i][0] If StringInStr($sDisabledTasks, "," & $sInternalName & ",") Then ContinueLoop $g_aTasks[$iTaskIdx][0] = $sInternalName $g_aTasks[$iTaskIdx][1] = $g_aMasterTasks[$i][1] $g_aTasks[$iTaskIdx][2] = $g_aMasterTasks[$i][2] $g_aTasks[$iTaskIdx][3] = 0 $g_aTasks[$iTaskIdx][4] = $g_aMasterTasks[$i][4] $g_aTasks[$iTaskIdx][5] = $g_aMasterTasks[$i][5] $g_aTasks[$iTaskIdx][6] = $g_aMasterTasks[$i][3] $iTaskIdx += 1 Next EndFunc ;==>_LoadConfiguration ;/** ; * @brief Creates the entire tray menu structure based on the loaded configuration. ; * ; * It iterates through the dynamic $g_aWorkers and $g_aTasks arrays and creates ; * main menu items or sub-menu items based on their MenuType property. ; * This ensures that the menu item index directly corresponds to the data array index. ; */ Func _CreateTrayMenu() Opt("TrayMenuMode", 3) TraySetToolTip($g_sAppName) ReDim $g_aWorkerTrayItems[$g_iNumWorkers] ReDim $g_aTaskTrayItems[$g_iNumTasks] Local $hSubWorkersMenu = 0, $hSubTasksMenu = 0 For $i = 0 To $g_iNumWorkers - 1 If $g_aWorkers[$i][6] = $MENU_TYPE_MAIN Then $g_aWorkerTrayItems[$i] = TrayCreateItem("[OFF] " & $g_aWorkers[$i][1]) Else If $hSubWorkersMenu = 0 Then $hSubWorkersMenu = TrayCreateMenu("Sub Workers") $g_aWorkerTrayItems[$i] = TrayCreateItem("[OFF] " & $g_aWorkers[$i][1], $hSubWorkersMenu) EndIf Next TrayCreateItem("") For $i = 0 To $g_iNumTasks - 1 If $g_aTasks[$i][6] = $MENU_TYPE_MAIN Then $g_aTaskTrayItems[$i] = TrayCreateItem($g_aTasks[$i][1]) Else If $hSubTasksMenu = 0 Then $hSubTasksMenu = TrayCreateMenu("Sub Tasks") $g_aTaskTrayItems[$i] = TrayCreateItem($g_aTasks[$i][1], $hSubTasksMenu) EndIf Next TrayCreateItem("") $g_iTrayExit = TrayCreateItem("Exit") TraySetState(1) EndFunc ;==>_CreateTrayMenu ;/** ; * @brief The main event loop for the Controller. ; * ; * It waits for and dispatches tray menu click events to the appropriate handler functions. ; */ Func _ControllerMainLoop() While 1 Local $iTrayMsg = TrayGetMsg() Switch $iTrayMsg Case 0 Case $g_iTrayExit _ExitController() Case Else Local $iIndex = _GetIndexFromTrayID($iTrayMsg, $g_aWorkerTrayItems) If $iIndex <> -1 Then _HandleWorkerClick($iIndex) ContinueLoop EndIf $iIndex = _GetIndexFromTrayID($iTrayMsg, $g_aTaskTrayItems) If $iIndex <> -1 Then _HandleTaskClick($iIndex) ContinueLoop EndIf EndSwitch Sleep(100) WEnd EndFunc ;==>_ControllerMainLoop ;/** ; * @brief Handles a click on a Worker menu item. ; * @param $iIndex The index of the clicked worker in the $g_aWorkers array. ; */ Func _HandleWorkerClick($iIndex) _UpdateWorkerState($iIndex, Not $g_aWorkers[$iIndex][4]) EndFunc ;==>_HandleWorkerClick ;/** ; * @brief Handles a click on a Task menu item. ; * @param $iIndex The index of the clicked task in the $g_aTasks array. ; */ Func _HandleTaskClick($iIndex) _RunTask($iIndex) EndFunc ;==>_HandleTaskClick ;/** ; * @brief Central function to change a worker's state (on/off). ; * @param $iIndex The index of the worker. ; * @param $bNewState The new state to apply (True for ON, False for OFF). ; */ Func _UpdateWorkerState($iIndex, $bNewState) $g_aWorkers[$iIndex][4] = $bNewState If $bNewState Then _StartWorker($iIndex) Else _StopWorker($iIndex) EndIf _UpdateTrayItemForWorker($iIndex) EndFunc ;==>_UpdateWorkerState ;/** ; * @brief Updates a worker's tray menu item text and checked state. ; * @param $iIndex The index of the worker. ; */ Func _UpdateTrayItemForWorker($iIndex) Local $sPrefix, $iTrayState If $g_aWorkers[$iIndex][4] Then $sPrefix = "[ON] " $iTrayState = $TRAY_CHECKED Else $sPrefix = "[OFF] " $iTrayState = $TRAY_UNCHECKED EndIf TrayItemSetText($g_aWorkerTrayItems[$iIndex], $sPrefix & $g_aWorkers[$iIndex][1]) TrayItemSetState($g_aWorkerTrayItems[$iIndex], $iTrayState) EndFunc ;==>_UpdateTrayItemForWorker ;/** ; * @brief Starts a worker sub-process. ; * @param $iIndex The index of the worker. ; */ Func _StartWorker($iIndex) If ProcessExists($g_aWorkers[$iIndex][3]) Then Return Local $sCommand = 'worker:' & $g_aWorkers[$iIndex][0] _WriteLog("INFO: Starting Worker '" & $g_aWorkers[$iIndex][1] & "'...") Local $iPID = _RunScript($sCommand) If $iPID > 0 Then $g_aWorkers[$iIndex][3] = $iPID $g_aWorkers[$iIndex][5] = $STATUS_RUNNING Else _WriteLog("ERROR: Failed to start Worker '" & $g_aWorkers[$iIndex][1] & "'.") $g_aWorkers[$iIndex][4] = False $g_aWorkers[$iIndex][5] = $STATUS_ERROR EndIf EndFunc ;==>_StartWorker ;/** ; * @brief Stops a worker sub-process gracefully. ; * @param $iIndex The index of the worker. ; */ Func _StopWorker($iIndex) Local $iPID = $g_aWorkers[$iIndex][3] If $iPID = 0 Or Not ProcessExists($iPID) Then $g_aWorkers[$iIndex][3] = 0 $g_aWorkers[$iIndex][5] = $STATUS_STOPPED Return EndIf _WriteLog("INFO: Stopping Worker '" & $g_aWorkers[$iIndex][1] & "' (PID: " & $iPID & ")...") Local $sRegKey = $g_sRegBase & "\" & $g_aWorkers[$iIndex][0] RegWrite($sRegKey, "Signal", "REG_SZ", "exit") If @error Then _WriteLog("ERROR: Failed to write exit signal to registry for " & $g_aWorkers[$iIndex][0]) Local $iResult = ProcessWaitClose($iPID, $g_iGracefulShutdownTimeout / 1000) If $iResult = 0 Then _WriteLog("WARN: Worker PID " & $iPID & " did not respond. Forcing shutdown.") ProcessClose($iPID) EndIf RegDelete($sRegKey) $g_aWorkers[$iIndex][3] = 0 $g_aWorkers[$iIndex][5] = $STATUS_STOPPED EndFunc ;==>_StopWorker ;/** ; * @brief Runs a task either directly or as a sub-process. ; * @param $iIndex The index of the task. ; */ Func _RunTask($iIndex) Local $sTaskName = $g_aTasks[$iIndex][1] _WriteLog("INFO: Running Task '" & $sTaskName & "'...") If $g_aTasks[$iIndex][5] = $TASK_RUN_TYPE_DIRECT Then TrayItemSetState($g_aTaskTrayItems[$iIndex], $TRAY_DISABLE) Call($g_aTasks[$iIndex][2], $sTaskName) TrayItemSetState($g_aTaskTrayItems[$iIndex], $TRAY_ENABLE) _WriteLog("INFO: Direct Task '" & $sTaskName & "' has completed.") Else If $g_aTasks[$iIndex][3] <> 0 And ProcessExists($g_aTasks[$iIndex][3]) Then Return Local $sCommand = 'task:' & $g_aTasks[$iIndex][0] Local $iPID = _RunScript($sCommand, False) If $iPID > 0 Then $g_aTasks[$iIndex][3] = $iPID _UpdateAllTaskMenusState() Else _WriteLog("ERROR: Failed to run Task '" & $sTaskName & "'.") EndIf EndIf EndFunc ;==>_RunTask ;/** ; * @brief Adlib function to monitor the status of running workers and tasks. ; */ Func _CheckStatus_Adlib() For $i = 0 To $g_iNumWorkers - 1 If $g_aWorkers[$i][4] And Not ProcessExists($g_aWorkers[$i][3]) Then _WriteLog("WARN: Worker '" & $g_aWorkers[$i][1] & "' died. Restarting...") $g_aWorkers[$i][5] = $STATUS_ERROR _UpdateTrayItemForWorker($i) _StartWorker($i) EndIf Next Local $bTaskStateChanged = False For $i = 0 To $g_iNumTasks - 1 If $g_aTasks[$i][5] = $TASK_RUN_TYPE_SUBAPP And $g_aTasks[$i][3] > 0 And Not ProcessExists($g_aTasks[$i][3]) Then $g_aTasks[$i][3] = 0 $bTaskStateChanged = True EndIf Next If $bTaskStateChanged Then _UpdateAllTaskMenusState() EndFunc ;==>_CheckStatus_Adlib ;/** ; * @brief Checks if any exclusive task is currently running as a sub-process. ; * @return True if an exclusive task is running, otherwise False. ; */ Func _IsExclusiveTaskRunning() For $i = 0 To $g_iNumTasks - 1 If $g_aTasks[$i][4] = $TASK_MODE_EXCLUSIVE And $g_aTasks[$i][3] > 0 And ProcessExists($g_aTasks[$i][3]) Then Return True EndIf Next Return False EndFunc ;==>_IsExclusiveTaskRunning ;/** ; * @brief Updates the enabled/disabled state of all task menu items based on current activity. ; */ Func _UpdateAllTaskMenusState() Local $bExclusiveRunning = _IsExclusiveTaskRunning() For $i = 0 To $g_iNumTasks - 1 If $bExclusiveRunning Then TrayItemSetState($g_aTaskTrayItems[$i], $TRAY_DISABLE) Else If $g_aTasks[$i][3] > 0 And ProcessExists($g_aTasks[$i][3]) Then TrayItemSetState($g_aTaskTrayItems[$i], $TRAY_DISABLE) Else TrayItemSetState($g_aTaskTrayItems[$i], $TRAY_ENABLE) EndIf EndIf Next EndFunc ;==>_UpdateAllTaskMenusState ;/** ; * @brief Adlib function to check for modifications to the Configs.ini file. ; */ Func _CheckForConfigChanges_Adlib() Local $iCurrentModDate = FileGetTime($g_sConfigFile, $FT_MODIFIED, $FT_STRING) If $iCurrentModDate <> $g_sLastConfigModDate Then _WriteLog("INFO: Configuration file change detected. Reloading...") _UnregisterAllMasterAdlibs() _StopAllWorkers() TraySetState(2) _LoadConfiguration() _CreateTrayMenu() _WriteLog("INFO: Configuration reloaded and menu recreated.") EndIf EndFunc ;==>_CheckForConfigChanges_Adlib ;/** ; * @brief Stops all currently active workers. ; */ Func _StopAllWorkers() For $i = 0 To $g_iNumWorkers - 1 If $g_aWorkers[$i][4] Then _StopWorker($i) Next EndFunc ;==>_StopAllWorkers ;/** ; * @brief A generic function to run the script as a sub-process. ; * @param $sArgument The argument to pass to the new process (e.g., "worker:MyWorker"). ; * @param $bPassControllerPID If True, the current controller's PID is passed as the second argument. ; * @return The PID of the new process, or 0 on failure. ; */ Func _RunScript($sArgument, $bPassControllerPID = True) Local $sControllerPID = ($bPassControllerPID ? " " & @AutoItPID : "") Local $sCommand = '"' & @ScriptFullPath & '" "' & $sArgument & '"' & $sControllerPID Local $sExecutable = (@Compiled ? "" : '"' & @AutoItExe & '" ') Return Run($sExecutable & $sCommand, @ScriptDir, @SW_HIDE) EndFunc ;==>_RunScript ;/** ; * @brief Performs all necessary cleanup before the Controller exits. ; */ Func _ExitController() _WriteLog("INFO: Controller shutting down...") _UnregisterAllMasterAdlibs() _CleanupAllRegistryKeys() _StopAllWorkers() Exit EndFunc ;==>_ExitController ;/** ; * @brief Unregisters all possible Adlib callbacks defined in the master lists. ; * ; * This is a crucial cleanup step to prevent orphaned callbacks, especially when reloading the configuration. ; */ Func _UnregisterAllMasterAdlibs() AdlibUnRegister("_CheckStatus_Adlib") AdlibUnRegister("_CheckForConfigChanges_Adlib") For $i = 0 To UBound($g_aMasterWorkers) - 1 AdlibUnRegister($g_aMasterWorkers[$i][2]) Next EndFunc ;==>_UnregisterAllMasterAdlibs ;/** ; * @brief Deletes the entire registry key used by the application for IPC. ; */ Func _CleanupAllRegistryKeys() RegDelete($g_sRegBase) If @error Then _WriteLog("ERROR: Failed to delete base registry key: " & $g_sRegBase) EndFunc ;==>_CleanupAllRegistryKeys ;/** ; * @brief Finds the array index corresponding to a given tray item ID. ; * @param $nID The tray item ID to find. ; * @param $aTrayItems The array of tray item IDs to search in. ; * @return The array index if found, otherwise -1. ; */ Func _GetIndexFromTrayID($nID, ByRef $aTrayItems) For $i = 0 To UBound($aTrayItems) - 1 If $aTrayItems[$i] = $nID Then Return $i Next Return -1 EndFunc ;==>_GetIndexFromTrayID ;/** ; * @brief Writes a message to both the console and the log file. ; * ; * This function provides a synchronized way to log events. Opening and closing the file ; * for each write minimizes the chance of file corruption from multiple processes. ; * @param $sMessage The message to log. ; */ Func _WriteLog($sMessage) Local $sTimeStamp = @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC Local $sFormattedMessage = $sTimeStamp & " - " & $sMessage & @CRLF ConsoleWrite($sFormattedMessage) Local $hFile = FileOpen($g_sLogFile, 2 + 8) ; Open in Write + Append mode to lock the file during write If $hFile = -1 Then Return FileWrite($hFile, $sFormattedMessage) FileClose($hFile) EndFunc ;==>_WriteLog ; =============================================================================================================================== ; --- WORKER / TASK SUB-PROCESS EXECUTION ; =============================================================================================================================== ;/** ; * @brief Initializes the script when run as a Worker sub-process. ; * @param $sInternalName The internal name of the worker to run. ; * @param $iControllerPID The PID of the parent Controller process to monitor. ; */ Func _RunAsWorker($sInternalName, $iControllerPID) $g_sWorkerInternalName = $sInternalName $g_iControllerPID = $iControllerPID $g_sWorkerRegKey = $g_sRegBase & "\" & $sInternalName RegDelete($g_sWorkerRegKey) Local $sFunction = "" For $i = 0 To UBound($g_aMasterWorkers) - 1 If $g_aMasterWorkers[$i][0] = $sInternalName Then $sFunction = $g_aMasterWorkers[$i][2] ExitLoop EndIf Next If $sFunction = "" Then Exit AdlibRegister($sFunction, 1000) AdlibRegister("_WorkerHeartbeat_Adlib", 2000) While 1 Sleep(100) WEnd EndFunc ;==>_RunAsWorker ;/** ; * @brief Adlib function for workers to monitor the Controller and exit signals. ; */ Func _WorkerHeartbeat_Adlib() If $g_iControllerPID > 0 And Not ProcessExists($g_iControllerPID) Then _WorkerExitGracefully() EndIf RegRead($g_sWorkerRegKey, "Signal") If @error Then _WorkerExitGracefully() Return EndIf If RegRead($g_sWorkerRegKey, "Signal") = "exit" Then _WorkerExitGracefully() EndIf EndFunc ;==>_WorkerHeartbeat_Adlib ;/** ; * @brief Performs all necessary cleanup for a Worker before it exits. ; */ Func _WorkerExitGracefully() AdlibUnRegister("_WorkerHeartbeat_Adlib") Local $sFunction = "" For $i = 0 To UBound($g_aMasterWorkers) - 1 If $g_aMasterWorkers[$i][0] = $g_sWorkerInternalName Then $sFunction = $g_aMasterWorkers[$i][2] ExitLoop EndIf Next If $sFunction <> "" Then AdlibUnRegister($sFunction) RegDelete($g_sWorkerRegKey) Exit EndFunc ;==>_WorkerExitGracefully ;/** ; * @brief Initializes the script when run as a Task sub-process. ; * @param $sInternalName The internal name of the task to run. ; */ Func _RunAsTask($sInternalName) Local $sFunction, $sDisplayName For $i = 0 To UBound($g_aMasterTasks) - 1 If $g_aMasterTasks[$i][0] = $sInternalName Then $sDisplayName = $g_aMasterTasks[$i][1] $sFunction = $g_aMasterTasks[$i][2] ExitLoop EndIf Next If $sFunction = "" Then Exit Call($sFunction, $sDisplayName) Exit EndFunc ;==>_RunAsTask ; =============================================================================================================================== ; --- SPECIFIC WORKER/TASK FUNCTIONS (IMPLEMENTATION) ; =============================================================================================================================== Func Worker1Function() _WriteLog("Worker 'Check Resources' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker1Function Func Worker2Function() _WriteLog("Worker 'Sync Files' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker2Function Func Worker3Function() _WriteLog("Worker 'Monitor Network' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker3Function Func Worker4Function() _WriteLog("Worker 'Backup DB' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker4Function Func Worker5Function() _WriteLog("Worker 'Cleanup Logs' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker5Function Func Worker6Function() _WriteLog("Worker 'Process Emails' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker6Function Func Worker7Function() _WriteLog("Worker 'Auto Screenshot' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker7Function Func Worker8Function() _WriteLog("Worker 'Monitor Temp' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker8Function Func Worker9Function() _WriteLog("Worker 'Check Updates' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker9Function Func Worker10Function() _WriteLog("Worker 'Security Scan' is running...") ; This is PlaceHoder - Your Code Repalce Here EndFunc ;==>Worker10Function Func TaskA_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(2000) EndFunc ;==>TaskA_Function Func TaskB_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(3000) EndFunc ;==>TaskB_Function Func TaskC_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskC_Function Func TaskD_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskD_Function Func TaskE_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskE_Function Func TaskF_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskF_Function Func TaskG_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskG_Function Func TaskH_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskH_Function Func TaskI_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1500) EndFunc ;==>TaskI_Function Func TaskJ_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Repalce Here Sleep(1000) EndFunc ;==>TaskJ_Function !
    3 points
  17. Uia and event hooks are different things. UIA cannot catch all. The event windows hooks are technically a deeper layer. For this example I would just find a message with an event spy and build an example for that in the help file. UIA cannot do much with java ui controls or browser things like playwright can do. So most likely there is not one UI interception framework. Yes, a uia udf as part of AutoIT would be nice but it's a lot of work.😀
    3 points
  18. You could grab the event sent by Excel before a workbook gets closed. Something like this: #include <Excel.au3> HotKeySet("+!e", "_Exit") ;Shift-Alt-E to Exit the script MsgBox(64, "Excel UDF: Events Example", "Hotkey to exit the script: 'Shift-Alt-E'!") ; Create application object and open a workbook Global $oExcel = _Excel_Open() Global $oWorkbook = _Excel_BookNew($oExcel) ObjEvent($oWorkbook, "Workbook_") While 1 Sleep(10) WEnd Exit Func Workbook_BeforeClose() MsgBox(0, "WorkbookBeforeClose", "Name: " & $oWorkbook.Name) _Excel_Close($oExcel) _Exit() EndFunc ;==>Workbook_BeforeClose Func _Exit() Exit EndFunc ;==>_Exit This example works for the workbook opened by this script. If the user opens and closes another workbook nothing will happen.
    3 points
  19. 1.8.6 released! Only one change, the help box that appears when writing function parameters should not dissapear, when adding "," anymore. It took me a while and the solution is not perfect, but it should be better than the previous experience
    3 points
  20. I can only test on my Notebook with Win11 24H2 and the solution was to set parent to the WorkerW handle under Progman. I found also the information after midnight to force WorkerW under Progman using DllCall("user32.dll", "lresult", "SendMessage","hwnd", $hProgman, "uint", 0x052C, "wparam", 0, "lparam", 0) but I was too sleepy to continue. ;Code by UEZ build 2025-07-18 beta #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;~ #include <WinAPIGdi.au3> ;~ #include <Array.au3> Global $aPrimary = GetPrimaryMonitorCoords() If @error Then Exit MsgBox(16, "Error", "Unable to get primary monitor") Global $hProgman = WinGetHandle("[CLASS:Progman]"), $hWorkerW, $i If Not $hProgman Then Exit MsgBox(16, "ERROR", "Couldn't find Progman", 30) _WinAPI_SendMessageTimeout($hProgman, 0x052C, 0, 0, 250, $SMTO_NORMAL) ;~ DllCall("user32.dll", "lresult", "SendMessage","hwnd", $hProgman, "uint", 0x052C, "wparam", 0, "lparam", 0) ;~ Sleep(250) ;~ $i = 1 ;~ While True ;~ $h = WinGetHandle("[CLASS:WorkerW;INSTANCE:" & $i & "]") ;~ $hWorkerW = _WinAPI_FindWindowEx($hProgman, $h, "WorkerW") ;~ If $hWorkerW Then ExitLoop ;~ $i += 1 ;~ If $i = 100 Then Exit MsgBox(16, "ERROR", "Couldn't find WorkerW under Progman", 30) ;~ WEnd Global $hWorkerW = _WinAPI_FindWindowEx($hProgman, 0, "WorkerW", "") If $hWorkerW = 0 Then Exit MsgBox(16, "ERROR", "Couldn't find WorkerW under Progman", 30) Local $aOrigin = GetDesktopOrigin() Local $iX = $aPrimary[0] - $aOrigin[0] Local $iY = $aPrimary[1] - $aOrigin[1] Global $hGUI = GUICreate("GUI behind Desktop icons", $aPrimary[4], $aPrimary[5], $iX, $iY, $WS_POPUP, $WS_EX_TOOLWINDOW) GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\msoobe.jpg", 0, 0, $aPrimary[4], $aPrimary[5]) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowPos($hGUI, $HWND_BOTTOM, 0, 0, 0, 0, BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE)) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED, $WS_EX_TRANSPARENT)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 220, $LWA_ALPHA) GUISetState(@SW_SHOWNOACTIVATE, $hGUI) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc ;==>_WinAPI_FindWindowEx Func GetPrimaryMonitorCoords() Local $tPoint = DllStructCreate("int x;int y") $tPoint.x = 0 $tPoint.y = 0 Local $hMonitor = _WinAPI_MonitorFromPoint($tPoint, $MONITOR_DEFAULTTOPRIMARY) If Not $hMonitor Then Return SetError(1, 0, 0) Local $tMI = DllStructCreate("dword cbSize;long rcMonitor[4];long rcWork[4];dword dwFlags") DllStructSetData($tMI, "cbSize", DllStructGetSize($tMI)) Local $aCall = DllCall("user32.dll", "bool", "GetMonitorInfoW", "handle", $hMonitor, "ptr", DllStructGetPtr($tMI)) If @error Or Not $aCall[0] Then Return SetError(2, 0, 0) Local $iLeft = $tMI.rcMonitor(1) Local $iTop = $tMI.rcMonitor(2) Local $iRight = $tMI.rcMonitor(3) Local $iBottom = $tMI.rcMonitor(4) Local $iWidth = $iRight - $iLeft Local $iHeight = $iBottom - $iTop Local $a[6] = [$iLeft, $iTop, $iRight, $iBottom, $iWidth, $iHeight] Return $a EndFunc ;==>GetPrimaryMonitorCoords Func GetDesktopOrigin() Local $minX = 0, $minY = 0, $x, $y Local $i = 0, $tDevice, $aRet, $tDevMode, $aED While True $tDevice = DllStructCreate("dword cb; char DeviceName[32]; char DeviceString[128]; dword StateFlags; char DeviceID[128]; char DeviceKey[128]") $tDevice.cb = DllStructGetSize($tDevice) $aRet = DllCall("user32.dll", "bool", "EnumDisplayDevicesA", "ptr", 0, "dword", $i, "ptr", DllStructGetPtr($tDevice), "dword", 0) If @error Or Not $aRet[0] Then ExitLoop If BitAND($tDevice.StateFlags, 1) Then $tDevMode = DllStructCreate( _ "byte dmDeviceName[32]; word dmSpecVersion; word dmDriverVersion; word dmSize; word dmDriverExtra; dword dmFields;" & _ "long dmPositionX; long dmPositionY; dword dmDisplayOrientation; dword dmDisplayFixedOutput;" & _ "short dmColor; short dmDuplex; short dmYResolution; short dmTTOption; short dmCollate; char dmFormName[32];" & _ "ushort dmLogPixels; dword dmBitsPerPel; dword dmPelsWidth; dword dmPelsHeight;" & _ "dword dmDisplayFlags; dword dmDisplayFrequency; dword dmICMMethod; dword dmICMIntent;" & _ "dword dmMediaType; dword dmDitherType; dword dmReserved1; dword dmReserved2; dword dmPanningWidth; dword dmPanningHeight") $tDevMode.dmSize = DllStructGetSize($tDevMode) $aED = DllCall("user32.dll", "bool", "EnumDisplaySettingsA", "str", $tDevice.DeviceName, "dword", -1, "ptr", DllStructGetPtr($tDevMode)) If Not @error And $aED[0] Then $x = $tDevMode.dmPositionX $y = $tDevMode.dmPositionY If $x < $minX Then $minX = $x If $y < $minY Then $minY = $y EndIf EndIf $i += 1 WEnd Local $a[2] = [$minX, $minY] Return $a EndFunc ;==>GetDesktopOrigin
    3 points
  21. It provides one of the WorkerW handles, not the WorkerW handle under Progman. 😉 This works for me: ;Code by UEZ build 2025-07-16 beta #include <WinAPI.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $hProgman = WinGetHandle("[CLASS:Progman]"), $hWorkerW, $i $i = 1 While True $h = WinGetHandle("[CLASS:WorkerW;INSTANCE:" & $i & "]") $hWorkerW = _WinAPI_FindWindowEx($hProgman, $h, "WorkerW", "") If $hWorkerW Then ExitLoop $i += 1 If $i = 100 Then Exit MsgBox(16, "ERROR", "Couldn't find WorkerW under Progman", 30) WEnd Global $SWP = BitOR($SWP_NOMOVE, $SWP_NOSIZE, $SWP_NOACTIVATE) $hGUI = GUICreate("Overlay", 400, 300, 10, 10, $WS_POPUP, $WS_EX_TOOLWINDOW) GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\msoobe.jpg", 0, 0, 400, 300) _WinAPI_SetParent($hGUI, $hWorkerW) _WinAPI_SetWindowPos($hGUI, $HWND_BOTTOM, 0,0,0,0, $SWP) _WinAPI_SetWindowLong($hGUI, $GWL_EXSTYLE, BitOR(_WinAPI_GetWindowLong($hGUI, $GWL_EXSTYLE), $WS_EX_LAYERED, $WS_EX_TRANSPARENT)) _WinAPI_SetLayeredWindowAttributes($hGUI, 0, 220, $LWA_ALPHA) GUISetState(@SW_SHOWNOACTIVATE, $hGUI) While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd Func _WinAPI_FindWindowEx($hParent, $hAfter, $sClass, $sTitle = "") Local $ret = DllCall("user32.dll", "hwnd", "FindWindowExW", "hwnd", $hParent, "hwnd", $hAfter, "wstr", $sClass, "wstr", $sTitle) If @error Or Not IsArray($ret) Then Return 0 Return $ret[0] EndFunc
    3 points
  22. I've created a label based solution for a simple status bar. May be it's interesting 4u. https://github.com/BugFix/AutoIt-Scripts/blob/main/Statusbar/statusbar_small.md#gallery
    3 points
  23. This works on my Win10 machine. #include <GUIConstantsEx.au3> #include <WinApi.au3> #include <WindowsConstants.au3> Global $hDeskWin = _WinGetDesktopHandle() Global $h_Desktop_SysListView32 = HWnd(@extended) Main() Func Main() Local $this = GUICreate("", 400, 400, @DesktopWidth - (400) - 20, 100, $WS_POPUP, $WS_EX_NOACTIVATE + $WS_EX_TRANSPARENT) _WinAPI_SetParent($this, $h_Desktop_SysListView32) Local $iPic = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\msoobe.jpg", 0, 0, 400, 400) ;GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) WinSetTrans($this, "", 200) _GuiRoundCorners($this, 16, 16) _WinAPI_SetWindowLong($this, $GWL_HWNDPARENT, ControlGetHandle("[CLASS:Progman]", "", "SysListView321")) ;hide in taskbar GUISetState(@SW_SHOWNOACTIVATE, $this) ;_WinAPI_SetWindowPos($this, $HWND_BOTTOM, Default, Default, Default, Default, BitOR($SWP_NOACTIVATE, $SWP_SHOWWINDOW, $SWP_NOMOVE, $SWP_NOSIZE )) ;not worked While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($this) EndFunc ;==>Main Func _GuiRoundCorners($h_win, $ixR, $iyR) Local $aPos = WinGetPos($h_win) If @error Then Return 0 Local $iW = $aPos[2] Local $iH = $aPos[3] Local $hRgn = _WinAPI_CreateRoundRectRgn(0, 0, $iW, $iH, $ixR, $iyR) _WinAPI_SetWindowRgn($h_win, $hRgn) EndFunc ;==>_GuiRoundCorners ; http://www.autoitscript.com/forum/topic/119783-desktop-class-workerw/page__view__findpost__p__903081 ; =============================================================================================================================== ; <_WinGetDesktopHandle.au3> ; ; Function to get the Windows' Desktop Handle. ; Since this is no longer a simple '[CLASS:Progman]' on Aero-enabled desktops, this method uses a slightly ; more involved method to find the correct Desktop Handle. ; ; Author: Ascend4nt, credits to Valik for pointing out the Parent->Child relationship: Desktop->'SHELLDLL_DefView' ; =============================================================================================================================== ; Example use: #cs #include <GuiListView.au3> $iTimer = TimerInit() $hDeskWin = _WinGetDesktopHandle() $hListView = HWnd(@extended) ConsoleWrite("Time elapsed:" & TimerDiff($iTimer) & " ms" & @CRLF) $iDeskItems = _GUICtrlListView_GetItemCount($hListView) ConsoleWrite("Handle to desktop: " & $hDeskWin & ", Title: '" & WinGetTitle($hDeskWin) & "', Handle to Listview: " & $hListView & ", # Items:" & $iDeskItems & ", Title: " & WinGetTitle($hListView) & @CRLF) MsgBox(0, "Desktop handle (with ListView) found", "Handle to desktop: " & $hDeskWin & ", Title: '" & WinGetTitle($hDeskWin) & "'," & @CRLF & "Handle to Listview: " & $hListView & @CRLF & "# Desktop Items:" & $iDeskItems) #ce Func _WinGetDesktopHandle() Local $i, $hDeskWin, $hSHELLDLL_DefView, $hListView ; The traditional Windows Classname for the Desktop, not always so on newer O/S's $hDeskWin = WinGetHandle("[CLASS:Progman]") ; Parent->Child relationship: Desktop->SHELLDLL_DefView $hSHELLDLL_DefView = ControlGetHandle($hDeskWin, '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]') ; No luck with finding the Desktop and/or child? If $hDeskWin = '' Or $hSHELLDLL_DefView = '' Then ; Look through a list of WorkerW windows - one will be the Desktop on Windows 7+ O/S's $aWinList = WinList("[CLASS:WorkerW]") For $i = 1 To $aWinList[0][0] $hSHELLDLL_DefView = ControlGetHandle($aWinList[$i][1], '', '[CLASS:SHELLDLL_DefView; INSTANCE:1]') If $hSHELLDLL_DefView <> '' Then $hDeskWin = $aWinList[$i][1] ExitLoop EndIf Next EndIf ; Parent->Child relationship: Desktop->SHELDLL_DefView->SysListView32 $hListView = ControlGetHandle($hSHELLDLL_DefView, '', '[CLASS:SysListView32; INSTANCE:1]') If $hListView = '' Then Return SetError(-1, 0, '') Return SetExtended($hListView, $hDeskWin) EndFunc ;==>_WinGetDesktopHandle
    3 points
  24. I tried to add these 2 controls (combo & input box) to my script found in this post with good results, on a maximizable / resizable GUI : These are the lines modified / added to the script, so you can try them too : 1) Lines modified : ; Local $iW = 300, $iH = 100 Local $iW = 600, $iH = 200 ; Local $aParts[3] = [90, 180, 280] Local $aParts[3] = [200, 400, 580] ; Local $idChangeText = GUICtrlCreateLabel("Change Text", 110, 25, 80, 30, $SS_CENTER + $SS_CENTERIMAGE), $iInc Local $idChangeText = GUICtrlCreateLabel("Change Text", $iW / 2 - 40, 50, 80, 30, $SS_CENTER + $SS_CENTERIMAGE), $iInc 2) Lines added : #include <ComboConstants.au3> ... Local $idComboBox = GUICtrlCreateCombo("Install", 100, 180, 100, 18, $CBS_DROPDOWNLIST) GUICtrlSetData($idComboBox, "Uninstall") GUICtrlSetBkColor(-1, 0xFF0000) ; red _WinAPI_SetParent(GUICtrlGetHandle($idComboBox), $g_hGUI) Local $idInput = GUICtrlCreateInput("Input in part 1", 300, 181, 100, 18) GUICtrlSetBkColor(-1, 0x00FF00) ; green _WinAPI_SetParent(GUICtrlGetHandle($idInput), $g_hGUI) * Please create $idComboBox and $idInput just after the label $idChangeText * IIRC your StatusBar height got a higher value, so you'll probably have to lower a bit the Y coord of both controls * Lucky me, I tried the _WinAPI_SetParent() on each control (combo & input), indicating... the GUI as parent and it "woke" them up both. Without this instruction, they didn't react, as you indicated. Hope it will work on your side, fingers crossed
    3 points
  25. Good news I found a way to display the vertical line constantly while dragging the horizontal scrollbar, with very few flickering. To do this : 1) Add the extended style $LVS_EX_DOUBLEBUFFER to your line _GUICtrlListView_SetExtendedListViewStyle(...) 2) In the code of my preceding post, please change one line as indicated below : ; If BitAND($wParam, 0xFFFF) = 0x4 Then ; LoWord . $SB_THUMBPOSITION = 0x4 . Msdn : "the user has dragged the scroll box (thumb) and released the mouse button" If BitAND($wParam, 0xFFFF) = 0x5 Then ; LoWord . $SB_THUMBTRACK = 0x5 . Msdn : "the user is dragging the scroll box"
    2 points
  26. Don't belittle yourself so much 😅 , your knowledge of AutoIt isn't bad at all. But I get your point @WildByDesign , yes. For beginners with JSON a proper example flow would be helpful. 🤝
    2 points
  27. ioa747

    _SectionsArrays

    _SectionsArrays A library for reading, writing, and managing 1D or 2D arrays, stored in a single text file using a section-based format. It provides functions to easily handle data, update existing sections, or add new ones. ; ; https://www.autoitscript.com/forum/topic/213059-_sectionsarrays/ ;--------------------------------------------------------------------------------------- ; Title...........: _SectionsArrays ; Description.....: A library for reading, writing, and managing 1D or 2D arrays, ; stored in a single text file using a section-based format. ; It provides functions to easily handle data, update existing sections, or add new ones. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.3 ; Note............: Testet in Win10 22H2 ;--------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <Array.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> Example() Func Example() Local $sArraysFilepath = @ScriptDir & "\arrays.txt" If Not FileExists($sArraysFilepath) Then _MakeArrays($sArraysFilepath) If @error Then ConsoleWrite("_MakeArrays @error=" & @error & @CRLF) Local $aSections = _ArraysFromFile($sArraysFilepath) If @error Then ConsoleWrite("_ArraysFromFile @error=" & @error & @CRLF) ShellExecute($sArraysFilepath) Sleep(500) _ArraysDisplay($aSections, "Array Sections") EndFunc ;==>Example Func _MakeArrays($sFilePath) ; Make examples arrays ; Prepare Sections array Local $aSections[1][2] $aSections[0][0] = 0 Local $Info ; "Monthly zoo Report" array Local $Array[][] = [ _ ["Month", "Bears", "Dolphins", "Whales"], _ ["jan", 8, 150, 80], _ ["feb", 54, 77, 54], _ ["mar", 93, 32, 10], _ ["apr", 116, 11, 76], _ ["may", 137, 6, 93], _ ["jun", 184, 1, 72]] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "Monthly zoo Report", $Array) ConsoleWrite("add $Info=" & $Info & @CRLF) ; "Base Items" array Local $aArray_Base[2][2] = [["Item 0 - 0", "Item 0 - 1"], ["Item 1 - 0", "Item 1 - 1"]] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "Base Items", $aArray_Base) ConsoleWrite("add $aArray_Base=" & $Info & @CRLF) ; "item Index" array Local $aIndex[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "item Index", $aIndex) ConsoleWrite("add $aIndex=" & $Info & @CRLF) ; "item Index2" array Local $aIndex2[1][10] = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] $Info = _AddArrayToArrays($aSections, "item Index2", $aIndex2) ConsoleWrite("add $aIndex2=" & $Info & @CRLF) ; Save arrays to file _ArraysToFile($sFilePath, $aSections) EndFunc ;==>_MakeArrays ;-------------------------------------------------------------------------------------------------------------------------------- ; Help functions (A library for reading, writing, and managing 1D or 2D arrays, stored in a single text file using a section-based format.) ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysDisplay(ByRef $aItems, $sTitle = "") ; Creates a GUI window to display and browse the contents of multiple arrays. Local $hGUI = GUICreate($sTitle, 300, 200, -1, -1, $WS_OVERLAPPEDWINDOW) Local $idListview = GUICtrlCreateListView("Sections | Arrays", 0, 0, 300, 200, $LVS_SINGLESEL) GUICtrlSetFont(-1, 10) _GUICtrlListView_SetExtendedListViewStyle($idListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) _GUICtrlListView_SetColumnWidth($idListview, 0, 170) _GUICtrlListView_SetColumnWidth($idListview, 1, 120) GUISetState(@SW_SHOW) Local $aIdItems[UBound($aItems, 1)] If @error Then Return SetError(@error, 0, 0) $aIdItems[0] = $aItems[0][0] For $i = 1 To $aIdItems[0] Local $sLabel = "error" Local $aArray = $aItems[$i][1] If IsArray($aArray) Then Local $iDimension = UBound($aArray, $UBOUND_DIMENSIONS) ; The dimension of the array e.g. 1/2/3 dimensional. Local $sDim = "" For $d = 1 To $iDimension $sDim &= "[" & UBound($aArray, $d) & "]" Next $sLabel = "Array" & $sDim EndIf $aIdItems[$i] = GUICtrlCreateListViewItem($aItems[$i][0] & " | {" & $sLabel & "}", $idListview) Next Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_RESIZED Local $iWH = WinGetClientSize($hGUI) GUICtrlSetPos($idListview, 0, 0, $iWH[0], $iWH[1]) Case $aIdItems[1] To $aIdItems[$aIdItems[0]] Local $id = $iMsg - $aIdItems[1] + 1 $aArray = $aItems[$id][1] _ArrayDisplay($aArray, $aItems[$id][0]) EndSwitch WEnd GUIDelete() EndFunc ;==>_ArraysDisplay ;-------------------------------------------------------------------------------------------------------------------------------- Func _AddArrayToArrays(ByRef $aArrays, $sName, $aNewArray) ; Adds a new array to the main array structure, or updates an existing one. Local $iCurrentSections = $aArrays[0][0] ; Check if the section name already exists For $i = 1 To $iCurrentSections If $aArrays[$i][0] = $sName Then ; Section exists, update the array $aArrays[$i][1] = $aNewArray Return True EndIf Next ; Section does not exist, add a new one ReDim $aArrays[$iCurrentSections + 2][2] ; Add the new section name and the array $aArrays[$iCurrentSections + 1][0] = $sName $aArrays[$iCurrentSections + 1][1] = $aNewArray ; Update the total number of sections count $aArrays[0][0] = $iCurrentSections + 1 Return True EndFunc ;==>_AddArrayToArrays ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysToFile($sFilePath, $aArrays, $sDelim_Col = "|") ; Saves a multi-array structure back to a text file. Local $sOutput = "" Local $iNumSections = $aArrays[0][0] ; Loop through each section For $i = 1 To $iNumSections Local $sSectionName = $aArrays[$i][0] Local $aCurrentArray = $aArrays[$i][1] ; Get the array dimension Local $iDimension = UBound($aCurrentArray, $UBOUND_DIMENSIONS) ; Append the section name with the dimension to the output string $sOutput &= "[" & $sSectionName & "]" & $iDimension & "D" & @CRLF ; Convert the array to a string Local $sArrayString = _ArrayToString($aCurrentArray, $sDelim_Col) ; Append the array string to the output, followed by a newline $sOutput &= $sArrayString & @CRLF & @CRLF Next Local $hFile = FileOpen($sFilePath, $FO_OVERWRITE + $FO_UTF8_NOBOM) If $hFile = -1 Then Return SetError(1, 0, False) EndIf FileWrite($hFile, $sOutput) FileClose($hFile) Return True EndFunc ;==>_ArraysToFile ;-------------------------------------------------------------------------------------------------------------------------------- Func _RemoveArraySection(ByRef $aArrays, $sName) ; Removes a section and its corresponding array from the main array structure. Local $iCurrentSections = $aArrays[0][0] ; Check if the section name exists For $i = 1 To $iCurrentSections If $aArrays[$i][0] = $sName Then _ArrayDelete($aArrays, $i) $aArrays[0][0] = $iCurrentSections - 1 ReDim $aArrays[$iCurrentSections][2] Return True EndIf Next Return False ; Section not found EndFunc ;==>_RemoveArraySection ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysFromFile($sFilePath, $sDelim_Col = "|") ; Reads a text file containing multiple sections and converts them into a 2D array structure. Local $sFileTxt = FileRead($sFilePath) If @error Then Return SetError(1, 0, "") ; Put a @CRLF in start, and convert all @LF, @CR to @CRLF $sFileTxt = @CRLF & StringRegExpReplace($sFileTxt, "(\r\n|\n)", @CRLF) ; split String in (@CRLF & "[") Local $aPart = StringSplit($sFileTxt, @CRLF & "[", 1) If $aPart[0] < 2 Then Return SetError(2, 0, "") Local $aSections[$aPart[0]][2] $aSections[0][0] = $aPart[0] - 1 For $i = 2 To $aPart[0] ; normal first line is the (name & ]) Local $iPos = StringInStr($aPart[$i], "]", 0, -1) If Not $iPos > 0 Or @error Then Return SetError(3, 0, "") ; find the name and the Dimension Local $sName = StringLeft($aPart[$i], $iPos - 1) Local $iDimension = 0 + Number(StringMid($aPart[$i], $iPos + 1, 1)) If Not ($iDimension = 1 Or $iDimension = 2) Then Return SetError(4, 0, "") ; remove leading CRLF or LF from front & back Local $sString = StringRegExpReplace(StringTrimLeft($aPart[$i], $iPos + 2), '(^[\r\n]+|[\r\n]+$)', '') Local $aArrayFromText ; $iDimension - 1 to $bForce2D => true $aArrayFromText = _ArrayFromString($sString, $sDelim_Col, Default, $iDimension - 1) $aSections[$i - 1][0] = $sName $aSections[$i - 1][1] = $aArrayFromText Next Return $aSections EndFunc ;==>_ArraysFromFile ;-------------------------------------------------------------------------------------------------------------------------------- Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
    2 points
  28. Here one way : ; From Nine #include <GDIPlus.au3> #include <GUIConstants.au3> Opt("MustDeclareVars", True) Example() Func Example() _GDIPlus_Startup() Local $hGUI = GUICreate("Example", 400, 400) GUISetState() Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF) Local $hBrush = _GDIPlus_LineBrushCreate(50, 200, 320, 200, 0xFF000000, 0xFFFFFFFF) Local $hFormat = _GDIPlus_StringFormatCreate() Local $hFamily = _GDIPlus_FontFamilyCreate("Arial") Local $hFont = _GDIPlus_FontCreate($hFamily, 28, 2) Local $tLayout = _GDIPlus_RectFCreate(80, 100, 320, 40) Local $aInfo = _GDIPlus_GraphicsMeasureString($hGraphic, "AutoIt Rulez !", $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphic, "AutoIt Rulez !", $hFont, $aInfo[0], $hFormat, $hBrush) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_FontDispose($hFont) _GDIPlus_BrushDispose($hBrush) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() EndFunc ;==>Example
    2 points
  29. argumentum

    _SectionsArrays

    ;Local $aIndex[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Local $aIndex[1][10] = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] It'd be nice to do something to differentiate between 1D and 2D. Tho this is the only scene where it would not conform to recreate the original array 🤔 Thanks for sharing Edit: ; split String in (@CRLF & @CRLF & "{") ; for 1D ? ; split String in (@CRLF & @CRLF & "[") ; for 2D ?, and yes I added a 2nd @CRLF Edit2: or, add what it is to it, like: [my array 1D] or [my array 2D] just as an internal indicator ?
    2 points
  30. Here a example how you can do it with jq directly instead of using the JSON.au3 UDF. Don't get me wrong, I like the JSON library (UDF) from @AspirinJunkie - he already knows that. I simply try to give you another perspective how you can handle a JSON file with a widespread (AutoIt independent) library. In case you want to stick with AutoIt, no problem, use the JQ adaption of @TheXman who creates this lovely json-processor. Best regards Sven
    2 points
  31. You'll have to parse the array first and then manually insert the correct index into your commands. If you want to do it in a "cleaner" way, you can just modify the Array in AutoIt and insert the whole thing back with your changes.
    2 points
  32. smbape

    Mediapipe UDF

    Update MediaPipe to 0.10.26
    2 points
  33. smbape

    Dlib UDF

    Update dlib to 20.0
    2 points
  34. Come checkout my Metro GUI designer. User Interface Builder
    2 points
  35. It was semi-manually, since i also needed to add parameter types and return types. 😅 semi, because i used my inline suggestions from my windsurf AI vscode extension to speed things up. That might be why the text is wrong at some places Edit: I've updated the summary for the two functions mentioned. It will be available with next version 😉
    2 points
  36. In native.au3 when documenting ControlGetHandle on line 1680 it says, "Returns the control's current text.", but it should be "Retrieves the internal handle of a control." Similarly, ControlGetFocus has the incorrect description text as well. It doesn't bother me, but if you auto-document there may be a bug? If you copy/pasted, then I'm sorry; that's a lot of work!
    2 points
  37. I’ve identified the root cause of the issue with $colNetAdapter.Count failing when querying Win32_NetworkAdapter via WMI. The problem arises from using the wbemFlagForwardOnly flag (0x20) in the ExecQuery method. This flag creates a forward-only cursor for the SWbemObjectSet collection, which optimizes performance for large datasets by allowing only sequential, one-time access to objects. However, this cursor type does not support the .Count property, resulting in the error: "The requested action with this object has failed."To resolve this, you should use only the wbemFlagReturnImmediately flag (0x10) or no flags at all, as this ensures the resulting SWbemObjectSet collection supports .Count #include <Array.au3> #include <MsgBoxConstants.au3> Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") If Not IsObj($objWMIService) Then MsgBox($MB_ICONERROR, "Error", "Unable to connect to WMI service. Check privileges or WMI service status.") Exit 1 EndIf Local $sQueryNetAdapter = 'SELECT * FROM Win32_NetworkAdapter' Local $colNetAdapter = $objWMIService.ExecQuery($sQueryNetAdapter, "WQL", 0x10) ; wbemFlagReturnImmediately If Not IsObj($colNetAdapter) Then MsgBox($MB_ICONERROR, "Error", "WMI query failed. Check query syntax or access to Win32_NetworkAdapter class.") Exit 2 EndIf ; Get the number of items in the collection Local $num = $colNetAdapter.Count If @error Then MsgBox($MB_ICONERROR, "Error", "Unable to access .Count property. Error code: " & @error) Exit 3 EndIf MsgBox($MB_OK, "Number of Adapters", "Number of network adapters: " & $num) ; Create an array to store the data Local $storearray[$num][2] Local $ind = 0 For $netadapt In $colNetAdapter If IsObj($netadapt) Then $storearray[$ind][0] = Not $netadapt.Manufacturer ? "N/A" : $netadapt.Manufacturer $storearray[$ind][1] = Not $netadapt.ProductName ? "N/A" : $netadapt.ProductName $ind += 1 EndIf Next ; Display the results (for verification) For $i = 0 To $num - 1 MsgBox($MB_OK, "Adapter " & $i, "Manufacturer: " & $storearray[$i][0] & @CRLF & "Product: " & $storearray[$i][1]) Next
    2 points
  38. You can use the native WinAPI GetPrivateProfileSection. It says that : Here my take on it : #include <Array.au3> Local $aSection = IniReadSectionEx("C:\Apps\AutoIt\SQLite\Sudoku.ini", "Setting") _ArrayDisplay($aSection) Func IniReadSectionEx($sFile, $sSection, $iBuffer = 64000, $iEntry = 1000, $iLine = 100) Local $tData = DllStructCreate("byte [" & $iBuffer & "]") Local $pData = DllStructGetPtr($tData) Local $aRet = DllCall("Kernel32.dll", "int", "GetPrivateProfileSection", "str", $sSection, "struct*", $tData, "int", $iBuffer, "str", $sFile) Local $tString, $aList[$iEntry + 1][2] = [[0]], $aSplit For $i = 1 To $iEntry $tString = DllStructCreate("char string[" & $iLine & "]", $pData) $sString = $tString.string If Not $sString Then ExitLoop $aList[0][0] += 1 $aSplit = StringSplit($sString, "=", $STR_NOCOUNT) $aList[$i][0] = $aSplit[0] $aList[$i][1] = $aSplit[1] $pData += StringLen($sString) + 1 Next ReDim $aList[$i][2] Return $aList EndFunc ;==>IniReadSectionEx
    2 points
  39. You can also try the function _StringSplit2D_EX() based on @AspirinJunkie function (link in the script below) . It splits nicely "items1.csv" which has a non-fixed number of columns. #include <Array.au3> #include <MsgBoxConstants.au3> #include <StringConstants.au3> Local $sFilePath = @ScriptDir & "\items1.csv" Local $sFileRead = FileRead($sFilePath) If @error Then Exit MsgBox($MB_TOPMOST, "FileRead", "@error = " & @error) Local $aRetArray = _StringSplit2D_EX($sFileRead, ",", @CRLF, True) ; True to allow a variable number of columns. If @error Then Exit MsgBox($MB_TOPMOST, "_StringSplit2D_EX", _ "@error = " & @error & @CRLF & _ "All rows don't have the same number of fields (line " & (@extended + 1) & ")") _ArrayDisplay($aRetArray, "2D array from delimited file") ;============================================== Func _StringSplit2D_EX(ByRef $sString, $sDelim_Col = "|", $sDelim_Row = @CRLF, $bExpand = False, $iAdd_EmptyCol = 0) ; based on AspirinJunkie's function _StringSplit2D found at https://autoit.de/thread/85380-1d-array-in-2d-array-splitten/ ; Thanks Nine for suggesting the 4th parameter $bExpand, to allow or not the same number of fields per row (as in _FileReadToArray) Local $a_FirstDim = StringSplit($sString, $sDelim_Row, $STR_ENTIRESPLIT + $STR_NOCOUNT) Local $iKeep_NbCol = Ubound(StringSplit($a_FirstDim[0], $sDelim_Col, $STR_ENTIRESPLIT + $STR_NOCOUNT)) ; keep nb cols row 0 Local $a_Out[UBound($a_FirstDim)][1 + $iAdd_EmptyCol], $a_Line, $i_2DMax = 1 For $i = 0 To UBound($a_FirstDim) - 1 $a_Line = StringSplit($a_FirstDim[$i], $sDelim_Col, $STR_ENTIRESPLIT + $STR_NOCOUNT) If (Not $bExpand) And (Ubound($a_Line) <> $iKeep_NbCol) Then Return SetError(3, $i, 0) ; same error # as _FileReadToArray If UBound($a_Line) > $i_2DMax Then ; when $bExpand = False, this test will be True maximum 1 time, never more. $i_2DMax = UBound($a_Line) ReDim $a_Out[UBound($a_Out)][$i_2DMax + $iAdd_EmptyCol] EndIf For $j = 0 To UBound($a_Line) - 1 $a_Out[$i][$j] = $a_Line[$j] Next Next Return $a_Out EndFunc ;==>_StringSplit2D_EX Edit: @ioa747 & @Musashi thanks for your appreciation. I already used several times this interesting function _StringSplit2D_EX . In case you'll use it one day, I just made a minor change in it, based on the "@extended idea" described in my other post later in this thread. For example, let's run the amended script above, with : 1) items1.csv is the one from OP's 1st post (the bad csv with a non-fixed number of columns) 2) Now this line : Local $aRetArray = _StringSplit2D_EX($sFileRead, ",", @CRLF, True) ; True to expand, it allows a variable number of columns in the rows. Please change its 4th param. True to False , which means that a variable number of columns is not allowed : Local $aRetArray = _StringSplit2D_EX($sFileRead, ",", @CRLF, False) ; False doesn't expand, it means the number of columns must be the same in all rows. Now a normal message error is displayed : Please notice "line 17" in the message : this is what @extended returned, apart from @error, it helps the user to quickly point at the 1st line where the error appears. This can be interesting in case of a big file in input. For the record, the 5th optional parameter allows to add 1 or more empty columns at the right of the array, during its creation, because sometimes we need them. Well... if I added this 5th optional parameter, then you can be sure I needed it one day If you want to try the 5th parameter, just use this line in the script, it will add 5 empty columns on the right, from Col6 to Col10 Local $aRetArray = _StringSplit2D_EX($sFileRead, ",", @CRLF, True, 5) Thanks for reading
    2 points
  40. yeah so I have a bunch of VMs on a 2011 iMac... but I doubt it'll handle win10. I can test on Win3.1 if you'd like It probably depends on what we want to achieve here. In honesty, I'd say the simplest fix to the "it's broken" problem is to just change what the example does. Otherwise sure, let's attempt to replicate the original behavior. It'll be a good learning exercise anyway. If a broader UDF is necessary I'm happy to contribute where I can - but this is probably jumping the gun... ATM I'm just prodding at things to see whats possible, so I'm not there yet! Anyway I've worked out the Win10 thing. You need to use a dll handle with DllCall rather than specifying a string - obvioulsy unloading "Oleacc.dll" causes issues!. I've no idea why the scite menus worked in win10, but the notepad ones cause an access violation.... Here's the update: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y ;x86 is broken - future Matt's problem!. #include <GuiMenu.au3> #include <SendMessage.au3> #include <WinAPIGdi.au3> #include <WinAPIMisc.au3> #include <WinAPIProc.au3> #include <WinAPISys.au3> #include <WindowsConstants.au3> #include <APIErrorsConstants.au3> Global Const $S_OK = 0, $S_FALSE = 1 Global Enum $VT_EMPTY = 0, _ $VT_I4 = 3, _ $VT_BSTR = 8, _ $VT_DISPATCH = 9 Global $tagVt_I4 = "align 2;ushort vt;word Pad[3];int data" Global $tagVt_Dispatch = "align 2;ushort vt;word Pad[3];ptr data" Global Const $sIID_NULL = "{00000000-0000-0000-0000-000000000000}" Global Const $sIID_IDispatch = "{00020400-0000-0000-C000-000000000046}" Global Const $sIID_IUnknown = "{00000000-0000-0000-C000-000000000046}" Global Const $sIID_IAccessible = "{618736e0-3c3d-11cf-810c-00aa00389b71}" Global $tagIDispatch = "GetTypeInfoCount hresult(uint*);" & _ "GetTypeInfo hresult(uint;int;ptr*);" & _ "GetIDsOfNames hresult(struct*;wstr;uint;int;int);" & _ "Invoke hresult(int;struct*;int;word;ptr*;ptr*;ptr*;uint*);" ;Use struct* instead of variant for input. if sending 0 as variant, the value doesn't seem to be sent as VT_I4. (Probably VT_EMPTY) Global $tagIAccessible = $tagIDispatch & _ "get_accParent hresult(ptr*);" & _ "get_accChildCount hresult(long*);" & _ "get_accChild hresult(struct*;ptr*);" & _ "get_accName hresult(struct*;bstr*);" & _ "get_accValue hresult(struct*;bstr*);" & _ "get_accDescription hresult(struct*;bstr*);" & _ "get_accRole hresult(struct*;variant*);" & _ "get_accState hresult(struct*;variant*);" & _ "get_accHelp hresult(struct*;bstr*);" & _ "get_accHelpTopic hresult(bstr*;struct*;long*);" & _ "get_accKeyboardShortcut hresult(struct*;bstr*);" & _ "get_accFocus hresult(struct*);" & _ "get_accSelection hresult(variant*);" & _ "get_accDefaultAction hresult(struct*;bstr*);" & _ "accSelect hresult(long;struct*);" & _ "accLocation hresult(long*;long*;long*;long*;struct*);" & _ "accNavigate hresult(long;variant;variant*);" & _ "accHitTest hresult(long;long;variant*);" & _ "accDoDefaultAction hresult(struct*);" & _ "put_accName hresult(struct*;bstr);" & _ "put_accValue hresult(struct*;bstr);" Global $__g_hDllOleacc = DllOpen("Oleacc.dll") Global $hEventProc = DllCallbackRegister('_EventProc', 'none', 'ptr;dword;hwnd;long;long;dword;dword') OnAutoItExitRegister('OnAutoItExit') Global $hEventHook = _WinAPI_SetWinEventHook($EVENT_SYSTEM_MENUPOPUPSTART, $EVENT_SYSTEM_MENUPOPUPEND, DllCallbackGetPtr($hEventProc)) Global $iNotepad_PID = ShellExecute('notepad.exe') While ProcessExists($iNotepad_PID) Sleep(1000) WEnd Func OnAutoItExit() _WinAPI_UnhookWinEvent($hEventHook) DllCallbackFree($hEventProc) DllClose($__g_hDllOleacc) EndFunc ;==>OnAutoItExit Func _EventProc($hEventHook, $iEvent, $hWnd, $iObjectID, $iChildID, $iThreadId, $iEventTime) ConsoleWrite(StringFormat('Hook: iEvent[%s] iObjectID[%s] iChildID[%s]', $iEvent, $iObjectID, $iChildID) & @CRLF) #forceref $hEventHook, $iObjectID, $iChildID, $iThreadId, $iEventTime Switch $iEvent Case $EVENT_SYSTEM_MENUPOPUPSTART ConsoleWrite(_WinAPI_GetClassName($hWnd) & @CRLF) Local $pObj = _WinAPI_AccessibleObjectFromEvent($hWnd, $iObjectID, $iChildID) If Not @error Then Local $oObj = ObjCreateInterface($pObj, $sIID_IAccessible, $tagIAccessible) Local $sName, $iCount, $oChildObj Local $tVt_I4 = DllStructCreate($tagVt_I4) $tVt_I4.vt = $VT_I4 SetError($oObj.get_accName($tVt_I4, $sName)) If @error Then $sName = StringFormat("ERR[0x%08x]", @error) ConsoleWrite("MENU: " & $sName & @CRLF) $oObj.get_accChildCount($iCount) Local $pChildObj Local $aChild = _WinAPI_AccessibleChildren($pObj, 0, $iCount) For $i = 0 To UBound($aChild) - 1 $sName = "" $oChildObj = 0 ConsoleWrite("CHILD[" & $i & "]: ") If IsPtr($aChild[$i]) Then ;Child has been retrieved as an object in its own right $oChildObj = ObjCreateInterface($aChild[$i], $sIID_IAccessible, $tagIAccessible) $tVt_I4.data = 0 Else $tVt_I4.data = $aChild[$i] SetError($oObj.get_accChild($tVt_I4, $pChildObj)) Switch @error Case $S_OK ;We shouldn't end up here. AccessibleChildren probably would've retuned a VT_DISPATCH for the child. $oChildObj = ObjCreateInterface($pChildObj, $sIID_IAccessible, $tagIAccessible) $tVt_I4.data = 0 Case $S_FALSE ;Child is an Element (get detials from this object.) $oChildObj = $oObj Case Else ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF) ContinueLoop EndSwitch EndIf SetError($oChildObj.get_accName($tVt_I4, $sName)) If (@error < $S_OK) Or @error > $S_FALSE Then ConsoleWrite(ConsoleWrite("ERROR: 0x" & Hex(@error) & @CRLF)) Else ConsoleWrite($sName & @CRLF) EndIf Next EndIf Case $EVENT_SYSTEM_MENUPOPUPEND EndSwitch EndFunc ;==>_EventProc Func _WinAPI_AccessibleObjectFromEvent($hWnd, $iID, $iChildID) Local $tVt_I4 = DllStructCreate($tagVt_I4) Local $aCall = DllCall($__g_hDllOleacc, "long", "AccessibleObjectFromEvent", "hwnd", $hWnd, "dword", $iID, "dword", $iChildID, "ptr*", 0, "struct*", $tVt_I4) If @error Then Return SetError(@error, 0, 0) ConsoleWrite(StringFormat("AccessibleObjectFromEvent: pIAccessible[%s], iChildID[%d]", $aCall[4], $tVt_I4.data) & @CRLF) Return SetError($aCall[0], 0, $aCall[4]) EndFunc Func _WinAPI_AccessibleChildren($pAccessible, $iChildStart, $iCount) Local $tBuff = DllStructCreate(StringFormat("byte data[%d]", $iCount * 24)) Local $aCall = DllCall($__g_hDllOleacc, "long", "AccessibleChildren", "ptr", $pAccessible, "int", $iChildStart, "int", $iCount, "struct*", $tBuff, "long*", 0) If @error Then Return SetError(@error, 0, 0) Local $aChildren[$aCall[5]], $tVt For $i = 0 To $aCall[5] - 1 $tVt = DllStructCreate($tagVt_I4, Ptr(DllStructGetPtr($tBuff) + $i * 24)) If $tVt.Vt = $VT_DISPATCH Then $tVt = DllStructCreate($tagVt_Dispatch, Ptr(DllStructGetPtr($tBuff) + $i * 24)) $aChildren[$i] = $tVt.data If $tVt.Vt = $VT_DISPATCH Then $aChildren[$i] = Ptr($aChildren[$i]) Next ReDim $aChildren[$i] Return SetError($aCall[0], $aCall[5], $aChildren) EndFunc
    2 points
  41. Nine

    edit ListView sub-items

    You can't, not with standard functionality of a list view . Only the item (first column) can be edited in place using $LVS_EDITLABELS. If you truly want it, you would need a workaround, like creating an input box when you dbl-click on a subitem. Here a simple example : #include <GUIConstants.au3> #include <GuiListView.au3> Opt("GUICloseOnESC", 0) Opt("MustDeclareVars", True) Global $hList, $idDummy Example() Func Example() Local $hMain = GUICreate("Example", 230, 170) Local $idList = GUICtrlCreateListView("Column 1|Column 2", 10, 10) GUICtrlCreateListViewItem("Item 1|Item 2", $idList) GUICtrlCreateListViewItem("Item 3|Item 4", $idList) $hList = GUICtrlGetHandle($idList) $idDummy = GUICtrlCreateDummy() GUIRegisterMsg($WM_NOTIFY, WM_NOTIFY) GUISetState() Local $iItem, $iSubItem, $aRect, $sData, $aPos = ControlGetPos($hMain, "", $idList) While True Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idDummy $iItem = _WinAPI_LoWord(GUICtrlRead($idDummy)) $iSubItem = _WinAPI_HiWord(GUICtrlRead($idDummy)) If $iSubItem = 0 Then ContinueLoop $aRect = _GUICtrlListView_GetSubItemRect($idList, $iItem, $iSubItem) $sData = GUICreateInput($hMain, _GUICtrlListView_GetItemText($idList, $iItem, $iSubItem), $aRect[0] + $aPos[0], $aRect[1] + $aPos[1], $aRect[2] - $aRect[0], $aRect[3] - $aRect[1]) If $sData Then _GUICtrlListView_SetItemText($idList, $iItem, $sData, $iSubItem) EndSwitch WEnd EndFunc ;==>Example Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $lParam) If $tInfo.hWndFrom = $hList And $tInfo.Code = $NM_DBLCLK Then GUICtrlSendToDummy($idDummy, _WinAPI_MakeLong($tInfo.Index, $tInfo.SubItem)) Return $GUI_RUNDEFMSG EndFunc ;==>WM_NOTIFY Func GUICreateInput($hWnd, $sText, $iLeft, $iTop, $iWidth, $iHeight) Local $hGUI = GUICreate("", $iWidth, $iHeight, $iLeft, $iTop + 1, $WS_POPUP, $WS_EX_MDICHILD, $hWnd) Local $idInput = GUICtrlCreateInput($sText, 0, 1, $iWidth, $iHeight - 1) Local $idOut = GUICtrlCreateDummy() GUISetState() GUISetState(@SW_DISABLE, $hWnd) Local $aAccel[2][2] = [["{ENTER}", $idInput], ["{ESC}", $idOut]], $sInput GUISetAccelerators($aAccel, $hGUI) While True Switch GUIGetMsg() Case $idInput $sInput = GUICtrlRead($idInput) ExitLoop Case $idOut ExitLoop EndSwitch WEnd GUIDelete($hGUI) GUISetState(@SW_ENABLE, $hWnd) GUISetState(@SW_RESTORE, $hWnd) Return $sInput EndFunc ;==>GUICreateInput
    2 points
  42. ioa747

    _DragNumAdjust

    _DragNumAdjust Adjust the value of a numeric control by dragging with the mouse. It also checks whether the Control key (faster) or Shift key (slower) is pressed while dragging, which allows the user to adjust the sensitivity of the adjustment speed. _DragNumAdjust ( $sControls, $iAxis = 1, $iSensitivity = 4 ) $sControls A string containing the IDs of the controls to be adjusted, separated by a vertical bar | Each control ID (Optionaly) is followed by its min and max values, separated by a semicolon ; e.g. _DragNumAdjust("$idNum1;-100;100|$idNum2;-50;50|$idNum3") Adjust control $idNum1 (min=-100, max=100) and $idNum2 (min=-50, max=50) and $idNum3 (without min/max limits) $iAxis [optional] The axis to drag. 0 for horizontal, 1 for vertical. (Default is 1) $iSensitivity [optional] The sensitivity factor for mouse sensitivity. Higher means slower change. (Default is 4) ; https://www.autoitscript.com/forum/topic/213011-_dragnumadjust/ ;---------------------------------------------------------------------------------------- ; Title...........: _DragNumAdjust.au3 ; Description.....: Adjust the value of a numeric control by dragging with the mouse. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.1 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GUIConstantsEx.au3> #include <WinAPIDlg.au3> #include <Array.au3> #include <Misc.au3> Global $hGUI, $idNum1, $idNum2, $idNum3, $idNum4 Example() Func Example() $hGUI = GUICreate("Example GUI", 320, 220) $idNum1 = GUICtrlCreateInput("100", 10, 20, 70, 20) $idNum2 = GUICtrlCreateInput("20", 130, 20, 70, 20) $idNum3 = GUICtrlCreateInput("3", 10, 50, 70, 20) $idNum4 = GUICtrlCreateInput("30", 130, 50, 70, 20) Local $idBtn = GUICtrlCreateButton("Ok", 40, 180, 60, 20) GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $idBtn ExitLoop EndSwitch ; Test with negative min/max values _DragNumAdjust("$idNum1;-100;100|$idNum2;-50;50|$idNum3;0;10|$idNum4", 0) ; Horizontal dragging WEnd EndFunc ;==>Example ; #FUNCTION# ==================================================================================================================== ; Name...........: _DragNumAdjust ; Description....: Adjust the value of a numeric control by dragging with the mouse. ; Syntax.........: _DragNumAdjust($sControls [, $iAxis = 1 [, $iSensitivity = 4]]) ; Parameters.....: $sControls - A string containing the IDs of the controls to be adjusted, separated by a vertical bar | ; Each control ID (Optionaly) is followed by its min and max values, separated by a semicolon ; ; $iAxis - [optional] The axis to drag. 0 for horizontal, 1 for vertical. (Default is 1) ; $iSensitivity - [optional] The sensitivity factor for mouse movement. Higher means slower change.(Default is 4) ; Return values .: Success: Returns None. (Just adjust the control value) ; Author ........: ioa747 ; Modified ......: ; Remarks .......: This function allows users to adjust numeric control values by dragging the mouse. ; Related .......: ControlGetHandle, GUIGetCursorInfo, MouseGetPos, _IsPressed ; Link ..........: https://www.autoitscript.com/forum/topic/213011-_dragnumadjust/ ; Example .......: _DragNumAdjust("$idNum1;-100;100|$idNum2|-50;50", 1) ; Adjust control $idNum1 (min=-100, max=100) and $idNum2 (min=-50, max=50) ; =============================================================================================================================== Func _DragNumAdjust($sControls, $iAxis = 1, $iSensitivity = 4) ; Define constants locally. Local Const $_GUI_CURSOR_ARROW = 2 ; Default ↖ Arrow cursor Local Const $_GUI_CURSOR_SIZENS = 11 ; Vertical ↕ SizeNS cursor Local Const $_GUI_CURSOR_SIZEWE = 13 ; Horizontal ↔ SizeWE cursor Local Const $_MAXINT = 2147483647 ; Maximum value for a 32-bit signed integer Local Const $_MININT = -2147483648 ; Minimum value for a 32-bit signed integer Local Static $aCtrlParameters ; Initialize $aCtrlParameters once If Not IsArray($aCtrlParameters) Then Local $aParts = StringSplit($sControls, "|") Local $aTempArray[$aParts[0] + 1][3] For $i = 1 To $aParts[0] Local $aTmp = StringSplit($aParts[$i], ";") $aTempArray[$i][0] = Execute($aTmp[1]) $aTempArray[$i][1] = ($aTmp[0] > 1 ? Number($aTmp[2]) : $_MININT) ; set Min $aTempArray[$i][2] = ($aTmp[0] > 2 ? Number($aTmp[3]) : $_MAXINT) ; set Max Next $aCtrlParameters = $aTempArray EndIf If Not WinActive($hGUI) Then Return ; Return if $hGUI has no focus Local $aMouseInfo = GUIGetCursorInfo($hGUI) ; $iFocusCtrlID = which control has the focus Local $hFocusCtrlHandle = ControlGetHandle($hGUI, "", ControlGetFocus($hGUI)) Local $iFocusCtrlID = _WinAPI_GetDlgCtrlID($hFocusCtrlHandle) Local $iCtrlIdx = -1 For $i = 1 To UBound($aCtrlParameters) - 1 If $aCtrlParameters[$i][0] = $iFocusCtrlID Then $iCtrlIdx = $i ExitLoop EndIf Next If $iCtrlIdx = -1 Then Return ; Return if no matching control index is found ; $iCtrlUnderMouse = which control is under the mouse Local $iCtrlUnderMouse = IsArray($aMouseInfo) ? $aMouseInfo[4] : 0 ; Return and set cursor to Default ↖ Arrow if $iCtrlUnderMouse has no focus If $iCtrlUnderMouse <> $iFocusCtrlID Then Return GUICtrlSetCursor($iFocusCtrlID, $_GUI_CURSOR_ARROW) ; Set cursor type based on axis Local $iCursorType = $_GUI_CURSOR_ARROW If $iAxis = 1 Then $iCursorType = $_GUI_CURSOR_SIZENS ElseIf $iAxis = 0 Then $iCursorType = $_GUI_CURSOR_SIZEWE Else Return ; Exit if invalid axis EndIf GUICtrlSetCursor($iFocusCtrlID, $iCursorType) If $aMouseInfo[2] = 1 Then ; Primary button down Local $startValue = GUICtrlRead($iFocusCtrlID) ; Store start value Local $lastDisplayedValue = $startValue ; start value Local $startPos = MouseGetPos($iAxis) ; Initial mouse position (Y or X) While $aMouseInfo[2] = 1 ; Primary button down $aMouseInfo = GUIGetCursorInfo($hGUI) ; Update control Local $currentPos = MouseGetPos($iAxis) ; Current mouse position (Y or X) Local $diff = Int(($startPos - $currentPos) / $iSensitivity) ; Adjust sensitivity If _IsPressed("11") Then ; Control key makes adjustment faster $diff *= 4 ElseIf _IsPressed("10") Then ; Shift key makes adjustment slower $diff = Int($diff / 4) EndIf If $iAxis = 0 Then $diff *= -1 ; Horizontal increases to the right Local $newValue = $startValue + $diff Local $sMin = $aCtrlParameters[$iCtrlIdx][1] Local $sMax = $aCtrlParameters[$iCtrlIdx][2] $newValue = ($newValue < $sMin ? $sMin : $newValue) $newValue = ($newValue > $sMax ? $sMax : $newValue) If $newValue <> $lastDisplayedValue Then GUICtrlSetData($iFocusCtrlID, $newValue) $lastDisplayedValue = $newValue ; Update last displayed value EndIf Sleep(10) WEnd GUICtrlSetCursor($iFocusCtrlID, $_GUI_CURSOR_ARROW) EndIf EndFunc ;==>_DragNumAdjust Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
    2 points
  43. Jos

    #Directive_If_Run

    Try the current beta v25.205.1420.11 of AutoIt3Wrapper. Added logic to strip the lines between #Autoit3Wrapper_If_* ---- #Autoit3Wrapper_(End)If(_*) that are not valid for the run and save the source to a temp file to process.
    2 points
  44. Thank you for the example. I've never experimented with child GUI before, so this is really quite neat. It's a very creative technique to cover up the line. I'm going to continue trying some ideas based on your example. One downside that I notice is that when you move the GUI around on the screen, it will occasionally show a flicker of the white line. I don't think that GuiCreate has any kind of double-buffer option to prevent flicker but I will try a few things to see. Thank you for your time as well. Yes, it looks like resize will definitely need some more code. There might be some differences depending on user systems' titlebar size (varying from resize and non-resize) and possibly some differences varying with DPI. I will see what I can do to measure those things.
    2 points
  45. ... ;~ GUISetState(@SW_SHOW) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ $hGuiRect = GUICreate("", 300, 2, 0, -1, $WS_POPUP, $WS_EX_MDICHILD, $hGUI) GUISetBkColor (0x202020) GUISetState(@SW_SHOW, $hGuiRect) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ GUISetState(@SW_SHOW, $hGUI) ... ..to avoid the flashing on load Edit: It certainly needs more code: but, it could work. =/
    2 points
  46. #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <WinAPITheme.au3> #include "GUIDarkMode_v0.02mod.au3" #include "ModernMenuRaw.au3" DllCall("User32.dll", "bool", "SetProcessDpiAwarenessContext", "HWND", "DPI_AWARENESS_CONTEXT" - 4) _SetMenuBkColor(0x202020) _SetMenuIconBkColor(0x202020) _SetMenuIconBkGrdColor(0x202020) _SetMenuSelectBkColor(0x202020) _SetMenuSelectRectColor(0x202020) _SetMenuSelectTextColor(0xFFFFFF) _SetMenuTextColor(0xFFFFFF) Example() Func Example() $hGUI = GUICreate("My GUI", 300, 200) ;Local $idFileMenu = GUICtrlCreateMenu("&File") Local $idFileMenu = _GUICtrlCreateODTopMenu("&File", $hGUI) GUICtrlCreateMenuItem("&Open", $idFileMenu) GUICtrlCreateMenuItem("&Save", $idFileMenu) GUICtrlCreateMenuItem("", $idFileMenu) Local $idOptionsMenu = GUICtrlCreateMenu("O&ptions", $idFileMenu) GUICtrlCreateMenuItem("View", $idOptionsMenu) GUICtrlCreateMenuItem("", $idOptionsMenu) GUICtrlCreateMenuItem("Tools", $idOptionsMenu) GUICtrlCreateMenuItem("", $idFileMenu) Local $idExitItem = GUICtrlCreateMenuItem("&Exit", $idFileMenu) ;Local $idHelpMenu = GUICtrlCreateMenu("&?") Local $idHelpMenu = _GUICtrlCreateODTopMenu("&?", $hGUI) Local $idAboutItem = GUICtrlCreateMenuItem("&About", $idHelpMenu) Local $idEndBtn = GUICtrlCreateButton("End", 110, 140, 70, 20) GuiDarkmodeApply($hGUI) GUISetState(@SW_SHOW) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ $hGuiRect = GUICreate("", 300, 2, 0, -1, $WS_POPUP, $WS_EX_MDICHILD, $hGUI) GUISetBkColor (0x202020) GUISetState(@SW_SHOW, $hGuiRect) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $idMsg ; Loop until the user exits. While 1 $idMsg = GUIGetMsg() Switch $idMsg Case $idExitItem, $idEndBtn, $GUI_EVENT_CLOSE ExitLoop Case $idAboutItem MsgBox($MB_SYSTEMMODAL, "About...", "Colored menu sample") EndSwitch WEnd EndFunc ;==>Example
    2 points
  47. I set a good challenge, it's giving good results I told @UEZ to come, he comes in like Superman 🤣
    2 points
  48. I've come this far, I'm struggling to figure out how to set the transparency. Testet in Win10 22H2 #include <GUIConstantsEx.au3> #include <WinAPI.au3> #include <WinAPISysInternals.au3> #include <WindowsConstants.au3> ; Getting the right WorkerW window Global $hWorkerW = _FindWorkerW_WithStyles() ConsoleWrite("$hWorkerW=" & $hWorkerW & @CRLF) If Not $hWorkerW Then Exit ConsoleWrite("! Error Could not find WorkerW window." & @CRLF) Main() Func Main() Local $this = GUICreate("", 400, 400, @DesktopWidth - (400) - 20, 100, $WS_POPUP, $WS_EX_NOACTIVATE) ;~ WinSetTrans($this, "", 200) ; not working GUISetBkColor(0x000000) Local $iPic = GUICtrlCreatePic("C:\Program Files (x86)\AutoIt3\Examples\GUI\msoobe.jpg", 0, 0, 0, 0) GUISetState(@SW_SHOW) ; Changes the parent window _WinAPI_SetParent($this, $hWorkerW) WinSetTrans($this, "", 100) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete($this) EndFunc ;==>Main Func _FindWorkerW_WithStyles($iWidth = @DesktopWidth, $iHeight = @DesktopHeight) ; Getting the right WorkerW window with criteria ; size: 1920, 1080 ; visible: Yes ; style: Popup,Tool Window,Transparent Local $aList = WinList("[CLASS:WorkerW]") For $i = 1 To $aList[0][0] Local $hWnd = $aList[$i][1] If Not IsHWnd($hWnd) Then ContinueLoop ; Get visibility If Not BitAND(WinGetState($hWnd), 2) Then ContinueLoop ; Get position and size Local $aPos = WinGetPos($hWnd) If @error Then ContinueLoop If $aPos[2] <> $iWidth Or $aPos[3] <> $iHeight Then ContinueLoop ; Get styles Local $nStyle = _WinAPI_GetWindowLong($hWnd, $GWL_STYLE) ; $GWL_STYLE Local $nExStyle = _WinAPI_GetWindowLong($hWnd, $GWL_EXSTYLE) ; $GWL_EXSTYLE ; Check for required style flags If BitAND($nStyle, $WS_POPUP) = $WS_POPUP _ And BitAND($nExStyle, $WS_EX_TOOLWINDOW) = $WS_EX_TOOLWINDOW _ And BitAND($nExStyle, $WS_EX_TRANSPARENT) = $WS_EX_TRANSPARENT Then Return $hWnd EndIf Next Return 0 ; Not found EndFunc ;==>_FindWorkerW_WithStyles
    2 points
  49. Jon

    AutoIt v3.3.17.1 Beta

    AutoIt v3.3.17.1 Beta View File 3.3.17.1 (July 08, 2025) (Beta) AutoIt: UDFs: - Fixed: Typo in variable name in Date.au3 introduced in previous beta. 3.3.17.0 (June 29, 2025) (Beta) AutoIt: - Changed: Windows 7/Server 2008 is now the minimum OS version required due to dev environment changes. - Added #3891: DllCall() performance optimisation. - Added: Standard Windows Fonts List for Win10/Win11. - Added #3906: GUICtrlCreateXXX creation in example assign to $idXXX to reflect Ctrl type. - Added: FileGetAttrib() retrieve Join folder (J) as created by FileCreateNTFSLink(). - Added: Split WindowsConstants.u3 in WindowsNotifsConstants.au3, WindowsStylesConstants.au3 and WindowsSysColor.au3. - Added: #3984: GUICtrlSetGraphic() doc precision. - Fixed: Doc Chr(0) handling inside functions. - Fixed #3923: Doc typo in "Send Key List". - Fixed: Regression #3135 handle leak (Thanks Nano, Rudi, Nine). - Fixed #3925: Doc With ... EndWith using DllStruct Type. - Fixed: Links in Tutorials example code (thanks argumentum). Au3info: - Added: Display mouse coordinate mode. - Fixed #3917: Crash under Win7. SciTE-Lite: - Fixed: Folding Fix for #Preprocessor foldblock when followed by a CommentBlock. UDFs: - Added: script examples when running under Win11 with new notepad.exe. - Added: _GUICtrlTreeView_GetItemByIndex() can retrieve handle of the list of main item ($hItem= -1). - Added: _IsPressed() can be called with numeric value as in "WinAPIsvkeysConstants.au3". - Added #3909: _DebugReportData() to report Array column formatted. - Added: libExamples referring MemoWrite() now refer to _MemoWrite() defined in Extras\HelpFileInternals.au3. - Added: _WinAPI_WaitSystemIdle(), _WinAPI_QueryDiskUsage(), _WinAPI_QueryProcessorUsage(), _WinAPI_QueryProcessCycleTime() - Added: Doc _WinAPI_GetWindowSubclass() example (Thanks pixelSearch). - Added: _WinAPI_GetKeyboardLayout() default value for the running thread. - Added: _WinAPI_GetUserDefaultLCID() example. - Added: _WinAPI_GetKeyboardLayoutLocale(). - Added: _WinAPI_GetKeyboardState() example (Thanks AutoXenon). - Added #3932: Try to use file in HelpFile\Extras instead of @ScriptDir. - Added #3934: _WinAPI_SetTimer() example. - Added: _IsPressed() can wait on one of several keys. - Added: _WinAPI_SendInput(). - Added #3960: _Div() integer division. - Added #3963: _WinAPI_OpenEvent(). - Added: _GDIPlus_ImageSaveToFile() doc precision for compression level. - Added: _WinAPI_GetCursorSize() and _WinAPI_SetCursorSize(). - Added: $FOLDERID_Documents Constants in APIShellExConstants.au3. - Added: Support _GUIToolTip*() to be used to external process. - Added: Support _GUICtrlHeader*() to be used to external process. - Added: Support _GUICtrlStatusBar*() to be used to external process. - Added #3988: _WinAPI_GetSystemPowerStatus() return Battery status saver. - Added #3985: _ArrayDisplay() + $WS_EX_TOPMOST. - Added #3991: _SQLite_ForeignKeys() and Add a parameter in _SQLite_Open() to set it also. - Added #3990: _IsPressed() return in @extended if the key is still pressed. - Added: _DebugSetup(..., 1) does not interact with script being debug, Report infos copied to clipboard - Added: _WinAPI_SetWindowTheme() example to demonstrate Checkbox or Radio controls coloring. - Added #3997: _WinAPI_RegisterShellHookWindow() example improvement. - Added #3999: _WinAPI_OemToChar() performance improvement. - Added #3946: _ChooseFont() updated defaults (thanks argumentum). - Added: _DateDiff(), _DateAdd() using array for [days, hours, minutes, seconds]. - Added: _DebugSetup() Type 6, same as 1 but a timeout to close the report log windows. - Fixed #3894: _WinAPI_GetProcessName() returns incorrect result when process ID is invalid. - Fixed: "Then SetError()" in several standard UDF. - Fixed #3921: Missing _GUICtrlStatusBar_SetParts() examples. - Fixed: Doc typo $GPIP_ERR* >> $GDIP_ERR*. - Fixed #3926: _GUICtrlTreeView_SetChildren() not set/reset chidren flag. - Fixed: _WinAPI_DisplayStruct() elements containing chr(124). - Fixed #3945: StringRegExp() /s include VT. - Fixed #3949: _ArrayDisplay() does show multiple subscript of an array. - Fixed #3954: links in libfunction constants. - Fixed: missing doc description $iSubItem = - 1 in _GUICtrlListView_SetItemText(). - Fixed #3959: _WinAPI_ShellUserAuthenticationDlg() example. - Fixed #3975: unrelated link in Pcre doc. - Fixed #3903: _GuiCtrlTab_GetItem() does work on external process. - Fixed #3992: _WinAPI_DwmSetWindowAttribute() does not support all MSDN attributes. - Fixed #4001: _GUICtrlListView_*() example ($tagNMITEMACTIVATE). - Fixed #4003: _ArrayPush() doc precision. - Fixed: _GUICtrlButton_SetSplitInfo() example crash. - Fixed: Support of Notepad under Win11 for _DebugSetup(). - Fixed #4022: Various doc duplicated words. - Fixed #4031: _DebugArrayDisplay() buttons display. - Fixed: _DebugArrayDisplay() not executed if @error on entering ($ARRAYDISPLAY_CHECKERROR if no display wanted on @error). - Fixed #4033: _DateTimeSplit() setting $aTimePart[0] whem no time defined. - Fixed #4024: _DebugSetup(,, 5) (notepad window) not working under Windows 11. - Fixed: _WinAPI_IsElevated() @extended return value (Thanks Argumentum). - Fixed #4039: _GUICtrlTreeView_Delete() with $hWnd. - Fixed #4038: _GUICtrlRichEdit_StreamToFile() extra new paragraph. - Fixed #4029: _Date_Time_SystemTimeToDateTimeStr() Wrong output. - Fixed #4040: _GUICtrlRichEdit_SetZoom() parameter limitation bug. - Fixed #4041: _GUICtrlStatusBar_SetIcon() not shown. Submitter Jon Submitted 07/08/2025 Category Beta  
    2 points
×
×
  • Create New...