Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/29/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.
    4 points
  2. 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
  3. 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
    2 points
  4. 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 New update Description: The IStream2 UDF (Interface Stream User Defined Function) is an AutoIt library designed to create, manipulate, and interact with IStream COM objects, implementing all methods of the IStream interface defined by Microsoft. This interface enables operations such as reading, writing, seeking, and copying on data streams, whether file-based or in-memory. Version 2 of this UDF has been optimized for native AutoIt usage, removing the dependency on AutoItObject.au3, making it lighter, self-contained, and more accessible.The UDF provides robust error handling through HRESULT codes, well-defined constants for COM flags (STGM, STGC, etc.), and comprehensive documentation for each function. It is ideal for developers looking to manipulate data streams in various contexts, such as file processing, memory management, or integration with structured storage systems. The previous version has been retained for compatibility reasons. This version 2 is designed to be fully compatible with any development using the IStorage interface, while avoiding data conflicts. IStream2.au3
    1 point
  5. @WildByDesign I did run into someone already mentioning sparse package manager and having to register the application along with other things that I didn't understand as it was C language specific. Then for now I'll stick with my workaround until I learn a thing or two about certificates and whatnot. Thank you for that.
    1 point
  6. Func Start($StringCall) ; argumentum ;~ If @AutoItExe = @ScriptFullPath Then this is an EXE Return ShellExecute(@AutoItExe, (@AutoItExe = @ScriptFullPath ? '' : ' "' & @ScriptFullPath & '" ') & $StringCall) ; this should work, I guess EndFunc Func Start($StringCall) ; 0xC0FFEE ;~ Run(@ComSpec & " /C AutoIt3.exe """ & @ScriptFullPath & """ ""Notify"" ""Hello World.""","C:\Program Files (x86)\AutoIt3") Return Run(@ComSpec & " /C AutoIt3.exe """ & @ScriptFullPath & """ " & $StringCall ,StringLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1) -1),@SW_HIDE) EndFunc the above 2 options should work better because AutoIt can be installed other than default. Regardless, I still get that "rc:-1073740771" crash ? PS: I'd love to dig deeper into the code and troubleshoot it but am too busy 😭
    1 point
  7. I tried the example and it works, but it leaves a lot to be desired having to specify buffer size, maximum line length, and number of elements. To be useful it has to work no matter what I throw at it, as certainly I would never know before-hand any of this without making the default limits very large to cover all bases. I mean, you could make the buffer equal to the file size and process elements in chunks of 1000, but how to know the maximum line length other than to make it overly large? Is there a better way? But the biggest issue is speed. Throwing a 200KB section at it with 3674 elements (most with line lengths of 50, max less than 100) took 59ms on my computer. Not too bad. However, I previously solved the 32KB section limit by reading the file as text and parsing it. My solution by comparison takes only 36ms; I expected the example using GetPrivateProfileSection to be faster. Perhaps someone more advanced could do it.
    1 point
  8. Maybe something like this? https://learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers Edit: And in SMF I use something like this for optional shell integration. RegWrite("HKEY_CURRENT_USER\Software\Classes\Directory\shell\Search with SMF", "Icon", "REG_EXPAND_SZ", """" & @ScriptFullPath & """") RegWrite("HKEY_CURRENT_USER\Software\Classes\Directory\shell\Search with SMF\command", "", "REG_SZ", """" & @ScriptFullPath & """ ""%l""") RegWrite("HKEY_CURRENT_USER\Software\Classes\Drive\shell\Search with SMF", "Icon", "REG_EXPAND_SZ", """" & @ScriptFullPath & """") RegWrite("HKEY_CURRENT_USER\Software\Classes\Drive\shell\Search with SMF\command", "", "REG_SZ", """" & @ScriptFullPath & """ ""%l""") RegWrite("HKEY_CURRENT_USER\Software\Classes\Directory\shell\Search with SMF for duplicate files", "Icon", "REG_EXPAND_SZ", """" & @ScriptFullPath & """") RegWrite("HKEY_CURRENT_USER\Software\Classes\Directory\shell\Search with SMF for duplicate files\command", "", "REG_SZ", """" & @ScriptFullPath & """ ""%l -duplicates""") RegWrite("HKEY_CURRENT_USER\Software\Classes\Drive\shell\Search with SMF for duplicate files", "Icon", "REG_EXPAND_SZ", """" & @ScriptFullPath & """") RegWrite("HKEY_CURRENT_USER\Software\Classes\Drive\shell\Search with SMF for duplicate files\command", "", "REG_SZ", """" & @ScriptFullPath & """ ""%l -duplicates""") and this in ICU for integration into desktop context menu RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\shell\ICU_ContextMenu_Anchor", "MUIVerb", "REG_SZ", "ICU") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\shell\ICU_ContextMenu_Anchor", "Position", "REG_SZ", "Bottom") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\shell\ICU_ContextMenu_Anchor", "Icon", "REG_EXPAND_SZ", @ScriptFullPath & ",0") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\shell\ICU_ContextMenu_Anchor", "ExtendedSubCommandsKey", "REG_SZ", "DesktopBackground\ContextMenus\ICU") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\001_ICU", "Icon", "REG_EXPAND_SZ", "shell32.dll,-22") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\001_ICU", "MUIVerb", "REG_SZ", "Open ICU Settings") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\001_ICU\command", "", "REG_EXPAND_SZ", @ScriptFullPath) RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\002_ICU", "Icon", "REG_EXPAND_SZ", "shell32.dll,-7") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\002_ICU", "MUIVerb", "REG_SZ", "Save Desktop Layout") RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\002_ICU", "CommandFlags", "REG_DWORD", 0x040) ; ECF_SEPARATORAFTER RegWrite("HKEY_CURRENT_USER\Software\Classes\DesktopBackground\ContextMenus\ICU\Shell\002_ICU\command", "", "REG_EXPAND_SZ", @ScriptFullPath & " save")
    1 point
  9. 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
    1 point
×
×
  • Create New...