Leaderboard
Popular Content
Showing content with the highest reputation since 08/08/2025 in all areas
-
AutoIt v3.3.18.0 has been released - mainly a UDF release. Thanks to @jpm and the MVPs who were responsible for the majority of code in this version. Download it here. Complete list of changes: History12 points
-
The work speaks for itself. ; https://www.autoitscript.com/forum/topic/213089-click-fun/#findComment-1545452 ;---------------------------------------------------------------------------------------- ; Title...........: _Explosion.au3 ; Description.....: Simulates an explosion effect on a series of popup windows. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.3 ; Note............: Testet in Win10 22H2 Date:28/08/2025 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <WindowsConstants.au3> #include <Math.au3> #include <GUIConstantsEx.au3> #include <WinAPIConstants.au3> _Example() Func _Example() Local $hGUI = GUICreate('Fireworks Example', 500, 300) Local $idBtn_Click = GUICtrlCreateButton("Click", 400, 270, 85, 25) Local $idBtn_Close = GUICtrlCreateButton("Close", 300, 270, 85, 25) GUISetState(@SW_SHOW) Local $msg, $aPos While True $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ; standard window close GUIDelete($hGUI) Sleep(50) $aPos = MouseGetPos() _Explosion($aPos[0] - 250, $aPos[1] + 150, 20) ExitLoop Case $idBtn_Close ; The window will shrink and then explode. $aPos = _Shrink($hGUI) _Explosion($aPos[0], $aPos[1]) ExitLoop Case $idBtn_Click ; explosion at the mouse cursor position. $aPos = MouseGetPos() _Explosion($aPos[0], $aPos[1]) EndSwitch WEnd EndFunc Func _Shrink($hWin, $iSteps = 10) Local $aWPos = WinGetPos($hWin) Local $iCenterX = $aWPos[0] + ($aWPos[2] / 2) Local $iCenterY = $aWPos[1] + ($aWPos[3] / 2) Local $iNewW, $iNewH, $iNewX, $iNewY For $i = 1 To $iSteps $iNewW = $aWPos[2] - ($i * $aWPos[2] / $iSteps) $iNewH = $aWPos[3] - ($i * $aWPos[3] / $iSteps) $iNewX = $aWPos[0] + (($aWPos[2] - $iNewW) / 2) $iNewY = $aWPos[1] + (($aWPos[3] - $iNewH) / 2) WinMove($hWin, '', $iNewX, $iNewY, $iNewW, $iNewH) Sleep(10) Next GUIDelete($hWin) Local $aPos[] = [$iCenterX, $iCenterY] Return $aPos EndFunc Func _Explosion($iX, $iY, $iFragments = 10) Local Const $aColors[5] = [0xFFD800, 0xFFFFFF, 0xD59262, 0x808141, 0x3B3C23] Local $aGUI[$iFragments][7] ; GUICreate For $i = 0 To $iFragments - 1 $aGUI[$i][1] = $iX ; x $aGUI[$i][2] = $iY ; y $aGUI[$i][3] = Random(5, 15, 1) ; w $aGUI[$i][4] = $aGUI[$i][3] ; h $aGUI[$i][5] = Random(15, 25, 1) ; speed $aGUI[$i][6] = $i * (360 / $iFragments); direction (circular) $aGUI[$i][0] = GUICreate('', $aGUI[$i][3], $aGUI[$i][4], $aGUI[$i][1], $aGUI[$i][2], $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetBkColor($aColors[Random(0, UBound($aColors) - 1, 1)]) GUISetState(@SW_SHOWNOACTIVATE) Next While 1 Local $bActive = False For $i = 0 To $iFragments - 1 If WinExists($aGUI[$i][0]) Then $bActive = True Local $fRad = _Radian($aGUI[$i][6]) $aGUI[$i][1] += ($aGUI[$i][5] * Cos($fRad)) $aGUI[$i][2] += ($aGUI[$i][5] * Sin($fRad)) $aGUI[$i][3] -= 1 $aGUI[$i][4] -= 1 $aGUI[$i][5] *= 0.95 WinMove($aGUI[$i][0], '', $aGUI[$i][1], $aGUI[$i][2], $aGUI[$i][3], $aGUI[$i][4]) If $aGUI[$i][3] <= 1 Or $aGUI[$i][4] <= 1 Then GUIDelete($aGUI[$i][0]) EndIf Next If Not $bActive Then ExitLoop Sleep(10) WEnd EndFunc have fun Thank you very much7 points
-
Latest update just released. See below for change log.6 points
-
Try this: ;Coded by UEZ build 2025-09-06 #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIConstants.au3> #include <WinAPISysWin.au3> _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172, $SC_DRAGMOVE = 0xF012 Global Const $iW = 300, $iH = $iW Global $hGUI = GUICreate("GDI+ Ring Progressbar", $iW, $iH, -1, -1, $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState() Global $aInterpolations[4][2] ;define the interpolated colors and positions $aInterpolations[0][0] = 3 $aInterpolations[1][0] = 0xFF800000 ;Red $aInterpolations[1][1] = 0 $aInterpolations[2][0] = 0xFFFF6700 ;Orange $aInterpolations[2][1] = 0.5 $aInterpolations[3][0] = 0xFFFFFF00 ;Yellow $aInterpolations[3][1] = 1.0 Global $fPerc = 0, $iSleep = 30 GUIRegisterMsg($WM_TIMER, "PlayAnim") DllCall("user32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", $iSleep, "int", 0) GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN") Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIRegisterMsg($WM_TIMER, "") GUIRegisterMsg($WM_LBUTTONDOWN, "") _GDIPlus_Shutdown() GUIDelete() Exit EndSwitch Until False Func PlayAnim() _GDIPlus_RingProgressbar($fPerc, $iW) $fPerc += 0.33333 If $fPerc > 100 Then $fPerc = 0 EndFunc ;==>PlayAnim Func _GDIPlus_RingProgressbar($fPerc, $iSize = 300, $sText = "Please wait...") Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iSize, $iSize) Local Const $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetPixelOffsetMode($hCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) _GDIPlus_GraphicsSetSmoothingMode($hCtxt, 2) If $fPerc < 0 Then $fPerc = 0 If $fPerc > 100 Then $fPerc = 100 Local Const $hPath = _GDIPlus_PathCreate(), _ $fRadius = $iSize / 1.5, $iX = ($iSize - $fRadius) / 2, $iY = ($iSize - $fRadius) / 2, _ $fDX = $iSize / 10, $fAngel = $fPerc * 3.6, $fSize = $iSize / 15 Local Const $hBrush = _GDIPlus_LineBrushCreate($iX, $fDX + $iY, $fRadius, $fRadius, 0, 0, 1) Local Const $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, $fRadius, $fRadius) _GDIPlus_MatrixRotate($hMatrix, -35, False) _GDIPlus_LineBrushMultiplyTransform($hBrush, $hMatrix, False) _GDIPlus_LineBrushSetPresetBlend($hBrush, $aInterpolations) _GDIPlus_MatrixDispose($hMatrix) Local Const $hPen = _GDIPlus_PenCreate2($hBrush, $fSize) _GDIPlus_PathAddArc($hPath, $iX, $fDX + $iY, $fRadius, $fRadius, -90, $fAngel) _GDIPlus_GraphicsDrawPath($hCtxt, $hPath, $hPen) _GDIPlus_PathReset($hPath) Local Const $hFamily = _GDIPlus_FontFamilyCreate("Verdana") Local Const $hFormat = _GDIPlus_StringFormatCreate() Local Const $tLayout = _GDIPlus_RectFCreate(0, $iSize / 12, $iSize, 0) Local Const $tLayout2 = _GDIPlus_RectFCreate(0, ($iSize + $iSize / 18) / 2, $iSize, 0) _GDIPlus_StringFormatSetAlign($hFormat, 1) Local Const $hBrush2 = _GDIPlus_BrushCreateSolid(0xF0FFFFFF) _GDIPlus_PenSetColor($hPen, 0xF0404040) _GDIPlus_PenSetWidth($hPen, $iSize / 100) _GDIPlus_PenSetLineJoin($hPen, 2) _GDIPlus_PathAddString($hPath, $sText, $tLayout, $hFamily, 0, $iSize / 12, $hFormat) _GDIPlus_PathAddString($hPath, StringFormat("%02d%", $fPerc), $tLayout2, $hFamily, 0, $iSize / 9, $hFormat) _GDIPlus_GraphicsDrawPath($hCtxt, $hPath, $hPen) _GDIPlus_GraphicsFillPath($hCtxt, $hPath, $hBrush2) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_PenDispose($hPen) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush2) _GDIPlus_PathDispose($hPath) Local $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _WinAPI_BitmapDisplayTransparentInGUI($hHBmp, $hGUI) _GDIPlus_BitmapDispose($hBitmap) _WinAPI_DeleteObject($hHBmp) EndFunc ;==>_GDIPlus_RingProgressbar Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $iFlags = $ULW_ALPHA, $bReleaseGDI = True, $tDest = Null, $iBGR = 0) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0) Local $tDim = DllStructCreate($tagBITMAP) If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) $tSize.X = $tDim.bmWidth $tSize.Y = $tDim.bmHeight $tBlend.Alpha = $iOpacity $tBlend.Format = 1 _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, $tDest, $tSize, $hMemDC, $tSource, $iBGR, $tBlend, $iFlags) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteDC($hMemDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) _SendMessage($hGUI, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0) EndFunc ;==>WM_LBUTTONDOWN5 points
-
Fastest method to get process name from handle
Musashi and 4 others reacted to AspirinJunkie for a topic
If every ounce of performance is really needed, then there are a few areas where optimization can be carried out to squeeze out a little more: #include <WinAPIProc.au3> Global $hUser32 = DllOpen('user32.dll') Global $hKernel32 = DllOpen('kernel32.dll') Global $hpsapi = DllOpen('psapi.dll') ; Run Notepad Run("notepad.exe") ; Wait up to 10 seconds for the Notepad window to appear. WinWait("[CLASS:Notepad]", "", 10) ; Retrieve the handle of the Notepad window using the classname of Notepad. Global $hWnd = WinGetHandle("[CLASS:Notepad]") ConsoleWrite("Notepad handle: " & $hWnd & @CRLF) ConsoleWrite("Notepad process: " & _WinAPI_GetWindowFileName3($hWnd) & @CRLF) ; time comparison Global Const $N = 1e4 Global $iT ConsoleWrite(@CRLF & " name time" & @CRLF & "---------------------------------------------" & @CRLF) ; the first measurement $iT = TimerInit() For $i = 1 To $N _WinAPI_GetWindowFileName($hWnd) Next $iT = TimerDiff($iT) ConsoleWrite(StringFormat("% 30s:\t%10.6f ms\n", "_WinAPI_GetWindowFileName ", ($iT) / $N)) ; the second measurement $iT = TimerInit() For $i = 1 To $N _WinAPI_GetWindowFileName2($hWnd) Next $iT = TimerDiff($iT) ConsoleWrite(StringFormat("% 30s:\t%10.6f ms\n", "_WinAPI_GetWindowFileName2", ($iT) / $N)) ; the third measurement $iT = TimerInit() For $i = 1 To $N _WinAPI_GetWindowFileName3($hWnd) Next $iT = TimerDiff($iT) ConsoleWrite(StringFormat("% 30s:\t%10.6f ms\n", "_WinAPI_GetWindowFileName3", ($iT) / $N)) ; close notepad WinKill($hWnd) Func _WinAPI_GetWindowFileName2($hWnd) Local Static $iNumChars = 512, $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iNumChars)) Local $aCall = DllCall($hUser32, "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0) Local $iPID = $aCall[2] $aCall = DllCall($hKernel32, 'handle', 'OpenProcess', 'dword', 0x00001010, 'bool', 0, 'dword', $iPID) Local $hProc = $aCall[0] DllCall($hpsapi, 'dword', 'GetModuleBaseNameW', 'handle', $hProc, 'handle', 0, 'struct*', $tBuff, 'int', $iNumChars) $aCall = DllCall($hKernel32, "bool", "CloseHandle", "handle", $hProc) Return DllStructGetData($tBuff, 1) EndFunc Func _WinAPI_GetWindowFileName3($hWnd) Local $aCall = DllCall($hKernel32, 'HANDLE', 'OpenProcess', 'DWORD', 0x410, 'BOOL', 0, 'DWORD', WinGetProcess($hWnd)), _ $hProc = $aCall[0] $aCall = DllCall($hpsapi, 'DWORD', 'GetModuleBaseNameW', 'HANDLE', $hProc, 'HANDLE', 0, 'WSTR', '', 'INT', 65536) DllCall($hKernel32, "BOOL", "CloseHandle", "HANDLE", $hProc) Return $aCall[3] EndFunc Otherwise, the solutions presented so far completely lack reasonable error management. And if only this function needs the DLL handles, then the global variables could be bypassed by defining them directly in the function as local static variables instead.5 points -
AutoIt Data Type Checker
argumentum and 4 others reacted to Trong for a topic
I had a dissatisfaction with IsNumber so this function was born: ; ========================================================================================= ; UDF: DataTypeChecker.au3 (strict-hex + numeric formats + IEEE754 + self-test: _RunSelfTest() ) ; Author: Dao Van Trong - TRONG.PRO ; Notes: ; - Type codes start at 1 (String = 1). IEEE-754 subtypes continue up to 24. ; - Unknown returns 0 (no numeric code assigned). ; - String detection order: Hex (0x... or bare even-length [0-9A-Fa-f]) → ; Numeric (US/EU/Thousands/Simple-EU) → Boolean-like → fallback String. ; - HWND is checked before Ptr to avoid misclassification. ; ========================================================================================= ; -------- Global Type Codes (1..24) -------- Global Const $TYPE_STRING = 1 Global Const $TYPE_INT32 = 2 Global Const $TYPE_INT64 = 3 Global Const $TYPE_DOUBLE = 4 Global Const $TYPE_BINARY = 5 Global Const $TYPE_BOOLEAN = 6 Global Const $TYPE_ARRAY = 7 Global Const $TYPE_MAP = 8 Global Const $TYPE_PTR = 9 Global Const $TYPE_STRUCT = 10 Global Const $TYPE_HWND = 11 Global Const $TYPE_OBJECT = 12 Global Const $TYPE_KEYWORD = 13 Global Const $TYPE_FUNCTION = 14 Global Const $TYPE_USERFUNCTION = 15 ; IEEE-754 sub-categories for Double Global Const $TYPE_POS_ZERO = 16 Global Const $TYPE_NEG_ZERO = 17 Global Const $TYPE_DENORMAL_POS = 18 Global Const $TYPE_DENORMAL_NEG = 19 Global Const $TYPE_NORMAL_POS = 20 Global Const $TYPE_NORMAL_NEG = 21 Global Const $TYPE_POS_INFINITY = 22 Global Const $TYPE_NEG_INFINITY = 23 Global Const $TYPE_NAN = 24 ; Unknown uses 0 (no constant) ; -------- Code → Name -------- Func _GetDataTypeName($i) Select Case $i = $TYPE_STRING Return "String" Case $i = $TYPE_INT32 Return "Int32" Case $i = $TYPE_INT64 Return "Int64" Case $i = $TYPE_DOUBLE Return "Double/Float" Case $i = $TYPE_BINARY Return "Binary/Hex" Case $i = $TYPE_BOOLEAN Return "Boolean" Case $i = $TYPE_ARRAY Return "Array" Case $i = $TYPE_MAP Return "Map" Case $i = $TYPE_PTR Return "Pointer" Case $i = $TYPE_STRUCT Return "DLL Struct" Case $i = $TYPE_HWND Return "Window Handle" Case $i = $TYPE_OBJECT Return "Object" Case $i = $TYPE_KEYWORD Return "Keyword" Case $i = $TYPE_FUNCTION Return "Function" Case $i = $TYPE_USERFUNCTION Return "UserFunction" Case $i = $TYPE_POS_ZERO Return "+Zero" Case $i = $TYPE_NEG_ZERO Return "-Zero" Case $i = $TYPE_DENORMAL_POS Return "deNormal (+)" Case $i = $TYPE_DENORMAL_NEG Return "deNormal (−)" Case $i = $TYPE_NORMAL_POS Return "Normal (+)" Case $i = $TYPE_NORMAL_NEG Return "Normal (−)" Case $i = $TYPE_POS_INFINITY Return "+Infinity" Case $i = $TYPE_NEG_INFINITY Return "-Infinity" Case $i = $TYPE_NAN Return "NaN" Case Else Return "Unknown" EndSelect EndFunc ;==>_GetDataTypeName ; -------- IEEE-754 classifier for Double (robust for 64-bit via hi/low dwords) -------- Func _CheckIEEE754Category($dVal) ; Overlay: write the double, then read two dwords at the same address Local $tDouble = DllStructCreate("double") DllStructSetData($tDouble, 1, $dVal) Local $p = DllStructGetPtr($tDouble) Local $tWords = DllStructCreate("dword;dword", $p) ; [1]=low, [2]=high on little-endian Local $low = DllStructGetData($tWords, 1) Local $high = DllStructGetData($tWords, 2) Local $sign = BitAND(BitShift($high, 31), 1) Local $exp = BitAND(BitShift($high, 20), 0x7FF) Local $fracHigh = BitAND($high, 0x000FFFFF) Local $fracLow = $low Local $fracIsZero = ($fracHigh = 0 And $fracLow = 0) If $exp = 0 Then If $fracIsZero Then Return ($sign ? $TYPE_NEG_ZERO : $TYPE_POS_ZERO) Else Return ($sign ? $TYPE_DENORMAL_NEG : $TYPE_DENORMAL_POS) EndIf ElseIf $exp = 0x7FF Then If $fracIsZero Then Return ($sign ? $TYPE_NEG_INFINITY : $TYPE_POS_INFINITY) Else Return $TYPE_NAN EndIf Else Return ($sign ? $TYPE_NORMAL_NEG : $TYPE_NORMAL_POS) EndIf EndFunc ;==>_CheckIEEE754Category ; -------- Decide Int32 vs Int64 by range -------- Func _IntCodeFromNumber($n) If $n >= -2147483648 And $n <= 2147483647 Then Return $TYPE_INT32 Else Return $TYPE_INT64 EndIf EndFunc ;==>_IntCodeFromNumber ; -------- Normalize & classify numeric strings -------- ; Returns: type code (2/3 for ints OR IEEE-754 sub-codes 16..24 for doubles) Func _ParseNumericString($s) ; US: 1,234.56 → remove commas, parse with dot If StringRegExp($s, '^[+-]?\d{1,3}(,\d{3})*(\.\d+)?$') Then Local $u = StringReplace($s, ",", "") If StringInStr($u, ".") Then Return _CheckIEEE754Category(Number($u)) Else ; For grouped integers (US), we follow user's expectation: ; treat as Double category (Normal +/-) rather than Int32/Int64 Return _CheckIEEE754Category(Number($u)) EndIf EndIf ; EU: 1.234,56 → remove dots, replace comma with dot If StringRegExp($s, '^[+-]?\d{1,3}(\.\d{3})*(,\d+)?$') Then Local $e = StringReplace(StringReplace($s, ".", ""), ",", ".") If StringInStr($s, ",") Then Return _CheckIEEE754Category(Number($e)) Else ; Grouped integer (EU) → follow same rule: classify via IEEE-754 Return _CheckIEEE754Category(Number($e)) EndIf EndIf ; Thousands only: 1,234 or 1.234 → strip separators If StringRegExp($s, '^[+-]?\d{1,3}([,\.]\d{3})+$') Then Local $t = StringReplace(StringReplace($s, ",", ""), ".", "") ; Per user's expected results: treat grouped integer as Double category Return _CheckIEEE754Category(Number($t)) EndIf ; Simple EU decimals: 123,45 → replace comma with dot If StringRegExp($s, '^[+-]?\d+,\d+$') Then Local $d = StringReplace($s, ",", ".") Return _CheckIEEE754Category(Number($d)) EndIf ; Plain ints/floats (no separators) If StringIsInt($s) Then Return _IntCodeFromNumber(Number($s)) If StringIsFloat($s) Then Return _CheckIEEE754Category(Number($s)) ; Not numeric Return 0 EndFunc ;==>_ParseNumericString ; -------- Parse strings: Hex → Numeric → Boolean-like → String -------- Func _ParseStringValue($s) $s = StringStripWS($s, 8) ; Hex with prefix 0x, body must have even length If StringRegExp($s, "^0[xX][0-9A-Fa-f]+$") Then Local $hexBody = StringMid($s, 3) If Mod(StringLen($hexBody), 2) = 0 Then Return $TYPE_BINARY EndIf ; Bare hex (0-9 A-F), even length accepted as hex (as requested) If StringRegExp($s, "^[0-9A-Fa-f]+$") Then If Mod(StringLen($s), 2) = 0 Then Return $TYPE_BINARY EndIf ; Numeric formats Local $numCode = _ParseNumericString($s) If $numCode <> 0 Then Return $numCode ; Boolean-like strings Switch StringLower($s) Case "true", "false" Return $TYPE_BOOLEAN EndSwitch ; Fallback string Return $TYPE_STRING EndFunc ;==>_ParseStringValue ; -------- Public: get type code for any value -------- Func _GetDataType($v) ; AutoIt-specific first (order matters) If IsArray($v) Then Return $TYPE_ARRAY If IsMap($v) Then Return $TYPE_MAP If IsHWnd($v) Then Return $TYPE_HWND If IsPtr($v) Then Return $TYPE_PTR If IsDllStruct($v) Then Return $TYPE_STRUCT If IsObj($v) Then Return $TYPE_OBJECT If IsKeyword($v) Then Return $TYPE_KEYWORD Local $sType = VarGetType($v) If IsFunc($v) Then If $sType = "UserFunction" Then Return $TYPE_USERFUNCTION Else Return $TYPE_FUNCTION EndIf EndIf ; Native primitives If $sType = "Int32" Then Return $TYPE_INT32 If $sType = "Int64" Then Return $TYPE_INT64 If $sType = "Double" Then Return _CheckIEEE754Category($v) If IsBinary($v) Then Return $TYPE_BINARY If IsBool($v) Then Return $TYPE_BOOLEAN ; Strings If IsString($v) Then Return _ParseStringValue($v) ; Unknown Return 0 EndFunc ;==>_GetDataType ; -------- Helper: is any numeric type? (native or string-based) -------- Func _IsNumber($v) Local $c = _GetDataType($v) Return ($c = $TYPE_INT32 Or $c = $TYPE_INT64 Or $c = $TYPE_DOUBLE Or _ $c = $TYPE_POS_ZERO Or $c = $TYPE_NEG_ZERO Or _ $c = $TYPE_DENORMAL_POS Or $c = $TYPE_DENORMAL_NEG Or _ $c = $TYPE_NORMAL_POS Or $c = $TYPE_NORMAL_NEG Or _ $c = $TYPE_POS_INFINITY Or $c = $TYPE_NEG_INFINITY Or _ $c = $TYPE_NAN) EndFunc ;==>_IsNumber ; ========================================================================================= ; SELF-TEST (English logs, prefixes: '+' OK, '!' ERROR, '-' INFO) ; ========================================================================================= Func _AddTest(ByRef $arr, $val, $expectedName, $label) ReDim $arr[UBound($arr) + 1][3] $arr[UBound($arr) - 1][0] = $val $arr[UBound($arr) - 1][1] = $expectedName $arr[UBound($arr) - 1][2] = $label EndFunc ;==>_AddTest Func __TestFunc() Return 1 EndFunc ;==>__TestFunc Func _RunSelfTest() ConsoleWrite("- Starting self-test..." & @CRLF) Local $tests[0][3] ; --- String fallback --- _AddTest($tests, "Hello", "String", "Plain string") ; Per requirement: bare [0-9A-F] with even length is HEX _AddTest($tests, "123ABC", "Binary/Hex", "Bare hex (even)") ; --- Int32 / Int64 --- _AddTest($tests, 42, "Int32", "Integer") _AddTest($tests, -999, "Int32", "Negative int") _AddTest($tests, 9223372036854775807, "Int64", "Max Int64") _AddTest($tests, -9223372036854775808, "Int64", "Min Int64") ; --- Double / IEEE754 normal --- _AddTest($tests, 3.14159, "Normal (+)", "Positive double") _AddTest($tests, -2.71828, "Normal (−)", "Negative double") ; --- Binary/Hex --- _AddTest($tests, "0x1A2B", "Binary/Hex", "Prefixed hex string") _AddTest($tests, "DEADBEEF", "Binary/Hex", "Bare hex string") ; --- Boolean --- _AddTest($tests, True, "Boolean", "True literal") _AddTest($tests, "false", "Boolean", "Boolean-like string") ; --- Array --- Local $arr[2] = [1, 2] _AddTest($tests, $arr, "Array", "Simple array") ; --- Map (correct syntax) --- Local $mMap[] $mMap["Key"] = "Value" _AddTest($tests, $mMap, "Map", "Map object") ; --- Ptr --- Local $p = Ptr(0x123456) _AddTest($tests, $p, "Pointer", "Pointer value") ; --- DllStruct --- Local $st = DllStructCreate("int;char[4]") _AddTest($tests, $st, "DLL Struct", "DllStruct sample") ; --- HWND (create GUI to ensure valid handle) --- Local $hGUI = GUICreate("DT Test", 1, 1, -100, -100) GUISetState(@SW_SHOW, $hGUI) _AddTest($tests, $hGUI, "Window Handle", "GUI handle") ; --- Object --- Local $o = ObjCreate("Scripting.Dictionary") _AddTest($tests, $o, "Object", "COM object") ; --- Keyword --- _AddTest($tests, Default, "Keyword", "Keyword Default") _AddTest($tests, Null, "Keyword", "Keyword Null") ; --- Function & UserFunction --- _AddTest($tests, Eval, "Function", "Builtin function") _AddTest($tests, __TestFunc, "UserFunction", "User-defined function") ; --- IEEE754 specials --- _AddTest($tests, +0.0, "+Zero", "Positive zero") _AddTest($tests, -0.0, "-Zero", "Negative zero") _AddTest($tests, (1.0 / 0.0), "+Infinity", "Positive infinity") _AddTest($tests, (-1.0 / 0.0), "-Infinity", "Negative infinity") _AddTest($tests, (0.0 / 0.0), "NaN", "Not-a-Number") ; --- Numeric strings: US/EU/Thousands/Simple-EU --- _AddTest($tests, "1,234.56", "Normal (+)", "US numeric string") _AddTest($tests, "1.234,56", "Normal (+)", "EU numeric string") _AddTest($tests, "1,234", "Normal (+)", "Thousand separator comma") _AddTest($tests, "1.234", "Normal (+)", "Thousand separator dot") _AddTest($tests, "123,45", "Normal (+)", "EU decimal comma") ; --- Run all --- For $i = 0 To UBound($tests) - 1 Local $input = $tests[$i][0] Local $expected = $tests[$i][1] Local $label = $tests[$i][2] Local $code = _GetDataType($input) Local $got = _GetDataTypeName($code) If $got = $expected Then ConsoleWrite("- " & '_IsNumber(' & $input & ") -> " & _IsNumber($input) & @CRLF) ConsoleWrite("+ " & $label & ' "' & $input & '" -> (' & $code & ') ' & $got & @CRLF) Else ConsoleWrite("! " & $label & ' "' & $input & '" -> (' & $code & ') ' & $got & " | Expected: " & $expected & @CRLF) EndIf Next ConsoleWrite("- Self-test complete." & @CRLF) ; Clean up GUI created for HWND test GUIDelete($hGUI) EndFunc ;==>_RunSelfTest ; ========================================================================================= ; Self-test routine: kiểm tra các giá trị mẫu và in PASS/FAIL ; ========================================================================================= Func _RunSelfTest2() Local $tests = [ _ ["String literal", "Hello", $TYPE_STRING], _ ["Int32 literal", 123, $TYPE_INT32], _ ["Int64 literal", 5000000000, $TYPE_INT64], _ ["Double normal +", 3.14, $TYPE_NORMAL_POS], _ ["Double normal −", -2.5, $TYPE_NORMAL_NEG], _ ["+Zero (double)", 0.0, $TYPE_POS_ZERO], _ ["-Zero (double)", -0.0, $TYPE_NEG_ZERO], _ ["Subnormal", Number("1e-320"), $TYPE_DENORMAL_POS], _ ["+Infinity", 1 / 0, $TYPE_POS_INFINITY], _ ["-Infinity", -1 / 0, $TYPE_NEG_INFINITY], _ ["NaN", 0 / 0, $TYPE_NAN], _ ["Hex 0x…", "0x1A2B", $TYPE_BINARY], _ ["Bare hex", "FACE", $TYPE_BINARY], _ ["US number", "1,234.56", $TYPE_NORMAL_POS], _ ["EU number", "1.234,56", $TYPE_NORMAL_POS], _ ["Thou only", "1,234", $TYPE_NORMAL_POS], _ ["Simple EU dec", "123,45", $TYPE_NORMAL_POS], _ ["Bool-like true", "true", $TYPE_BOOLEAN], _ ["Bool-like false", "false", $TYPE_BOOLEAN] _ ] Local $allOK = True ConsoleWrite(@CRLF & "---- Running DataTypeChecker Self-Test ----" & @CRLF) For $i = 0 To UBound($tests) - 1 Local $desc = $tests[$i][0] Local $val = $tests[$i][1] Local $exp = $tests[$i][2] Local $got = _GetDataType($val) Local $name = _GetDataTypeName($got) If $got = $exp Then ConsoleWrite("- _IsNumber(" & $val & ') -> ' & _IsNumber($val) & @CRLF) ConsoleWrite("+ PASS: " & $desc & ' "' & $val & '" -> ' & $name & " (" & $got & ")" & @CRLF) Else ConsoleWrite("! FAIL: " & $desc & ' "' & $val & '" -> Expected ' & _ _GetDataTypeName($exp) & " (" & $exp & "), Got " & _ $name & " (" & $got & ")" & @CRLF) $allOK = False EndIf Next ConsoleWrite("---- Self-Test " & ($allOK ? "+ PASSED" : "! FAILED") & " ----" & @CRLF & @CRLF) Return $allOK EndFunc ;==>_RunSelfTest2 ; Uncomment to run self-test on execute ; _RunSelfTest() ; _RunSelfTest2()5 points -
Brief: native WinMove() has a "speed" parameter for a more fluent movement. unfortunately, that applies to the change in position, but not the change in size. the position changes in the specified "speed", but size changes abruptly. _WinPose() is similar to WinMove(), except that move and resize are simultaneous, both conform to the speed parameter. UDF: (save as "WinPose.au3") #include-once #include <WinAPISysWin.au3> ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinPose ; Description ...: same as native WinMove(), except that move and resize are simultaneous, both conform to the speed parameter. ; Syntax ........: _WinPose($hWnd, $sText, $x, $y, $w, $h[, $speed = 0]) ; Parameters ....: $hWnd - the title/hWnd/class of the window to pose. ; $sText - the text of the window to pose. ; $x - X coordinate to move to. ; $y - Y coordinate to move to. ; $w - [optional] new width of the window. ; $h - [optional] new height of the window. ; $speed - [optional] the speed to pose the window (smaller value = faster speed, 0 = instantaneous). ; Return values .: Success - a handle to the window. ; Failure - 0 if the window is not found (also sets @error to non-zero). ; Author ........: orbs ; Modified ......: ; Remarks .......: parameters and return values are practically identical to those of the native WinMove() function. ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================================== Func _WinPose($hWnd, $sText, $x, $y, $w = Default, $h = Default, $speed = 0) ; find the window to move If Not IsHWnd($hWnd) Then $hWnd = WinGetHandle($hWnd, $sText) If @error Then Return SetError(1, 0, False) EndIf Local $aPos = WinGetPos($hWnd) If @error Then Return SetError(2, 0, False) ; initialize variables Local Enum $pos_x, $pos_y, $pos_w, $pos_h Local Enum $aiCurrent, $aiTarget, $aiDelta, $aiRatio Local $aPosTarget[4][4] = [[$aPos[$pos_x], $x, 0, 0], [$aPos[$pos_y], $y, 0, 0], [$aPos[$pos_w], $w, 0, 0], [$aPos[$pos_h], $h, 0, 0]] ; accomodate for Default keyword For $iElement = 0 To 3 If $aPosTarget[$iElement][$aiTarget] = Default Then $aPosTarget[$iElement][$aiTarget] = $aPos[$iElement] Next ; calculate delta For $iElement = 0 To 3 $aPosTarget[$iElement][$aiDelta] = $aPosTarget[$iElement][$aiTarget] - $aPosTarget[$iElement][$aiCurrent] Next ; find the maximum delta Local $iMaxElement = 0, $iMaxDelta = 0 For $iElement = 0 To 3 If Abs($aPosTarget[$iElement][$aiDelta]) > $iMaxDelta Then $iMaxElement = $iElement $iMaxDelta = $aPosTarget[$iElement][$aiDelta] EndIf Next ; accomodate for negative delta If ($aPosTarget[$iMaxElement][$aiTarget] - $aPos[$iMaxElement]) < 0 Then $iMaxDelta = -$iMaxDelta ; calculate ratio for all elements For $iElement = 0 To 3 $aPosTarget[$iElement][$aiRatio] = $aPosTarget[$iElement][$aiDelta] / $iMaxDelta Next ; move & resize the window gradually For $iStep = 0 To $iMaxDelta For $iElement = 0 To 3 $aPosTarget[$iElement][$aiCurrent] += $aPosTarget[$iElement][$aiRatio] Next For $i = 1 To $speed _WinAPI_MoveWindow($hWnd, _ $aPosTarget[$pos_x][$aiCurrent], _ $aPosTarget[$pos_y][$aiCurrent], _ $aPosTarget[$pos_w][$aiCurrent], _ $aPosTarget[$pos_h][$aiCurrent], False) Next Next ; validate final outcome is as expected Return WinMove($hWnd, '', $x, $y, $w, $h) EndFunc ;==>_WinPose Example: #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <AutoItConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include 'WinPose.au3' Global Const $iMinW = 250, $iMinH = 100 Global $x, $y, $w, $h, $speed Global $hGUI = GUICreate('_WinPose() Example', $iMinW, $iMinH) Global $gButton = GUICtrlCreateButton('Click Me!', 25, 25, 200, 50) GUICtrlSetResizing(-1, $GUI_DOCKBORDERS) GUISetState(@SW_SHOW) Global $msg While True $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE ExitLoop Case $gButton $w = Random($iMinW, @DesktopWidth / 3, 1) $h = Random($iMinH, @DesktopHeight / 3, 1) $x = Random(0, @DesktopWidth - $w, 1) $y = Random(0, @DesktopHeight - $h, 1) $speed = Random(10, 100, 1) _WinPose($hGUI, '', $x, $y, $w, $h, $speed) EndSwitch WEnd click the button to pose the window in a new random position and size, in a random speed. enjoy 🙂5 points
-
Goal: select the squares to match every row and column results (screenshot below). you can change the puzzle type (addition or multiplication), grid size (3x3 to 9x9), and other preferences. Dependency: this app is also a showcase for the WinPose UDF (which was actually developed for it). Script: #Region wrapper directives #AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=N #AutoIt3Wrapper_Compile_both=N #AutoIt3Wrapper_Icon=MagicMath.ico #AutoIt3Wrapper_UseUpx=N #AutoIt3Wrapper_Res_Description=Magic Math #AutoIt3Wrapper_Res_Fileversion=1.0.0.0 #AutoIt3Wrapper_Res_ProductVersion=1.0.0.0 #AutoIt3Wrapper_Res_LegalCopyright=Or Ben Shabat (or.ben.shabat@gmail.com) #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/SO /RM #EndRegion wrapper directives #NoTrayIcon #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <ColorConstants.au3> #include <FontConstants.au3> #include <AutoItConstants.au3> #include <EditConstants.au3> #include <Math.au3> #include 'WinPose.au3' ; init ; - general Global Const $sAppName = 'Magic Math' ; - colors Global Const $iDefaultSqrSize = 45 Global Const $iDefaultColCount = 5 Global Const $iDefaultRowCount = 5 Global Const $iDefaultResizeSpeed = 50 Global Const $iColor_BoxText = $COLOR_BLACK Global Const $iColor_BoxTextError = $COLOR_RED Global Const $iColor_BoxUnchecked = $COLOR_LIGHTGRAY Global Const $iColor_BoxChecked = $COLOR_LIGHTGREEN Global Const $iColor_BoxEliminated = $COLOR_DARKGRAY Global Const $iColor_BoxResult = $COLOR_PEACHPUFF Global Const $iColor_MenuItem = $COLOR_DARKBLUE Global Const $iColor_MenuItemPressed = $COLOR_LIGHTGRAY Global Const $iColor_MenuItemEmphasis = $COLOR_WHITE Global Const $iColor_Vprimary = $COLOR_LIMEGREEN Global Const $iColor_Vsecondary = $COLOR_AQUA ; - symbols Global Const $symSetup = Chr(64) ; Webdings Global Const $symRenew = Chr(81) ; Wingdings 3 Global Const $symSolve = Chr(97) ; Webdings Global Const $symHelp = Chr(115) ; Webdings Global Const $symP = Chr(200) ; Wingdings 2 Global Const $symX = Chr(208) ; Wingdings 2 Global Const $symV = Chr(252) ; Wingdings ; declare variables Global $bPuzzleTypeIsAddition = True Global $iColCount = $iDefaultColCount, $iRowCount = $iDefaultRowCount, $iSqrSize = $iDefaultSqrSize, $iResizeSpeed = $iDefaultResizeSpeed Global $iGUI_Width, $iGUI_Height, $hGUI Global $aPos, $iWDiff, $iHDiff ; - main GUI Global $gMenu_New, $gMenu_Solve, $gMenu_Pref, $gMenu_Help, $gdGUIStart, $gdGUIEnd, $gdGridStart, $gdGridEnd Global Enum $iGrid_iValue, $iGrid_gID, $iGrid_bSelected, $iGrid_bChecked, $iGrid_bEliminated, $iGrid_iDimCount Global $aGrid[$iColCount][$iRowCount][$iGrid_iDimCount] Global Enum $iResult_iValue, $iResult_iDiff, $iResult_iDimCount Global $aResultOfRow[$iRowCount][$iResult_iDimCount] Global $aResultOfCol[$iColCount][$iResult_iDimCount] Global $gPuzzleType Global $bUserInputAllowed Global $bCheckForVictory ; - pref GUI Global $gPuzzleType_Addition, $gPuzzleType_Multiplication, _ $gGridWidth_Down, $gGridWidth_Data, $gGridWidth_Up, _ $gGridHeight_Down, $gGridHeight_Data, $gGridHeight_Up, _ $gSqrSize_Down, $gSqrSize_Data, $gSqrSize_Up, _ $gResizeSpeed_data, _ $gOK ; GUI $iGUI_Width = $iSqrSize * ($iColCount + 3) + 2 $iGUI_Height = $iSqrSize * ($iRowCount + 2) + 2 $hGUI = GUICreate($sAppName, $iGUI_Width, $iGUI_Height) $aPos = WinGetPos($hGUI) $iWDiff = $aPos[2] - $iGUI_Width $iHDiff = $aPos[3] - $iGUI_Height BuildGUI() GUISetState(@SW_SHOW, $hGUI) ; main loop Global $msg Global $aCursorInfo $bCheckForVictory = False While True $msg = GUIGetMsg() Switch $msg Case $gMenu_New GUICtrlSetBkColor($gMenu_New, $iColor_MenuItemPressed) Sleep(100) Renew() Sleep(100) GUICtrlSetBkColor($gMenu_New, $GUI_BKCOLOR_TRANSPARENT) Case $gMenu_Solve GUICtrlSetBkColor($gMenu_Solve, $iColor_MenuItemPressed) Sleep(100) Solve() Sleep(100) GUICtrlSetBkColor($gMenu_Solve, $GUI_BKCOLOR_TRANSPARENT) Case $gMenu_Pref GUICtrlSetBkColor($gMenu_Pref, $iColor_MenuItemPressed) Sleep(100) BuildGUI(Pref()) Sleep(100) GUICtrlSetBkColor($gMenu_Pref, $GUI_BKCOLOR_TRANSPARENT) Case $gMenu_Help GUICtrlSetBkColor($gMenu_Help, $iColor_MenuItemPressed) Sleep(100) BuildGUI(Help()) Sleep(100) GUICtrlSetBkColor($gMenu_Help, $GUI_BKCOLOR_TRANSPARENT) Case $gdGridStart To $gdGridEnd If $bUserInputAllowed Then For $iRow = 0 To $iRowCount - 1 For $iCol = 0 To $iColCount - 1 If $msg = $aGrid[$iCol][$iRow][$iGrid_gID] Then $aGrid[$iCol][$iRow][$iGrid_bEliminated] = False $aGrid[$iCol][$iRow][$iGrid_bChecked] = Not $aGrid[$iCol][$iRow][$iGrid_bChecked] GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $aGrid[$iCol][$iRow][$iGrid_bChecked] ? $iColor_BoxChecked : $iColor_BoxUnchecked) EndIf Next Next $bCheckForVictory = True EndIf Case $GUI_EVENT_SECONDARYUP $aCursorInfo = GUIGetCursorInfo() If $aCursorInfo[4] > $gdGridStart And $aCursorInfo[4] < $gdGridEnd Then If $bUserInputAllowed Then For $iRow = 0 To $iRowCount - 1 For $iCol = 0 To $iColCount - 1 If $aCursorInfo[4] = $aGrid[$iCol][$iRow][$iGrid_gID] Then $aGrid[$iCol][$iRow][$iGrid_bChecked] = False $aGrid[$iCol][$iRow][$iGrid_bEliminated] = Not $aGrid[$iCol][$iRow][$iGrid_bEliminated] GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $aGrid[$iCol][$iRow][$iGrid_bEliminated] ? $iColor_BoxEliminated : $iColor_BoxUnchecked) EndIf Next Next $bCheckForVictory = True EndIf EndIf Case $GUI_EVENT_CLOSE ExitLoop EndSwitch If $bCheckForVictory Then If IsVictoryAchieved() Then ShowVictory() GUICtrlSetBkColor($gMenu_New, $iColor_MenuItemEmphasis) Sleep(125) Renew() Sleep(125) GUICtrlSetBkColor($gMenu_New, $GUI_BKCOLOR_TRANSPARENT) EndIf $bCheckForVictory = False EndIf WEnd Func Renew($bNew = True) $bUserInputAllowed = True Local $bNoZeroResults GUISetState(@SW_LOCK) Do $bNoZeroResults = True For $iRow = 0 To $iRowCount - 1 For $iCol = 0 To $iColCount - 1 If $bNew Then $aGrid[$iCol][$iRow][$iGrid_iValue] = $bPuzzleTypeIsAddition ? Random(1, 9, 1) : Random(2, 9, 1) $aGrid[$iCol][$iRow][$iGrid_bSelected] = (Random() < 0.5) $aGrid[$iCol][$iRow][$iGrid_bChecked] = False $aGrid[$iCol][$iRow][$iGrid_bEliminated] = False EndIf GUICtrlSetData($aGrid[$iCol][$iRow][$iGrid_gID], $aGrid[$iCol][$iRow][$iGrid_iValue]) GUICtrlSetColor($aGrid[$iCol][$iRow][$iGrid_gID], $iColor_BoxText) Select Case $aGrid[$iCol][$iRow][$iGrid_bChecked] GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $iColor_BoxChecked) Case $aGrid[$iCol][$iRow][$iGrid_bEliminated] GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $iColor_BoxEliminated) Case Else GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $iColor_BoxUnchecked) EndSelect GUICtrlSetCursor($aGrid[$iCol][$iRow][$iGrid_gID], $MCID_ARROW) Next Next Local $iResult For $iRow = 0 To $iRowCount - 1 $iResult = 0 For $iCol = 0 To $iColCount - 1 If $aGrid[$iCol][$iRow][$iGrid_bSelected] Then $iResult = Accumulate($iResult, $aGrid[$iCol][$iRow][$iGrid_iValue]) Next If $iResult = 0 Then $bNoZeroResults = False GUICtrlSetData($aResultOfRow[$iRow][$iResult_iValue], $iResult) GUICtrlSetFont($aResultOfRow[$iRow][$iResult_iValue], _Min($iSqrSize / 3, $iSqrSize / StringLen($iResult))) Next For $iCol = 0 To $iColCount - 1 $iResult = 0 For $iRow = 0 To $iRowCount - 1 If $aGrid[$iCol][$iRow][$iGrid_bSelected] Then $iResult = Accumulate($iResult, $aGrid[$iCol][$iRow][$iGrid_iValue]) Next If $iResult = 0 Then $bNoZeroResults = False GUICtrlSetData($aResultOfCol[$iCol][$iResult_iValue], $iResult) GUICtrlSetFont($aResultOfCol[$iCol][$iResult_iValue], _Min($iSqrSize / 3, $iSqrSize / StringLen($iResult))) Next Until $bNoZeroResults GUISetState(@SW_UNLOCK) EndFunc ;==>Renew Func Accumulate(ByRef $iBase, $iDelta) If $iBase = 0 Then Return $iDelta If $bPuzzleTypeIsAddition Then Return $iBase + $iDelta Else Return $iBase * $iDelta EndIf EndFunc ;==>Accumulate Func Solve() $bUserInputAllowed = False For $iRow = 0 To $iRowCount - 1 For $iCol = 0 To $iColCount - 1 GUICtrlSetBkColor($aGrid[$iCol][$iRow][$iGrid_gID], $aGrid[$iCol][$iRow][$iGrid_bSelected] ? $iColor_BoxChecked : $iColor_BoxEliminated) If $aGrid[$iCol][$iRow][$iGrid_bSelected] <> $aGrid[$iCol][$iRow][$iGrid_bChecked] Then GUICtrlSetColor($aGrid[$iCol][$iRow][$iGrid_gID], $iColor_BoxTextError) GUICtrlSetCursor($aGrid[$iCol][$iRow][$iGrid_gID], $MCID_NO) Next Next EndFunc ;==>Solve Func IsVictoryAchieved() Local $iResult For $iRow = 0 To $iRowCount - 1 $iResult = 0 For $iCol = 0 To $iColCount - 1 If $aGrid[$iCol][$iRow][$iGrid_bChecked] Then $iResult = Accumulate($iResult, $aGrid[$iCol][$iRow][$iGrid_iValue]) Next If GUICtrlRead($aResultOfRow[$iRow][$iResult_iValue]) <> $iResult Then Return False Next For $iCol = 0 To $iColCount - 1 $iResult = 0 For $iRow = 0 To $iRowCount - 1 If $aGrid[$iCol][$iRow][$iGrid_bChecked] Then $iResult = Accumulate($iResult, $aGrid[$iCol][$iRow][$iGrid_iValue]) Next If GUICtrlRead($aResultOfCol[$iCol][$iResult_iValue]) <> $iResult Then Return False Next Return True EndFunc ;==>IsVictoryAchieved Func ShowVictory() Sleep(150) Local $gV = GUICtrlCreateLabel($symV, 0, 0, $iGUI_Width, $iGUI_Height, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont($gV, _Min($iGUI_Height, $iGUI_Width) * 0.6, Default, Default, 'Wingdings') GUICtrlSetBkColor($gV, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetColor($gV, $iColor_Vprimary) For $i = 1 To 2 Sleep(125) GUICtrlSetColor($gV, $iColor_Vsecondary) Sleep(125) GUICtrlSetColor($gV, $iColor_Vprimary) Next Sleep(1000) GUICtrlDelete($gV) Sleep(250) EndFunc ;==>ShowVictory Func BuildGUI($bNew = True) GUISetFont($iSqrSize / 3, Default, Default, 'Tahoma') ; GUI contents $gdGUIStart = GUICtrlCreateDummy() ; - menu $gMenu_Pref = GUICtrlCreateLabel($symSetup, 1, 1 + $iSqrSize / 2, $iSqrSize * 1.5 - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetTip(-1, 'Set your preferences and construct a new puzzle', 'Setup') GUICtrlSetFont(-1, $iSqrSize / 2, Default, Default, 'Webdings') GUICtrlSetColor(-1, $iColor_MenuItem) GUICtrlSetCursor(-1, $MCID_HAND) $gMenu_New = GUICtrlCreateLabel($symRenew, 1, $iSqrSize + 1 + $iSqrSize / 2, $iSqrSize * 1.5 - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetTip(-1, 'Construct a new puzzle using current preferences', 'New Puzzle') GUICtrlSetFont(-1, $iSqrSize / 2, Default, Default, 'Wingdings 3') GUICtrlSetColor(-1, $iColor_MenuItem) GUICtrlSetCursor(-1, $MCID_HAND) $gMenu_Solve = GUICtrlCreateLabel($symV, 1, $iSqrSize * 2 + 1 + $iSqrSize / 2, $iSqrSize * 1.5 - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetTip(-1, 'I give up :(', 'Show Solution') GUICtrlSetFont(-1, $iSqrSize / 2, Default, Default, 'Wingdings') GUICtrlSetColor(-1, $iColor_MenuItem) GUICtrlSetCursor(-1, $MCID_HAND) $gMenu_Help = GUICtrlCreateLabel($symHelp, 1, $iSqrSize * 3 + 1 + $iSqrSize / 2, $iSqrSize * 1.5 - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetTip(-1, 'What do I do here?', 'Instructions') GUICtrlSetFont(-1, $iSqrSize / 2, Default, Default, 'Webdings') GUICtrlSetColor(-1, $iColor_MenuItem) GUICtrlSetCursor(-1, $MCID_HAND) ; - grid ; -- center part ReDim $aGrid[$iColCount][$iRowCount][$iGrid_iDimCount] $gdGridStart = GUICtrlCreateDummy() For $iRow = 0 To $iRowCount - 1 For $iCol = 0 To $iColCount - 1 $aGrid[$iCol][$iRow][$iGrid_gID] = GUICtrlCreateLabel('', ($iCol + 1) * $iSqrSize + 2 + $iSqrSize / 2, $iRow * $iSqrSize + 2 + $iSqrSize / 2, $iSqrSize - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) Next Next $gdGridEnd = GUICtrlCreateDummy() ; -- results of rows ReDim $aResultOfRow[$iRowCount][$iResult_iDimCount] For $iRow = 0 To $iRowCount - 1 $aResultOfRow[$iRow][$iResult_iValue] = GUICtrlCreateLabel('', ($iColCount + 1) * $iSqrSize + 2 + $iSqrSize / 2, $iRow * $iSqrSize + 2 + $iSqrSize / 2, $iSqrSize - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, $iColor_BoxResult) Next ; -- results of cols ReDim $aResultOfCol[$iColCount][$iResult_iDimCount] For $iCol = 0 To $iColCount - 1 $aResultOfCol[$iCol][$iResult_iValue] = GUICtrlCreateLabel('', ($iCol + 1) * $iSqrSize + 2 + $iSqrSize / 2, $iRowCount * $iSqrSize + 2 + $iSqrSize / 2, $iSqrSize - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, $iColor_BoxResult) Next ; -- puzzle type GUICtrlCreateLabel($bPuzzleTypeIsAddition ? $symP : $symX, ($iColCount + 1) * $iSqrSize + 2 + $iSqrSize / 2, $iRowCount * $iSqrSize + 2 + $iSqrSize / 2, $iSqrSize - 2, $iSqrSize - 2, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, Default, Default, Default, 'Wingdings 2') GUICtrlSetBkColor(-1, $iColor_MenuItemEmphasis) GUICtrlSetTip(-1, ($bPuzzleTypeIsAddition ? 'Addition' : 'Multplication'), 'Puzzle Type:') ; - populate grid Renew($bNew) ; finalize GUI $gdGUIEnd = GUICtrlCreateDummy() EndFunc ;==>BuildGUI Func Pref() Local Const $iSUI_W = 200, $iSUI_H = 280, $iSUI_ButtonH = 30, $iSUI_ButtonSpacing = 10 GUISetFont(9.5, Default, Default, 'Tahoma') Local $x = 10, $y = 10, $dy = 25 ; delete all controls DeleteAllControls() ; resize GUI WinSetTrans($hGUI, '', 192) WinSetTitle($hGUI, '', $sAppName & ' Setup') _WinPoseAroundCenter($hGUI, $iSUI_W + $iWDiff, $iSUI_H + $iHDiff, $iResizeSpeed) WinSetTrans($hGUI, '', 255) ; generate controls $gdGUIStart = GUICtrlCreateDummy() GUICtrlCreateLabel('Puzzle', $x, $y, 85, Default, $SS_CENTERIMAGE) GUICtrlSetFont(-1, Default, 600) $x += 5 $y += $dy GUICtrlCreateLabel('Puzzle Type:', $x, $y, 80, Default, $SS_CENTERIMAGE) $x += 90 $gPuzzleType_Addition = GUICtrlCreateLabel($symP, $x, $y, 41, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 12, Default, Default, 'Wingdings 2') $x += 42 $gPuzzleType_Multiplication = GUICtrlCreateLabel($symX, $x, $y, 41, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 12, Default, Default, 'Wingdings 2') Pref_RefreshPuzzleTypeButtons($gPuzzleType_Addition, $gPuzzleType_Multiplication) $x -= 42 $x -= 90 $y += $dy GUICtrlCreateLabel('Columns:', $x, $y, 80, Default, $SS_CENTERIMAGE) $x += 90 $gGridWidth_Down = GUICtrlCreateLabel('-', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x += 25 $gGridWidth_Data = GUICtrlCreateLabel($iColCount, $x, $y, 33, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, $COLOR_LIGHTBLUE) $x += 35 $gGridWidth_Up = GUICtrlCreateLabel('+', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x -= 35 $x -= 25 $x -= 90 $y += $dy GUICtrlCreateLabel('Rows:', $x, $y, Default, Default, $SS_CENTERIMAGE) $x += 90 $gGridHeight_Down = GUICtrlCreateLabel('-', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x += 25 $gGridHeight_Data = GUICtrlCreateLabel($iRowCount, $x, $y, 33, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, $COLOR_LIGHTBLUE) $x += 35 $gGridHeight_Up = GUICtrlCreateLabel('+', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x -= 35 $x -= 25 $x -= 90 $y += $dy $x -= 5 $y += $dy GUICtrlCreateLabel('Appearance', $x, $y, 85, Default, $SS_CENTERIMAGE) GUICtrlSetFont(-1, Default, 600) $y += $dy $x += 5 GUICtrlCreateLabel('Square Size:', $x, $y, Default, Default, $SS_CENTERIMAGE) $x += 90 $gSqrSize_Down = GUICtrlCreateLabel('-', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x += 25 $gSqrSize_Data = GUICtrlCreateLabel($iSqrSize, $x, $y, 33, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetBkColor(-1, $COLOR_LIGHTBLUE) $x += 35 $gSqrSize_Up = GUICtrlCreateLabel('+', $x, $y, 23, 22, BitOR($SS_CENTER, $SS_CENTERIMAGE)) GUICtrlSetFont(-1, 13, 800) GUICtrlSetBkColor(-1, $COLOR_LIGHTGRAY) GUICtrlSetCursor(-1, $MCID_HAND) $x -= 35 $x -= 25 $x -= 90 $y += $dy GUICtrlCreateLabel('Resize speed:', $x, $y, Default, Default, $SS_CENTERIMAGE) $x += 90 $gResizeSpeed_data = GUICtrlCreateSlider($x, $y, 80) GUICtrlSetLimit(-1, 100) GUICtrlSetData(-1, $iResizeSpeed) $x -= 90 #cs FUTURE DEVELOPMENT ----- BUILD PHASE: allow zero sum/prod use 8 & 9 in multiplication puzzle (HARDER) increase/decrease target squares count (determine probability of a square to participate) allow negative numbers (HARDER) ----- GAME PHASE: show target squares count show current/target squares count allow marking cols & rows as balanced automatically mark cols & rows as balanced automatically mark invalid selection (div creating mod, sum/prod exceeding result) show diff calc allow hints allow real-time switch puzzle type #ce Local $gOK = GUICtrlCreateButton('Done', $iSUI_ButtonSpacing, $iSUI_H - $iSUI_ButtonH - $iSUI_ButtonSpacing, $iSUI_W - $iSUI_ButtonSpacing * 2, $iSUI_ButtonH) $gdGUIEnd = GUICtrlCreateDummy() ; user interaction While True $msg = GUIGetMsg() Switch $msg Case $gPuzzleType_Addition If Not $bPuzzleTypeIsAddition Then $bPuzzleTypeIsAddition = True Pref_RefreshPuzzleTypeButtons($gPuzzleType_Addition, $gPuzzleType_Multiplication) EndIf Case $gPuzzleType_Multiplication If $bPuzzleTypeIsAddition Then $bPuzzleTypeIsAddition = False Pref_RefreshPuzzleTypeButtons($gPuzzleType_Addition, $gPuzzleType_Multiplication) EndIf Case $gGridWidth_Up $iColCount = _Min($iColCount + 1, 9) GUICtrlSetData($gGridWidth_Data, $iColCount) Case $gGridWidth_Down $iColCount = _Max($iColCount - 1, 3) GUICtrlSetData($gGridWidth_Data, $iColCount) Case $gGridHeight_Up $iRowCount = _Min($iRowCount + 1, 9) GUICtrlSetData($gGridHeight_Data, $iRowCount) Case $gGridHeight_Down $iRowCount = _Max($iRowCount - 1, 3) GUICtrlSetData($gGridHeight_Data, $iRowCount) Case $gSqrSize_Up $iSqrSize = _Min($iSqrSize + 5, 60) GUICtrlSetData($gSqrSize_Data, $iSqrSize) Case $gSqrSize_Down $iSqrSize = _Max($iSqrSize - 5, 20) GUICtrlSetData($gSqrSize_Data, $iSqrSize) Case $gOK, $GUI_EVENT_CLOSE $iResizeSpeed = GUICtrlRead($gResizeSpeed_data) ExitLoop EndSwitch WEnd ; delete all controls DeleteAllControls() ; - resize GUI WinSetTrans($hGUI, '', 192) WinSetTitle($hGUI, '', $sAppName) $iGUI_Width = $iSqrSize * ($iColCount + 3) + 2 $iGUI_Height = $iSqrSize * ($iRowCount + 2) + 2 _WinPoseAroundCenter($hGUI, $iGUI_Width + $iWDiff, $iGUI_Height + $iHDiff, $iResizeSpeed) WinSetTrans($hGUI, '', 255) Return True EndFunc ;==>Pref Func Pref_RefreshPuzzleTypeButtons($gPuzzleType_Addition, $gPuzzleType_Multiplication) GUICtrlSetBkColor($gPuzzleType_Addition, $bPuzzleTypeIsAddition ? $COLOR_LIGHTBLUE : $COLOR_LIGHTGRAY) GUICtrlSetCursor($gPuzzleType_Addition, $bPuzzleTypeIsAddition ? $MCID_ARROW : $MCID_HAND) GUICtrlSetBkColor($gPuzzleType_Multiplication, $bPuzzleTypeIsAddition ? $COLOR_LIGHTGRAY : $COLOR_LIGHTBLUE) GUICtrlSetCursor($gPuzzleType_Multiplication, $bPuzzleTypeIsAddition ? $MCID_HAND : $MCID_ARROW) EndFunc ;==>Pref_RefreshPuzzleTypeButtons Func Help() Local Const $iSUI_W = 410, $iSUI_H = 350, $iSUI_ButtonH = 30, $iSUI_ButtonSpacing = 10 GUISetFont(9.5, Default, Default, 'Tahoma') Local $x = 15, $y = 10, $dy = 25 ; delete all controls DeleteAllControls() ; resize GUI WinSetTrans($hGUI, '', 192) WinSetTitle($hGUI, '', $sAppName & ' Instructions') _WinPoseAroundCenter($hGUI, $iSUI_W + $iWDiff, $iSUI_H + $iHDiff, $iResizeSpeed) WinSetTrans($hGUI, '', 255) ; generate controls $gdGUIStart = GUICtrlCreateDummy() GUICtrlCreateLabel('WARNING! This game may be highly addictive :-)' & @CRLF & @CRLF & _ 'Click the gray squares in the middle to select them and paint them green. The selected squares in every row must match the result of the row, displayed on the right-hand side; the selected squares in every column must match the result of the column, displayed at the bottom.' & @CRLF & @CRLF & _ 'If you eliminate a square, you may right-click it to paint it dark gray.' & @CRLF & @CRLF & _ 'The type of the puzzle - Addition or Multiplication - is indicated in the white square at the bottom-right corner.' & @CRLF & @CRLF & _ 'Click the "Tools" icon on the upper-left corner to change puzzle type, grid size and other preferences.' & @CRLF & @CRLF & _ 'Enjoy :-)', $x, $y, $iSUI_W - $x * 2, $iSUI_H - 60) $y += $dy $gOK = GUICtrlCreateButton('OK, I think I got it...', $iSUI_ButtonSpacing, $iSUI_H - $iSUI_ButtonH - $iSUI_ButtonSpacing, $iSUI_W - $iSUI_ButtonSpacing * 2, $iSUI_ButtonH) $gdGUIEnd = GUICtrlCreateDummy() ; user interaction While True $msg = GUIGetMsg() Switch $msg Case $gOK, $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd ; delete all controls DeleteAllControls() ; resize GUI WinSetTrans($hGUI, '', 192) WinSetTitle($hGUI, '', $sAppName) _WinPoseAroundCenter($hGUI, $iGUI_Width + $iWDiff, $iGUI_Height + $iHDiff, $iResizeSpeed) WinSetTrans($hGUI, '', 255) Return False EndFunc ;==>Help Func GuiCtrlDeleteAndZero(ByRef $gID) If GUICtrlDelete($gID) Then $gID = 0 Return 1 Else Return 0 EndIf EndFunc ;==>GuiCtrlDeleteAndZero Func DeleteAllControls() Local $gIDStart = $gdGUIStart Local $gIDEnd = $gdGUIEnd For $gID = $gIDStart To $gIDEnd GuiCtrlDeleteAndZero($gID) Next EndFunc ;==>DeleteAllControls Func _WinPoseAroundCenter($hGUI, $iNewWidth, $iNewHeight, $iSpeed = 0) Local $aPos = WinGetPos($hGUI) Local $x = $aPos[0] + $aPos[2] / 2 - $iNewWidth / 2 If $x < 0 Then $x = 0 If $x + $iNewWidth > @DesktopWidth Then $x = @DesktopWidth - $iNewWidth Local $y = $aPos[1] + $aPos[3] / 2 - $iNewHeight / 2 If $y < 0 Then $y = 0 If $y + $iNewHeight > @DesktopHeight Then $y = @DesktopHeight - $iNewHeight _WinPose($hGUI, '', $x, $y, $iNewWidth, $iNewHeight, $iSpeed) EndFunc ;==>_WinPoseAroundCenter enjoy! MagicMath.ico5 points
-
You may have a look here: Or here (old):4 points
-
Hey mate, Yeah so there's a bit you can do.. _WinAPI_GetWindowFileName calls a few things, which we can streamline if we're planning to call it 10000 times,. Func _WinAPI_GetWindowFileName($hWnd) Local $iPID = 0 Local $aCall = DllCall("user32.dll", "bool", "IsWindow", "hwnd", $hWnd) If $aCall[0] Then $aCall = DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0) $iPID = $aCall[2] EndIf If Not $iPID Then Return SetError(1, 0, '') Local $sResult = _WinAPI_GetProcessFileName($iPID) If @error Then Return SetError(@error, @extended, '') Return $sResult EndFunc Func _WinAPI_GetProcessFileName($iPID = 0) If Not $iPID Then $iPID = @AutoItPID Local $hProcess = DllCall('kernel32.dll', 'handle', 'OpenProcess', 'dword', ((_WinAPI_GetVersion() < 6.0) ? 0x00000410 : 0x00001010), _ 'bool', 0, 'dword', $iPID) If @error Or Not $hProcess[0] Then Return SetError(@error + 20, @extended, '') Local $sPath = _WinAPI_GetModuleFileNameEx($hProcess[0]) Local $iError = @error DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hProcess[0]) If $iError Then Return SetError(@error, 0, '') Return $sPath EndFunc Func _WinAPI_GetModuleFileNameEx($hProcess, $hModule = 0) Local $aCall = DllCall(@SystemDir & '\psapi.dll', 'dword', 'GetModuleFileNameExW', 'handle', $hProcess, 'handle', $hModule, _ 'wstr', '', 'int', 4096) If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, '') Return $aCall[3] EndFunc Firstly I'd be using dll handles with DllOpen instead of using file names in DllCall, this should save open/closing Dlls all the time! That IsWindow call in GetWindowFilename is there as a sanity check. So if you're reasonably happy that you won't sent it rubbish, that can go. GetVersion doesn't need to be called 10000 times. 6.0 is Vista, so we probably don't really care about this anymore... but if you do - just call GetVersion once before your loop, or store it as a static or something. Use GetModuleBaseNameW instead of GetModuleFileNameExW - that will get you just the "notepad.exe" part of the process name We don't need to allocate the string buffer and free it 10000 times either (assuming the func returns a null-terminated string). Create a buffer once beforehand and just reuse it. #include <WinAPISysWin.au3> #include <WinAPIProc.au3> #include <Array.au3> #include <WinAPISys.au3> #include <File.au3> Global $maxruns = 10000 Global $hUser32 = DllOpen('user32.dll') Global $hKernel32 = DllOpen('kernel32.dll') Global $hpsapi = DllOpen('psapi.dll') ; Run Notepad Run("notepad.exe") ; Wait 10 seconds for the Notepad window to appear. WinWait("[CLASS:Notepad]", "", 10) Global $iPID = ProcessExists("notepad.exe") ; Retrieve the handle of the Notepad window using the classname of Notepad. Global $hWnd = WinGetHandle("[CLASS:Notepad]") ConsoleWrite("Notepad handle: " & $hWnd & @CRLF) Example3() Func Example3() Local $hTimer = TimerInit() For $i = 1 To $maxruns Local $test = _WinAPI_GetWindowFileName2($hWnd) Next Local $fDiff = TimerDiff($hTimer) ConsoleWrite("Timer: " & $fDiff & @CRLF) ConsoleWrite("_WinAPI_GetWindowFileName: " & $test & @CRLF) EndFunc Func _WinAPI_GetWindowFileName2($hWnd) Local Static $iNumChars = 512, $tBuff = DllStructCreate(StringFormat("wchar[%d]", $iNumChars)) Local $aCall = DllCall($hUser32, "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0) Local $iPID = $aCall[2] $aCall = DllCall($hKernel32, 'handle', 'OpenProcess', 'dword', 0x00001010, 'bool', 0, 'dword', $iPID) Local $hProc = $aCall[0] DllCall($hpsapi, 'dword', 'GetModuleBaseNameW', 'handle', $hProc, 'handle', 0, 'struct*', $tBuff, 'int', $iNumChars) $aCall = DllCall($hKernel32, "bool", "CloseHandle", "handle", $hProc) Return DllStructGetData($tBuff, 1) EndFunc Obviously you'll want to put some error checks back in, and clean up when you're done.. but you get the idea Edit: and the time comparison.. Notepad handle: 0x00000000005B0D40 Timer: 548.97 _WinAPI_GetWindowFileName2: Notepad.exe Timer: 1794.9062 _WinAPI_GetWindowFileName: C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2507.26.0_x64__8wekyb3d8bbwe\Notepad\Notepad.exe4 points
-
JSON UDF in pure AutoIt
ioa747 and 3 others reacted to AspirinJunkie for a topic
There is a new version. This brings a significant performance increase. In my tests, _JSON_Parse() is now around 40–55% faster, and for _JSON_Generate(), the increase is around 15–35%. I didn't thought there was still such potential in the code. However, I still had a few ideas in mind that required quite a bit of restructuring, but I've now tackled them accordingly. In my opinion, it was worth it. In the process, I removed ByRef everywhere, so that direct value transfer is now possible for all functions (which was a request). I also added notes on how to handle .json files to the Readme.md (@WildByDesign: I hope that was what you meant?).4 points -
Play with the colors, angle and translations: ;AutoIt v3.3.9.21 or higher needed! ;coded by UEZ build 2013-10-13 #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $iW = 300, $iH = 300 Global Const $hGUI = GUICreate("GDI+ Ring Progressbar", $iW, $iH, -1, -1, $WS_POPUPWINDOW, $WS_EX_TOPMOST) GUISetBkColor(0) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW, $iH) ;~ GUICtrlSetState(-1, $GUI_DISABLE) GUISetState() Global $hHBmp_BG, $hB, $fPerc, $iSleep = 60 GUIRegisterMsg($WM_TIMER, "PlayAnim") DllCall("user32.dll", "int", "SetTimer", "hwnd", $hGUI, "int", 0, "int", $iSleep, "int", 0) Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUIRegisterMsg($WM_TIMER, "") _WinAPI_DeleteObject($hHBmp_BG) _GDIPlus_Shutdown() GUIDelete() Exit EndSwitch Until False Func PlayAnim() $hHBmp_BG = _GDIPlus_RingProgressbar($fPerc) $hB = GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBmp_BG) If $hB Then _WinAPI_DeleteObject($hB) _WinAPI_DeleteObject($hHBmp_BG) $fPerc += 0.33333 If $fPerc > 100 Then $fPerc = 0 EndFunc ;==>PlayAnim Func _GDIPlus_RingProgressbar($fPerc, $iSize = 300, $sText = "Please wait...") Local Const $hBmp = _GDIPlus_BitmapCreateFromMemory(_Background_Texture()) Local Const $hTexture = _GDIPlus_TextureCreate($hBmp) _GDIPlus_BitmapDispose($hBmp) Local Const $hBitmap = _GDIPlus_BitmapCreateFromScan0($iSize, $iSize) Local Const $hCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetPixelOffsetMode($hCtxt, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) _GDIPlus_GraphicsSetSmoothingMode($hCtxt, 2) _GDIPlus_GraphicsFillRect($hCtxt, 0, 0, $iSize, $iSize, $hTexture) If $fPerc < 0 Then $fPerc = 0 If $fPerc > 100 Then $fPerc = 100 Local Const $hPath = _GDIPlus_PathCreate(), $hPath2 = _GDIPlus_PathCreate(), _ $fRadius = $iSize / 1.5, $iX = ($iSize - $fRadius) / 2, $iY = ($iSize - $fRadius) / 2, _ $fDX = $iSize / 10, $fAngel = $fPerc * 360 / 100, $fSize = $iSize / 15 _GDIPlus_PathAddEllipse($hPath, $iX, $fDX + $iY, $fRadius, $fRadius) Local $hBrush = _GDIPlus_LineBrushCreate($iX, $fDX + $iY, $fRadius, $fRadius, 0, 0, 1) Local $aInterpolations[4][2] ;define the interpolated colors and positions $aInterpolations[0][0] = 3 $aInterpolations[1][0] = 0xFF800000 ;Red $aInterpolations[1][1] = 0 $aInterpolations[2][0] = 0xFFFF6700 ;Orange $aInterpolations[2][1] = 0.5 $aInterpolations[3][0] = 0xFFFFFF00 ;Yellow $aInterpolations[3][1] = 1.0 $hMatrix = _GDIPlus_MatrixCreate() _GDIPlus_MatrixTranslate($hMatrix, $fRadius, $fRadius) _GDIPlus_MatrixRotate($hMatrix, -35, False) _GDIPlus_LineBrushMultiplyTransform($hBrush, $hMatrix, False) _GDIPlus_LineBrushSetPresetBlend($hBrush, $aInterpolations) _GDIPlus_MatrixDispose($hMatrix) Local Const $hPen = _GDIPlus_PenCreate2($hBrush, $fSize) _GDIPlus_GraphicsDrawPath($hCtxt, $hPath, $hPen) _GDIPlus_PathReset($hPath) Local Const $hPen2 = _GDIPlus_PenCreate2($hTexture, $fSize + 4) _GDIPlus_PathAddArc($hPath, $iX, $fDX + $iY, $fRadius, $fRadius, -90, $fAngel) _GDIPlus_GraphicsDrawPath($hCtxt, $hPath, $hPen2) _GDIPlus_PathReset($hPath) Local Const $hFamily = _GDIPlus_FontFamilyCreate("Verdana") Local Const $hFormat = _GDIPlus_StringFormatCreate() Local Const $tLayout = _GDIPlus_RectFCreate(0, $iSize / 12, $iSize, 0) Local Const $tLayout2 = _GDIPlus_RectFCreate(0, ($iSize + $iSize / 18) / 2, $iSize, 0) _GDIPlus_StringFormatSetAlign($hFormat, 1) Local Const $hBrush2 = _GDIPlus_BrushCreateSolid(0xE0FFFFFF) _GDIPlus_PenSetColor($hPen, 0x80000000) _GDIPlus_PenSetWidth($hPen, 4) _GDIPlus_PathAddString($hPath, $sText, $tLayout, $hFamily, 0, $iSize / 12, $hFormat) _GDIPlus_PathAddString($hPath, StringFormat("%02d%", $fPerc), $tLayout2, $hFamily, 0, $iSize / 9, $hFormat) _GDIPlus_GraphicsDrawPath($hCtxt, $hPath, $hPen) _GDIPlus_GraphicsFillPath($hCtxt, $hPath, $hBrush2) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPen2) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BrushDispose($hBrush2) _GDIPlus_BrushDispose($hTexture) _GDIPlus_PathDispose($hPath) _GDIPlus_PathDispose($hPath2) _GDIPlus_GraphicsDispose($hCtxt) Local Const $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _GDIPlus_BitmapDispose($hBitmap) Return $hHBmp EndFunc ;Code below was generated by: 'File to Base64 String' Code Generator v1.12 Build 2013-05-17 Func _Background_Texture($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Background_Texture $Background_Texture &= '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' $Background_Texture &= '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' $Background_Texture &= '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' $Background_Texture &= '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' $Background_Texture &= '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' $Background_Texture &= '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' $Background_Texture &= 'LDtyT0/mXl/5NOLjdHdfuZrUd46l0feIgZuiLJ89Qb51eMRqmGGruU5O9yhvUKrEpXe63MNc5bmK037iLdxC+dvMA8yir0Mo4v7l2l8icq5RyzfLAUVy7lXdNoHR3FLbHcTJj8xC+YOdfn+pyYf98QbtraVYVydwr52wOzANnUwsKh48QC8GMo9H+4lHwf7iDN8DnxKVMZEt2lr0/UpvT9SsUvXEprN66lZcOonQ/UD1x15mJ95ue7fUVW3wTTznxMlls49wnfjNTFb4Sr3Xcep2fuBaBecTqu5tQcssFX+Iq+94lafklLtV9TkZs8QqlXvVQz23yQPJMwdYuIplY3yd6iW4WJStWZay1+pVZvHqBhWMv6iZ5q4VWenmNGm/XqGRd7ceIE4zviU8moJZX8zbnT+CYsPGczQwUYOeY88/5l1M3p0Rb1cMmBgdGY7b3UwMXPC4c7C55t2cSlv4JR33EKp317hYr0lH3EtyOWX4/ECnszBo14l28My8Smhy5mHkSoZCu5Xl+5k/NxS/LzGqMc4zMXj+YUtMRWLvUKcL28+o4ZvcWM6Gs/1FpSOtXCrOxz49Rl86efEoOmqggmHB3/U326P4g0FLqGWFH3FbL9y17ddxRmrw/cFQoXG43bDqLjNxY1TK9j5hjRhqGuZisjv/ALCYdiCVqa9hMmWy9TutIgpd76lUeXUT/wAJWhXMq+W5w9yt+WDBfc05d9R8lmm37mO37Rd5+43q/wAoIwCy1c7OGJ/Z/UHHJl59RVHZf+4izjrrx7l5d64g5tvA/wAQBvo/xFLv/FQwLG5i5qkBT0/uD1f3LKVeu5Yu2eV1j7i8zrqXlWj/AHMXG31F5/z5gY3ALq9zJ/qXvn6m/O4yfZxBJnGepSHflU5bc8RmR4fzB15eJeOHLHGj8zw6/wCoa18TxO+GXejbuWdjuDODuZGn7hnEdkSuJ6PuJdY2gJz9oBeb3AvNwCu67Qe7s4iCn0HxEA3eq3AbZ2/iFLldPEo96/UA7Sl4vSyUo3qUfzzBvlqXfx/U87/zB2Hj9xyi3USjbU9n3AKq31Ck53APqUOrgC5xBh7JgHGY/wApW3u3mVxdOZi7HMHJvD3FuFH+HMESWYOe/wCpZVN/cWsJndx6wtvcMtO5Yc8p+5zpmlKe5R4m3Nza7gAvvqL4XFfPD3BTd1uNlpOINbO1fUHZyNTXMEDcbbYT9QKKvLDGVTs4RrK8VjPiDhF8xcNhSOWXjdRpNygV0g0Z/ma7tcGOVr3CpeZQS7+5QrvD3HDl+Zk/3L3FucZhYN4e41eTJDLbvuFptw6l5ydxO0queeo5b/MKrKuYYCunME3lwwwxbX/uYtOx8TTC8xsjgthZkv3FLhYg0orS4zLTpKDamY/5cDPGnnxAyImu4jWq13GxqjHZF4X8iYC3Tsl7y2rp17lqeDw8xxb/AAQMmtdyimVn45nHe4FM+eZWC7jk4lW8biYXUSuNX3ALo3/uZRS0XFTYNwSs1cE8b3UsMK3EGzwxLyrW9RYbrcd8bi5++ai8PqZPzLVmoiEK3Loa5HHuDbZ9RtM1vqO8Vm4tjJuO8xhxx8kqgXHm/Crn/9k=' Local $bString = Binary(_Base64Decode($Background_Texture)) If $bSaveBinary Then Local $hFile = FileOpen($sSavePath & "\Dark Texture 300x300.jpg", 18) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Background_Texture Func _Base64Decode($sB64String) Local $a_Call = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "ptr", 0, "dword*", 0, "ptr", 0, "ptr", 0) If @error Or Not $a_Call[0] Then Return SetError(1, 0, "") Local $a = DllStructCreate("byte[" & $a_Call[5] & "]") $a_Call = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryA", "str", $sB64String, "dword", 0, "dword", 1, "struct*", $a, "dword*", $a_Call[5], "ptr", 0, "ptr", 0) If @error Or Not $a_Call[0] Then Return SetError(2, 0, "") Return DllStructGetData($a, 1) EndFunc ;==>_Base64Decode3 points
-
UDF: #include-once ; #INDEX# ======================================================================================================================= ; Title .........: Windows Version Detector UDF ; AutoIt Version : 3.3.16.1+ ; Description ...: Detects Windows versions for both live (currently running) and offline installations. ; Author ........: Dao Van Trong - TRONG.PRO ; Remarks .......: This UDF can inspect a Windows directory on another drive to determine its version, ; product name, build number, and edition, which is useful for OS deployment or analysis tools. ; It first attempts to read from the offline registry hive and falls back to file version metadata ; if the registry is inaccessible. ; Link ..........: https://www.autoitscript.com/forum/topic/213103-windows-version-detector/ ; Version .......: 3.0 ; =============================================================================================================================== ; #INCLUDES# ==================================================================================================================== #include <FileConstants.au3> #include <APIRegConstants.au3> #include <APIErrorsConstants.au3> #include <StringConstants.au3> ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== ; Global Const $OPEN_EXISTING = 3 ; Not required, defined in FileConstants.au3 ; Global Const $GENERIC_READ = 0x80000000 ; Not required, defined in FileConstants.au3 ; Global Const $FV_FILEDESCRIPTION = "FileDescription" ; Global Const $FV_PRODUCTNAME = "ProductName" ; Global Const $HKEY_LOCAL_MACHINE = 0x80000002 ; Global Const $ERROR_SUCCESS = 0 ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _DetectWindowsVersion ; _OSVersion ; _RegReadMulti ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _OSVersion ; Description....: Returns a short OS version code (e.g., "WIN_10", "WIN_11") based on the OS build number. ; Syntax.........: _OSVersion([$sWindowsPath = @WindowsDir[, $iBuild = 0]]) ; Parameters.....: $sWindowsPath - [optional] Path to the Windows folder. Default is the live @WindowsDir. ; $iBuild - [optional] A specific build number to evaluate. Default is 0 (auto-detect). ; Return values..: Success - A string containing the short OS code (e.g., "WIN_11"). ; Failure - "UNKNOWN" and sets @error: ; |1 - _DetectWindowsVersion failed to get OS info. @extended contains the error from that function. ; |2 - Failed to parse the build number from the detected version info. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is a wrapper function for _DetectWindowsVersion and __GetShortOsNameByBuild. ; Related........: _DetectWindowsVersion, __GetShortOsNameByBuild ; Example........: ; Local $sShortOS = _OSVersion() ; MsgBox(0, "Current Short OS Name", $sShortOS) ; ; Local $sOfflineShortOS = _OSVersion("D:\Windows") ; If Not @error Then MsgBox(0, "Offline Short OS Name", $sOfflineShortOS) ; =============================================================================================================================== Func _OSVersion($sWindowsPath = @WindowsDir, $iBuild = 0) Local $sProductName = "" If (Int($iBuild) < 1) Then $iBuild = 0 If (($sWindowsPath = @WindowsDir) Or ($sWindowsPath = Default) Or (StringStripWS($sWindowsPath, 8) == '')) Then $sWindowsPath = @WindowsDir ; Auto-detect if build not provided If $iBuild < 1 Then Local $aInfo = _DetectWindowsVersion($sWindowsPath) If @error Then Return SetError(1, @error, "UNKNOWN") ; Parse build from the array structure: [4] = BuildData Local $aBuildParts = StringSplit($aInfo[4], "|") If $aBuildParts[0] < 1 Then Return SetError(2, 0, "UNKNOWN") $iBuild = Int($aBuildParts[1]) $sProductName = $aInfo[2] EndIf Return __GetShortOsNameByBuild($iBuild, $sProductName) EndFunc ;==>_OSVersion ; #FUNCTION# ==================================================================================================================== ; Name...........: _DetectWindowsVersion ; Description....: Detects detailed OS information for a live or offline Windows installation. ; Syntax.........: _DetectWindowsVersion([$sWindowsPath = @WindowsDir]) ; Parameters.....: $sWindowsPath - [optional] Path to the Windows folder. Default is the live @WindowsDir. ; Return values..: Success - A 7-element array with detailed OS information: ; |[0] - State: "Live" or "Offline" ; |[1] - ShortOS: Short OS code (e.g., "WIN_10") ; |[2] - ProductName: Full product name (e.g., "Windows 10 Pro") ; |[3] - VersionFullName: Descriptive version name (e.g., "Windows 10 Version 22H2 (Build 19045.123)") ; |[4] - BuildData: Pipe-separated build info (e.g., "19045|22H2|...|UBR") ; |[5] - EditionID: Registry Edition ID (e.g., "Professional") ; |[6] - EditionType: Simplified edition type (e.g., "Pro") ; Failure - Returns an empty 7-element array and sets @error: ; |1 - The specified path is not a valid Windows directory. ; |2 - Failed to get version info from both offline registry and file metadata. ; |3 - Essential data (ProductName or BuildData) could not be determined. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: For offline systems, it first tries to load the SOFTWARE registry hive. If that fails, it falls back ; to reading version information from core system files like kernel32.dll. ; Related........: _OSVersion ; Example........: ; Local $aVersionInfo = _DetectWindowsVersion("D:\Windows") ; If @error Then ; ConsoleWrite("! Error: Failed to detect Windows version. Error code: " & @error & @CRLF) ; Else ; ConsoleWrite("> OS Detection Success:" & @CRLF) ; ConsoleWrite(" - State: " & $aVersionInfo[0] & @CRLF) ; ConsoleWrite(" - Short Name: " & $aVersionInfo[1] & @CRLF) ; ConsoleWrite(" - Product Name: " & $aVersionInfo[2] & @CRLF) ; ConsoleWrite(" - Full Version: " & $aVersionInfo[3] & @CRLF) ; EndIf ; =============================================================================================================================== Func _DetectWindowsVersion($sWindowsPath = @WindowsDir) Local $aResult[7] = ["", "", "", "", "", "", ""] ; Normalize and validate path Local $sPath = __NormalizePath($sWindowsPath) If Not __IsValidWindowsPath($sPath) Then Return SetError(1, 0, $aResult) EndIf ; Determine state: Live or Offline Local $bLive = __IsSystemLive($sPath) $aResult[0] = $bLive ? "Live" : "Offline" If $bLive Then ; --- Live: read registry values --- Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ; Read values directly to correct positions $aResult[5] = RegRead($sKey, "EditionID") $aResult[2] = RegRead($sKey, "ProductName") If @error Or $aResult[2] = "" Then $aResult[2] = $aResult[5] ; Build number with fallback Local $aBuildArr = _RegReadMulti($sKey, "CurrentBuildNumber|CurrentBuild", "", "|", "|", True) Local $sBuild = ($aBuildArr[0] <> "") ? $aBuildArr[0] : $aBuildArr[1] ; Additional fields: DisplayVersion, ReleaseId, CurrentVersion, UBR Local $sExtra = _RegReadMulti($sKey, "DisplayVersion|ReleaseId|CurrentVersion|UBR", "", "|", "|", False) ; Trim trailing separators While StringRight($sExtra, 1) = "|" $sExtra = StringLeft($sExtra, StringLen($sExtra) - 1) WEnd If $sExtra <> "" Then $sBuild &= "|" & $sExtra $aResult[4] = $sBuild ; Parse build from array structure Local $iBuild = 0, $aBuildParts = StringSplit($sBuild, "|") If IsArray($aBuildParts) Then If $aBuildParts[0] > 0 Then $iBuild = Int($aBuildParts[1]) EndIf ; Set derived fields $aResult[1] = __GetShortOsNameByBuild($iBuild, $aResult[2]) $aResult[3] = __GetVersionNameByBuild($sBuild, $aResult[2]) $aResult[6] = __GetEditionType($aResult[2], $aResult[5]) Else ; --- Offline: try hive first, then fallback to file metadata --- If Not __ReadOfflineRegistryDirect($sPath, $aResult) Then If Not __ReadVersionFromFiles($sPath, $aResult) Then Return SetError(2, 0, $aResult) EndIf EndIf EndIf ; Validate essential data If $aResult[2] = "" Or $aResult[4] = "" Then Return SetError(3, 0, $aResult) EndIf Return SetError(0, 0, $aResult) EndFunc ;==>_DetectWindowsVersion ; #FUNCTION# ==================================================================================================================== ; Name...........: _RegReadMulti ; Description....: Reads multiple registry values from the same key in a single call. ; Syntax.........: _RegReadMulti($sKey, $vFields[, $sDefault = ""[, $sSplitChar = "|"[, $sJoinChar = "|"[, $bReturnArray = False]]]]) ; Parameters.....: $sKey - Full registry key path (e.g., "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion"). ; $vFields - An array or a delimiter-separated string of registry value names. ; $sDefault - [optional] The default value to use if a registry value is not found. Default is "". ; $sSplitChar - [optional] Delimiter used to split $vFields if it is a string. Default is "|". ; $sJoinChar - [optional] Delimiter used to join the results into a string if $bReturnArray is False. Default is "|". ; $bReturnArray - [optional] If True, the function returns an array of values. If False, it returns a joined string. Default is False. ; Return values..: Success - If $bReturnArray is False, returns a string of values joined by $sJoinChar. ; - If $bReturnArray is True, returns an array of the values. ; Failure - Returns an empty string or an array of default values, and sets @error: ; |1 - The registry key $sKey is empty. ; |2 - The field list $vFields is an empty string. ; |3 - The field list $vFields is invalid or empty after processing. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function simplifies reading several related registry values at once, reducing repetitive code. ; Related........: RegRead ; Example........: ; ; Read multiple values into a single string ; Local $sKey = "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ; Local $sInfo = _RegReadMulti($sKey, "ProductName|EditionID|CurrentBuild") ; ConsoleWrite("Joined Info: " & $sInfo & @CRLF) ; ; ; Read multiple values into an array ; Local $aInfo = _RegReadMulti($sKey, "ProductName|EditionID|CurrentBuild", "", "|", "|", True) ; ConsoleWrite("Product Name from array: " & $aInfo[0] & @CRLF) ; =============================================================================================================================== Func _RegReadMulti($sKey, $vFields, $sDefault = "", $sSplitChar = "|", $sJoinChar = "|", $bReturnArray = False) Local $aNames, $iErrorCode = 0, $iExtended = 0 If ($sDefault = "") Or ($sDefault = Default) Then $sDefault = "" If ($bReturnArray) Then $bReturnArray = True Local $aDefaultResult[1] = [$sDefault] If IsArray($vFields) Then If UBound($vFields) > 0 Then $aNames = $vFields Else $aNames = $aDefaultResult $iErrorCode = 3 $iExtended = 1 EndIf Else If $vFields = "" Then $aNames = $aDefaultResult $iErrorCode = 2 $iExtended = 1 ElseIf $sSplitChar <> "" And StringInStr($vFields, $sSplitChar) Then Local $aSplit = StringSplit($vFields, $sSplitChar, 3) If UBound($aSplit) > 0 Then $aNames = $aSplit For $i = 0 To UBound($aNames) - 1 $aNames[$i] = StringStripWS($aNames[$i], 3) Next Else $aNames = $aDefaultResult $iErrorCode = 3 $iExtended = 1 EndIf Else Local $aTmp[1] = [StringStripWS($vFields, 3)] $aNames = $aTmp EndIf EndIf Local $aResult[UBound($aNames)] If $sKey = "" Then For $i = 0 To UBound($aResult) - 1 $aResult[$i] = $sDefault Next If $iErrorCode = 0 Then $iErrorCode = 1 $iExtended = UBound($aResult) Else For $i = 0 To UBound($aNames) - 1 Local $sValue = RegRead($sKey, $aNames[$i]) $aResult[$i] = (@error) ? $sDefault : $sValue Next EndIf If $bReturnArray Then Return SetError($iErrorCode, $iExtended, $aResult) Else Return SetError($iErrorCode, $iExtended, __ArrayToString($aResult, $sJoinChar)) EndIf EndFunc ;==>_RegReadMulti ;=============================================================================================================================== ; Private Functions ;=============================================================================================================================== ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __ReadOfflineRegistryDirect ; Description....: (Private) Mounts an offline SOFTWARE hive and reads version info directly from the registry. ; Syntax.........: __ReadOfflineRegistryDirect($sPath, ByRef $aResult) ; Parameters.....: $sPath - The full, normalized path to the offline Windows folder. ; $aResult - A ByRef 7-element array to be populated with version information. ; Return values..: Success - True, and the $aResult array is populated. ; Failure - False, the $aResult array is unchanged. @error is not set by this helper. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is the primary method for detecting offline OS versions. It requires administrative privileges ; to load and unload registry hives. A temporary key is created in HKLM during the operation. ; Related........: __LoadOfflineHive, __UnloadOfflineHive, _DetectWindowsVersion ; =============================================================================================================================== Func __ReadOfflineRegistryDirect($sPath, ByRef $aResult) Local $sHiveFile = $sPath & "\System32\Config\SOFTWARE" If Not FileExists($sHiveFile) Then Return False Local $sTempKey = "TEMP_SW_" & Random(1000, 9999, 1) If Not __LoadOfflineHive($sHiveFile, $sTempKey) Then Return False Local $sKey = "HKLM\" & $sTempKey & "\Microsoft\Windows NT\CurrentVersion" $aResult[5] = RegRead($sKey, "EditionID") $aResult[2] = RegRead($sKey, "ProductName") If @error Or $aResult[2] = "" Then $aResult[2] = $aResult[5] Local $aBuildArr = _RegReadMulti($sKey, "CurrentBuildNumber|CurrentBuild", "", "|", "|", True) Local $sBuild = $aBuildArr[0] <> "" ? $aBuildArr[0] : $aBuildArr[1] Local $sExtra = _RegReadMulti($sKey, "DisplayVersion|ReleaseId|CurrentVersion|UBR", "", "|", "|", False) While StringRight($sExtra, 1) = "|" $sExtra = StringLeft($sExtra, StringLen($sExtra) - 1) WEnd If $sExtra <> "" Then $sBuild &= "|" & $sExtra $aResult[4] = $sBuild Local $iBuild = 0, $aBuildParts = StringSplit($sBuild, "|") If IsArray($aBuildParts) Then If $aBuildParts[0] > 0 Then $iBuild = Int($aBuildParts[1]) EndIf $aResult[1] = __GetShortOsNameByBuild($iBuild, $aResult[2]) $aResult[3] = __GetVersionNameByBuild($aResult[4], $aResult[2]) $aResult[6] = __GetEditionType($aResult[2], $aResult[5]) __UnloadOfflineHive($sTempKey) Return True EndFunc ;==>__ReadOfflineRegistryDirect ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __ReadVersionFromFiles ; Description....: (Private) Reads Windows version info from file metadata as a fallback method. ; Syntax.........: __ReadVersionFromFiles($sPath, ByRef $aResult) ; Parameters.....: $sPath - The full, normalized path to the offline Windows folder. ; $aResult - A ByRef 7-element array to be populated with version information. ; Return values..: Success - True, and the $aResult array is populated. ; Failure - False if a build number cannot be determined. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function is used when the offline registry hive cannot be loaded. It reads the version from ; key system files like kernel32.dll or ntoskrnl.exe. Edition detection is less reliable with this method. ; Related........: _DetectWindowsVersion, FileGetVersion ; =============================================================================================================================== Func __ReadVersionFromFiles($sPath, ByRef $aResult) Local $aSystemFiles = [ _ $sPath & "\System32\kernel32.dll", _ $sPath & "\System32\ntoskrnl.exe", _ $sPath & "\System32\ntdll.dll" _ ] Local $sBuild = "", $sVersion = "" For $i = 0 To UBound($aSystemFiles) - 1 If FileExists($aSystemFiles[$i]) Then Local $sFileVersion = FileGetVersion($aSystemFiles[$i]) If $sFileVersion <> "" Then Local $aVersionParts = StringSplit($sFileVersion, ".") If $aVersionParts[0] >= 3 Then $sBuild = $aVersionParts[3] $sVersion = $aVersionParts[1] & "." & $aVersionParts[2] ExitLoop EndIf EndIf EndIf Next If $sBuild = "" Then Return SetError(1, 0, False) Local $sProductName = "Windows" Local $sEditionID = "Unknown" If FileExists($sPath & "\System32\ServerManager.exe") Then $sProductName = "Windows Server" $sEditionID = "ServerStandard" ElseIf FileExists($sPath & "\System32\ProfSvc.dll") Then $sProductName = "Windows Professional" $sEditionID = "Professional" Else $sProductName = "Windows Home" $sEditionID = "Home" EndIf $aResult[2] = $sProductName $aResult[4] = $sBuild & "|" & $sVersion $aResult[5] = $sEditionID Local $iBuild = 0, $aBuildParts = StringSplit($sBuild, "|") If IsArray($aBuildParts) Then If $aBuildParts[0] > 0 Then $iBuild = Int($aBuildParts[1]) EndIf $aResult[1] = __GetShortOsNameByBuild($iBuild, $aResult[2]) $aResult[3] = __GetVersionNameByBuild($aResult[4], $aResult[2]) $aResult[6] = __GetEditionType($aResult[2], $aResult[5]) Return SetError(0, 0, True) EndFunc ;==>__ReadVersionFromFiles ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __GetShortOsNameByBuild ; Description....: (Private) Converts an OS build number and product name into a short, standardized code. ; Syntax.........: __GetShortOsNameByBuild($iBuild[, $sProductName = '']) ; Parameters.....: $iBuild - The OS build number (e.g., 19045, 22621). ; $sProductName - [optional] The full product name (e.g., "Windows Server 2022"). ; Used to differentiate between Client and Server SKUs with similar build numbers. ; Return values..: Success - A short OS code string (e.g., "WIN_10", "WIN_2022"). ; Failure - "UNKNOWN" if the build number does not match any known version. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function contains the core logic for mapping build numbers to OS versions. ; Related........: _OSVersion, _DetectWindowsVersion ; Example........: [Internal Use Only] ; __GetShortOsNameByBuild(19045) ; Returns "WIN_10" ; __GetShortOsNameByBuild(17763, "Windows Server 2019") ; Returns "WIN_2019" ; =============================================================================================================================== Func __GetShortOsNameByBuild($iBuild = 0, $sProductName = '') Local $bIsServer = (StringInStr($sProductName, "Server") > 0) Select ; --- Windows NT Classic --- Case $iBuild = 528 Return "WIN_NT31" Case $iBuild = 807 Return "WIN_NT35" Case $iBuild = 1057 Return "WIN_NT351" Case $iBuild = 1381 Return "WIN_NT4" ; --- Windows 9x/ME --- Case $iBuild >= 950 And $iBuild <= 1111 Return "WIN_95" Case $iBuild = 1998 Return "WIN_98" Case $iBuild = 2222 Return "WIN_98SE" Case $iBuild = 3000 Return "WIN_ME" ; --- Windows 2000/XP/Server 2003 --- Case $iBuild = 2195 Return $bIsServer ? "WIN_2000SRV" : "WIN_2000" Case $iBuild = 2600 Return StringInStr($sProductName, "Embedded") ? "WIN_XPe" : "WIN_XP" Case $iBuild = 3790 Return $bIsServer ? "WIN_2003" : "WIN_XP64" ; --- Windows Vista/Server 2008 --- Case $iBuild >= 6000 And $iBuild <= 6003 Return $bIsServer ? "WIN_2008" : "WIN_VISTA" ; --- Windows 7/Server 2008 R2 --- Case $iBuild = 7600 Or $iBuild = 7601 Return $bIsServer ? "WIN_2008R2" : "WIN_7" ; --- Windows 8/Server 2012 --- Case $iBuild = 9200 Return $bIsServer ? "WIN_2012" : "WIN_8" ; --- Windows 8.1/Server 2012 R2 --- Case $iBuild = 9600 Return $bIsServer ? "WIN_2012R2" : "WIN_81" ; --- Windows 10/Server 2016+ --- Case $iBuild >= 10240 And $iBuild <= 19045 If $bIsServer Then Switch $iBuild Case 14393 Return "WIN_2016" Case 17763 Return "WIN_2019" Case 20348 Return "WIN_2022" Case Else Return "WIN_2016" ; Default for Windows 10 era servers EndSwitch Else Return "WIN_10" EndIf ; --- Windows Server 2022 --- Case $iBuild = 20348 Return "WIN_2022" ; --- Windows 11/Server 2025 --- Case $iBuild >= 22000 And $iBuild <= 26200 If $bIsServer Then Return ($iBuild = 26100) ? "WIN_2025" : "WIN_2022" Else Return "WIN_11" EndIf ; --- Future versions --- Case $iBuild > 26200 Return $bIsServer ? "WIN_SRV_FUTURE" : "WIN_FUTURE" ; --- Unknown --- Case Else Return "UNKNOWN" EndSelect EndFunc ;==>__GetShortOsNameByBuild ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __NormalizePath ; Description....: (Private) Converts a path to its full, absolute form and removes any trailing backslashes. ; Syntax.........: __NormalizePath($sPath) ; Parameters.....: $sPath - The file or directory path to normalize. ; Return values..: Success - A string containing the normalized path. ; Failure - The original path with forward slashes replaced by backslashes. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Uses the GetFullPathNameW API call for reliable path conversion. ; Example........: __NormalizePath("C:\Windows\System32\..") ; Returns "C:\Windows" ; =============================================================================================================================== Func __NormalizePath($sPath) Local Const $MAX = 260 Local $tBuf = DllStructCreate("wchar[" & $MAX & "]") Local $aRet = DllCall("kernel32.dll", "dword", "GetFullPathNameW", _ "wstr", $sPath, "dword", $MAX, _ "ptr", DllStructGetPtr($tBuf), "ptr", 0) If @error Or $aRet[0] = 0 Then Return StringReplace($sPath, "/", "\") Return StringRegExpReplace(DllStructGetData($tBuf, 1), "\\+$", "") EndFunc ;==>__NormalizePath ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __IsValidWindowsPath ; Description....: (Private) Validates if a given path points to a valid Windows installation root folder. ; Syntax.........: __IsValidWindowsPath($sPath) ; Parameters.....: $sPath - The normalized path to check. ; Return values..: Returns True if the path appears to be a valid Windows directory, otherwise returns False. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: It checks for the existence of key directories (System32, System32\Config) and files (kernel32.dll, ntdll.dll). ; Related........: _DetectWindowsVersion ; Example........: __IsValidWindowsPath("C:\Windows") ; Returns True ; __IsValidWindowsPath("C:\Program Files") ; Returns False ; =============================================================================================================================== Func __IsValidWindowsPath($sPath) If Not FileExists($sPath) Then Return False If Not FileExists($sPath & "\System32") Then Return False If Not FileExists($sPath & "\System32\Config") Then Return False Local $iCount = 0 If FileExists($sPath & "\System32\kernel32.dll") Then $iCount += 1 If FileExists($sPath & "\System32\ntdll.dll") Then $iCount += 1 Return $iCount > 0 EndFunc ;==>__IsValidWindowsPath ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __IsSystemLive ; Description....: (Private) Determines if the target Windows folder is the currently running (live) operating system. ; Syntax.........: __IsSystemLive($sPath) ; Parameters.....: $sPath - The normalized path to the Windows directory. ; Return values..: Returns True if the system is live, otherwise returns False. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: First, it compares the path to @WindowsDir. If they don't match, it checks if core system ; files (like the registry hives or ntoskrnl.exe) are locked, which indicates they are in use. ; Related........: __IsFileLocked, _DetectWindowsVersion ; Example........: __IsSystemLive("C:\Windows") ; Returns True (usually) ; __IsSystemLive("D:\Windows") ; Returns False ; =============================================================================================================================== Func __IsSystemLive($sPath) If __NormalizePath(@WindowsDir) = $sPath Then Return True Local $aCheck = [ _ $sPath & "\System32\Config\SYSTEM", _ $sPath & "\System32\Config\SOFTWARE", _ $sPath & "\System32\ntoskrnl.exe" _ ] For $i = 0 To UBound($aCheck) - 1 If __IsFileLocked($aCheck[$i]) Then Return True Next Return False EndFunc ;==>__IsSystemLive ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __IsFileLocked ; Description....: (Private) Checks if a file is locked (in use) by attempting to open it with read-only access. ; Syntax.........: __IsFileLocked($sFile) ; Parameters.....: $sFile - The full path to the file to check. ; Return values..: Returns True if the file is locked or doesn't exist. Returns False if the file can be opened. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Uses the CreateFileW API call. A handle of -1 indicates the file is locked by another process. ; Related........: __IsSystemLive ; =============================================================================================================================== Func __IsFileLocked($sFile) If Not FileExists($sFile) Then Return False Local $h = DllCall("kernel32.dll", "handle", "CreateFileW", _ "wstr", $sFile, "dword", $GENERIC_READ, _ "dword", 0, "ptr", 0, _ "dword", $OPEN_EXISTING, "dword", 0, _ "handle", 0) If @error Or $h[0] = -1 Then Return True DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $h[0]) Return False EndFunc ;==>__IsFileLocked ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __LoadOfflineHive ; Description....: (Private) Loads an offline registry hive into HKEY_LOCAL_MACHINE under a temporary key. ; Syntax.........: __LoadOfflineHive($sHiveFile, $sTempKey) ; Parameters.....: $sHiveFile - Path to the registry hive file (e.g., "D:\Windows\System32\Config\SOFTWARE"). ; $sTempKey - The name for the temporary key under HKLM. ; Return values..: Returns True on success, False on failure. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: Requires administrative privileges. It enables SeBackupPrivilege before calling RegLoadKeyW. ; Related........: __UnloadOfflineHive, __EnableBackupPrivilege ; =============================================================================================================================== Func __LoadOfflineHive($sHiveFile, $sTempKey) __EnableBackupPrivilege() Local $aRet = DllCall("advapi32.dll", "long", "RegLoadKeyW", _ "handle", $HKEY_LOCAL_MACHINE, _ "wstr", $sTempKey, _ "wstr", $sHiveFile) Return IsArray($aRet) And $aRet[0] = $ERROR_SUCCESS EndFunc ;==>__LoadOfflineHive ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __UnloadOfflineHive ; Description....: (Private) Unloads a previously loaded offline registry hive. ; Syntax.........: __UnloadOfflineHive($sTempKey) ; Parameters.....: $sTempKey - The name of the temporary key under HKLM to unload. ; Return values..: Returns True on success, False on failure. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This is a crucial cleanup step to ensure the registry is left in a clean state. ; Related........: __LoadOfflineHive ; =============================================================================================================================== Func __UnloadOfflineHive($sTempKey) Local $aRet = DllCall("advapi32.dll", "long", "RegUnloadKeyW", _ "handle", $HKEY_LOCAL_MACHINE, _ "wstr", $sTempKey) Return IsArray($aRet) And $aRet[0] = $ERROR_SUCCESS EndFunc ;==>__UnloadOfflineHive ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __EnableBackupPrivilege ; Description....: (Private) Enables the SeBackupPrivilege for the current process. ; Syntax.........: __EnableBackupPrivilege() ; Parameters.....: None. ; Return values..: Returns True on success, False on failure. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This privilege is required to perform certain system-level operations, such as loading ; and unloading registry hives using RegLoadKey/RegUnloadKey. ; Related........: __LoadOfflineHive ; =============================================================================================================================== Func __EnableBackupPrivilege() Local $hProc = DllCall("kernel32.dll", "handle", "GetCurrentProcess")[0] Local $a = DllCall("advapi32.dll", "bool", "OpenProcessToken", _ "handle", $hProc, "dword", 0x00000020, "handle*", 0) If @error Or Not $a[0] Then Return False Local $hToken = $a[3] Local $tLUID = DllStructCreate("int64") DllCall("advapi32.dll", "bool", "LookupPrivilegeValueW", _ "ptr", 0, "wstr", "SeBackupPrivilege", "ptr", DllStructGetPtr($tLUID)) Local $tPriv = DllStructCreate("dword;int64;dword") DllStructSetData($tPriv, 1, 1) DllStructSetData($tPriv, 2, DllStructGetData($tLUID, 1)) DllStructSetData($tPriv, 3, 0x00000002) DllCall("advapi32.dll", "bool", "AdjustTokenPrivileges", _ "handle", $hToken, "bool", False, "ptr", DllStructGetPtr($tPriv), _ "dword", 0, "ptr", 0, "ptr", 0) DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $hToken) Return True EndFunc ;==>__EnableBackupPrivilege ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __GetVersionNameByBuild ; Description....: (Private) Converts raw build data into a full, descriptive Windows version string. ; Syntax.........: __GetVersionNameByBuild($sBuildData[, $sProductName = ""]) ; Parameters.....: $sBuildData - A pipe-separated string containing build information (Build|DisplayVersion|ReleaseId|etc.). ; $sProductName - [optional] The full product name, used to differentiate between Client and Server versions. ; Return values..: A string containing the full descriptive name, including build number (e.g., "Windows 11 Version 23H2 (Build 22631.123)"). ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function holds the detailed mapping of build numbers and version IDs (like 22H2) to their common names. ; Related........: _DetectWindowsVersion ; Example........: __GetVersionNameByBuild("19045|22H2") ; Returns "Windows 10 Version 22H2 (2022 Update) (Build 19045)" ; =============================================================================================================================== Func __GetVersionNameByBuild($sBuildData, $sProductName = "") If Not StringInStr($sBuildData, "|") And StringIsDigit($sBuildData) Then $sBuildData &= "||||" EndIf Local $aBuildParts = StringSplit($sBuildData, "|") If $aBuildParts[0] < 1 Then Return "Unknown Windows Version" Local $iBuild = Int($aBuildParts[1]) Local $sDisplayVersion = ($aBuildParts[0] >= 2) ? $aBuildParts[2] : "" Local $sReleaseId = ($aBuildParts[0] >= 3) ? $aBuildParts[3] : "" Local $sCurrentVersion = ($aBuildParts[0] >= 4) ? $aBuildParts[4] : "" Local $sUBR = ($aBuildParts[0] >= 5) ? $aBuildParts[5] : "" Local $bIsServer = (StringInStr($sProductName, "Server") > 0) Local $sName = "" Select ; --- Windows NT Classic --- Case $iBuild = 528 $sName = "Windows NT 3.1" Case $iBuild = 807 $sName = "Windows NT 3.5" Case $iBuild = 1057 $sName = "Windows NT 3.51" Case $iBuild = 1381 $sName = "Windows NT 4.0" ; --- Windows 9x/ME --- Case $iBuild >= 950 And $iBuild <= 1111 $sName = ($iBuild <= 1110) ? "Windows 95" : "Windows 95 OSR2" Case $iBuild = 1998 $sName = "Windows 98" Case $iBuild = 2222 $sName = "Windows 98 Second Edition" Case $iBuild = 3000 $sName = "Windows Millennium Edition" ; --- Windows 2000/XP/Server 2003 --- Case $iBuild = 2195 $sName = $bIsServer ? "Windows 2000 Server" : "Windows 2000 Professional" Case $iBuild = 2600 $sName = "Windows XP" Case $iBuild = 3790 $sName = $bIsServer ? "Windows Server 2003 R2" : "Windows XP Professional x64 Edition" ; --- Windows Vista/Server 2008 --- Case $iBuild = 6000 $sName = $bIsServer ? "Windows Server 2008" : "Windows Vista" Case $iBuild = 6001 $sName = $bIsServer ? "Windows Server 2008 SP1" : "Windows Vista SP1" Case $iBuild = 6002 Or $iBuild = 6003 $sName = $bIsServer ? "Windows Server 2008 SP2" : "Windows Vista SP2" ; --- Windows 7/Server 2008 R2 --- Case $iBuild = 7600 $sName = $bIsServer ? "Windows Server 2008 R2" : "Windows 7" Case $iBuild = 7601 $sName = $bIsServer ? "Windows Server 2008 R2 SP1" : "Windows 7 SP1" ; --- Windows 8/Server 2012 --- Case $iBuild = 9200 $sName = $bIsServer ? "Windows Server 2012" : "Windows 8" ; --- Windows 8.1/Server 2012 R2 --- Case $iBuild = 9600 $sName = $bIsServer ? "Windows Server 2012 R2" : "Windows 8.1" ; --- Windows 10 Versions --- Case $iBuild = 10240 $sName = "Windows 10 Version 1507 (RTM)" Case $iBuild = 10586 $sName = "Windows 10 Version 1511 (November Update)" Case $iBuild = 14393 $sName = $bIsServer ? "Windows Server 2016" : "Windows 10 Version 1607 (Anniversary Update)" Case $iBuild = 15063 $sName = "Windows 10 Version 1703 (Creators Update)" Case $iBuild = 16299 $sName = "Windows 10 Version 1709 (Fall Creators Update)" Case $iBuild = 17134 $sName = "Windows 10 Version 1803 (April 2018 Update)" Case $iBuild = 17763 $sName = $bIsServer ? "Windows Server 2019" : "Windows 10 Version 1809 (October 2018 Update)" Case $iBuild = 18362 $sName = "Windows 10 Version 1903 (May 2019 Update)" Case $iBuild = 18363 $sName = "Windows 10 Version 1909 (November 2019 Update)" Case $iBuild >= 19041 And $iBuild <= 19045 If $sDisplayVersion <> "" Then Switch $sDisplayVersion Case "20H2" $sName = "Windows 10 Version 20H2 (October 2020 Update)" Case "21H1" $sName = "Windows 10 Version 21H1 (May 2021 Update)" Case "21H2" $sName = "Windows 10 Version 21H2 (November 2021 Update)" Case "22H2" $sName = "Windows 10 Version 22H2 (2022 Update)" Case Else $sName = "Windows 10 Version 2004 (May 2020 Update)" EndSwitch ElseIf $sReleaseId <> "" Then Switch $sReleaseId Case "2009" $sName = "Windows 10 Version 20H2 (October 2020 Update)" Case Else $sName = "Windows 10 Version 2004 (May 2020 Update)" EndSwitch Else $sName = "Windows 10 Version 2004 (May 2020 Update)" EndIf ; --- Windows Server 2022 --- Case $iBuild = 20348 $sName = "Windows Server 2022" ; --- Windows 11 Versions --- Case $iBuild = 22000 $sName = "Windows 11 Version 21H2" Case $iBuild >= 22621 And $iBuild <= 22631 If $sDisplayVersion <> "" Then Switch $sDisplayVersion Case "22H2" $sName = "Windows 11 Version 22H2 (2022 Update)" Case "23H2" $sName = "Windows 11 Version 23H2 (2023 Update)" Case Else $sName = "Windows 11 Version 22H2 (2022 Update)" EndSwitch Else $sName = "Windows 11 Version 22H2 (2022 Update)" EndIf Case $iBuild >= 26000 And $iBuild <= 26100 $sName = $bIsServer ? "Windows Server 2025" : "Windows 11 Version 24H2 (2024 Update)" ; --- Future/Insider Builds --- Case $iBuild > 26100 $sName = $bIsServer ? "Windows Server (Insider Preview)" : "Windows 11 (Insider Preview)" ; --- Unknown --- Case Else If StringInStr($sProductName, "Windows 11") Then $sName = "Windows 11" ElseIf StringInStr($sProductName, "Windows 10") Then $sName = "Windows 10" ElseIf StringInStr($sProductName, "Server") Then $sName = "Windows Server" Else $sName = "Unknown Windows Version" EndIf EndSelect Local $sBuildDetails = " (Build " & $iBuild If $sUBR <> "" And $sUBR <> "0" Then $sBuildDetails &= "." & $sUBR $sBuildDetails &= ")" Return $sName & $sBuildDetails EndFunc ;==>__GetVersionNameByBuild ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __GetEditionType ; Description....: (Private) Determines a simplified, standardized Edition Type from the full ProductName or EditionID string. ; Syntax.........: __GetEditionType($sProductName[, $sEditionID = '']) ; Parameters.....: $sProductName - The full product name (e.g., "Windows 10 Pro for Workstations"). ; $sEditionID - [optional] The EditionID from the registry (e.g., "ProfessionalWorkstation"). This is preferred. ; Return values..: A string containing the simplified edition type (e.g., "Pro for Workstations", "Enterprise LTSC", "Home"). ; Returns "Unknown" if the edition cannot be determined. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function contains extensive logic to parse various edition names, including special versions ; like N, KN, LTSC, and IoT. It checks the more reliable EditionID first before falling back to parsing the product name. ; Related........: _DetectWindowsVersion ; Link...........: ; Example........: [Internal Use Only] ; __GetEditionType("Windows 10 Enterprise LTSC 2021", "EnterpriseS") ; Returns "Enterprise LTSC" ; __GetEditionType("Windows 11 Home") ; Returns "Home" ; =============================================================================================================================== Func __GetEditionType($sProductName, $sEditionID = '') ; Prefer EditionID when provided Local $sLowerID = StringLower($sEditionID) If $sLowerID <> '' Then Switch True ; China-specific Case StringInStr($sLowerID, 'corecountryspecific') Or StringInStr($sLowerID, 'corechina') Return 'Home China' Case StringInStr($sLowerID, 'professionalcountryspecific') Or StringInStr($sLowerID, 'professionalchina') Return 'Pro China' Case StringInStr($sLowerID, 'enterprisegovchina') Return 'Enterprise Government China' Case StringInStr($sLowerID, 'enterpriseg') Or StringInStr($sLowerID, 'enterprisegovernment') Return 'Enterprise G' ; Europe N editions Case StringInStr($sLowerID, 'coren') Return 'Home N' Case StringInStr($sLowerID, 'professionaln') Return 'Pro N' Case StringInStr($sLowerID, 'enterprisen') Return 'Enterprise N' Case StringInStr($sLowerID, 'educationn') Return 'Education N' ; Korea KN editions Case StringInStr($sLowerID, 'corekn') Return 'Home KN' Case StringInStr($sLowerID, 'professionalkn') Return 'Pro KN' Case StringInStr($sLowerID, 'enterprisekn') Return 'Enterprise KN' ; LTSC / LTSB Case StringInStr($sLowerID, 'enterprises') Or _ StringInStr($sLowerID, 'enterpriseltsc') Or _ StringInStr($sLowerID, 'enterpriseltsb') Return 'Enterprise LTSC' ; IoT editions Case StringInStr($sLowerID, 'iotenterprise') Return 'IoT Enterprise' Case StringInStr($sLowerID, 'iotcore') Return 'IoT Core' ; Mobile editions Case StringInStr($sLowerID, 'mobileenterprise') Return 'Mobile Enterprise' Case StringInStr($sLowerID, 'mobile') Return 'Mobile' ; Other special SKUs Case StringInStr($sLowerID, 'mixedreality') Return 'Mixed Reality' Case StringInStr($sLowerID, 'proeducation') Return 'Pro Education' Case StringInStr($sLowerID, 'proforworkstations') Return 'Pro for Workstations' ; Generic EditionID patterns Case StringInStr($sLowerID, 'enterprise') Return 'Enterprise' Case StringInStr($sLowerID, 'professional') Return 'Professional' Case StringInStr($sLowerID, 'standard') Return 'Standard' Case StringInStr($sLowerID, 'datacenter') Return 'Datacenter' Case StringInStr($sLowerID, 'essentials') Return 'Essentials' Case StringInStr($sLowerID, 'starter') Return 'Starter' Case StringInStr($sLowerID, 'home') Return 'Home' EndSwitch EndIf ; Fallback to product name if EditionID was empty or unrecognized Local $sLower = StringLower($sProductName) ; === Windows Server Editions === If StringInStr($sLower, "server") Then ; Windows Server 2022/2025 If StringInStr($sLower, "2022") Or StringInStr($sLower, "2025") Then If StringInStr($sLower, "azure") Then Return "Server Datacenter: Azure Edition" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" If StringInStr($sLower, "essentials") Then Return "Server Essentials" Return "Server" EndIf ; Windows Server 2019 If StringInStr($sLower, "2019") Then If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" Return "Server 2019" EndIf ; Windows Server 2016 If StringInStr($sLower, "2016") Then If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" If StringInStr($sLower, "foundation") Then Return "Server Foundation" Return "Server 2016" EndIf ; Generic Server If StringInStr($sLower, "essentials") Then Return "Server Essentials" If StringInStr($sLower, "datacenter") Then Return "Server Datacenter" If StringInStr($sLower, "standard") Then Return "Server Standard" Return "Server" EndIf ; === Windows Client Editions === ; Windows 11 Editions If StringInStr($sLower, "windows 11") Then If StringInStr($sLower, "mixed reality") Then Return "Mixed Reality" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "home") Then Return "Home" Return "Windows 11" EndIf ; Windows 10 Editions If StringInStr($sLower, "windows 10") Then If StringInStr($sLower, "mobile enterprise") Then Return "Mobile Enterprise" If StringInStr($sLower, "mobile") Then Return "Mobile" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "iot core") Then Return "IoT Core" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "home") Then Return "Home" Return "Windows 10" EndIf ; Windows 8.1 Editions If StringInStr($sLower, "windows 8.1") Or StringInStr($sLower, "8.1") Then If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "single language") Then Return "Single Language" If StringInStr($sLower, "pro") And StringInStr($sLower, "media center") Then Return "Pro with Media Center" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "core") Or StringInStr($sLower, "windows 8.1") Then Return "Core" Return "Windows 8.1" EndIf ; Windows 8 Editions If StringInStr($sLower, "windows 8") Then If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then Return "Pro" If StringInStr($sLower, "core") Or StringInStr($sLower, "windows 8") Then Return "Core" Return "Windows 8" EndIf ; Windows 7 Editions If StringInStr($sLower, "windows 7") Or StringInStr($sLower, "7") Then If StringInStr($sLower, "starter") Then Return "Starter" If StringInStr($sLower, "home basic") Then Return "Home Basic" If StringInStr($sLower, "home premium") Then Return "Home Premium" If StringInStr($sLower, "ultimate") Then Return "Ultimate" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Then Return "Professional" Return "Windows 7" EndIf ; === Generic Edition Detection (for older versions or fallback) === If StringInStr($sLower, "embedded") Then Return "Embedded" If StringInStr($sLower, "starter") Then Return "Starter" If StringInStr($sLower, "ultimate") Then Return "Ultimate" If StringInStr($sLower, "mixed reality") Then Return "Mixed Reality" If StringInStr($sLower, "iot enterprise") Then Return "IoT Enterprise" If StringInStr($sLower, "iot core") Then Return "IoT Core" If StringInStr($sLower, "iot") Then Return "IoT" If StringInStr($sLower, "mobile enterprise") Then Return "Mobile Enterprise" If StringInStr($sLower, "mobile") Then Return "Mobile" If StringInStr($sLower, "rt") Then Return "RT" If StringInStr($sLower, "pro for workstations") Then Return "Pro for Workstations" If StringInStr($sLower, "workstation") Then Return "Workstation" If StringInStr($sLower, "pro education") Then Return "Pro Education" If StringInStr($sLower, "education") Then Return "Education" If StringInStr($sLower, "enterprise") Then Return "Enterprise" If StringInStr($sLower, "professional") Or StringInStr($sLower, "pro") Then If StringInStr($sLower, "media center") Then Return "Pro with Media Center" Return "Professional" EndIf If StringInStr($sLower, "home premium") Then Return "Home Premium" If StringInStr($sLower, "home basic") Then Return "Home Basic" If StringInStr($sLower, "home") Then Return "Home" If StringInStr($sLower, "core") Then Return "Core" If StringInStr($sLower, "single language") Then Return "Single Language" If StringInStr($sLower, "millennium") Then Return "Millennium Edition" If StringInStr($sLower, "second edition") Then Return "Second Edition" If $sProductName <> "" Then Return "Standard" Return "Unknown" EndFunc ;==>__GetEditionType ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: __ArrayToString ; Description....: Converts an array to a string, with elements separated by a delimiter. ; Syntax.........: __ArrayToString($aArray[, $sDelimiter = "|"]) ; Parameters.....: $aArray - The array to convert. ; $sDelimiter - [optional] The delimiter to use between array elements. Default is "|". ; Return values..: Success - A string containing the joined array elements. ; Failure - An empty string if the input is not a valid array, and sets @error to 1. ; =============================================================================================================================== Func __ArrayToString($aArray, $sDelimiter = "|") If Not IsArray($aArray) Then Return SetError(1, 0, "") Local $sResult = "" For $i = 0 To UBound($aArray) - 1 If $i > 0 Then $sResult &= $sDelimiter $sResult &= $aArray[$i] Next Return $sResult EndFunc ;==>__ArrayToString : TEST : ; =============================================================================================================================== ; TEST SECTION - Enhanced testing with better error handling ; =============================================================================================================================== Func _GetSystemInfo() ; 1. Keyboard Layout (HKL) Local $sKeyboard = @KBLayout ; 2. OS Name và Version Local $sKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" Local $sProductName = RegRead($sKey, "ProductName") ; ex: "Windows 11 Pro" Local $sMajor = StringRegExpReplace($sProductName, ".*Windows[ ]+(\d+).*", "\1") Local $sReleaseId = RegRead($sKey, "ReleaseId") ; ex: "2009" / "21H2" Local $sOS = "WIN_" & $sMajor & "/" & $sReleaseId ; 3. CPU Architecture Local $sCPUArch = StringUpper(@CPUArch) ; ex: "X64", "X86", "IA64" ; 4. OS Architecture Local $sOSArch = StringUpper(@OSArch) ; ex: "X64", "X86" ; 5. Environment Language (LANGID) Local $sLangID = @OSLang ; Kết hợp chuỗi trả về Local $sReturn = "> Keyboard:" & $sKeyboard & " > OS:" & $sOS & " > CPU:" & $sCPUArch & " > OS:" & $sOSArch & " Environment (Language:" & $sLangID & ")" Return $sReturn EndFunc ;==>_GetSystemInfo #Region TEST ; #INTERNAL_FUNCTION# =========================================================================================================== ; Name...........: TEST ; Description....: (Private) Runs a test suite for the Windows Version Detector UDF. ; Syntax.........: TEST() ; Return values..: None. Writes test results to the console. ; Author.........: Dao Van Trong - TRONG.PRO ; Remarks........: This function is for development and debugging purposes. It is only executed when the script is run directly ; Related........: _DetectWindowsVersion, __GetEditionType ; Example........: [Internal Use Only for Script Execution] ; =============================================================================================================================== Global $logContent Func TEST() _ConsoleWrite("> === Windows Version Detector v3: Test Suite ===" & @CRLF) _ConsoleWrite("> Current date/time: " & @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @CRLF) _ConsoleWrite(_GetSystemInfo() & @CRLF & @CRLF) ; Test 1: Local $aTestPath = ["C:\Windows", "D:\Windows", "E:\Windows"] ; Common live/offline paths For $sTestPath In $aTestPath If FileExists($sTestPath) Then _ConsoleWrite("> Testing path: " & $sTestPath & @CRLF) Else _ConsoleWrite("> Testing invalid path: " & $sTestPath & @CRLF) EndIf Local $aOSVinfo = _DetectWindowsVersion($sTestPath) If @error Then _ConsoleWrite("! [FAILED] Error code: " & @error & @CRLF) _ConsoleWrite("! [CHECK] IsArray($aOSVinfo): " & (IsArray($aOSVinfo) ? 'True' : 'False') & @CRLF) Else _ConsoleWrite("+ [SUCCESS]" & @CRLF) _ConsoleWrite("- ✓ SystemType [0]: " & $aOSVinfo[0] & @CRLF) _ConsoleWrite("- ✓ ShortName [1]: " & $aOSVinfo[1] & @CRLF) _ConsoleWrite("- ✓ ProductName [2]: " & $aOSVinfo[2] & @CRLF) _ConsoleWrite("- ✓ VersionName [3]: " & $aOSVinfo[3] & @CRLF) _ConsoleWrite("- ✓ BuildData [4]: " & $aOSVinfo[4] & @CRLF) _ConsoleWrite("- ✓ EditionID [5]: " & $aOSVinfo[5] & @CRLF) _ConsoleWrite("- ✓ Edition [6]: " & $aOSVinfo[6] & @CRLF) EndIf _ConsoleWrite(@CRLF) Next ; Test 2: Special Edition Detection Test _ConsoleWrite("> 2. Testing special edition detection capabilities:" & @CRLF) ; Test cases format: [ProductName, EditionID, ExpectedEditionType] Local $aTestCases = [ _ ["Windows 10 Home", "CoreCountrySpecific", "Home China"], _ ["Windows 11 Home", "CoreCountrySpecific", "Home China"], _ ["Windows 10 Pro", "ProfessionalCountrySpecific", "Pro China"], _ ["Windows 10 Home N", "CoreN", "Home N"], _ ["Windows 11 Pro N", "ProfessionalN", "Pro N"], _ ["Windows 10 Home KN", "CoreKN", "Home KN"], _ ["Windows 10 Enterprise G", "EnterpriseG", "Enterprise G"], _ ["Windows 10 Enterprise LTSC", "EnterpriseS", "Enterprise LTSC"], _ ["Windows 10 IoT Enterprise", "IoTEnterprise", "IoT Enterprise"] _ ] For $i = 0 To UBound($aTestCases) - 1 Local $sProductName = $aTestCases[$i][0] Local $sEditionID = $aTestCases[$i][1] Local $sExpected = $aTestCases[$i][2] Local $sResult = __GetEditionType($sProductName, $sEditionID) Local $sStatus = ($sResult = $sExpected) ? "+ ✓ PASS" : "! ✗ FAIL" _ConsoleWrite($sStatus & " | ProductName: " & StringFormat("%-28s", $sProductName) & " | EditionID: " & StringFormat("%-27s", $sEditionID) & " | Result: " & $sResult & @CRLF) Next _ConsoleWrite(@CRLF & '> TEST END' & @CRLF) EndFunc ;==>TEST Func _ConsoleWrite($s = '') $logContent &= $s ConsoleWrite($s) EndFunc ;==>_ConsoleWrite ; run test If Not @Compiled Then TEST() ClipPut($logContent) EndIf #EndRegion TEST > Result test: > === Windows Version Detector v3: Test Suite === > Current date/time: 2025-09-08 11:46:25 > Keyboard:00000409 > OS:WIN_10/2009 > CPU:X64 > OS:X64 Environment (Language:0409) > Testing path: C:\Windows + [SUCCESS] - ✓ SystemType [0]: Live - ✓ ShortName [1]: WIN_10 - ✓ ProductName [2]: Windows 10 Enterprise LTSC 2021 - ✓ VersionName [3]: Windows 10 Version 22H2 (2022 Update) (Build 19045.6216) - ✓ BuildData [4]: 19045|22H2|2009|6.3|6216 - ✓ EditionID [5]: EnterpriseS - ✓ Edition [6]: Enterprise LTSC > Testing invalid path: D:\Windows ! [FAILED] Error code: 1 ! [CHECK] IsArray($aOSVinfo): True > Testing invalid path: E:\Windows ! [FAILED] Error code: 1 ! [CHECK] IsArray($aOSVinfo): True > 2. Testing special edition detection capabilities: + ✓ PASS | ProductName: Windows 10 Home | EditionID: CoreCountrySpecific | Result: Home China + ✓ PASS | ProductName: Windows 11 Home | EditionID: CoreCountrySpecific | Result: Home China + ✓ PASS | ProductName: Windows 10 Pro | EditionID: ProfessionalCountrySpecific | Result: Pro China + ✓ PASS | ProductName: Windows 10 Home N | EditionID: CoreN | Result: Home N + ✓ PASS | ProductName: Windows 11 Pro N | EditionID: ProfessionalN | Result: Pro N + ✓ PASS | ProductName: Windows 10 Home KN | EditionID: CoreKN | Result: Home KN + ✓ PASS | ProductName: Windows 10 Enterprise G | EditionID: EnterpriseG | Result: Enterprise G + ✓ PASS | ProductName: Windows 10 Enterprise LTSC | EditionID: EnterpriseS | Result: Enterprise LTSC + ✓ PASS | ProductName: Windows 10 IoT Enterprise | EditionID: IoTEnterprise | Result: IoT Enterprise > TEST END3 points
-
pixelsearch, analytical and comprehensive as always, thank you very much The solution proposed by Danyfirex 🏆, in this particular post is completely functional #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <GuiTab.au3> ;>> Target: C:\Program Files (x86)\AutoIt3\Examples\Helpfile\GUICtrlCreateTab.au3 If Not WinExists("My GUI Tab") Then Exit Local $hWnd = WinWait("My GUI Tab", "", 1) ConsoleWrite("$hWnd=" & $hWnd & @CRLF) Local $hCtrl = ControlGetHandle($hWnd, "", "SysTabControl321") ConsoleWrite("$hCtrl=" & $hCtrl & @CRLF) Local $hParentWnd = _WinAPI_GetParent($hCtrl) ConsoleWrite("$hParentWnd=" & $hParentWnd & @CRLF) ; Show number of tabs Local $iTabCnt = _GUICtrlTab_GetItemCount($hCtrl) ConsoleWrite("Number of tabs: " & $iTabCnt & @CRLF & @CRLF) Local $sItemText, $aItem ; Now is working !! For $x = 0 To $iTabCnt - 1 $aItem = _GUICtrlTab_GetItemEx($hCtrl, $x) $sItemText = $aItem[1] ConsoleWrite("$sItemText=" & $sItemText & @CRLF) Next Func _GUICtrlTab_GetItemEx($hWnd, $iIndex) If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) Local $tagTCITEMEx = $tagTCITEM & ";ptr Filler" ; strange the Filler is erased by TCM_GETITEM : MS Bug!!! If Not _WinAPI_InProcess($hWnd, $__g_hGUICtrl_LastWnd) Then ;x86 read remote x64 If (Not @AutoItX64) And (Not _WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "INT64") EndIf ;x64 read remote x86 If (@AutoItX64) And (_WinAPI_IsWow64Process(DllCall("user32.dll", "dword", "GetWindowThreadProcessId", "hwnd", $hWnd, "dword*", 0)[2])) Then $tagTCITEMEx = StringReplace($tagTCITEMEx, "ptr", "ULONG") EndIf EndIf Local $tItem = DllStructCreate($tagTCITEMEx) DllStructSetData($tItem, "Mask", $TCIF_ALLDATA) DllStructSetData($tItem, "StateMask", BitOR($TCIS_HIGHLIGHTED, $TCIS_BUTTONPRESSED)) Local $tBuffer, $iMsg If _GUICtrlTab_GetUnicodeFormat($hWnd) Then $tBuffer = $__g_tTabBuffer $iMsg = $TCM_GETITEMW Else $tBuffer = $__g_tTabBufferANSI $iMsg = $TCM_GETITEMA EndIf Local $iRet = __GUICtrl_SendMsg($hWnd, $iMsg, $iIndex, $tItem, $tBuffer, True, 4, True) Local $aItem[4] $aItem[0] = DllStructGetData($tItem, "State") $aItem[1] = DllStructGetData($tBuffer, "Text") $aItem[2] = DllStructGetData($tItem, "Image") $aItem[3] = DllStructGetData($tItem, "Param") Return SetError($iRet = 0, 0, $aItem) EndFunc ;==>_GUICtrlTab_GetItem This way, I avoid having to make a helper script like a bridge, I just add the function. Mission accomplished. Thank you very much3 points
-
_GUICtrlTab_GetItemText the target crashes on dissimilar architecture
Danyfirex and 2 others reacted to pixelsearch for a topic
@ioa747 Hi When you call _GUICtrlTab_GetItemText, then _GUICtrlTab_GetItem is called And _GuiCtrlTab_GetItem had issues as seen on Trac Ticket 3903 and in this post. In the post, @Danyfirex worked on this x86-x64 issue and maybe he could give an advice here if he got time ? Also I notice code in _GUICtrlTab_GetItem has been updated in new release 3.3.17.1 (beta) . Did you check your script with 3.3.17.1 , maybe it's solved with the new release ? Fingers crossed & good luck3 points -
To flesh this out a bit more - I attempted to recreate this example.. The XML looks like this... <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="3*"/> <ColumnDefinition Width="5*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="2*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Border Background="#2f5cb6"/> <Border Grid.Column ="1" Background="#1f3d7a"/> <Border Grid.Row="1" Grid.ColumnSpan="2" Background="#152951"/> <StackPanel Grid.Column="1" Margin="40,0,0,0" VerticalAlignment="Center"> <TextBlock Foreground="White" FontSize="25" Text="Today - 64° F"/> <TextBlock Foreground="White" FontSize="25" Text="Partially Cloudy"/> <TextBlock Foreground="White" FontSize="25" Text="Precipitation: 25%"/> </StackPanel> <StackPanel Grid.Row="1" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <TextBlock Foreground="White" FontSize="25" Text="High: 66°" Margin="0,0,20,0"/> <TextBlock Foreground="White" FontSize="25" Text="Low: 43°" Margin="0,0,20,0"/> <TextBlock Foreground="White" FontSize="25" Text="Feels like: 63°"/> </StackPanel> <Image Margin="20" Source="Assets/partially-cloudy.png"/> </Grid> Now last time out we were specifying our Row/Column definitions like this.. Local $tGridLen = DllStructCreate("align 1;double Value;ulong GridUnitType") $tGridLen.GridUnitType = $mGridUnitType["Star"] $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") $tGridLen.Value = 2 IRowDefinition_SetHeight($pRowDef, $tGridLen) IVector_Append($pRowDefs, $pRowDef) The default interface for a "RowDefinition" is IRowDefinition - but it seems ActivateInstance doesn't put us there. So appending the object to the collection worked OK- the cells obviously appeared. But setting the height property was actually failing. So the learning is: If you're instantiating via ActivateInstance, you should always follow up with a _WinRT_SwitchInterface. Local $tGridLen = DllStructCreate("align 1;double Value;ulong GridUnitType") $tGridLen.GridUnitType = $mGridUnitType["Star"] $pRowDef = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.RowDefinition") _WinRT_SwitchInterface($pRowDef, $sIID_IRowDefinition) ;ADD THIS! $tGridLen.Value = 2 IRowDefinition_SetHeight($pRowDef, $tGridLen) IVector_Append($pRowDefs, $pRowDef) In this example, we have a few new controls: stackpanels - these work like grids, but the're 1-dimentional. (Edit: Well they have a width and height, but its just one row or one column of panels!) You don't need to assign a "grid spot" for the controls of a stackpanel though - they seem to appear in the order they were added in the IPanel::Children collection. Vectors do assign indexes to child items by memory - so I'd imagine if we shuffled items around via IVector, the GUI would probably follow suit (untested). textblocks - not much to be said about these. But at this point, I'll quickly mention that IFrameworkElement interface seems to look after most of the spatial things for a control (its margins, vertical and horizontal alignment, min/max sizing etc). And this is common across everything we've seen so far. Then we have an image - this one is a bit more interesting. You load it in with a URI, so for local storage we'll need to specify something like file:///C:/path/to/file.blah. Once you have yourself an uri object - we can bring the file in via a BitmapImage object. And finally we associate that with the UI object "controls.Image" Local $pURI_Fact = _WinRT_GetActivationFactory("Windows.Foundation.Uri", $sIID_IUriRuntimeClassFactory) Local $pImageURI = IUriRuntimeClassFactory_CreateWithRelativeUri($pURI_Fact, "file:///C:/FilePath/", "image.png") Local $pBitmap = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Media.Imaging.BitmapImage") _WinRT_SwitchInterface($pBitmap, $sIID_IBitmapImage) IBitmapImage_SetUriSource($pBitmap, $pImageURI) Local $pImage = _WinRT_ActivateInstance("Microsoft.UI.Xaml.Controls.Image") _WinRT_SwitchInterface($pImage, $sIID_IImage) IImage_SetSource($pImage, $pBitmap) The loading is asynchronous, so if you need the dimensions of the source for example - those details are only available once the image is ready. If those properties are important we can register a delegate that will fire once the image is loded. Also, if the image fails to load, there's a delegate for that too... Local $pImgFailedDgte = _WinRT_CreateDelegate("ImageLoadFail") Local $iImgFailedDgteTkn = IBitmapImage_AddHdlrImageFailed($pBitmap, $pImgFailedDgte) ;Attempt to load image IBitmapImage_SetUriSource($pBitmap, $pImageURI) Func ImageLoadFail($pThis, $pSource, $pArgs) #forceref $pThis, $pSource, $pArgs ConsoleWrite("Image failed to load!" & @CRLF) EndFunc Final point on this example, I've tied the content bridge's size (the container encompassing the xaml controls) to the Windows WM_SIZE message. Case $WM_SIZE $tRect.Width = BitAND(0xFFFF, $lParam) $tRect.Height = BitShift($lParam, 16) IDesktopSiteBridge_MoveAndResize($pBridge, $tRect) $iReturn = _WinAPI_DefWindowProcW($hWnd, $iMsg, $wParam, $lParam) And resizing the window actually works remarkably well. I guess I was expecting some flicker or something- so that was a pleasant surprise! WindowTest Grid.zip3 points
-
UDF: #include-once #cs ---------------------------------------------------------------------------- ; LZNT1 Compression ; AutoIt Version: 3.3.16.1+ ; Description: Supports compression and decompression of binary data and strings using the Windows LZNT1 algorithm. ; Author: trancexx + rewritten & extended by Dao Van Trong - TRONG.PRO ; ; Functions: ; _LZNT_Compress($bInput, $iEngine = 2, $bBase64 = False, $iLineLen = 1024) ; _LZNT_Decompress($vInput, $iOrigSize = 0, $iEngine = 2, $bBase64 = False) ; _LZNT_CompressString($sInput, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024) ; _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False) ; #ce ---------------------------------------------------------------------------- ; =============================================================================================================================== ; Public Function: Compress Binary ; =============================================================================================================================== ; Description: Compresses binary data using the LZNT1 algorithm. ; Parameters: ; $bInput - Binary data to be compressed. ; $iEngine - Compression engine. ; 2 (default) = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD ; 258 = COMPRESSION_ENGINE_MAXIMUM ; $bBase64 - True to return a Base64 string, False to return binary data. ; $iLineLen - Line length when returning a Base64 string (default is 1024 characters). ; Return Value: Returns the compressed data (binary or Base64). ; On Failure: Returns an empty string (""), @error is set to: ; 1 = Error calling RtlGetCompressionWorkSpaceSize. ; 2 = Error calling RtlCompressBuffer. ; 3 = Error converting to Base64 in __Base64Encode. ; @extended is set to the original length of the binary data. ; Author: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _LZNT_Compress($bInput, $iEngine = 2, $bBase64 = False, $iLineLen = 1024) If Not IsBinary($bInput) Then $bInput = Binary($bInput) If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 2 Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]") DllStructSetData($tInput, 1, $bInput) Local $aCall = DllCall("ntdll.dll", "int", "RtlGetCompressionWorkSpaceSize", _ "ushort", $iEngine, "dword*", 0, "dword*", 0) If @error Or $aCall[0] Then Return SetError(1, 0, "") Local $tWork = DllStructCreate("byte[" & $aCall[2] & "]") Local $tBuffer = DllStructCreate("byte[" & 16 * DllStructGetSize($tInput) & "]") $aCall = DllCall("ntdll.dll", "int", "RtlCompressBuffer", _ "ushort", $iEngine, _ "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _ "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _ "dword", 4096, "dword*", 0, "ptr", DllStructGetPtr($tWork)) If @error Or $aCall[0] Then Return SetError(2, 0, "") Local $tOut = DllStructCreate("byte[" & $aCall[7] & "]", DllStructGetPtr($tBuffer)) Local $bOut = DllStructGetData($tOut, 1) If $bBase64 Then Return SetError(0, DllStructGetSize($tInput), __Base64Encode($bOut, $iLineLen)) Return SetError(0, DllStructGetSize($tInput), $bOut) EndFunc ;==>_LZNT_Compress ; =============================================================================================================================== ; Public Function: Decompress Binary ; =============================================================================================================================== ; Description: Decompresses LZNT1-compressed binary data. ; Parameters: ; $vInput - Compressed data, can be binary or a Base64 string. ; $iOrigSize - Estimated original size of the uncompressed data. If < 1, it will be estimated automatically. ; $iEngine - Compression engine used. ; 2 (default) = COMPRESSION_FORMAT_LZNT1 | $COMPRESSION_ENGINE_STANDARD ; 258 = COMPRESSION_ENGINE_MAXIMUM ; $bBase64 - True if $vInput is a Base64 string, False if it is binary data. ; Return Value: Returns the decompressed binary data. ; On Failure: Returns an empty string (""), @error is set to: ; 1 = Decompression error, or $vInput is not Base64 when $bBase64 is True. ; @extended is set to 0. ; Author: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _LZNT_Decompress($vInput, $iOrigSize = 0, $iEngine = 2, $bBase64 = False) Local $bInput If $bBase64 Then $bInput = __Base64Decode($vInput) Else $bInput = $vInput EndIf If Not IsBinary($bInput) Then $bInput = Binary($bInput) If $iEngine <> 2 And $iEngine <> 258 Then $iEngine = 2 Local $tInput = DllStructCreate("byte[" & BinaryLen($bInput) & "]") DllStructSetData($tInput, 1, $bInput) If $iOrigSize < 1 Then $iOrigSize = 16 * DllStructGetSize($tInput) Local $tBuffer = DllStructCreate("byte[" & $iOrigSize & "]") Local $aCall = DllCall("ntdll.dll", "int", "RtlDecompressBuffer", _ "ushort", $iEngine, _ "ptr", DllStructGetPtr($tBuffer), "dword", DllStructGetSize($tBuffer), _ "ptr", DllStructGetPtr($tInput), "dword", DllStructGetSize($tInput), _ "dword*", 0) If @error Or $aCall[0] Then Return SetError(1, 0, "") Local $tOut = DllStructCreate("byte[" & $aCall[6] & "]", DllStructGetPtr($tBuffer)) Return SetError(0, $aCall[6], DllStructGetData($tOut, 1)) EndFunc ;==>_LZNT_Decompress ; =============================================================================================================================== ; Public Function: Compress String ; =============================================================================================================================== ; Description: Compresses a string and returns the compressed data. ; Parameters: ; $sInput - String to be compressed. ; $iEncoding - String encoding. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8) ; $iEngine - Compression engine (same as _LZNT_Compress).(2 or 258) ; $bBase64 - True to return a Base64 string, False to return binary. ; $iLineLen - Line length when returning a Base64 string. ; Return Value: Returns the compressed data (binary or Base64). ; On Failure: Returns an empty string (""), @error is set to: ; 1, 2, 3 (same as _LZNT_Compress). ; @extended is set to the original length of the string data. ; Author: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _LZNT_CompressString($sInput, $iEncoding = 4, $iEngine = 2, $bBase64 = False, $iLineLen = 1024) Local $bData = StringToBinary($sInput, $iEncoding) Return _LZNT_Compress($bData, $iEngine, $bBase64, $iLineLen) EndFunc ;==>_LZNT_CompressString ; =============================================================================================================================== ; Public Function: Decompress String ; =============================================================================================================================== ; Description: Decompresses data and returns a string. ; Parameters: ; $vInput - Compressed data. ; $iOrigSize - Estimated original size of the uncompressed data. ; $iEncoding - Encoding to convert the decompressed binary to a string. (1=ANSI, 2=UTF16LE, 3=UTF16BE, 4=UTF8) ; $iEngine - Compression engine used (same as _LZNT_Decompress).(2 or 258) ; $bBase64 - True if $vInput is a Base64 string, False if it is binary. ; Return Value: Returns the decompressed string. ; On Failure: Returns an empty string (""), @error is set to: ; 1 = Decompression error (same as _LZNT_Decompress). ; @extended is set to 0. ; Author: Dao Van Trong - TRONG.PRO ; =============================================================================================================================== Func _LZNT_DecompressString($vInput, $iOrigSize = 0, $iEncoding = 4, $iEngine = 2, $bBase64 = False) Local $bData = _LZNT_Decompress($vInput, $iOrigSize, $iEngine, $bBase64) If @error Then Return SetError(1, 0, "") Return BinaryToString($bData, $iEncoding) EndFunc ;==>_LZNT_DecompressString ; =============================================================================================================================== ; Internal helper: Base64 Encode ; =============================================================================================================================== Func __Base64Encode($bData, $iLineLen = 1024) If Not IsBinary($bData) Then Return SetError(1, 0, "") Local $pInput = DllStructCreate("byte[" & BinaryLen($bData) & "]") DllStructSetData($pInput, 1, $bData) ; 1st call to get required length Local $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _ "ptr", DllStructGetPtr($pInput), _ "dword", DllStructGetSize($pInput), _ "dword", 0x1, _ ; CRYPT_STRING_BASE64 "ptr", 0, _ "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(2, 0, "") Local $iLen = $aCall[5] Local $tOut = DllStructCreate("wchar[" & $iLen & "]") ; 2nd call to actually encode $aCall = DllCall("Crypt32.dll", "bool", "CryptBinaryToStringW", _ "ptr", DllStructGetPtr($pInput), _ "dword", DllStructGetSize($pInput), _ "dword", 0x1, _ "ptr", DllStructGetPtr($tOut), _ "dword*", $iLen) If @error Or Not $aCall[0] Then Return SetError(3, 0, "") Local $sOut = DllStructGetData($tOut, 1) ; Remove CRLF inserted by Crypt32 $sOut = StringReplace($sOut, @CRLF, "") ; Manual wrap for embedding in AutoIt source If $iLineLen > 0 And StringLen($sOut) > $iLineLen Then Local $sWrapped = "" For $i = 1 To StringLen($sOut) Step $iLineLen $sWrapped &= StringMid($sOut, $i, $iLineLen) & @CRLF Next $sOut = StringTrimRight($sWrapped, 2) EndIf Return $sOut EndFunc ;==>__Base64Encode ; =============================================================================================================================== ; Internal helper: Base64 Decode ; =============================================================================================================================== Func __Base64Decode($sBase64) If Not IsString($sBase64) Then Return SetError(1, 0, "") ; strip whitespace / CRLF $sBase64 = StringStripWS($sBase64, 8) ; 1st call to get required length Local $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _ "wstr", $sBase64, _ "dword", 0, _ "dword", 0x1, _ ; CRYPT_STRING_BASE64 "ptr", 0, _ "dword*", 0, _ "dword*", 0, _ "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(2, 0, "") Local $iLen = $aCall[5] Local $tOut = DllStructCreate("byte[" & $iLen & "]") ; 2nd call to decode $aCall = DllCall("Crypt32.dll", "bool", "CryptStringToBinaryW", _ "wstr", $sBase64, _ "dword", 0, _ "dword", 0x1, _ "ptr", DllStructGetPtr($tOut), _ "dword*", $iLen, _ "dword*", 0, _ "dword*", 0) If @error Or Not $aCall[0] Then Return SetError(3, 0, "") Return DllStructGetData($tOut, 1) EndFunc ;==>__Base64Decode #cs ; =============================================================================================================================== ; SELF-TEST FOR LZNT + BASE64 UDF ; =============================================================================================================================== ; Test string with 10 languages Global Const $sTest = "Hello 你好 नमस्ते Hola Bonjour مرحبا হ্যালো Привет Olá Xin chào 🚀" ConsoleWrite("!===== SELF TEST START =====" & @CRLF) ConsoleWrite("+ Original String: " & $sTest & @CRLF) ConsoleWrite("- Original Length: " & StringLen($sTest) & " chars" & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 1) Compress binary ; ------------------------------------------------------------------------------------------------------------------------------- Local $bInput = StringToBinary($sTest, 4) ; UTF-8 Local $bCompressed = _LZNT_Compress($bInput, 2, False) Local $iOrigSize = @extended ConsoleWrite(@CRLF & "- [1] Compress Binary (HEX)" & @CRLF) ConsoleWrite("+ OrigSize: " & $iOrigSize & " CompressedSize: " & BinaryLen($bCompressed) & @CRLF) ; Decompress binary Local $bDecompressed = _LZNT_Decompress($bCompressed, $iOrigSize, 2, False) ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 2) Compress binary + Base64 ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedB64 = _LZNT_Compress($bInput, 2, True, 32) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [2] Compress Binary (Base64)" & @CRLF) ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedB64 & @CRLF) ; Decompress binary from Base64 $bDecompressed = _LZNT_Decompress($sCompressedB64, $iOrigSize, 2, True) ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 3) Compress String (HEX) ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedStr = _LZNT_CompressString($sTest, 4, 2, False) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [3] Compress String (HEX)" & @CRLF) ConsoleWrite("+ CompressedSize: " & BinaryLen($sCompressedStr) & @CRLF) ; Decompress String Local $sDecompressed = _LZNT_DecompressString($sCompressedStr, $iOrigSize, 4, 2, False) ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF) ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 4) Compress String (Base64) ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedStrB64 = _LZNT_CompressString($sTest, 4, 2, True, 40) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [4] Compress String (Base64)" & @CRLF) ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedStrB64 & @CRLF) ; Decompress String $sDecompressed = _LZNT_DecompressString($sCompressedStrB64, $iOrigSize, 4, 2, True) ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF) ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ConsoleWrite("!===== SELF TEST END =====" & @CRLF) #ce EG: ;#include "LZNT_Compress_Engine.AU3" ; =============================================================================================================================== ; SELF-TEST FOR LZNT + BASE64 UDF ; =============================================================================================================================== ; Test string with 10 languages Global Const $sTest = "Hello 你好 नमस्ते Hola Bonjour مرحبا হ্যালো Привет Olá Xin chào 🚀" ConsoleWrite("!===== SELF TEST START =====" & @CRLF) ConsoleWrite("+ Original String: " & $sTest & @CRLF) ConsoleWrite("- Original Length: " & StringLen($sTest) & " chars" & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 1) Compress binary ; ------------------------------------------------------------------------------------------------------------------------------- Local $bInput = StringToBinary($sTest, 4) ; UTF-8 Local $bCompressed = _LZNT_Compress($bInput, 2, False) Local $iOrigSize = @extended ConsoleWrite(@CRLF & "- [1] Compress Binary (HEX)" & @CRLF) ConsoleWrite("+ OrigSize: " & $iOrigSize & " CompressedSize: " & BinaryLen($bCompressed) & @CRLF) ; Decompress binary Local $bDecompressed = _LZNT_Decompress($bCompressed, $iOrigSize, 2, False) ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 2) Compress binary + Base64 ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedB64 = _LZNT_Compress($bInput, 2, True, 32) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [2] Compress Binary (Base64)" & @CRLF) ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedB64 & @CRLF) ; Decompress binary from Base64 $bDecompressed = _LZNT_Decompress($sCompressedB64, $iOrigSize, 2, True) ConsoleWrite("" & (BinaryToString($bDecompressed, 4) = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 3) Compress String (HEX) ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedStr = _LZNT_CompressString($sTest, 4, 2, False) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [3] Compress String (HEX)" & @CRLF) ConsoleWrite("+ CompressedSize: " & BinaryLen($sCompressedStr) & @CRLF) ; Decompress String Local $sDecompressed = _LZNT_DecompressString($sCompressedStr, $iOrigSize, 4, 2, False) ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF) ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ; ------------------------------------------------------------------------------------------------------------------------------- ; 4) Compress String (Base64) ; ------------------------------------------------------------------------------------------------------------------------------- Local $sCompressedStrB64 = _LZNT_CompressString($sTest, 4, 2, True, 40) $iOrigSize = @extended ConsoleWrite(@CRLF & "- [4] Compress String (Base64)" & @CRLF) ConsoleWrite("+ Compressed (B64): " & @CRLF & $sCompressedStrB64 & @CRLF) ; Decompress String $sDecompressed = _LZNT_DecompressString($sCompressedStrB64, $iOrigSize, 4, 2, True) ConsoleWrite("- Decompressed String: " & $sDecompressed & @CRLF) ConsoleWrite("" & ($sDecompressed = $sTest ? '- Decompressed OK' : '! Decompressed NG') & @CRLF) ConsoleWrite("!===== SELF TEST END =====" & @CRLF) #ce !3 points
-
WinRT - WinUI3
Gianni and 2 others reacted to WildByDesign for a topic
I personally really appreciate these longer blog-like posts. You are learning this WinUI3 stuff as you go and we are learning along with you (thanks to you). I think that this teaching style of posts is the only way to go, honestly. I also think that this has a lot of great potential for any of us who use AutoIt for making GUI programs. This has the potential to create more opportunities for designing modern looking GUI apps in AutoIt and that is definitely a bonus. Therefore, for any of us that have an interest in that area and who are following along with you, I personally am very thankful for the amount of detail that you share in your posts. You have a good teaching style.3 points -
I have to use passwords in a lot of my scripts. I have an SQL server where each script has it's own database where I store passwords as an encrypted string along with any other config/test/log data. I also only allow specific users access to that database via AD. The decryption keys are also unique to each script. This lets me keep passwords secure and lets me control who can access my apps as if the database connection fails then the app closes with a message to contact me for access.3 points
-
_QuoteAutoIt() for strings in code that contain quote
Trong and 2 others reacted to AspirinJunkie for a topic
Are you aware that you can escape the respective quote characters in AutoIt string definitions by simply doubling them? So to create an AutoIt-compliant string definition for the AutoIt code itself from a string, you do not need to split it into individual strings and reassemble them, but simply double the quotes. This would be shorter, probably clearer and also better performing. In concrete terms, the following should also achieve your actual goal $result = '"' & StringReplace($raw, '"', '""', 0, 1) & '"' ; or equally: $result = "'" & StringReplace($raw, "'", "''", 0, 1) & "'"3 points -
Jugador From a place of kindness and introspection, there is a general principle and lesson for anyone, that surpasses this topic, but still related to the genesis of this topic. That principle is "unit testing". If we unit test our code, we are never surprised or blindsided by results we didn't expect. And trust me, in my early days I was blind sided many many times. Unit testing also implies "never assuming" your own code is perfect. Build "test code" to test your "production code". But not only your own code, but supplied Autoit UDFs, members UDF, DLLs, COM objects, APIs etc. And not everything Microsoft publishes works as expected. We see this every single day in our MSP business. And if timing is important to a set of code, build in tests for timing. That way there are no surprises. You can build code with certainty. Code Complete 2, is one of the many great books on coding standards. I was recommended to read it by my seasoned genius programmer who has programmed in a dozen different languages with a reputation for error free code. I've read it half a dozen times, the last four taking extensive notes, and deriving and creating standards to use with AutoIT, and programming in general. Not the only book, but a good start. I've got 20+ years on mLipok, but he has insights I don't have, and is definitely not childish. Like him I have a business and staff, and yes, I program, purely out of necessity, in AutoIT. I/we program purely because what we need doesn't exist. My business is IT and Technology, not software. The heavy lifting is done in C# or Delphi, by my genius programmer(s). Full blown applications written by them, plus upgrades, are still running after 18 years of 24/7/365 continuous running without any bugs or errors. I know when to bow down to programming gods. Although I started programming in the late 80's, it was purely on a needs basis, not a full time occupation. I still regard myself as a novice, and am very grateful to the people on here like mLipok, Jos, Jon, Argumentum and many many others who provide valuable insights. 🙂3 points
-
Hi guys, apologies in advance for the wall of text! Just an update as to where things are ATM - I've have gone on a tangent re: resolving IIDs for paramatised interfaces. This is more of a core WinRT thing - but I thought I'd take whoever is interested along on the ride... So I attempted to create a grid (Microsoft.UI.Xaml.Controls.Grid) which should theoretically allows us drop other controls within it. Basically its a layout thing to divide up the window. Want an "OK" button down the bottom right? Just nest the button in the cell that is down there!. Creating a grid, then extracting the row and column definitions is easy enough. #include "Include\Classes\Microsoft.UI.Xaml.Controls.Grid.au3" ;-- Setup window etc. -- Local $pGrid_Fact = _WinRT_GetActivationFactory("Microsoft.UI.Xaml.Controls.Grid", $sIID_IGridFactory) Local $pGrid = IGridFactory_CreateInstance($pGrid_Fact, 0, $pInner) Local $pColDefs = IGrid_GetColumnDefinitions($pGrid) Local $pRowDefs = IGrid_GetRowDefinitions($pGrid) Looking at $pColDefs, we can determine its a "Microsoft.UI.Xaml.Controls.ColumnDefinitionCollection". We know this by inspecting Microsoft.UI.Xaml.Controls.Grid in the class explorer. Otherwise _WinRT_DisplayInterfaces($pColDefs ) or _WinRT_DisplayClass($pColDefs ) will get you to the same place. Method : get_ColumnDefinitions Fn : value = get_ColumnDefinitions() P0 : value type: Microsoft.UI.Xaml.Controls.ColumnDefinitionCollection After digging in the metadata we can resolve some IIDs of $pColDefs, but at best _WinRT_DisplayInterfaces() only gives us: Class: Microsoft.UI.Xaml.Controls.ColumnDefinitionCollection {CDFBA81A-54FA-557D-A712-21640F16C534} {749BC47C-1743-5C21-9CED-C8A1134C7BA7} {80741C8F-A401-5C63-B6C4-15D165E541C7} {E7BEAEE7-160E-50F7-8789-D63463F979FA} - IDependencyObject {EB24C20B-9816-4AC7-8CFF-36F67A118F4E} {00000038-0000-0000-C000-000000000046} - IWeakReferenceSource {DF0B3D60-548F-101B-8E65-08002B2BD119} - ISupportErrorInfo {00000000-0000-0000-C000-000000000046} - IUnknown {AF86E2E0-B12D-4C6A-9C5A-D7AA65101E90} - IInspectable But what we're looking for is these collection interfaces. TypeDef : Microsoft.UI.Xaml.Controls.ColumnDefinitionCollection Extends : System.Object Interface : Windows.Foundation.Collections.IVector`1<Microsoft.UI.Xaml.Controls.ColumnDefinition> Interface : Windows.Foundation.Collections.IIterable`1<Microsoft.UI.Xaml.Controls.ColumnDefinition> The class explorer tells us IVector should be there. Windows.Foundation.Collections.IVector`1 has a GUID defined as "{913337E9-11A1-4345-A3A2-4E7F956E222D}". so what gives? It does not appear in our list because the IVector`1 GUID is NOT an IID, it is something else called a PIID. It needs to be combined with the datatype in order to give us the IID for Windows.Foundation.Collections.IVector`1<Microsoft.UI.Xaml.Controls.ColumnDefinition>. We can probably just assume the top GUID maps to this... but we really need a way to resolve it properly. The IIDs for paramatiesed interfaces are calculated at runtime so we can't just dig in the metadata for them. Enter RoGetParameterizedTypeInstanceIID. This is the can of worms that I'm still trying to nail down - so stay tuned for part 2! Once all that is sorted I'll also need to fix the WinRT Library generator. At the moment methods involving arrays don't generate correctly, which is kinda important when dealing with collections!!!3 points
-
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.au33 points
-
Auto(it)Runs This script utilizes the sysinternals autorunsc command-line tool to scan and analyze autorun entries on a Windows system. https://learn.microsoft.com/en-us/sysinternals/downloads/autoruns The script's primary function is to extract information from the autorunsc.exe scan results, to Autoit, which can be used for various purposes and understanding system startup behavior. Using the $STDOUT stream and not the -c switch (Print output as CSV), so that you don't have to export the data to disk every time I explored it experimentally, and these are the results. ; https://www.autoitscript.com/forum/topic/213070-autoitruns/ ;---------------------------------------------------------------------------------------- ; Title...........: Auto(it)Runs.au3 ; Description.....: This script utilizes the sysinternals `autorunsc` command-line tool ; to scan and analyze autorun entries on a Windows system. ; The script's primary function is to extract information from the autorun scan results, ; which can be used for various purposes and understanding system startup behavior. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.9 ; Note............: Testet in Win10 22H2 Date:10/08/2025 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #RequireAdmin #include <GUIConstantsEx.au3> #include <EditConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <AutoItConstants.au3> #include <StringConstants.au3> #include <ListViewConstants.au3> #include <GuiListView.au3> Example() ;--------------------------------------------------------------------------------------- Func Example() Local $sCMD = CreateCmdGUI() ConsoleWrite("$sCMD=" & $sCMD & @CRLF) Local $aEntries = AutorunSnapshot($sCMD) If @error Then ConsoleWrite("! @error:" & @error & " " & $aEntries & @CRLF) Local $iPos = StringInStr($sCMD, '-o "') ; check if -o Switch in $sCMD then execute the output file If $iPos > 1 Then ShellExecute(StringLeft(StringTrimLeft($sCMD, $iPos + 3), StringInStr(StringTrimLeft($sCMD, $iPos + 3), '"') - 1)) Else DisplayGUI($aEntries, "Autorun Entries") EndIf EndFunc ;==>Example ;--------------------------------------------------------------------------------------- Func CreateCmdGUI() ; Optional GUI to build the autorunsc cmdline ; Switches for the "-a" group (Group A) Local $aGroupA[18][3] = [ _ [0, "*", "All"], [0, "b", "Boot execute"], [0, "c", "Codecs"], _ [0, "d", "Appinit DLLs"], [0, "e", "Explorer addons"], [0, "g", "Sidebar gadgets"], _ [0, "h", "Image hijacks"], [0, "i", "Internet Explorer addons"], [0, "k", "Known DLLs"], _ [0, "l", "Logon startups (default)"], [0, "m", "WMI entries"], [0, "n", "Winsock protocol"], _ [0, "o", "Office addins"], [0, "p", "Printer monitor DLLs"], [0, "r", "LSA security providers"], _ [0, "s", "Services & non-disabled drivers"], [0, "t", "Scheduled tasks"], [0, "w", "Winlogon entries"] _ ] ; Switches for other parameters (Group B) Local $aGroupB[12][3] = [ _ [0, "-ct", "Print as tab-delimited"], [0, "-c", "Print as CSV"], [0, "-x", "Print output as XML"], _ [0, "-o", "Write output to the file."], [0, "-h", "Show file hashes."], [0, "-m", "Hide Microsoft entries"], _ [0, "-t", "Show timestamps in normalized UTC."], [0, "-s", "Verify digital signatures"], _ [0, "-u", "Show unsigned/unknown files"], [0, "-vrs", "VirusTotal check & upload"], _ [0, "-nobanner", "Do not show startup banner"], [0, "*", "Scan all user profiles"] _ ] ; Create the Autorunsc GUI GUICreate("Autorunsc GUI", 600, 560) GUISetFont(9, 400, 0, "Tahoma") ; Create the input box for the command GUICtrlCreateLabel("Generated Command:", 10, 10, 200, 20) Local $idInputbox = GUICtrlCreateInput("", 10, 30, 580, 25, $ES_AUTOHSCROLL) GUICtrlSetState($idInputbox, $GUI_DISABLE) ; Create the input box for the output file Local $idLblOutFile = GUICtrlCreateLabel("Output file:", 310, 420, 200, 20) GUICtrlSetState(-1, $GUI_HIDE) Local $idOutFile = GUICtrlCreateInput("output.txt", 310, 440, 260, 20) GUICtrlSetState(-1, $GUI_HIDE) Local $idExecuteButton = GUICtrlCreateButton("Execute", 420, 500, 140, 25) ; Create Group 1 for "-a" switches on the left GUICtrlCreateGroup("Autostart Entry Selection (-a)", 10, 70, 280, 480) Local $iX = 20, $iY = 90 For $i = 0 To UBound($aGroupA) - 1 $aGroupA[$i][0] = GUICtrlCreateCheckbox($aGroupA[$i][1] & " (" & $aGroupA[$i][2] & ")", $iX, $iY, 260, 20) $iY += 25 Next ; Set default selections in (Group A) GUICtrlSetState($aGroupA[1][0], $GUI_CHECKED) ; -a b GUICtrlSetState($aGroupA[9][0], $GUI_CHECKED) ; -a l GUICtrlCreateGroup("", -99, -99, 1, 1) ; Close the group ; Create Group 2 for other switches on the right GUICtrlCreateGroup("Other Options", 300, 70, 290, 330) $iX = 310 $iY = 90 For $i = 0 To UBound($aGroupB) - 1 $aGroupB[$i][0] = GUICtrlCreateCheckbox($aGroupB[$i][1] & " (" & $aGroupB[$i][2] & ")", $iX, $iY, 260, 20) $iY += 25 Next ; Set default selections in (Group B) GUICtrlSetState($aGroupB[11][0], $GUI_CHECKED) ; * user profiles GUICtrlCreateGroup("", -99, -99, 1, 1) ; Close the group GUISetState(@SW_SHOW) Local $nMsg, $bNeedUpdate = True While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aGroupA[0][0] ; Handle the "All" checkbox logic If GUICtrlRead($aGroupA[0][0]) = $GUI_CHECKED Then For $i = 1 To UBound($aGroupA) - 1 GUICtrlSetState($aGroupA[$i][0], $GUI_DISABLE) GUICtrlSetState($aGroupA[$i][0], $GUI_UNCHECKED) Next Else For $i = 1 To UBound($aGroupA) - 1 GUICtrlSetState($aGroupA[$i][0], $GUI_ENABLE) Next EndIf $bNeedUpdate = True Case $aGroupA[1][0] To $aGroupA[17][0] ; Handle other "-a" checkboxes If GUICtrlRead($nMsg) = $GUI_CHECKED Then GUICtrlSetState($aGroupA[0][0], $GUI_DISABLE) Else Local $bAnyChecked = False For $i = 1 To UBound($aGroupA) - 1 If GUICtrlRead($aGroupA[$i][0]) = $GUI_CHECKED Then $bAnyChecked = True ExitLoop EndIf Next If Not $bAnyChecked Then GUICtrlSetState($aGroupA[0][0], $GUI_ENABLE) EndIf EndIf $bNeedUpdate = True Case $idOutFile $bNeedUpdate = True Case $idExecuteButton Return GUICtrlRead($idInputbox) Case $aGroupB[0][0] To $aGroupB[11][0] $bNeedUpdate = True EndSwitch If $bNeedUpdate Then Local $sCommand = "" Local $sAGroupSwitches = "" ; Build the string for "-a" switches For $i = 0 To UBound($aGroupA) - 1 If GUICtrlRead($aGroupA[$i][0]) = $GUI_CHECKED Then $sAGroupSwitches &= $aGroupA[$i][1] EndIf Next ; Add the "-a" switch only once if any option is selected If StringLen($sAGroupSwitches) > 0 Then $sCommand &= " -a " & $sAGroupSwitches ; Add switches from Group B For $i = 0 To UBound($aGroupB) - 1 If GUICtrlRead($aGroupB[$i][0]) = $GUI_CHECKED Then $sCommand &= " " & $aGroupB[$i][1] EndIf Next ; if Output file is checked If GUICtrlRead($aGroupB[3][0]) = $GUI_CHECKED Then GUICtrlSetState($idLblOutFile, $GUI_SHOW) GUICtrlSetState($idOutFile, $GUI_SHOW) Local $sOutFile = @ScriptDir & "\" & GUICtrlRead($idOutFile) $sCommand = StringReplace($sCommand, "-o", '-o "' & $sOutFile & '"') ; Set default selections in (Group B) GUICtrlSetState($aGroupB[0][0], $GUI_ENABLE) ; -ct GUICtrlSetState($aGroupB[1][0], $GUI_ENABLE) ; -c GUICtrlSetState($aGroupB[2][0], $GUI_ENABLE) ; -x GUICtrlSetState($aGroupB[4][0], $GUI_ENABLE) ; -h GUICtrlSetState($aGroupB[6][0], $GUI_ENABLE) ; -t GUICtrlSetState($aGroupB[7][0], $GUI_ENABLE) ; -s GUICtrlSetState($aGroupB[8][0], $GUI_ENABLE) ; -u GUICtrlSetState($aGroupB[9][0], $GUI_ENABLE) ; -vrs GUICtrlSetState($aGroupB[10][0], $GUI_ENABLE) ; -nobanner Else GUICtrlSetState($idLblOutFile, $GUI_HIDE) GUICtrlSetState($idOutFile, $GUI_HIDE) ; Set default selections in (Group B) GUICtrlSetState($aGroupB[0][0], $GUI_CHECKED) ; -ct GUICtrlSetState($aGroupB[0][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[1][0], $GUI_UNCHECKED) ; -c GUICtrlSetState($aGroupB[1][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[2][0], $GUI_UNCHECKED) ; -x GUICtrlSetState($aGroupB[2][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[4][0], $GUI_UNCHECKED) ; -h GUICtrlSetState($aGroupB[4][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[6][0], $GUI_CHECKED) ; -t GUICtrlSetState($aGroupB[6][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[7][0], $GUI_UNCHECKED) ; -s GUICtrlSetState($aGroupB[7][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[8][0], $GUI_UNCHECKED) ; -u GUICtrlSetState($aGroupB[8][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[9][0], $GUI_UNCHECKED) ; -vrs GUICtrlSetState($aGroupB[9][0], $GUI_DISABLE) GUICtrlSetState($aGroupB[10][0], $GUI_CHECKED) ; -nobanner GUICtrlSetState($aGroupB[10][0], $GUI_DISABLE) EndIf GUICtrlSetData($idInputbox, $sCommand) $bNeedUpdate = False EndIf WEnd Exit ;Return SetError(1, 0, "") EndFunc ;==>CreateCmdGUI ;--------------------------------------------------------------------------------------- Func AutorunSnapshot($sCmdSwitches = '-a bl -t -ct -nobanner *') ; Extract Entries to array ; https://learn.microsoft.com/en-us/sysinternals/downloads/autoruns ; Make sure autorunsc.exe is located in a subfolder named "Autoruns" in @ScriptDir Local Const $sAutorunscPath = @ScriptDir & "\Autoruns\autorunsc64.exe" ; Verify that autorunsc.exe exists. If Not FileExists($sAutorunscPath) Then Return SetError(1, 0, "! Error: The autorunsc.exe file was not found") ; Usage: autorunsc [-a <*|bdeghiklmoprsw>] [-c|-ct] [-h] [-m] [-s] [-u] [-vt] [-o <output file>] [[-z <systemroot> <userprofile>] | [user]]] ; -a Autostart entry selection: ; * All. ; b Boot execute. ; c Codecs. ; d Appinit DLLs. ; e Explorer addons. ; g Sidebar gadgets (Vista and higher) ; h Image hijacks. ; i Internet Explorer addons. ; k Known DLLs. ; l Logon startups (this is the default). ; m WMI entries. ; n Winsock protocol and network providers. ; o Office addins. ; p Printer monitor DLLs. ; r LSA security providers. ; s Autostart services and non-disabled drivers. ; t Scheduled tasks. ; w Winlogon entries. ; -c Print output as CSV. ; -ct Print output as tab-delimited values. ; -h Show file hashes. ; -m Hide Microsoft entries (signed entries if used with -s). ; -o Write output to the specified file. ; -s Verify digital signatures. ; -t Show timestamps in normalized UTC (YYYYMMDD-hhmmss). ; -u If VirusTotal check is enabled, show files that are unknown ; by VirusTotal or have non-zero detection, otherwise show only ; unsigned files. ; -x Print output as XML. ; -v[rs] Query VirusTotal (www.virustotal.com) for malware based on file hash. ; Add 'r' to open reports for files with non-zero detection. Files ; reported as not previously scanned will be uploaded to VirusTotal ; if the 's' option is specified. Note scan results may not be ; available for five or more minutes. ; -vt Before using VirusTotal features, you must accept ; VirusTotal terms of service. See: https://www.virustotal.com/en/about/terms-of-service/ ; If you haven't accepted the terms and you omit this ; option, you will be interactively prompted. ; -z Specifies the offline Windows system to scan. ; user Specifies the name of the user account for which ; autorun items will be shown. Specify '*' to scan ; all user profiles. ; -nobanner Do not display the startup banner and copyright message. ; Construct the command to run autorunsc.exe ; Local $sCommand = '"' & $sAutorunscPath & '" -a bl -m -t -ct -nobanner *' <<- Default -<< Local $sCommand = '"' & $sAutorunscPath & '" ' & $sCmdSwitches ; $sCmdSwitches = '-a bl -t -ct -nobanner *' ; Run autorunsc.exe Local $iPID = Run($sCommand, "", @SW_HIDE, $STDOUT_CHILD) ; Wait until the process has closed ProcessWaitClose($iPID) ; Read the Stdout stream of the PID Local $sOutput = StdoutRead($iPID) ; Possible ANSI to UTF16 conversion $sOutput = BinaryToString(StringToBinary($sOutput, $SB_ANSI), $SB_UTF16LE) ; <<- important -<< ;ConsoleWrite("$sOutput=" & $sOutput & @CRLF) ; Use StringSplit to split the output of StdoutRead to an array. All carriage returns (@CR) are stripped and @LF is used as the delimiter. Local $aDataArray = StringSplit(StringTrimRight(StringStripCR($sOutput), 1), @LF) If @error Then Return SetError(2, 0, "! Error: It appears there was an error trying to get the STDOUT.") ;_ArrayDisplay($aDataArray) Local $aPart, $aData[UBound($aDataArray)][12], $idx = 0 ; Skip 1st line with header For $i = 2 To UBound($aDataArray) - 1 $aPart = StringSplit($aDataArray[$i], @TAB) If $aPart[0] = 11 Then $idx += 1 $aData[$idx][0] = $idx $aData[$idx][1] = $aPart[1] $aData[$idx][2] = $aPart[2] $aData[$idx][3] = $aPart[3] $aData[$idx][4] = $aPart[4] $aData[$idx][5] = $aPart[5] $aData[$idx][6] = $aPart[6] $aData[$idx][7] = $aPart[7] $aData[$idx][8] = $aPart[8] $aData[$idx][9] = $aPart[9] $aData[$idx][10] = $aPart[10] $aData[$idx][11] = $aPart[11] EndIf Next ;_ArrayDisplay($aData) ReDim $aData[$idx + 1][12] $aData[0][0] = $idx $aData[0][1] = "Time" $aData[0][2] = "EntryLocation" $aData[0][3] = "Entry" $aData[0][4] = "Enabled" $aData[0][5] = "Category" $aData[0][6] = "Profile" $aData[0][7] = "Description" $aData[0][8] = "Company" $aData[0][9] = "ImagePath" $aData[0][10] = "Version" $aData[0][11] = "LaunchString" Return $aData EndFunc ;==>AutorunSnapshot ;--------------------------------------------------------------------------------------- Func DisplayGUI($aItems, $sTitle = "") ; Optional GUI to Display the extracted Entries ; Create GUI GUICreate($sTitle, 1600, 600) Local $idListview = GUICtrlCreateListView("", 2, 2, 1600, 600, -1, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_CHECKBOXES)) GUISetState(@SW_SHOW) ; ["idx", "Time", "EntryLocation", "Entry", "Enabled", "Category", "Profile", "Description", "Company", "ImagePath", "Version", "LaunchString"] ; Add columns _GUICtrlListView_AddColumn($idListview, "idx", 30) _GUICtrlListView_AddColumn($idListview, "Time", 100) _GUICtrlListView_AddColumn($idListview, "EntryLocation", 450) _GUICtrlListView_AddColumn($idListview, "Entry", 150) _GUICtrlListView_AddColumn($idListview, "Enabled", 60) _GUICtrlListView_AddColumn($idListview, "Category", 60) _GUICtrlListView_AddColumn($idListview, "Profile", 60) _GUICtrlListView_AddColumn($idListview, "Description", 100) _GUICtrlListView_AddColumn($idListview, "Company", 100) _GUICtrlListView_AddColumn($idListview, "ImagePath", 300) _GUICtrlListView_AddColumn($idListview, "Version", 40) _GUICtrlListView_AddColumn($idListview, "LaunchString", 300) _GUICtrlListView_SetItemCount($idListview, $aItems[0][0]) ; remove $aItems header _ArrayDelete($aItems, 0) _GUICtrlListView_AddArray($idListview, $aItems) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete() EndFunc ;==>DisplayGUI ;--------------------------------------------------------------------------------------- Please, every comment is appreciated! leave your comments and experiences here! Thank you very much3 points
-
Open all files starting with "0" in subfolder?
pixelsearch and 2 others reacted to Diana (Cda) for a topic
Thank you so much for everyone's kind help! Apologies in delay in replying, I don't know what I was doing wrong, but it was like beating my head against the wall somehow (my mom passed away 3 months ago, so suspect I was also just having trouble with details, who knows <sigh>). But I came back to this again. When I leave my apartment, I like to shut down all things running apps in the systray except what's there "automatically", as it were. Then when I come home, start up those extra things I like to have running when I'm around. Ultimately, pixelsearch kindly wrote up the code to include that TRUE statement which escaped me because of the presentation before as just describing what to do (and I see now I must still have been affected by mom's passing as I just couldn't make heads or tails of that). Here is the what worked just now, but I removed the suggested "_ArrayDisplay($array)" line as that created some havoc, too, and I find it's not really necessary, just an extra confusing step, it seems. #include <file.au3> #include <Array.au3> Local $array = _FileListToArray(@ScriptDir & "\Startup\", "0*.*", 1, TRUE) ;_ArrayDisplay($array) For $i = 1 To $array[0] ShellExecute($array[$i]) Next Thank you!3 points -
Based on post simple-circular-progressbar-with-smooth-edges-gradient-color , I created _CircularProgress , with the idea of calling it as a single function. ; https://www.autoitscript.com/forum/topic/213118-_circularprogress/ ;---------------------------------------------------------------------------------------- ; Title...........: _CircularProgress.au3 ; Description.....: Creates a customizable circular progress bar using GDI+ graphics. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.5 ; Note............: Testet in Win10 22H2 Date:08/09/2025 ; Based on post ..: https://www.autoitscript.com/forum/topic/213113-simple-circular-progressbar-with-smooth-edges-gradient-color/#findComment-1545755 ;---------------------------------------------------------------------------------------- #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 <WinAPISysWin.au3> #include <Constants.au3> #include <WindowsConstants.au3> #include <Array.au3> _Example() ; as demo ;~ _Example2() ; as demo Func _Example() Local $aList[2000] Local $iCnt = UBound($aList) ConsoleWrite("$iCnt=" & $iCnt & @CRLF) Local $nProgress For $i = 1 To UBound($aList) $nProgress = Int($i / $iCnt * 100) ConsoleWrite($i & ") $nProgress=" & $nProgress & @CRLF) _CircularProgress($nProgress) Next Sleep(200) ; Give it some time to see the 100%. _CircularProgress(101) ; Clean up the progress bar window EndFunc ;==>_Example Func _Example2() Local $aList[2000] Local $iCnt = UBound($aList) Local $nProgress _CircularProgress(0, @DesktopWidth * 0.8, @DesktopHeight * 0.4, 200, 20) For $i = 1 To UBound($aList) $nProgress = Int($i / $iCnt * 100) _CircularProgress($nProgress) Next For $i = 1 To 3 _CircularProgress($nProgress, -1, -1, -1, -1, 0xFFFFFF, 0x4CFF00, 0xF6FF00) Sleep(500) _CircularProgress($nProgress, -1, -1, -1, -1, 0xFFFFFF, 0xF6FF00, 0x4CFF00) Sleep(500) Next _CircularProgress(101) ; Clean up the progress bar window EndFunc ;==>_Example ; #FUNCTION# ==================================================================================================================== ; Name...........: _CircularProgress ; Description....: Creates a customizable circular progress bar using GDI+ graphics. ; Syntax.........: _CircularProgress($iPercent [, $iLeft = -1 [, $iTop = -1 [, $iSize = 300 [, $iThickness = 30 [, $TextCol = 0xFFFFFF [, $StartCol = 0xFF0000, $EndCol = 0xFFFF00]]]]]]) ; Parameters.....: $iPercent - The percentage complete for the progress bar (0 to 100). ; $iLeft - [optional] X-coordinate of the top-left corner. (Default is -1 for center) ; $iTop - [optional] Y-coordinate of the top-left corner. (Default is -1 for center) ; $iSize - [optional] width and height of the circular progress bar. (Default is 300) ; $iThickness - [optional] Thickness of the progress arc. (Default is 30) ; $TextCol - [optional] Color of the text within the progress bar. (Default is White) ; $StartCol - [optional] Start color of the progress arc gradient. (Default is Yellow) ; $EndCol - [optional] End color of the progress arc gradient. (Default is Red) ; Return values .: Success: create the progress bar GUI ; Author ........: ioa747 ; Modified ......: 08/09/2025 - v0.5 ; Remarks .......: Cleanup is handled automatically by passing an $iPercent > 100. ; Avoid using 0x050505 Color for $TextCol, $StartCol, or $EndCol, as it is used as a transparency color for the background. ; Related .......: _GDIPlus_Startup, _GDIPlus_GraphicsCreateFromHWND, etc. ; Link ..........: https://www.autoitscript.com/forum/topic/213113-simple-circular-progressbar-with-smooth-edges-gradient-color/#findComment-1545755 ; Example .......: _CircularProgress(50, -1, -1, 300, 20, 0x00FF00, 0xFF00FF, 0xFFFFFF) ; =============================================================================================================================== Func _CircularProgress($iPercent, $iLeft = -1, $iTop = -1, $iSize = 300, $iThickness = 30, $TextCol = 0xFFFFFF, $StartCol = 0xFFFF00, $EndCol = 0xFF0000) Local Static $hGUI, $hGraphics, $hBmp, $hBmpGraphics, $inSize, $iRadius, $inThickness, $iX, $iY, $bInit = False ; initialize RingProgressBar (if not) If Not $bInit Then _GDIPlus_Startup() $inThickness = $iThickness $inSize = $iSize $iRadius = ($inSize - 4) / 2 $iX = $inSize / 2 $iY = $iX ; transparent layered window $hGUI = GUICreate("RingProgressBar", $inSize, $inSize, $iLeft, $iTop, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) GUISetBkColor(0x050505) ; 0x050505 _WinAPI_SetLayeredWindowAttributes($hGUI, 0x050505) GUISetState(@SW_SHOWNOACTIVATE) ; Create a graphics object linked to the GUI $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ; Create an off-screen bitmap for double-buffering $hBmp = _GDIPlus_BitmapCreateFromScan0($inSize, $inSize) $hBmpGraphics = _GDIPlus_ImageGetGraphicsContext($hBmp) $bInit = True EndIf ; Clean up the RingProgressBar (if $iPercent > 100) If $iPercent > 100 Then ; Cleanup _GDIPlus_GraphicsDispose($hBmpGraphics) _GDIPlus_BitmapDispose($hBmp) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() GUIDelete($hGUI) $bInit = False Return EndIf ; Colors from RGB to ARGB $TextCol = "0xFF" & StringTrimLeft(Hex($TextCol), 2) $StartCol = "0xFF" & StringTrimLeft(Hex($StartCol), 2) $EndCol = "0xFF" & StringTrimLeft(Hex($EndCol), 2) _GDIPlus_GraphicsClear($hBmpGraphics, 0x00050505) _GDIPlus_GraphicsSetSmoothingMode($hBmpGraphics, 2) _GDIPlus_GraphicsSetTextRenderingHint($hBmpGraphics, 5) ; Draw full ring background Local $hBrushBG = _GDIPlus_BrushCreateSolid(0xFF050505) _GDIPlus_GraphicsFillEllipse($hBmpGraphics, $iX - $iRadius, $iY - $iRadius, $iRadius * 2, $iRadius * 2, $hBrushBG) _GDIPlus_BrushDispose($hBrushBG) ; Draw progress arc as pie Local $angle = ($iPercent / 100) * 360 Local $hBrushProg = _GDIPlus_LineBrushCreate($iX - $iRadius, $iY, $iX + $iRadius, $iY, $EndCol, $StartCol, 1) _GDIPlus_GraphicsFillPie($hBmpGraphics, $iX - $iRadius, $iY - $iRadius, $iRadius * 2, $iRadius * 2, -90, $angle, $hBrushProg) _GDIPlus_BrushDispose($hBrushProg) ; Draw inner circle Local $innerR = $iRadius - $inThickness Local $hBrushWhite = _GDIPlus_BrushCreateSolid(0xFF050505) _GDIPlus_GraphicsFillEllipse($hBmpGraphics, $iX - $innerR, $iY - $innerR, $innerR * 2, $innerR * 2, $hBrushWhite) _GDIPlus_BrushDispose($hBrushWhite) Local $hFontFamily = _GDIPlus_FontFamilyCreate("Times New Roman") Local $iFontSize = $iRadius * 0.3 Local $hFont = _GDIPlus_FontCreate($hFontFamily, $iFontSize, 1) Local $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 2) _GDIPlus_StringFormatSetLineAlign($hFormat, 2) Local $hBrushText = _GDIPlus_BrushCreateSolid($TextCol) ; Draw percentage text Local $rect = _GDIPlus_RectFCreate(($inSize - ($iFontSize * 4)) / 2, ($inSize - ($iFontSize * 2)) / 2, $iFontSize * 4, $iFontSize * 2) _GDIPlus_GraphicsDrawStringEx($hBmpGraphics, $iPercent & "%", $hFont, $rect, $hFormat, $hBrushText) _GDIPlus_FontFamilyDispose($hFontFamily) _GDIPlus_FontDispose($hFont) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_BrushDispose($hBrushText) _GDIPlus_GraphicsDrawImage($hGraphics, $hBmp, 0, 0) EndFunc ;==>_CircularProgress Please, every comment is appreciated! leave your comments and experiences here! Thank you very much2 points
-
It looks ugly on my Notebook: You may use: Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $iOpacity = 0xFF, $iFlags = $ULW_ALPHA, $bReleaseGDI = True, $tDest = Null, $iBGR = 0) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) = $WS_EX_LAYERED Then Return SetError(1, 0, 0) Local $tDim = DllStructCreate($tagBITMAP) If Not _WinAPI_GetObject($hHBitmap, DllStructGetSize($tDim), DllStructGetPtr($tDim)) Then Return SetError(2, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0), $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC), $hOld = _WinAPI_SelectObject($hMemDC, $hHBitmap) $tSize.X = $tDim.bmWidth $tSize.Y = $tDim.bmHeight $tBlend.Alpha = $iOpacity $tBlend.Format = 1 _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, $tDest, $tSize, $hMemDC, $tSource, $iBGR, $tBlend, $iFlags) _WinAPI_ReleaseDC(0, $hScrDC) _WinAPI_SelectObject($hMemDC, $hOld) _WinAPI_DeleteDC($hMemDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI to get a proper display. See for an example. _WinAPI_SetLayeredWindowAttributes() only makes is ugly!2 points
-
_WinAPI_DwmEnableBlurBehindWindow in Windows 11
ioa747 and one other reacted to WildByDesign for a topic
In several of my projects, I have continued to use (and improve upon) the wonderful _WinAPI_DwmEnableBlurBehindWindow10 script by @scintilla4evr which paved the way for blur options on modern versions of Windows. I have completely opened the script up with more options and wanted to share the results back with the community for anyone else to enjoy. I have renamed the function to _WinAPI_DwmEnableBlurBehindWindow11 since it is geared more toward Windows 11 options. It may or may not work with Windows 10. Some of the AccentFlags may need to be adjusted with Windows 10. And I've made it possible to change those values when calling the function. Maybe somebody will make some sort of continuously changing, random color changing blur increasing and decreasing levels of color transparency with it. 😄 I have included inside the function the contents of a function called _percentageOfHex() that was shared to me by @argumentum that takes a percentage 0-100 and returns the Hexadecimal color code for transparency which gets put together with the main color passed to form a COLORREF that can control color transparency levels. I combined that function into _WinAPI_DwmEnableBlurBehindWindow11 to keep things as simple as possible. Script with Examples:2 points -
Yes just hide the window, or do not show them at all.2 points
-
The animation examples are not optimized for speed rather proof-of-concept versions. To speed up you can do some optimization, e.g. what you wrote or not to create the texture every time as it is static or calling GDI+ functions directly or ... There are also plenty of examples how to show the progress in a transparent GUI.2 points
-
Fastest method to get process name from handle
WildByDesign and one other reacted to MattyD for a topic
To be fair, Libraries like "user32.dll" would already be loaded by autoit for its own purposes, so I'd imagine doing a DllCall("user32.dll", blah) would probably just result in adding/removing a reference to the already loaded dll. So the time saving would be much less than say "wlanapi.dll" for example, which I assume fully loads/unloads the dll during the call.. #include <WinAPISys.au3> Local $hOrigUser32Handle = _WinAPI_GetModuleHandle("user32.dll") ConsoleWrite("user32 before load: " & $hOrigUser32Handle & @CRLF) $hUser32Dll = _WinAPI_LoadLibrary("user32.dll") ConsoleWrite("user32 after load: " & _WinAPI_GetModuleHandle("user32.dll") & @CRLF) ConsoleWrite("Same Handle = " & ($hUser32Dll = $hOrigUser32Handle) & @CRLF) _WinAPI_FreeLibrary($hUser32Dll) ConsoleWrite("user32 after free: " & _WinAPI_GetModuleHandle("user32.dll") & @CRLF & @CRLF) ConsoleWrite("wlanapi before load: " & _WinAPI_GetModuleHandle("wlanapi.dll") & @CRLF) $hWlanapiDll = _WinAPI_LoadLibrary("wlanapi.dll") ConsoleWrite("wlanapi after load: " & _WinAPI_GetModuleHandle("wlanapi.dll") & @CRLF) _WinAPI_FreeLibrary($hWlanapiDll) ConsoleWrite("wlanapi after free: " & _WinAPI_GetModuleHandle("wlanapi.dll") & @CRLF)2 points -
Alrighty, here's a couple of general notes around this attachment, then there will be a follow up post with more detail around the Grid stuff. (last one for the weekend I promise!) We can now include "Include\WinRT_WinUI3.au3" which exposes _WinUI3_Startup and _WinUI3_Shutdown. This is basically those boostrapper calls to spin up and down the runtime. In WinRT.au3, I've popped _WinRT_SwitchInterface in as a standard func so we don't have to do multi-step calls through IUnknown to jump between interfaces. I've also added a _WinRT_CreateDelegate() and _WinRT_DestroyDelegate() in WinRT.au3 to do the heavy lifting for creating delegates. So the syntax now looks like this: ; Creation $pBtnClickDelegate = _WinRT_CreateDelegate("BtnClick") $iBtnClickHandlerTkn = IButtonBase_AddHdlrClick($pButton, $pBtnClickDelegate) ; Teardown IButtonBase_RemoveHdlrClick($pButton, $iBtnClickHandlerTkn) _WinRT_DestroyDelegate($pBtnClickDelegate) Func BtnClick($pThis, $pSender, $pArgs) ;Do stuff EndFunc I'll still need to fix up a few more things before popping this all up on sourceforge - but just thought I'd get these quality of life things out the door while I'm feeling energetic! WindowTest - Grid.zip2 points
-
ermar, Certainly - how about this: #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include "GUIListViewEx.au3" Opt("GUIOnEventMode", 1) ; Create GUI $hGUI = GUICreate("LVEx Example", 320, 320) ; Create ListView $cListView = GUICtrlCreateListView("Tom|Dick|Harry", 10, 10, 300, 300, $LVS_SHOWSELALWAYS) _GUICtrlListView_SetExtendedListViewStyle($cListView, $LVS_EX_FULLROWSELECT) _GUICtrlListView_SetColumnWidth($cListView, 0, 93) _GUICtrlListView_SetColumnWidth($cListView, 1, 93) _GUICtrlListView_SetColumnWidth($cListView, 2, 93) ; Set font GUICtrlSetFont($cListView, 12, Default, Default, "Courier New") ; Note edit control will use same font ; Create array and fill listview Global $aLV_List[20] For $i = 0 To UBound($aLV_List) - 1 If Mod($i, 5) Then $aLV_List[$i] = "Tom " & $i & "|Dick " & $i & "|Harry " & $i Else $aLV_List[$i] = "Tom " & $i & "||Harry " & $i EndIf GUICtrlCreateListViewItem($aLV_List[$i], $cListView) Next ; Initiate LVEx $iLV_Left_Index = _GUIListViewEx_Init($cListView, $aLV_List) ; Column 1 & 2 editable - simple text _GUIListViewEx_SetEditStatus($iLV_Left_Index, "1;2") ; Register for sorting, dragging and editing - but do NOT register WM_Notify _GUIListViewEx_MsgRegister(Default) ; Now register the user WM_NOTIFY handler GUIRegisterMsg(0x004E, "_User_WM_NOTIFY_Handler") GUISetState() GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_Ex") While 1 Sleep(10) $vRet = _GUIListViewEx_EventMonitor(0) If @error Then MsgBox($MB_SYSTEMMODAL, "Error", "Event error: " & @error) EndIf Switch @extended Case 1 If $vRet = "" Then MsgBox($MB_SYSTEMMODAL, "Edit", "Edit aborted" & @CRLF) Else _ArrayDisplay($vRet, "ListView " & _GUIListViewEx_GetActive() & " content edited", Default, 8) EndIf EndSwitch WEnd Func _Exit_Ex() Exit EndFunc Func _User_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam) ; Do whatever the user handler is supposed to do here ; Must be LAST line of the handler Return(_GUIListViewEx_WM_NOTIFY_Handler($hWnd, $iMsg, $wParam, $lParam)) EndFunc Please ask if you have any questions. M232 points
-
I slightly modified something I had ready, and here are the results #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <AutoItConstants.au3> #include <MsgBoxConstants.au3> Opt("TrayAutoPause", 0) HotKeySet("{END}", "main") ; <- HotKeySet -<< While 1 Sleep(50) WEnd Exit ;--------------------------------------------------------------------------------------- Func main() Local $sDomain = GetDomain() MsgBox(4096, "Domain:", $sDomain) EndFunc ;==>main ;--------------------------------------------------------------------------------------- Func GetDomain($sFullUrl = "") Local $sDomain = "", $iError = 0 If $sFullUrl = "" Then $sFullUrl = _ExtractLink() If Not @error Then ; Regex pattern to match the domain. Local $aMatch = StringRegExp($sFullUrl, '(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n?]+)', 3) If Not @error Then $sDomain = $aMatch[0] Else $iError = @error $sDomain = "Could not extract domain." EndIf Else ; I can't recognize the Url $iError = @error $sDomain = "I can't recognize the Url" EndIf Return SetError($iError, 0, $sDomain) EndFunc ;==>GetDomain ;--------------------------------------------------------------------------------------- Func _ExtractLink() ; Extract Link Local $hWnd = WinGetHandle("[ACTIVE]") Local $sTitle = WinGetTitle($hWnd) Local $sResult If StringRegExp($sTitle, "(?i)(.* — Mozilla Firefox.*|.* - Google Chrome.*)") Then Local $ClipBak = ClipGet() ; backUp ClipData WinActivate($hWnd) Send("{F6}") ; go in adresse bar Sleep(10) Send("{CTRLDOWN}") ; copy the link Send("c") Send("{CTRLUP}") Send("{F6}") ; deselect the link Sleep(100) Local $sLnk = ClipGet() Sleep(100) $sResult = $sLnk ClipPut($ClipBak) ; Restore backUp ClipData Return $sResult EndIf Return SetError(1, 0, "") EndFunc ;==>_ExtractLink2 points
-
I wrote a dll and the wrapper to convert non-animated WebP images to a GDI/GDI+ format / encode any GDI+ supported image to WebP format for use in Autoit. What is WebP? You can find more information about WebP and WebP tools / source codes here: https://developers.google.com/speed/webp Maybe useful for one or the other... 🙂 WebP.au3: #cs Copyright (c) 2022 - 2025 UEZ The following terms apply to the use of this code (AutoIt scripts and both DLLs), unless otherwise agreed upon in writing with the author: 1. **No commercial use** Any commercial usage - including but not limited to selling, licensing, integrating into commercial software, or using in revenue-generating products - is prohibited. 2. **Modification allowed, for non-commercial use only** You may modify or adapt the code as long as it remains non-commercial. Even in modified versions, the original author must be clearly credited as UEZ. 3. **Attribution required** In any non-commercial distribution or use, clear credit must be given to the original author: UEZ. For exceptions or commercial licensing, please contact: uez at hotmail de Third-Party Library Notice: This project uses the WebP library (libwebp) from Google. libwebp is licensed under the BSD 3-Clause License. See: https://chromium.googlesource.com/webm/libwebp/ #ce ;Version 0.5.0 build 2025-08-23 beta #include-once #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <Memory.au3> #include <MsgBoxConstants.au3> #include <WinAPIGdi.au3> #include <WindowsConstants.au3> #include <WinAPIConstants.au3> #include <WinAPISysWin.au3> ;~ #include <WinAPIDiag.au3> #include <Array.au3> ;WEBP_HINT_ENUMARTION Enum $WEBP_HINT_DEFAULT = 0, _ ; default preset. $WEBP_HINT_PICTURE, _ ; digital picture, like portrait, inner shot $WEBP_HINT_PHOTO, _ ; outdoor photograph, with natural lighting $WEBP_HINT_GRAPH, _ ; Discrete tone image (graph, map-tile etc). $WEBP_HINT_LAST Global Const $tagWebPConfig = _ "long lossless;" & _ "float quality;" & _ "long method;" & _ "long image_hint;" & _ "long target_size;" & _ "float target_PSNR;" & _ "long segments;" & _ "long sns_strength;" & _ "long filter_strength;" & _ "long filter_sharpness;" & _ "long filter_type;" & _ "long autofilter;" & _ "long alpha_compression;" & _ "long alpha_filtering;" & _ "long alpha_quality;" & _ "long pass;" & _ "long show_compressed;" & _ "long preprocessing;" & _ "long partitions;" & _ "long partition_limit;" & _ "long emulate_jpeg_size;" & _ "long thread_level;" & _ "long low_memory;" & _ "long near_lossless;" & _ "long exact;" & _ "long use_delta_palette;" & _ "long use_sharp_yuv;" & _ "long qmin;" & _ "long qmax" Global Const $tagWebPBitstreamFeatures = "struct;long width; long height; long has_alpha; long has_animation; long format; ulong pad[5];endstruct" Global $g_hDLL ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_Ver ; Description ...: Displays the DLL version information in a messagebox window ; Syntax ........: WebP_Ver([$sPath2DLL = ""]) ; Parameters ....: $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir ; Return values .: None ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_Ver($sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found DllCall($sDLL, "none", "WebP_DLL_Version") Return True EndFunc ;==>WebP_Ver ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_Ver2 ; Description ...: Returns the DLL version information ; Syntax ........: WebP_Ver([$sPath2DLL = ""]) ; Parameters ....: $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir ; Return values .: DLL version ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_Ver2($sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local $aResult = DllCall($sDLL, "str", "Web_DLL_Version2") If @error Or Not IsArray($aResult) Then Return SetError(2, 0, 0) Return $aResult[0] EndFunc ;==>WebP_Ver2 ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_BitmapGetInfo ; Description ...: Gets some rudimentary information about the WebP image ; Syntax ........: WebP_BitmapGetInfo($sFilename[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - file to load ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir ; Return values .: Struct ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_BitmapGetInfo($sFilename, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) ;file not found Local $iFileSize = FileGetSize($sFilename), $nBytes Local $tBuffer = DllStructCreate("struct;byte bin[" & $iFileSize & "];endstruct") Local Const $hFile = _WinAPI_CreateFile($sFilename, 2, 2) _WinAPI_ReadFile($hFile, $tBuffer, $iFileSize, $nBytes) _WinAPI_CloseHandle($hFile) If Int(BinaryMid($tBuffer.bin, 1, 4)) <> 1179011410 Or Int(BinaryMid($tBuffer.bin, 9, 6)) <> 88331643929943 Then Return SetError(3, 0, 0) ;header must contain RIFF and WEBPVP Local $tWebPBitstreamFeatures = DllStructCreate($tagWebPBitstreamFeatures) Local $aReturn = DllCall($sDLL, "long", "WebP_BitmapGetInfo", "struct*", $tBuffer, "uint", $iFileSize, "struct*", $tWebPBitstreamFeatures) If Not IsArray($aReturn) Or @error Then Return SetError(4, 0, 0) If $aReturn[0] = 0 Then Return SetError(5, 0, 0) Return $tWebPBitstreamFeatures EndFunc ;==>WebP_BitmapGetInfo ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_BitmapCreateGDIp ; Description ...: Converts (decodes) a WebP image from disk to a GDI / GDI+ bitmap handle ; Syntax ........: WebP_BitmapCreateGDIp($sFilename[, $bGDIImage = False[, $bDither = False[, $iDitherStrength = 32[, ; $bCountColors = False[, $sPath2DLL = ""]]]]]) ; Parameters ....: $sFilename - file to load ; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle). If True then output is GDI bitmap handle. ; $bDither - [optional] a boolean value. Default is False. If true pseudo dithering (noise) will applied to image. ; $iDitherStrength - [optional] an integer value. Default is 32. Valid values are from 0 to 64. ; $bCountColors - [optional] a boolean value. Default is False. If True then the colors will be counted and saved in extended. Use @extended to get color count. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir ; Return values .: GDI / GDIPlus bitmap handle and color count if $bCountColors = True in extended. ; Author ........: UEZ ; Modified ......: ; Remarks .......: For animated WebP images see below! Dithering makes only sense for images which are heavily compressed. ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_BitmapCreateGDIp($sFilename, $bGDIImage = False, $bDither = False, $iDitherStrength = 32, $bCountColors = False, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) ;file not found $iDitherStrength = $iDitherStrength > 64 ? 64 : $iDitherStrength < 0 ? 0 : $iDitherStrength Local $iFileSize = FileGetSize($sFilename), $nBytes If $iFileSize < 1 Then Return SetError(3, 0, 0) Local $tBuffer = DllStructCreate("byte bin[" & $iFileSize & "]") Local Const $hFile = _WinAPI_CreateFile($sFilename, 2, 2) _WinAPI_ReadFile($hFile, $tBuffer, $iFileSize, $nBytes) _WinAPI_CloseHandle($hFile) If Int(BinaryMid($tBuffer.bin, 1, 4)) <> 1179011410 Or Int(BinaryMid($tBuffer.bin, 9, 6)) <> 88331643929943 Then Return SetError(4, 0, 0) ;header must contain RIFF and WEBPVP Local $tColors = DllStructCreate("struct;ulong cc;endstruct") Local Const $aBitmap = DllCall($sDLL, "ptr", "WebP_BitmapCreateGDIp", "struct*", $tBuffer, "uint", $iFileSize, "boolean", $bDither, "ubyte", $iDitherStrength, "boolean", $bGDIImage, _ "boolean", $bCountColors, "struct*", $tColors) If Not IsArray($aBitmap) Or @error Then Return SetError(5, 0, 0) If $aBitmap[0] = 0 Then Return SetError(6, 0, 0) Return SetExtended($tColors.cc, $aBitmap[0]) EndFunc ;==>WebP_BitmapCreateGDIp ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_BitmapCreateGDIpFromMem ; Description ...: Converts (decodes) a WebP image from memory to a GDI / GDI+ bitmap handle ; Syntax ........: WebP_BitmapCreateGDIpFromMem($tBuffer[, $iBufferSize = 0[, $bGDIImage = False[, $bDither = False[, ; $iDitherStrength = 32[, $bCountColors = False[, $sPath2DLL = ""]]]]]]) ; Parameters ....: $tBuffer - a dll struct with WebP binary data as content or pointer to the memory data. ; $iBufferSize - the size of the binary data (file size). ; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle). If True then output is GDI bitmap handle. ; $bDither - [optional] a boolean value. Default is False. If true pseudo dithering (noise) will applied to image. ; $iDitherStrength - [optional] an integer value. Default is 32. Valid values are from 0 to 64. ; $bCountColors - [optional] a boolean value. Default is False. If True then the colors will be counted and saved in extended. Use @extended to get color count. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir ; Return values .: GDI / GDIPlus bitmap handle and color count if $bCountColors = True in extended. ; Author ........: UEZ ; Modified ......: ; Remarks .......: Currently only WebP images are supported - no animated WebP images yet! ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_BitmapCreateGDIpFromMem($tBuffer, $iBufferSize = 0, $bGDIImage = False, $bDither = False, $iDitherStrength = 32, $bCountColors = False, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If $iBufferSize = 0 Then Return SetError(2, 0, 0) Local $binMem If IsPtr($tBuffer) Then Local $tMem = DllStructCreate("byte bin[" & $iBufferSize & "]", $tBuffer) $binMem = $tMem.bin Else $binMem = DllStructGetData($tBuffer, 1) EndIf If Int(BinaryMid($binMem, 1, 4)) <> 1179011410 Or Int(BinaryMid($binMem, 9, 6)) <> 88331643929943 Then Return SetError(3, 0, 0) ;header must contain RIFF and WEBPVP Local $tColors = DllStructCreate("ulong cc") Local Const $aBitmap = DllCall($sDLL, "ptr", "WebP_BitmapCreateGDIp", "struct*", $tBuffer, "uint", $iBufferSize, "boolean", $bDither, "ubyte", $iDitherStrength, "boolean", _ $bGDIImage, "boolean", $bCountColors, "struct*", $tColors) If Not IsArray($aBitmap) Or @error Then Return SetError(4, 0, 0) If $aBitmap[0] = 0 Then Return SetError(5, 0, 0) Return SetExtended($tColors.cc, $aBitmap[0]) EndFunc ;==>WebP_BitmapCreateGDIpFromMem ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_CreateWebPLossySimpleFromBitmap ; Description ...: Converts a GDI+ bitmap to WebP lossy image and save it to HD ; Syntax ........: WebP_CreateWebPLossySimpleFromBitmap($sFilename, $hBitmap[, $iQuality = 75[, $sPath2DLL = ""]]) ; Parameters ....: $sFilename - file to load ; $hBitmap - GDIPlus bitmap handle ; $iQuality - [optional] an integer value. Default is 75. Valid range is 0 - 100. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 to -4 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_CreateWebPLossySimpleFromBitmap($sFilename, $hBitmap, $iQuality = 75, $sPath2DLL = "") If $sFilename = "" Then Return SetError(1, 0, 0) Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "long", "WebP_CreateWebPLossySimpleFromBitmap", "wstr", $sFilename, "ptr", $hBitmap, "float", $iQuality) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] = 0 Then Return SetError(4, 0, 0) Return 1 EndFunc ;==>WebP_CreateWebPLossySimpleFromBitmap ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_CreateWebPLosslessSimpleFromBitmap ; Description ...: Converts a GDI+ bitmap to WebP lossless image and save it to HD ; Syntax ........: WebP_CreateWebPLosslessSimpleFromBitmap($sFilename, $hBitmap[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - file to load ; $hBitmap - GDIPlus bitmap handle ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 0 for failure, 1 for success. ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_CreateWebPLosslessSimpleFromBitmap($sFilename, $hBitmap, $sPath2DLL = "") If $sFilename = "" Then Return SetError(1, 0, 0) Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "long", "WebP_CreateWebPLosslessSimpleFromBitmap", "wstr", $sFilename, "ptr", $hBitmap) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] = 0 Then Return SetError(4, 0, 0) Return 1 EndFunc ;==>WebP_CreateWebPLosslessSimpleFromBitmap ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_CreateWebPAdvancedFromBitmap ; Description ...: Converts a bitmap to WebP lossy / lossless image and save it to HD ; Syntax ........: WebP_CreateWebPAdvancedFromBitmap($sFilename, $hBitmap[, $lossless = 0[, $quality = 75.0[, $method = 4[, ; $sns_strength = 50[, $filter_sharpness = 0[, $filter_strength = 60[, $pass = 6[, $near_lossless = 100[, ; $alpha_compression = 1[, $alpha_filtering = 1[, $alpha_quality = 100[, $target_size = 0[, ; $WebPImageHint = $WEBP_HINT_DEFAULT[, $NoSave = False[, $sPath2DLL = ""]]]]]]]]]]]]]]]) ; Parameters ....: $sFilename - a string value. ; $hBitmap - a handle value. ; $lossless - [optional] an unknown value. Default is 0. ; $quality - [optional] an unknown value. Default is 75.0. ; $method - [optional] a map. Default is 4. ; $sns_strength - [optional] a string value. Default is 50. ; $filter_sharpness - [optional] a floating point value. Default is 0. ; $filter_strength - [optional] a floating point value. Default is 60. ; $pass - [optional] a pointer value. Default is 6. ; $near_lossless - [optional] a general number value. Default is 100. ; $alpha_compression - [optional] an array of unknowns. Default is 1. ; $alpha_filtering - [optional] an array of unknowns. Default is 1. ; $alpha_quality - [optional] an array of unknowns. Default is 100. ; $target_size - [optional] a dll struct value. Default is 0. ; $WebPImageHint - [optional] an unknown value. Default is $WEBP_HINT_DEFAULT. ; $NoSave - [optional] an unknown value. Default is False. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: negative value up to -8 for failure, 1 for success or the struct with information (pointers, size) if $NoSave = True ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_CreateWebPAdvancedFromBitmap($sFilename, $hBitmap, $lossless = 0, $quality = 75.0, $method = 4, $sns_strength = 50, _ $filter_sharpness = 0, $filter_strength = 60, $pass = 6, $near_lossless = 100, $alpha_compression = 1, $alpha_filtering = 1, $alpha_quality = 100, _ $target_size = 0, $WebPImageHint = $WEBP_HINT_DEFAULT, $NoSave = False, $sPath2DLL = "") If $sFilename = "" And $NoSave = False Then Return SetError(1, 0, 0) Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found Local $tMem = DllStructCreate("struct;ptr pPic; ptr pWriter; ptr pMemData; uint memsize;endstruct") Local $tWebPConfig = DllStructCreate($tagWebPConfig) FilltWebPConfigWithDefaults($tWebPConfig) With $tWebPConfig .lossless = $lossless .quality = ($quality < 0) ? 0 : (($quality > 100) ? 100 : $quality) .method = ($method < 0) ? 0 : (($method > 6) ? 6 : $method) .image_hint = ($WebPImageHint < 0) ? 0 : (($WebPImageHint > 4) ? 4 : $WebPImageHint) .target_size = $target_size ;in bytes .sns_strength = ($sns_strength < 0) ? 0 : (($sns_strength > 100) ? 100 : $sns_strength) .filter_strength = ($filter_strength < 0) ? 0 : (($filter_strength > 100) ? 100 : $filter_strength) .filter_sharpness = ($filter_sharpness < 0) ? 0 : (($filter_sharpness > 7) ? 7 : $filter_sharpness) .alpha_compression = $alpha_compression .alpha_filtering = ($alpha_filtering < 0) ? 0 : (($alpha_filtering > 2) ? 2 : $alpha_filtering) .alpha_quality = ($alpha_quality < 0) ? 0 : (($alpha_quality > 100) ? 100 : $alpha_quality) .pass = ($pass < 0) ? 0 : (($pass > 10) ? 10 : $pass) .near_lossless = ($near_lossless < 0) ? 0 : (($near_lossless > 100) ? 100 : $near_lossless) .exact = BitAND($near_lossless = 0, $lossless = 1) ? 1 : 0 EndWith Local $aReturn = DllCall($sDLL, "long", "WebP_CreateWebPAdvancedFromBitmap", _ "wstr", $sFilename, _ ;Webp filename "ptr", $hBitmap, _ ;handle to GDI+ bitmap "struct*", $tWebPConfig, _ ;WebP config settings "bool", $NoSave, _ "struct*", $tMem) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) If $NoSave And $tMem.memsize = 0 Then SetError(5, 0, 0) Return ($NoSave ? $tMem : $aReturn[0]) EndFunc ;==>WebP_CreateWebPAdvancedFromBitmap ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ReencodeWebPImage ; Description ...: Re-encodes a WebP image ; Syntax ........: WebP_ReencodeWebPImage($sFilename, $sOutfile, $tConfig[, $iNewWidth = 0[, $iNewHeight = 0[, $pImageData = 0[, ; $pImageDataSize = 0[, $sPath2DLL = ""]]]]]) ; Parameters ....: $sFilename - a string value. ; $sOutfile - a string value. ; $tConfig - a dll struct value. Must be a struct using $tagWebPConfig! ; $iNewWidth - [optional] an integer value. Default is 0. ; $iNewHeight - [optional] an integer value. Default is 0. ; $pImageData - [optional] a pointer value. Default is 0. A pointer to a memory block with loaded WebP image. ; $pImageDataSize - [optional] a pointer value. Default is 0. Size of the memory block. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 1 on success, otherwise error -> -1 to -11 ; Author ........: UEZ ; Modified ......: ; Remarks .......: If $pImageData is set, then $sFilename will be ignored in the WebP_ReencodeWebPImage() funtion ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ReencodeWebPImage($sFilename, $sOutfile, $tConfig, $iNewWidth = 0, $iNewHeight = 0, $pImageData = 0, $pImageDataSize = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) If Not IsDllStruct($tConfig) Then Return SetError(3, 0, 0) Local Const $aReturn = DllCall($sDLL, "long", "WebP_ReencodeWebPImage", "wstr", $sFilename, "wstr", $sOutfile, "struct*", $tConfig, "ptr", $pImageData, "int", $pImageDataSize, _ "ushort", $iNewWidth, "ushort", $iNewHeight) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return $aReturn[0] EndFunc ;==>WebP_ReencodeWebPImage ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_FreeUp ; Description ...: Release the ressources from $tMem struct ; Syntax ........: WebP_FreeUp(Byref $tMem[, $sPath2DLL = ""]) ; Parameters ....: $tMem - [in/out] a dll struct value. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 1 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: https://developers.google.com/speed/webp ; Example .......: No ; =============================================================================================================================== Func WebP_FreeUp(ByRef $tMem, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "long", "WebP_FreeUp", "struct*", $tMem) If @error Or Not IsArray($aReturn) Then Return SetError(2, 0, 0) If $aReturn[0] < 1 Then Return SetError(3, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_FreeUp ; #FUNCTION# ==================================================================================================================== ; Name ..........: BitmapCountColors ; Description ...: Counts the colors used by the bitmap ; Syntax ........: BitmapCountColors($hBitmap) ; Parameters ....: $hBitmap - a handle to a GDI+ bitmap. ; $bGDIImage - [optional] a boolean value. Default is False (GDIPlus bitmap handle). ; Return values .: Number of colors used by the image. ; Author ........: UEZ ; Modified ......: ; Remarks .......: The result may differ from other programs for JPG images depending on the decoder. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func BitmapCountColors($hBitmap = 0, $bGDIImage = False, $sPath2DLL = "") If IsPtr($hBitmap) = 0 Or $hBitmap = 0 Then SetError(1, 0, 0) Local Const $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "ulong", "BitmapCountColors", "ptr", $hBitmap) If @error Or Not IsArray($aReturn) Then Return SetError(2, 0, 0) If $aReturn[0] < 0 Then Return SetError(3, 0, $aReturn[0]) Return $aReturn[0] EndFunc ;==>BitmapCountColors ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ExtractAnimFramesToDisk ; Description ...: Extracts the frames of a WebP animated file ; Syntax ........: WebP_ExtractAnimFramesToDisk($sFile, $sDestPath = ""[, $sOutputFormat = "webp"[, $sPath2DLL = ""]]) ; Parameters ....: $sFilename - path to webp anim file. ; $sDestPath - destination folder. If empty then script path will be used. ; $sOutputFormat - [optional] a string value. Default is "webp". Any GDI+ supported or WebP image format. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: number of extracted frames on success, otherwise error -> -1 to -3 ; Author ........: UEZ ; Modified ......: ; Remarks .......: If output image format is WebP then frames will be saved lossless. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ExtractAnimFramesToDisk($sFilename, $sDestPath = "", $sOutputFormat = "webp", $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local Const $aReturn = DllCall($sDLL, "long", "WebP_ExtractAnimFramesToDisk", "wstr", $sFilename, "wstr", $sDestPath, "str", StringStripWS($sOutputFormat, $STR_STRIPALL)) If @error Or Not IsArray($aReturn) Then Return SetError(2, 0, 0) If $aReturn[0] < 1 Then Return SetError(3, 0, $aReturn[0]) Return $aReturn[0] EndFunc ;==>WebP_ExtractAnimFramesToDisk ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_GetAmountOfAnimFrames ; Description ...: Get the amount of frames from an animated webp file ; Syntax ........: WebP_GetAmountOfAnimFrames($sFilename[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - path to webp anim file. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 0 for failure, otherwise the amount of frames ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_GetAmountOfAnimFrames($sFilename, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local Const $aResult = DllCall($sDLL, "int", "WebP_GetAmountOfAnimFrames", "wstr", $sFilename) If Not IsArray($aResult) Or @error Then Return SetError(2, 0, 0) If $aResult[0] = 0 Then Return SetError(3, 0, 0) Return $aResult[0] EndFunc ;==>WebP_GetAmountOfAnimFrames ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_GetLengthOfAnim ; Description ...: Get the length of a WebP animation ; Syntax ........: WebP_GetLengthOfAnim($sFilename[, $sPath2DLL = "c:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Graphical Stuff\WebP\_WebP_x64.dll"]) ; Parameters ....: $sFilename - a string value. ; $sPath2DLL - [optional] a string value. Default is "c:\_BZ25LN\Coding\FreeBASIC\__UEZ\_Graphical Stuff\WebP\_WebP_x64.dll". ; Return values .: length in milli seconds, otherwise error -> -1 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_GetLengthOfAnim($sFilename, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local Const $aResult = DllCall($sDLL, "int", "WebP_GetLengthOfAnim", "wstr", $sFilename) If Not IsArray($aResult) Or @error Then Return SetError(2, 0, 0) If $aResult[0] = 0 Then Return SetError(3, 0, 0) Return $aResult[0] EndFunc ;==>WebP_GetLengthOfAnim ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ExtractAnimFramesToMem ; Description ...: Extracts all frames from a webp animated file to the memory ; Syntax ........: WebP_ExtractAnimFramesToMem($sFilename, Byref $iUB[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - path to webp anim file. ; $iUB - [in/out] an integer value. Needed to save the amount of data in struct array -> frames * 2 ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 0 for failure, otherwise struct array with pointer to the GDI+ image and frame delay ; Author ........: UEZ ; Modified ......: ; Remarks .......: You must dispose all frames when done. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ExtractAnimFramesToMem($sFilename, ByRef $iUB, $bDither = False, $iDitherStrength = 32, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local $iFrames = WebP_GetAmountOfAnimFrames($sFilename, $sPath2DLL) If Not $iFrames Or @error Then Return SetError(2, 0, 0) Local $tImgPtr = DllStructCreate((@AutoItX64 ? "int64 array[" : "int array[") & $iFrames * 2 + 2 & "]") Local Const $aReturn = DllCall($sDLL, "long", "WebP_ExtractAnimFramesToMem", "wstr", $sFilename, "ptr*", DllStructGetPtr($tImgPtr), "boolean", $bDither, "ubyte", $iDitherStrength) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) $iUB = $iFrames * 2 Return $tImgPtr EndFunc ;==>WebP_ExtractAnimFramesToMem ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_CreateWebPCreateAnim ; Description ...: Creates an WebP animation file ; Syntax ........: WebP_CreateWebPCreateAnim($aFilenames, $sOutfile[, $quality = 75.0[, $lossless = 0[, $method = 4[, ; $filter_strength = 60[, $sns_strength = 50[, $pass = 6[, $filter_sharpness = 0[, ; $near_lossless = 100[, $alpha_compression = 1[, $alpha_filtering = 1[, $alpha_quality = 100[, ; $target_size = 0[, $loop_count = 0[, $WebPImageHint = $WEBP_HINT_DEFAULT[, $iDefaultDelay = 75[, ; $pCallback = 0[, $sPath2DLL = ""]]]]]]]]]]]]]]]]]) ; Parameters ....: $aFilenames - an 2D array of pathes to the image files and delay per frame. ; $sOutfile - filename of WebP animation output file. ; $quality - [optional] an unknown value. Default is 75.0. Valid range is 0 - 100. ; $lossless - [optional] an unknown value. Default is 0. 0 for lossy encoding / 1 for lossless. ; $method - [optional] a map. Default is 4. Valid range is 0 - 6 (0=fast, 6=slower-better). ; $filter_strength - [optional] a floating point value. Default is 60. Range: [0 = off .. 100 = strongest] ; $sns_strength - [optional] a string value. Default is 50. Spatial Noise Shaping. 0=off, 100=maximum ; $pass - [optional] a pointer value. Default is 1. Number of entropy-analysis passes (in [1..10]). ; $filter_sharpness - [optional] a floating point value. Default is 0. Range: [0 = off .. 7 = least sharp] ; $near_lossless - [optional] a general number value. Default is 0 Near lossless encoding [0 = max loss .. 100 = off (default)]. ; $alpha_compression - [optional] an array of unknowns. Default is 1. Algorithm for encoding the alpha plane (0 = none,1 = compressed with WebP lossless). Default is 1. ; $alpha_filtering - [optional] an array of unknowns. Default is 1. Predictive filtering method for alpha plane.0: none, 1: fast, 2: best. Default if 1. ; $alpha_quality - [optional] an array of unknowns. Default is 100. Between 0 (smallest size) and 100 (lossless). Default is 100. ; $target_size - [optional] a dll struct value. Default is 0. If non-zero, set the desired target size in bytes. ; $loop_count - [optional] an unknown value. Default is 0. 0 = endless. ; $WebPImageHint - [optional] an unknown value. Default is $WEBP_HINT_DEFAULT. ; $iDefaultDelay - [optional] an integer value. Default is 75. Delay in milli seconds. ; $pCallback - [optional] a pointer value. Default is 0. Pointer to a callback address for progress hook. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 to -12 ; Author ........: UEZ ; Modified ......: ; Remarks .......: All frames must have same image dimension. First image defines the dimension of the animation. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_CreateWebPCreateAnim($aFilenames, $sOutfile, $quality = 75.0, $lossless = 1, $method = 4, $filter_strength = 60, $sns_strength = 50, _ $pass = 1, $filter_sharpness = 0, $near_lossless = 0, $alpha_compression = 1, $alpha_filtering = 1, $alpha_quality = 100, _ $target_size = 0, $loop_count = 0, $WebPImageHint = $WEBP_HINT_DEFAULT, $iDefaultDelay = 75, $pCallback = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If $sOutfile = "" Then Return SetError(2, 0, 0) If Not IsArray($aFilenames) Or UBound($aFilenames) < 2 Then Return SetError(3, 0, 0) Local $iNumberOfFrames = UBound($aFilenames), $i Local $tArrayFrames = DllStructCreate("ptr ptr[" & $iNumberOfFrames & "]"), $tArrayFramesDelay = DllStructCreate("uint delay[" & $iNumberOfFrames & "]") Local $tArrayAnim[$iNumberOfFrames], $tArrayFrameDelay[$iNumberOfFrames], $aDim, $iW, $iH For $i = 0 To $iNumberOfFrames - 1 If Not FileExists($aFilenames[$i][0]) Then Return SetError(4, 0, 0) $tArrayAnim[$i] = DllStructCreate("wchar path[" & StringLen($aFilenames[$i][0]) + 1 & "]") $tArrayAnim[$i].path = $aFilenames[$i][0] $tArrayFrames.ptr(($i + 1)) = DllStructGetPtr($tArrayAnim[$i]) $tArrayFramesDelay.delay(($i + 1)) = (UBound($aFilenames, 2) ? ($aFilenames[$i][1] > 0 ? $aFilenames[$i][1] : $iDefaultDelay) : $iDefaultDelay) Next Local $tAnim = DllStructCreate("ptr pFrames;ptr pDelays") $tAnim.pFrames = DllStructGetPtr($tArrayFrames) $tAnim.pDelays = DllStructGetPtr($tArrayFramesDelay) If StringRight($sOutfile, 5) <> ".webp" Then $sOutfile &= ".webp" $loop_count = $loop_count < 0 ? 0 : $loop_count Local $tWebPConfig = DllStructCreate($tagWebPConfig) FilltWebPConfigWithDefaults($tWebPConfig) With $tWebPConfig .lossless = $lossless .quality = ($quality < 0) ? 0 : (($quality > 100) ? 100 : $quality) .method = ($method < 0) ? 0 : (($method > 6) ? 6 : $method) .image_hint = ($WebPImageHint < 0) ? 0 : (($WebPImageHint > 4) ? 4 : $WebPImageHint) .target_size = $target_size ;in bytes .sns_strength = ($sns_strength < 0) ? 0 : (($sns_strength > 100) ? 100 : $sns_strength) .filter_strength = ($filter_strength < 0) ? 0 : (($filter_strength > 100) ? 100 : $filter_strength) .filter_sharpness = ($filter_sharpness < 0) ? 0 : (($filter_sharpness > 7) ? 7 : $filter_sharpness) .alpha_compression = $alpha_compression .alpha_filtering = ($alpha_filtering < 0) ? 0 : (($alpha_filtering > 2) ? 2 : $alpha_filtering) .alpha_quality = ($alpha_quality < 0) ? 0 : (($alpha_quality > 100) ? 100 : $alpha_quality) .pass = ($pass < 0) ? 0 : (($pass > 10) ? 10 : $pass) .near_lossless = ($near_lossless < 0) ? 0 : (($near_lossless > 100) ? 100 : $near_lossless) EndWith Local $aReturn = DllCall($sDLL, "long", "WebP_CreateWebPCreateAnim", _ "struct*", $tAnim, _ ;array of filenames with GDi+ supported images and delay per frame "uint", $iNumberOfFrames, _ ;amount of frames "wstr", $sOutfile, _ ;output filename "long", $loop_count, _ ;loop count -> 0 = endless "struct*", $tWebPConfig, _ ;WebP config settings "ptr", $pCallback) ;callback pointer for progress status If @error Or Not IsArray($aReturn) Then Return SetError(5, 0, 0) If $aReturn[0] < 1 Then Return SetError(6, 0, $aReturn[0]) ReDim $tArrayAnim[0] ReDim $tArrayFrameDelay[0] Return 1 EndFunc ;==>WebP_CreateWebPCreateAnim ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_CreateWebPCreateAnimFromScreenCapture ; Description ...: Capture the screen to WebP animation file ; Syntax ........: WebP_CreateWebPCreateAnimFromScreenCapture($x, $y, $w, $h, $sec, $sOutfile[, $fps = 30[, $CapCursor = 1[, ; $quality = 75.0[, $lossless = 0[, $method = 0[, $filter_strength = 60[, $sns_strength = 50[, $pass = 1[, ; $level = 6[, $filter_sharpness = 0[, $near_lossless = 100[, $alpha_compression = 0[, ; $alpha_filtering = 0[, $alpha_quality = 100[, $target_size = 0[, $loop_count = 0[, ; $WebPPreset = $WEBP_HINT_DEFAULT[, $pCallback = 0[, $sPath2DLL = ""]]]]]]]]]]]]]]]]]]]) ; Parameters ....: $x - x position on the screen where to start the capturing. ; $y - y position on the screen where to start the capturing. ; $w - width of the screen to capture. ; $h - height of the screen to capture. ; $sec - seconds to capture ; $sOutfile - filename of WebP animation output file. ; $fps - [optional] a floating point value. Default is 30 fps. ; $CapCursor - [optional] an unknown value. Default is 1. ; $quality - [optional] an unknown value. Default is 75.0. Valid range is 0 - 100. ; $lossless - [optional] an unknown value. Default is 0. 0 for lossy encoding / 1 for lossless. ; $method - [optional] a map. Default is 0. Valid range is 0 - 6 (0=fast, 6=slower-better). ; $filter_strength - [optional] a floating point value. Default is 60. Range: [0 = off .. 100 = strongest] ; $sns_strength - [optional] a string value. Default is 50. Spatial Noise Shaping. 0=off, 100=maximum ; $pass - [optional] a pointer value. Default is 1. Number of entropy-analysis passes (in [1..10]). ; $filter_sharpness - [optional] a floating point value. Default is 0. Range: [0 = off .. 7 = least sharp] ; $near_lossless - [optional] a general number value. Default is 100. Near lossless encoding [0 = max loss .. 100 = off (default)]. ; $alpha_compression - [optional] an array of unknowns. Default is 0. Algorithm for encoding the alpha plane (0 = none,1 = compressed with WebP lossless). Default is 1. ; $alpha_filtering - [optional] an array of unknowns. Default is 0. Predictive filtering method for alpha plane.0: none, 1: fast, 2: best. Default if 1. ; $alpha_quality - [optional] an array of unknowns. Default is 100. Between 0 (smallest size) and 100 (lossless). Default is 100. ; $target_size - [optional] a dll struct value. Default is 0. If non-zero, set the desired target size in bytes. ; $loop_count - [optional] an unknown value. Default is 0. 0 = endless. ; $WebPImageHint - [optional] an unknown value. Default is $WEBP_HINT_DEFAULT. ; $pCallback - [optional] a pointer value. Default is 0. Callback pointer for progress status ; $bXPMode - [optional] a boolean value. Default is False. If true 24 bit capturing will be activated instead of 32 bit. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 to -10 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_CreateWebPCreateAnimFromScreenCapture($x, $y, $w, $h, $sec, $sOutfile, $fps = 30, $CapCursor = 1, $quality = 75.0, $lossless = 0, $method = 0, $filter_strength = 60, $sns_strength = 50, _ $pass = 1, $filter_sharpness = 0, $near_lossless = 100, $alpha_compression = 0, $alpha_filtering = 0, $alpha_quality = 100, $target_size = 0, $loop_count = 0, _ $WebPImageHint = $WEBP_HINT_DEFAULT, $pCallback = 0, $bXPMode = False, $sPath2DLL = "") If $w < 1 Or $h < 1 Or $fps < 1 Or $sec < 1 Then Return SetError(1, 0, 0) Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found $loop_count = $loop_count < 0 ? 0 : $loop_count Local $tWebPConfig = DllStructCreate($tagWebPConfig) FilltWebPConfigWithDefaults($tWebPConfig) With $tWebPConfig .lossless = $lossless .quality = ($quality < 0) ? 0 : (($quality > 100) ? 100 : $quality) .method = ($method < 0) ? 0 : (($method > 6) ? 6 : $method) .image_hint = ($WebPImageHint < 0) ? 0 : (($WebPImageHint > 4) ? 4 : $WebPImageHint) .target_size = $target_size ;in bytes .sns_strength = ($sns_strength < 0) ? 0 : (($sns_strength > 100) ? 100 : $sns_strength) .filter_strength = ($filter_strength < 0) ? 0 : (($filter_strength > 100) ? 100 : $filter_strength) .filter_sharpness = ($filter_sharpness < 0) ? 0 : (($filter_sharpness > 7) ? 7 : $filter_sharpness) .alpha_compression = $alpha_compression .alpha_filtering = ($alpha_filtering < 0) ? 0 : (($alpha_filtering > 2) ? 2 : $alpha_filtering) .alpha_quality = ($alpha_quality < 0) ? 0 : (($alpha_quality > 100) ? 100 : $alpha_quality) .pass = ($pass < 0) ? 0 : (($pass > 10) ? 10 : $pass) .near_lossless = ($near_lossless < 0) ? 0 : (($near_lossless > 100) ? 100 : $near_lossless) EndWith Local $sCall = ($bXPMode ? "WebP_CreateWebPCreateAnimFromScreenCaptureXP" : "WebP_CreateWebPCreateAnimFromScreenCapture") Local $aReturn = DllCall($sDLL, "long", $sCall, _ "long", $x, _ ;x position of the screen "long", $y, _ ;y position of the screen "ulong", $w, _ ;width of the screen to capture "ulong", $h, _ ;height of the screen to capture "long", $sec, _ ;duration in seconds "ushort", $fps, _ ;fps for capturing "wstr", $sOutfile, _ ;output file name "ubyte", $CapCursor, _ ;capture cursor "long", $loop_count, _ ;loop count -> 0 = endless. "struct*", $tWebPConfig, _ ;WebP config settings "ptr", $pCallback) ;callback pointer for progress status If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_CreateWebPCreateAnimFromScreenCapture ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ConvertGIF2WebP ; Description ...: Converts a GIF animation to WebP animation ; Syntax ........: WebP_ConvertGIF2WebP($sGIFAnimFile, $sOutWebPFile[, $quality = 75.0[, $lossless = 1[, $method = 6[, ; $filter_strength = 60[, $sns_strength = 50[, $pass = 10[, $filter_sharpness = 0[, ; $near_lossless = 100[, $alpha_compression = 1[, $alpha_filtering = 1[, $alpha_quality = 100[, ; $target_size = 0[, $loop_count = 0[, $WebPPreset = $WEBP_HINT_DEFAULT[, $pCallback = 0[, ; $sPath2DLL = ""]]]]]]]]]]]]]]]]) ; Parameters ....: $sGIFAnimFile - a string value. ; $sOutWebPFile - a string value. ; $quality - [optional] an unknown value. Default is 75.0. Valid range is 0 - 100. ; $lossless - [optional] an unknown value. Default is 1. 0 for lossy encoding / 1 for lossless. ; $method - [optional] a map. Default is 6. Valid range is 0 - 6 (0=fast, 6=slower-better). ; $filter_strength - [optional] a floating point value. Default is 60. Range: [0 = off .. 100 = strongest] ; $sns_strength - [optional] a string value. Default is 50. Spatial Noise Shaping. 0=off, 100=maximum ; $pass - [optional] a pointer value. Default is 10. Number of entropy-analysis passes (in [1..10]). ; $filter_sharpness - [optional] a floating point value. Default is 0. Range: [0 = off .. 7 = least sharp] ; $near_lossless - [optional] a general number value. Default is 100. Near lossless encoding [0 = max loss .. 100 = off (default)]. ; $alpha_compression - [optional] an array of unknowns. Default is 1. Algorithm for encoding the alpha plane (0 = none,1 = compressed with WebP lossless). Default is 1. ; $alpha_filtering - [optional] an array of unknowns. Default is 1. Predictive filtering method for alpha plane.0: none, 1: fast, 2: best. Default if 1. ; $alpha_quality - [optional] an array of unknowns. Default is 100. Between 0 (smallest size) and 100 (lossless). Default is 100. ; $target_size - [optional] a dll struct value. Default is 0. If non-zero, set the desired target size in bytes. ; $loop_count - [optional] an unknown value. Default is 0. 0 = endless. ; $WebPPreset - [optional] an unknown value. Default is $WEBP_HINT_DEFAULT. ; $pCallback - [optional] a pointer value. Default is 0. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 1 on success, otherwise error -> -1 to -11 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ConvertGIF2WebP($sGIFAnimFile, $sOutWebPFile, $quality = 75.0, $lossless = 1, $method = 6, $filter_strength = 60, $sns_strength = 50, _ $pass = 10, $filter_sharpness = 0, $near_lossless = 100, $alpha_compression = 1, $alpha_filtering = 1, $alpha_quality = 100, _ $target_size = 0, $loop_count = 0, $WebPImageHint = $WEBP_HINT_DEFAULT, $pCallback = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If $sOutWebPFile = "" Then Return SetError(2, 0, 0) If StringRight($sOutWebPFile, 5) <> ".webp" Then $sOutWebPFile &= ".webp" $loop_count = $loop_count < 0 ? 0 : $loop_count Local $tWebPConfig = DllStructCreate($tagWebPConfig) FilltWebPConfigWithDefaults($tWebPConfig) With $tWebPConfig .lossless = $lossless .quality = ($quality < 0) ? 0 : (($quality > 100) ? 100 : $quality) .method = ($method < 0) ? 0 : (($method > 6) ? 6 : $method) .image_hint = ($WebPImageHint < 0) ? 0 : (($WebPImageHint > 4) ? 4 : $WebPImageHint) .target_size = $target_size ;in bytes .sns_strength = ($sns_strength < 0) ? 0 : (($sns_strength > 100) ? 100 : $sns_strength) .filter_strength = ($filter_strength < 0) ? 0 : (($filter_strength > 100) ? 100 : $filter_strength) .filter_sharpness = ($filter_sharpness < 0) ? 0 : (($filter_sharpness > 7) ? 7 : $filter_sharpness) .alpha_compression = $alpha_compression .alpha_filtering = ($alpha_filtering < 0) ? 0 : (($alpha_filtering > 2) ? 2 : $alpha_filtering) .alpha_quality = ($alpha_quality < 0) ? 0 : (($alpha_quality > 100) ? 100 : $alpha_quality) .pass = ($pass < 0) ? 0 : (($pass > 10) ? 10 : $pass) .near_lossless = ($near_lossless < 0) ? 0 : (($near_lossless > 100) ? 100 : $near_lossless) EndWith Local $aReturn = DllCall($sDLL, "long", "WebP_ConvertGIF2WebP", _ "wstr", $sGIFAnimFile, _ ;GIF animated input file "wstr", $sOutWebPFile, _ ;WebP animation output file "long", $loop_count, _ ;loop count -> 0 = endless "struct*", $tWebPConfig, _ ;WebP config settings "ptr", $pCallback) ;callback pointer for progress status If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_ConvertGIF2WebP ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ConvertAPNG2WebP ; Description ...: Converts a PNG animation to WebP animation ; Syntax ........: WebP_ConvertAPNG2WebP($sAPNGAnimFile, $sOutWebPFile[, $quality = 75.0[, $lossless = 1[, $method = 5[, ; $filter_strength = 60[, $sns_strength = 50[, $pass = 10[, $filter_sharpness = 0[, ; $near_lossless = 100[, $alpha_compression = 1[, $alpha_filtering = 1[, $alpha_quality = 100[, ; $target_size = 0[, $loop_count = 0[, $WebPPreset = $WEBP_HINT_DEFAULT[, $iDefaultDelay = 50[, ; $pCallback = 0[, $sPath2DLL = ""]]]]]]]]]]]]]]]]]]) ; Parameters ....: $sAPNGAnimFile - a string value. ; $sOutWebPFile - a string value. ; $quality - [optional] an unknown value. Default is 75.0. Valid range is 0 - 100. ; $lossless - [optional] an unknown value. Default is 1. 0 for lossy encoding / 1 for lossless. ; $method - [optional] a map. Default is 6. Valid range is 0 - 6 (0=fast, 6=slower-better). ; $filter_strength - [optional] a floating point value. Default is 60. Range: [0 = off .. 100 = strongest] ; $sns_strength - [optional] a string value. Default is 50. Spatial Noise Shaping. 0=off, 100=maximum ; $pass - [optional] a pointer value. Default is 10. Number of entropy-analysis passes (in [1..10]). ; $filter_sharpness - [optional] a floating point value. Default is 0. Range: [0 = off .. 7 = least sharp] ; $near_lossless - [optional] a general number value. Default is 100. Near lossless encoding [0 = max loss .. 100 = off (default)]. ; $alpha_compression - [optional] an array of unknowns. Default is 1. Algorithm for encoding the alpha plane (0 = none,1 = compressed with WebP lossless). Default is 1. ; $alpha_filtering - [optional] an array of unknowns. Default is 1. Predictive filtering method for alpha plane.0: none, 1: fast, 2: best. Default if 1. ; $alpha_quality - [optional] an array of unknowns. Default is 100. Between 0 (smallest size) and 100 (lossless). Default is 100. ; $target_size - [optional] a dll struct value. Default is 0. If non-zero, set the desired target size in bytes. ; $loop_count - [optional] an unknown value. Default is 0. 0 = endless. ; $WebPPreset - [optional] an unknown value. Default is $WEBP_HINT_DEFAULT. ; $iDefaultDelay - [optional] an integer value. Default is 50. ; $pCallback - [optional] a pointer value. Default is 0. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 1 on success, otherwise error -> -1 to -13 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ConvertAPNG2WebP($sAPNGAnimFile, $sOutWebPFile, $quality = 75.0, $lossless = 1, $method = 6, $filter_strength = 60, $sns_strength = 50, _ $pass = 10, $filter_sharpness = 0, $near_lossless = 100, $alpha_compression = 1, $alpha_filtering = 1, $alpha_quality = 100, _ $target_size = 0, $loop_count = 0, $WebPImageHint = $WEBP_HINT_DEFAULT, $iDefaultDelay = 50, $pCallback = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If $sOutWebPFile = "" Then Return SetError(2, 0, 0) If StringRight($sOutWebPFile, 5) <> ".webp" Then $sOutWebPFile &= ".webp" $loop_count = $loop_count < 0 ? 0 : $loop_count Local $tWebPConfig = DllStructCreate($tagWebPConfig) FilltWebPConfigWithDefaults($tWebPConfig) With $tWebPConfig .lossless = $lossless .quality = ($quality < 0) ? 0 : (($quality > 100) ? 100 : $quality) .method = ($method < 0) ? 0 : (($method > 6) ? 6 : $method) .image_hint = ($WebPImageHint < 0) ? 0 : (($WebPImageHint > 4) ? 4 : $WebPImageHint) .target_size = $target_size ;in bytes .sns_strength = ($sns_strength < 0) ? 0 : (($sns_strength > 100) ? 100 : $sns_strength) .filter_strength = ($filter_strength < 0) ? 0 : (($filter_strength > 100) ? 100 : $filter_strength) .filter_sharpness = ($filter_sharpness < 0) ? 0 : (($filter_sharpness > 7) ? 7 : $filter_sharpness) .alpha_compression = $alpha_compression .alpha_filtering = ($alpha_filtering < 0) ? 0 : (($alpha_filtering > 2) ? 2 : $alpha_filtering) .alpha_quality = ($alpha_quality < 0) ? 0 : (($alpha_quality > 100) ? 100 : $alpha_quality) .pass = ($pass < 0) ? 0 : (($pass > 10) ? 10 : $pass) .thread_level = 1 .near_lossless = ($near_lossless < 0) ? 0 : (($near_lossless > 100) ? 100 : $near_lossless) EndWith $iDefaultDelay = ($iDefaultDelay < 0) ? 0 : $iDefaultDelay Local $aReturn = DllCall($sDLL, "long", "WebP_ConvertAPNG2WebP", _ "wstr", $sAPNGAnimFile, _ ;GIF animated input file "wstr", $sOutWebPFile, _ ;WebP animation output file "long", $loop_count, _ ;loop count -> 0 = endless "long", $iDefaultDelay, _ ;delay of each frame "struct*", $tWebPConfig, _ ;WebP config settings "ptr", $pCallback) ;callback pointer for progress status If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_ConvertAPNG2WebP ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ReencodeAnimWebPImage ; Description ...: Re-encodes a WebP animated image ; Syntax ........: WebP_ReencodeAnimWebPImage($sFilename, $sOutfile, $tConfig[, $iNewWidth = 0[, $iNewHeight = 0[, ; $sPath2DLL = ""]]]) ; Parameters ....: $sFilename - a string value. ; $sOutfile - a string value. ; $tConfig - a dll struct value. ; $iNewWidth - [optional] an integer value. Default is 0. ; $iNewHeight - [optional] an integer value. Default is 0. ; $sPath2DLL - [optional] a string value. Default is "". ; Return values .: 1 on success, otherwise error -> -1 to -10 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ReencodeAnimWebPImage($sFilename, $sOutfile, $tConfig, $iNewWidth = 0, $iNewHeight = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) If Not IsDllStruct($tConfig) Then Return SetError(3, 0, 0) Local Const $aReturn = DllCall($sDLL, "long", "WebP_ReencodeAnimWebPImage", "wstr", $sFilename, "wstr", $sOutfile, "struct*", $tConfig, "ushort", $iNewWidth, "ushort", $iNewHeight) If @error Or Not IsArray($aReturn) Then Return SetError(4, 0, 0) If $aReturn[0] < 1 Then Return SetError(5, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_ReencodeAnimWebPImage ; #FUNCTION# ==============================================================================================================DllCallbackGetPtr($iCB)====== ; Name ..........: WebP_GetAnimFileInfo ; Description ...: Get information about a WebP anim file ; Syntax ........: WebP_GetAnimFileInfo($sFilename, Byref $tAnimInfo[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - path to webp anim file. ; $tAnimInfo - [in/out] a dll struct value. Must be "ulong Width;ulong Height;ulong FrameCount;ulong Duration;double FPS" ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 to -6 ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_GetAnimFileInfo($sFilename, ByRef $tAnimInfo, $sPath2DLL = "") If Not FileExists($sFilename) Then Return SetError(1, 0, 0) Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(2, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "long", "WebP_GetAnimFileInfo", "wstr", $sFilename, "struct*", $tAnimInfo) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_GetAnimFileInfo ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_GetImagesDiffFromFile ; Description ...: Displays the difference of two WebP images. ; Syntax ........: WebP_GetImagesDiffFromFile($sFilename1, $sFilename2[, $iMetricType = 1[, $sPath2DLL = ""]]) ; Parameters ....: $sFilename1 - a string value. First WebP image filename. ; $sFilename2 - a string value. Second WebP image filename. ; $iMetricType - [optional] an integer value. Default is 1. Valid values 0 - 2. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: array with distortion values, otherwise error ; Author ........: UEZ ; Modified ......: ; Remarks .......: Possible metric type: ; 0: PSNR - Peak signal-to-noise ratio - measures numerical deviation (higher = better). ; Value range Interpretation ; > 50 dB Excellent quality - barely visible ; 40-50 dB Very good quality ; 30-40 dB Good to medium quality ; < 30 dB Clearly visible losses ; 1: SSIM - Structural Similarity Index - takes visual perception into account (0 - 100, closer to 100 = better). ; Value range Interpretation ; 95 - 100 Almost identical / perfect quality ; 90 - 95 Very good quality ; 85 - 90 Good quality ; < 85 Visible structural differences ; 2: LSIM - Local Similarity - more detailed, for local differences (more experimental). Same as SSIM. ; ; Both images must have same dimension! ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_GetImagesDiffFromFile($sFilename1, $sFilename2, $iMetricType = 1, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename1) Then Return SetError(2, 0, 0) If Not FileExists($sFilename2) Then Return SetError(3, 0, 0) $iMetricType = ($iMetricType > 2) ? 2 : ($iMetricType < 0 ? 0 : $iMetricType) Local $tDistortion = DllStructCreate("float d[5]") Local $aReturn = DllCall($sDLL, "long", "WebP_GetImagesDiffFromFile", "wstr", $sFilename1, "wstr", $sFilename2, "long", $iMetricType, "ptr*", DllStructGetPtr($tDistortion)) If @error Or Not IsArray($aReturn) Then Return SetError(4, 0, 0) If $aReturn[0] < 1 Then Return SetError(5, 0, $aReturn[0]) Local $aDistortion[5] = [$tDistortion.d((1)), $tDistortion.d((2)), $tDistortion.d((3)), $tDistortion.d((4)), $tDistortion.d((5))] Return $aDistortion EndFunc ;==>WebP_GetImagesDiffFromFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_ScaleImage ; Description ...: Resizes a WebP image. ; Syntax ........: WebP_ScaleImage($sSourceFile, $iW, $iH, $sDestFile[, $sPath2DLL = ""]) ; Parameters ....: $sSourceFile - source WebP file to load. ; $iW - an integer value. ; $iH - an integer value. ; $sDestFile - destination WebP file to save. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 to -9 ; Author ........: UEZ ; Modified ......: ; Remarks .......: Resized image will be saved lossless. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_ScaleImage($sSourceFile, $iW, $iH, $sDestFile, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found Local $aReturn = DllCall($sDLL, "long", "WebP_ScaleImage", "wstr", $sSourceFile, "long", $iW, "long", $iH, "wstr", $sDestFile) If @error Or Not IsArray($aReturn) Then Return SetError(2, 0, 0) If $aReturn[0] < 1 Then Return SetError(3, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_ScaleImage ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_GetImageQuality ; Description ...: Estimates the quality of a WebP image. ; Syntax ........: WebP_GetImageQuality($sFilename[, $sPath2DLL = ""]) ; Parameters ....: $sFilename - source WebP file to load. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: the quality of the WebP image. 0 - 100 for lossy - 101 for lossless. 0 or negative value on error. ; Author ........: UEZ ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_GetImageQuality($sFilename, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) Local $aReturn = DllCall($sDLL, "long", "WebP_GetImageQuality", "wstr", $sFilename) If @error Or Not IsArray($aReturn) Then Return SetError(2, 0, 0) If $aReturn[0] < 1 Then Return SetError(3, 0, $aReturn[0]) Return $aReturn[0] EndFunc ;==>WebP_GetImageQuality ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_PlayAnimFile ; Description ...: Plays an animated WebP file and display it in the GUI ; Syntax ........: WebP_PlayAnimFile($sFilename, $hGUI[, $w = 0[, $h = 0[, $pCallback = 0[, $sPath2DLL = ""]]]]) ; Parameters ....: $sFilename - path to webp anim file. ; $hGUI - the handle to the GUI to copy the frames to it. ; $w - [optional] an unknown value. Default is 0. If 0 the width from the animation file will be used. ; $h - [optional] a handle value. Default is 0. If 0 the height from the animation file will be used. ; $pCallback - [optional] a pointer value. Default is 0. ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: a pointer to the thread on success, otherwise error -> 0 ; Author ........: UEZ ; Modified ......: ; Remarks .......: Don't use $pCallback yet because it is not working properly! Don't forget DllClose($g_hDLL) when done! DllOpen must be used otherwise crash. ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_PlayAnimFile($sFilename, $hGUI, $w = 0, $h = 0, $pCallback = 0, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not FileExists($sFilename) Then Return SetError(2, 0, 0) $g_hDLL = DllOpen($sDLL) Local $aReturn = DllCall($g_hDLL, "ptr", "WebP_PlayAnimFile", "wstr", $sFilename, "hwnd", HWnd($hGUI), "ulong", $w, "ulong", $h, "ptr", $pCallback) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return $aReturn[0] EndFunc ;==>WebP_PlayAnimFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: WebP_StopAnimFile ; Description ...: Stops the animation which was started by WebP_PlayAnimFile() function. ; Syntax ........: WebP_StopAnimFile($pThread[, $sPath2DLL = ""]) ; Parameters ....: $pThread - a thread parameter pointer ; $sPath2DLL - [optional] a string value. Default is "". Path to WebP dll if not in script dir. ; Return values .: 1 on success, otherwise error -> -1 ; Author ........: UEZ ; Modified ......: ; Remarks .......: You must call WebP_PlayAnimFile() before you call WebP_StopAnimFile()! Don't forget DllClose($g_hDLL) when done! ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func WebP_StopAnimFile($pThread, $sPath2DLL = "") Local $sDLL = Path2DLL($sPath2DLL) If Not FileExists($sDLL) Then Return SetError(1, 0, 0) ;DLL not found If Not $g_hDLL Then Return SetError(2, 0, 0) Local $aReturn = DllCall($g_hDLL, "long", "WebP_StopAnimFile", "ptr", $pThread) If @error Or Not IsArray($aReturn) Then Return SetError(3, 0, 0) If $aReturn[0] < 1 Then Return SetError(4, 0, $aReturn[0]) Return 1 EndFunc ;==>WebP_StopAnimFile ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_MarkScreenRegion ; Description ...: Selected area on desktop will be captured and save to clipbord or GDI bitmap handle will be returned. ; Syntax ........: _WinAPI_MarkScreenRegion([$iFillMode = 0]) ; Parameters ....: $iFillMode - [optional] an integer value. Default is 0. ; 0: marked area filled with solid color ; 1: marked area filled with hatch pattern ($HS_DIAGCROSS) ; 2: marked area without any fill pattern / color - only red border ; Return values .: 0 / 1 / -1 / array with coordinates [x, y, w, h] ; Author ........: UEZ ; Version .......: 0.90 build 2025-06-27 ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: no ; =============================================================================================================================== Func _WinAPI_MarkScreenRegion($iFillMode = 0) If @OSBuild > 6299 Then ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms724832(v=vs.85).aspx DllCall("Shcore.dll", "long", "PROCESS_DPI_AWARENESS", 1) ;PROCESS_SYSTEM_DPI_AWARE = 1 (https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx) Else DllCall("User32.dll", "bool", "SetProcessDPIAware") EndIf Local $iOld = AutoItSetOption("MouseCoordMode", 1) Local Const $hDesktop = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hDesktop) ;should work also on multi screens Local Const $iW = $aFullScreen[2], $iH = $aFullScreen[3] Local Const $hGUI_MarkScreen = GUICreate("", $iW, $iH, $aFullScreen[0], $aFullScreen[1], $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED)) GUISetState(@SW_SHOW, $hGUI_MarkScreen) Local Const $hDC = _WinAPI_GetDC($hGUI_MarkScreen) Local Const $hGfxDC = _WinAPI_CreateCompatibleDC($hDC) Local Const $hBitmapGDI = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local $hObjOld = _WinAPI_SelectObject($hGfxDC, $hBitmapGDI) Local $tSize = DllStructCreate($tagSIZE) $tSize.x = $iW $tSize.y = $iH Local $tSource = DllStructCreate($tagPOINT) Local $tBlend = DllStructCreate($tagBLENDFUNCTION) $tBlend.Alpha = 0xFF $tBlend.Format = 1 Local $tDest = DllStructCreate($tagPOINT), $pPoint = DllStructGetPtr($tDest) $tDest.x = $aFullScreen[0] $tDest.y = $aFullScreen[1] Local Const $hPen = _WinAPI_CreatePen($PS_SOLID, 1, 0x0000FF) Local Const $hPen_Orig = _WinAPI_SelectObject($hGfxDC, $hPen) Local $hBrush, $iAlpha2, $iFlag $iFillMode = $iFillMode > 2 ? 2 : $iFillMode < 0 ? 0 : $iFillMode Switch $iFillMode Case 0 $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, 0x808080) $iAlpha2 = 0xA0 $iFlag = $ULW_ALPHA Case 1 $hBrush = _WinAPI_CreateBrushIndirect($BS_HATCHED, 0x808000, $HS_DIAGCROSS) $iAlpha2 = 0x30 $iFlag = $ULW_ALPHA Case 2 $hBrush = _WinAPI_CreateBrushIndirect($BS_HOLLOW, 0x000000) $iAlpha2 = 0xFF ;not needed $iFlag = $ULW_COLORKEY EndSwitch Local $hBrush_Orig = _WinAPI_SelectObject($hGfxDC, $hBrush) Local $aMPos[5], $aMPos_old[4], $tRECT = _WinAPI_CreateRect(0, 0, 0, 0) Do GUISetCursor(16, 1, $hGUI_MarkScreen) $aMPos = GUIGetCursorInfo($hGUI_MarkScreen) $aMPos_old[0] = $aMPos[0] $aMPos_old[1] = $aMPos[1] $aMPos_old[2] = MouseGetPos(0) $aMPos_old[3] = MouseGetPos(1) Switch $aMPos[2] Case 0 ;display crosshair _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) _WinAPI_DrawLine($hGfxDC, $tDest.x, $aMPos[1], $iW, $aMPos[1]) _WinAPI_DrawLine($hGfxDC, $aMPos[0], $tDest.y, $aMPos[0], $iH) _WinAPI_UpdateLayeredWindow($hGUI_MarkScreen, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $ULW_COLORKEY) Case 1 ; $tBlend.Alpha = $iAlpha2 While $aMPos[2] ;mark region GUISetCursor(14, 1, $hGUI_MarkScreen) ;WinGetHandle(AutoItWinGetTitle())) $aMPos = GUIGetCursorInfo($hGUI_MarkScreen) _WinAPI_BitBlt($hGfxDC, 0, 0, $iW, $iH, $hGfxDC, 0, 0, $CAPTUREBLT) ;clear bitmap ;draw rectangle $tRECT.Left = $aMPos_old[0] $tRECT.Top = $aMPos_old[1] $tRECT.Right = $aMPos[0] $tRECT.Bottom = $aMPos[1] _WinAPI_Rectangle($hGfxDC, $tRECT) If $iFillMode <> 2 Then _WinAPI_InvertRect($hGfxDC, $tRECT) _WinAPI_UpdateLayeredWindow($hGUI_MarkScreen, $hDC, $tDest, $tSize, $hGfxDC, $tSource, 0, $tBlend, $iFlag) Sleep(10) WEnd _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_MarkScreen, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) _WinAPI_SelectObject($hGfxDC, $hBrush_Orig) _WinAPI_DeleteObject($hBrush) GUIDelete($hGUI_MarkScreen) AutoItSetOption("MouseCoordMode", $iOld) Local $aCoords[4] = [($aMPos[0] > $aMPos_old[2] ? $aMPos_old[2] : $aMPos[0]), ($aMPos[1] > $aMPos_old[3] ? $aMPos_old[3] : $aMPos[1]), Abs($tRECT.Right - $tRECT.Left) + 1, Abs($tRECT.Bottom - $tRECT.Top) + 1] Return $aCoords EndSwitch Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _WinAPI_SelectObject($hGfxDC, $hObjOld) _WinAPI_ReleaseDC($hGUI_MarkScreen, $hDC) _WinAPI_DeleteDC($hGfxDC) _WinAPI_DeleteObject($hBitmapGDI) _WinAPI_SelectObject($hGfxDC, $hPen_Orig) _WinAPI_DeleteObject($hPen) GUIDelete($hGUI_MarkScreen) AutoItSetOption("MouseCoordMode", $iOld) Return -1 EndSwitch Until False EndFunc ;==>_WinAPI_MarkScreenRegion ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: Path2DLL ; Description ...: Return the path to the _WebP_x??.dll ; Author ........: UEZ ; Modified.......: ; Remarks .......: This function is used internally by WebP.au3 ; =============================================================================================================================== Func Path2DLL($sPath2DLL = "") Return $sPath2DLL ? $sPath2DLL : @ScriptDir & (@AutoItX64 ? "\_WebP_x64.dll" : "\_WebP_x86.dll") EndFunc ;==>Path2DLL ; #INTERNAL_USE_ONLY#============================================================================================================ ; Name...........: FilltWebPConfigWithDefaults ; Description ...: Set the default $tWebPConfig struct parameters ; Author ........: UEZ ; Modified.......: ; Remarks .......: This function is used internally by WebP.au3 ; =============================================================================================================================== Func FilltWebPConfigWithDefaults(ByRef $tWebPConfig) With $tWebPConfig .lossless = 0 .quality = 75 .method = 4 .image_hint = 0 .target_size = 0 .target_PSNR = 0 .segments = 4 .sns_strength = 50 .filter_strength = 60 .filter_sharpness = 0 .filter_type = 1 .autofilter = 0 .alpha_compression = 1 .alpha_filtering = 1 .alpha_quality = 100 .pass = 1 .show_compressed = 0 .preprocessing = 0 .partitions = 0 .partition_limit = 0 .emulate_jpeg_size = 0 .thread_level = 0 .low_memory = 0 .near_lossless = 100 .exact = 0 .use_delta_palette = 0 .use_sharp_yuv = 0 .qmin = 0 .qmax = 100 EndWith EndFunc ;==>FilltWebPConfigWithDefaults WebP Advanced Encoder GUI: ;Coded by UEZ build 2025-08-06 #AutoIt3Wrapper_UseX64=n #AutoIt3Wrapper_Res_HiDpi=n #AutoIt3Wrapper_Version=p #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_Run_Au3Stripper=y #Au3Stripper_Parameters=/so /pe ;/rm #AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_stripped.au3" #pragma compile(Icon, WebP_logo_2010_by_Simo99.ico) #pragma compile(FileVersion, 0.9.9.1) #pragma compile(ProductVersion, 3.3.16.1) #pragma compile(CompanyName, "UEZ Software Development") #pragma compile(ProductName, "WebP Advanced Encoder GUI") AutoItSetOption("MustDeclareVars", 1) #include <Array.au3> #include <ComboConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <GuiMenu.au3> #include <GuiStatusBar.au3> #include <Memory.au3> #include <SliderConstants.au3> #include <StaticConstants.au3> #include <WinAPISysWin.au3> #include <WinAPITheme.au3> #include <WindowsConstants.au3> #include "WebP.au3" Break(0) If @OSBuild < 10240 Then MsgBox($MB_ICONWARNING, "Warning", "Your Windows version is not support!", 30) If WebP_Ver2() < "0.4.3" Then Exit MsgBox($MB_ICONERROR, "ERROR", "DLL Version v0.4.3+ required!", 30) Global Const $ver = "v0.99.1", $build = "build 2025-08-06" #Region TichySID Global Const $tagIMAGE_DOS_HEADER = 'WORD e_magic;WORD e_cblp;WORD e_cp;WORD e_crlc;WORD e_cparhdr;WORD e_minalloc;WORD e_maxalloc;WORD e_ss;WORD e_sp;WORD e_csum;WORD e_ip;WORD e_cs;WORD e_lfarlc;WORD e_ovno;WORD e_res[4];WORD e_oemid;WORD e_oeminfo;WORD e_res2[10];LONG e_lfanew;' Global Const $tagIMAGE_FILE_HEADER = 'WORD Machine;WORD NumberOfSections;DWORD TimeDateStamp;DWORD PointerToSymbolTable;DWORD NumberOfSymbols;WORD SizeOfOptionalHeader;WORD Characteristics;' Global $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;DWORD SizeOfInitializedData;DWORD SizeOfUninitializedData;DWORD AddressOfEntryPoint;DWORD BaseOfCode;DWORD BaseOfData;PTR ImageBase;DWORD SectionAlignment;DWORD FileAlignment;WORD MajorOperatingSystemVersion;WORD MinorOperatingSystemVersion;WORD MajorImageVersion;WORD MinorImageVersion;WORD MajorSubsystemVersion;WORD MinorSubsystemVersion;DWORD Win32VersionValue;DWORD SizeOfImage;DWORD SizeOfHeaders;DWORD CheckSum;WORD Subsystem;WORD DllCharacteristics;PTR SizeOfStackReserve;PTR SizeOfStackCommit;PTR SizeOfHeapReserve;PTR SizeOfHeapCommit;DWORD LoaderFlags;DWORD NumberOfRvaAndSizes;' If @AutoItX64 Then $tagIMAGE_OPTIONAL_HEADER = 'WORD Magic;BYTE MajorLinkerVersion;BYTE MinorLinkerVersion;DWORD SizeOfCode;DWORD SizeOfInitializedData;DWORD SizeOfUninitializedData;DWORD AddressOfEntryPoint;DWORD BaseOfCode;PTR ImageBase;DWORD SectionAlignment;DWORD FileAlignment;WORD MajorOperatingSystemVersion;WORD MinorOperatingSystemVersion;WORD MajorImageVersion;WORD MinorImageVersion;WORD MajorSubsystemVersion;WORD MinorSubsystemVersion;DWORD Win32VersionValue;DWORD SizeOfImage;DWORD SizeOfHeaders;DWORD CheckSum;WORD Subsystem;WORD DllCharacteristics;PTR SizeOfStackReserve;PTR SizeOfStackCommit;PTR SizeOfHeapReserve;PTR SizeOfHeapCommit;DWORD LoaderFlags;DWORD NumberOfRvaAndSizes;' Global Const $tagIMAGE_NT_HEADER = 'DWORD Signature;' & $tagIMAGE_FILE_HEADER & $tagIMAGE_OPTIONAL_HEADER Global Const $tagIMAGE_SECTION_HEADER = 'CHAR Name[8];DWORD VirtualSize;DWORD VirtualAddress;DWORD SizeOfRawData;DWORD PointerToRawData;DWORD PointerToRelocations;DWORD PointerToLinenumbers;WORD NumberOfRelocations;WORD NumberOfLinenumbers;DWORD Characteristics;' Global Const $tagIMAGE_DATA_DIRECTORY = 'DWORD VirtualAddress;DWORD Size;' Global Const $tagIMAGE_BASE_RELOCATION = 'DWORD VirtualAddress;DWORD SizeOfBlock;' Global Const $tagIMAGE_IMPORT_DESCRIPTOR = 'DWORD OriginalFirstThunk;DWORD TimeDateStamp;DWORD ForwarderChain;DWORD Name;DWORD FirstThunk;' Global Const $tagIMAGE_IMPORT_BY_NAME = 'WORD Hint;char Name[1];' Global Const $tagIMAGE_EXPORT_DIRECTORY = 'DWORD Characteristics;DWORD TimeDateStamp;WORD MajorVersion;WORD MinorVersion;DWORD Name;DWORD Base;DWORD NumberOfFunctions;DWORD NumberOfNames;DWORD AddressOfFunctions;DWORD AddressOfNames;DWORD AddressOfNameOrdinals;' Global $_KERNEL32DLL = DllOpen('kernel32.dll') Global $_MFHookPtr, $_MFHookBak, $_MFHookApi = 'LocalCompact' Global Const $tagModule = 'PTR ExportList;PTR CodeBase;PTR ImportList;PTR DllEntry;DWORD Initialized;' Global Const $SID_MEMORY = 1 Global Const $SID_NON_DEFAULT = 2 Global $hTitchysidDll, $iSubsongCount = 0 #EndRegion ; enum _PROCESS_DPI_AWARENESS -> https://msdn.microsoft.com/en-us/library/windows/desktop/dn280512(v=vs.85).aspx Global Enum $DPI_AWARENESS_INVALID = -1, $PROCESS_DPI_UNAWARE = 0, $PROCESS_SYSTEM_DPI_AWARE, $PROCESS_PER_MONITOR_DPI_AWARE ;https://docs.microsoft.com/en-us/windows/desktop/hidpi/dpi-awareness-context Global Enum $Context_UnawareGdiScaled = -5, $Context_PerMonitorAwareV2, $Context_PerMonitorAware, $Context_SystemAware, $Context_Unaware ; enum _MONITOR_DPI_TYPE Global Enum $MDT_EFFECTIVE_DPI = 0, $MDT_ANGULAR_DPI, $MDT_RAW_DPI Global Const $MDT_DEFAULT = $MDT_EFFECTIVE_DPI Global Const $SM_CXPADDEDBORDER = 92 _GDIPlus_Startup() ;~ Global $aDPI = _WinAPI_GetDpiForMonitor() ;_GDIPlus_GraphicsGetDPIRatio() Global $aDPI = [1, 1] Global $hGUI_About, $iFPS = 0, $iShowFPS = 0, $bExit, $bGUIBgColor = 0xFF808080 #Region GUI Global Const $SC_DRAGMOVE = 0xF012, $iW = 322, $iH = 694 Global Const $hGUI = GUICreate("WAE GUI " & $ver & " Beta by UEZ", $iW, $iH, @DesktopWidth - $iW - 8, -1, -1, BitOR($WS_EX_ACCEPTFILES, $WS_EX_APPWINDOW, $WS_EX_TOPMOST, $WS_EX_NOACTIVATE)) GUISetFont(10 * $aDPI[0], 400, 0, "Arial Narrow") Global Const $Title = GUICtrlCreateLabel("WebP Advanced Encoder GUI", 5, 8, 310, 41) GUICtrlSetFont(-1, 21 * $aDPI[0], 400, 0, "Arial Narrow") Global Const $icLoad = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -127, 8, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER)) GUICtrlSetTip(-1, "Load a GDI+ supported image") Global Const $icSave = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -259, 56, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER)) GUICtrlSetTip(-1, "Save compressed image in WebP format.") Global Const $icReset = GUICtrlCreateIcon(@SystemDir & "\shell32.dll", -239, 104, 60, 32, 32, BitOR($GUI_SS_DEFAULT_ICON, $WS_BORDER)) GUICtrlSetTip(-1, "Reset image position if image was moved (only for images larger than preview window).") GUICtrlCreateLabel("", 0, 106, $iW - 2, 2, $SS_ETCHEDHORZ) Global Const $lbPresets = GUICtrlCreateLabel("Presets", 10, 125, 39, 20) Global Const $cbPreset = GUICtrlCreateCombo("Default", 120, 120, $iW - 177, 25, BitOR($CBS_DROPDOWN, $CBS_AUTOHSCROLL)), $hcbPreset = GUICtrlGetHandle($cbPreset) GUICtrlSetData(-1, "Picture|Photo|Graph|Last") Global Const $chkbLossless = GUICtrlCreateCheckbox("&Lossless", 120, 152, 97, 17) GUICtrlSetTip(-1, "Enable lossless compression. Default: lossy.") Global Const $lbEncoding = GUICtrlCreateLabel("Encoding", 10, 152, 48, 20) Global Const $lbQuality = GUICtrlCreateLabel("Quality", 10, 176, 36, 20) Global Const $slQuality = GUICtrlCreateSlider(116, 176, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslQuality = GUICtrlGetHandle($slQuality) GUICtrlSetLimit(-1, 100, 0) GUICtrlSetData(-1, 75) GUICtrlSetTip(-1, "Between 0 and 100. 0 gives the smallest size and 100 the largest.") Global Const $ipQuality = GUICtrlCreateInput("", $iW - 48, 172, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slQuality)) Global Const $lbMethod = GUICtrlCreateLabel("Method", 10, 210, 39, 20) Global Const $slMethod = GUICtrlCreateSlider(116, 210, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslMethod = GUICtrlGetHandle($slMethod) GUICtrlSetLimit(-1, 6, 0) GUICtrlSetData(-1, 4) GUICtrlSetTip(-1, "Quality/speed trade-off (0=fast, 6=slower-better.") Global Const $ipMethod = GUICtrlCreateInput("", $iW - 48, 206, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slMethod)) Global Const $lbSNS_Strength = GUICtrlCreateLabel("SNS-Strength", 10, 242, 66, 20) Global Const $slSNS_Strength = GUICtrlCreateSlider(116, 244, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslSNS_Strength = GUICtrlGetHandle($slSNS_Strength) GUICtrlSetLimit(-1, 100, 0) GUICtrlSetData(-1, 50) GUICtrlSetTip(-1, "Spatial Noise Shaping. 0=off, 100=maximum.") Global Const $ipSSN_Strength = GUICtrlCreateInput("", $iW - 48, 240, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slSNS_Strength)) Global Const $lbFilterSharpness = GUICtrlCreateLabel("Filter Sharpness", 10, $iW - 48, 81, 20) Global Const $slFilter_Sharpness = GUICtrlCreateSlider(116, 278, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslFilter_Sharpness = GUICtrlGetHandle($slFilter_Sharpness) GUICtrlSetLimit(-1, 7, 0) GUICtrlSetTip(-1, "Range: [0 = off .. 7 = least sharp].") Global Const $ipFilter_Sharpness = GUICtrlCreateInput("", $iW - 48, 274, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slFilter_Sharpness)) Global Const $lbFilter_Strength = GUICtrlCreateLabel("Filter Strenght", 010, 304, 69, 20) Global Const $slFilter_Strength = GUICtrlCreateSlider(116, 312, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslFilter_Strength = GUICtrlGetHandle($slFilter_Strength) GUICtrlSetLimit(-1, 100, 0) GUICtrlSetData(-1, 60) GUICtrlSetTip(-1, "Range: [0 = off .. 100 = strongest]") Global Const $ipFilter_Strength = GUICtrlCreateInput("", $iW - 48, 308, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slFilter_Strength)) Global Const $lbPass = GUICtrlCreateLabel("Pass", 10, 344, 27, 20) Global Const $slPass = GUICtrlCreateSlider(116, 346, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslPass = GUICtrlGetHandle($slPass) GUICtrlSetLimit(-1, 10, 1) GUICtrlSetData(-1, 1) GUICtrlSetTip(-1, "Number of entropy-analysis passes (in [1..10]).") Global Const $ipPass = GUICtrlCreateInput("", $iW - 48, 342, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slPass)) Global Const $lbNear_Lossless = GUICtrlCreateLabel("Near Lossless", 10, 378, 80, 20) Global Const $slNear_Lossless = GUICtrlCreateSlider(116, 380, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslNear_Lossless = GUICtrlGetHandle($slNear_Lossless) GUICtrlSetLimit(-1, 100, 0) GUICtrlSetData(-1, 100) GUICtrlSetTip(-1, "Specify the level of near-lossless image preprocessing. The range is 0 (maximum preprocessing) to 100 (no preprocessing, the default).") Global Const $ipNear_Lossless = GUICtrlCreateInput("", $iW - 48, 374, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slNear_Lossless)) Global Const $lbLevel = GUICtrlCreateLabel("Level", 10, 411, 30, 20) Global Const $slLevel = GUICtrlCreateSlider(116, 414, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslLevel = GUICtrlGetHandle($slLevel) GUICtrlSetLimit(-1, 9, 0) GUICtrlSetData(-1, 6) GUICtrlSetTip(-1, "Switch on lossless compression mode with the specified level between 0 and 9, with level 0 being the fastest, 9 being the slowest.") GUICtrlSetState(-1, $GUI_DISABLE) Global Const $ipLevel = GUICtrlCreateInput("", $iW - 48, 410, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slLevel)) Global Const $lbAlpha_Compression = GUICtrlCreateLabel("Alpha Compression", 10, 444, 96, 20) Global Const $chkbAlpha_Compression = GUICtrlCreateCheckbox("&Enable", 120, 444, 97, 17) GUICtrlSetState(-1, $GUI_CHECKED) Global Const $lbAlpha_Filtering = GUICtrlCreateLabel("Alpha Filtering", 10, 478, 71, 20) Global Const $slAlpha_Filtering = GUICtrlCreateSlider(114, 482, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslAlpha_Filtering = GUICtrlGetHandle($slAlpha_Filtering) GUICtrlSetLimit(-1, 2, 0) GUICtrlSetData(-1, 1) GUICtrlSetTip(-1, "Predictive filtering method for alpha plane. 0: none, 1: fast, 2: best. Default if 1.") Global Const $ipAlpha_Filtering = GUICtrlCreateInput("", $iW - 48, 478, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slAlpha_Filtering)) Global Const $lbAlpha_Quality = GUICtrlCreateLabel("Alpha Quality", 8, 516, 66, 20) Global Const $slAlpha_Quality = GUICtrlCreateSlider(114, 516, $iW - 164, 21, BitOR($GUI_SS_DEFAULT_SLIDER, $TBS_ENABLESELRANGE)), $hslAlpha_Quality = GUICtrlGetHandle($slAlpha_Quality) GUICtrlSetLimit(-1, 100, 0) GUICtrlSetData(-1, 100) GUICtrlSetTip(-1, "Between 0 (smallest size) and 100 (lossless).") Global Const $ipAlpha_Quality = GUICtrlCreateInput("", $iW - 48, 512, 28, 24, BitOR($GUI_SS_DEFAULT_INPUT, $ES_CENTER, $ES_READONLY)) GUICtrlSetData(-1, GUICtrlRead($slAlpha_Quality)) Global Const $lbTarget_Size = GUICtrlCreateLabel("Target Size", 10, 552, 58, 20) Global Const $ipTarget_Size = GUICtrlCreateInput("0", 120, 550, $iW - 177, 24, $ES_NUMBER) GUICtrlSetTip(-1, "If non-zero, set the desired target size in bytes (lossy mode only!).") Global Const $chkbCountColors = GUICtrlCreateCheckbox("&Count Colors", 10, 590, 87, 17) Global Const $lbColorOriginal = GUICtrlCreateLabel("Source:", 101, 590, 38, 20) Global Const $ipColorOriginal = GUICtrlCreateInput("0", 142, 588, 60, 24, BitOR($ES_NUMBER, $ES_READONLY)) Global Const $lbColorWebP = GUICtrlCreateLabel("WebP:", 215, 590, 32, 20) Global Const $ipColorWebP = GUICtrlCreateInput("0", 250, 588, 60, 24, BitOR($ES_NUMBER, $ES_READONLY)) Global Const $btnShow = GUICtrlCreateButton("Show Original Image", 10, 630, 123, 25) GUICtrlSetTip(-1, "Press lmb and hold it to display original image.") Global Const $btnApply = GUICtrlCreateButton("&Apply Settings", 188, 630, 123, 25) Global Const $StatusBar = _GUICtrlStatusBar_Create($hGUI), $iSBColor = 0xE9CFEC _WinAPI_SetWindowTheme($StatusBar, "", "") _GUICtrlStatusBar_SetText($StatusBar, " Welcome to 'WebP Advanced Encoder GUI' ٩(●̮̮̃•̃)۶") _GUICtrlStatusBar_SetBkColor($StatusBar, $iSBColor) Global Const $hGUI_Image = GUICreate("", 0, 0, -1, -1, $WS_EX_TOOLWINDOW, BitOR($WS_EX_TOOLWINDOW, $WS_EX_APPWINDOW)) GUISetBkColor(BitAND(0xFFFFFF, $bGUIBgColor), $hGUI_Image) Global Const $iPic_WebP = GUICtrlCreatePic("", 0, 0, 0, 0), $hPic_WebP = GUICtrlGetHandle($iPic_WebP) ;~ Global Const $iW_Zoom = @DesktopWidth * 0.25, $iH_Zoom = @DesktopHeight * 0.25 ;~ Global Const $hGUI_Image_Zoom = GUICreate("", $iW_Zoom, $iH_Zoom, 0, 0, $WS_POPUP) Global Const $dw = _WinAPI_GetSystemMetrics($SM_CXDLGFRAME), $dh = _WinAPI_GetSystemMetrics($SM_CYDLGFRAME) + _WinAPI_GetSystemMetrics($SM_CYSIZE) + 1 Global Enum $idAbout = 5000, $idResetPicPos, $idResetValues Global Const $hMenu_Sys = _GUICtrlMenu_GetSystemMenu($hGUI) _GUICtrlMenu_AppendMenu($hMenu_Sys, $MF_SEPARATOR, 0, 0) _GUICtrlMenu_AppendMenu($hMenu_Sys, $MF_STRING, $idAbout, "About") Global Const $hImage_Icon = _GDIPlus_BitmapCreateFromMemory(_WebP_Icon()) Global Const $hIcon = _GDIPlus_HICONCreateFromBitmap($hImage_Icon) _WinAPI_SetClassLongEx($hGUI, -34, $hIcon) _GDIPlus_ImageDispose($hImage_Icon) GUISetState(@SW_HIDE, $hGUI_Image) GUISetState(@SW_SHOW, $hGUI) ;~ GUISetState(@SW_SHOW, $hGUI_Image_Zoom) _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI, 2) Global Const $iDummy_About = GUICtrlCreateDummy(), $iDummy_Return = GUICtrlCreateDummy() Global $sFileLoad, $hImage, $hImage_GDI, $hHBitmap, $aDim, $aPixelFormat, $pMemData, $pMemData_Size, $tMem, $mp, $sFileSave, $hFile, $nBytes, $nBytes, $iResetPosX, $iResetPosY, _ $hImage_tmp GUIRegisterMsg($WM_DROPFILES, "WM_DROPFILES") GUIRegisterMsg($WM_LBUTTONDOWN, "WM_LBUTTONDOWN") GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU") GUIRegisterMsg($WM_SYSCOMMAND, "WM_SYSCOMMAND") GUIRegisterMsg($WM_HSCROLL, "WM_HSCROLL") #EndRegion GUI Global $aGUIGetMsg, $aMPos1, $aMPos2, $iMPx, $iMPy, $iMPx_p = 0, $iMPy_p = 0, $bBigger = False, $iResult, $old_cursor, $bNew = False While 1 $mp = GUIGetCursorInfo($hGUI) If $hImage And $mp[2] And $mp[4] = $btnShow Then _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hImage_GDI)) While $mp[2] $mp = GUIGetCursorInfo($hGUI) Sleep(10) WEnd _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)) EndIf $mp = GUIGetCursorInfo($hGUI_Image) $aMPos1 = MouseGetPos() If $mp[4] = $iPic_WebP And $mp[2] And $bBigger And WinActive($hGUI_Image) Then While $mp[2] $mp = GUIGetCursorInfo($hGUI_Image) Sleep(10) $aMPos2 = MouseGetPos() $iMPx = $iMPx_p + $aMPos2[0] - $aMPos1[0] $iMPy = $iMPy_p + $aMPos2[1] - $aMPos1[1] ControlMove($hGUI_Image, "", $iPic_WebP, $iMPx, $iMPy) WEnd $iMPx_p = $iMPx $iMPy_p = $iMPy EndIf $aGUIGetMsg = GUIGetMsg(1) Switch $aGUIGetMsg[1] Case $hGUI Switch $aGUIGetMsg[0] Case $GUI_EVENT_CLOSE GUIRegisterMsg($WM_DROPFILES, "") GUIRegisterMsg($WM_LBUTTONDOWN, "") GUIRegisterMsg($WM_COMMAND, "") GUIRegisterMsg($WM_CONTEXTMENU, "") GUIRegisterMsg($WM_SYSCOMMAND, "") GUIRegisterMsg($WM_HSCROLL, "") ;~ If IsDllStruct($tMem) Then WebP_FreeUp($tMem) _WinAPI_DestroyIcon($hIcon) If $hImage_tmp Then _GDIPlus_ImageDispose($hImage_tmp) If $hImage Then _GDIPlus_ImageDispose($hImage) If $hHBitmap Then _WinAPI_DeleteObject($hHBitmap) If $hImage_GDI Then _WinAPI_DeleteObject($hImage_GDI) If $hGUI_Image Then GUIDelete($hGUI_Image) _GDIPlus_Shutdown() GUIDelete($hGUI_Image) GUIDelete($hGUI) DllClose($_KERNEL32DLL) Exit Case $btnApply, $iDummy_Return If $hImage Then CompressAndDisplay($hImage) EndIf Case $icLoad $sFileLoad = FileOpenDialog("Select an image to compress", "", "Images (*.jpg;*.bmp;*.png;*.gif;*.tif;*webp)") If @error Then ContinueLoop LoadImage($sFileLoad) Case $icSave If $hImage Then $sFileSave = FileSaveDialog("Save WebP Image", "", "WebP Image (*.webp)", BitOR($FD_PATHMUSTEXIST, $FD_PROMPTOVERWRITE), StringRegExpReplace($sFileLoad, ".+\\(.+)\..*", "$1") & ".webp", $hGUI) If @error Then ContinueLoop $hFile = _WinAPI_CreateFile($sFileSave, 1) $iResult = _WinAPI_WriteFile($hFile, $tMem.pMemData, $tMem.memsize, $nBytes) _WinAPI_CloseHandle($hFile) If Not $iResult Then MsgBox($MB_ICONERROR, "ERROR", "Unable to save WebP image to disk!", 30, $hGUI) Else MsgBox($MB_ICONINFORMATION, "Information", "WebP image successfully save to disk", 10, $hGUI) EndIf EndIf Case $icReset ResetImage() Case $slAlpha_Filtering GUICtrlSetData($ipAlpha_Filtering, GUICtrlRead($slAlpha_Filtering)) Case $slAlpha_Quality GUICtrlSetData($ipAlpha_Quality, GUICtrlRead($slAlpha_Quality)) Case $slFilter_Sharpness GUICtrlSetData($ipFilter_Sharpness, GUICtrlRead($slFilter_Sharpness)) Case $slFilter_Strength GUICtrlSetData($ipFilter_Strength, GUICtrlRead($slFilter_Strength)) Case $slLevel GUICtrlSetData($ipLevel, GUICtrlRead($slLevel)) Case $slMethod GUICtrlSetData($ipMethod, GUICtrlRead($slMethod)) Case $slNear_Lossless GUICtrlSetData($ipNear_Lossless, GUICtrlRead($slNear_Lossless)) Case $slPass GUICtrlSetData($ipPass, GUICtrlRead($slPass)) Case $slQuality GUICtrlSetData($ipQuality, GUICtrlRead($slQuality)) Case $slSNS_Strength GUICtrlSetData($ipSSN_Strength, GUICtrlRead($slSNS_Strength)) Case $iDummy_About AutoItSetOption("GUIOnEventMode", 1) GDIPlus_About(11 * $aDPI[0], -12, 24.5) AutoItSetOption("GUIOnEventMode", 0) Case $btnShow If BitAND(WinGetState($hGUI_Image), $WIN_STATE_VISIBLE) = $WIN_STATE_VISIBLE Then WinActivate($hGUI_Image) EndSwitch Case $hGUI_Image Switch $aGUIGetMsg[0] Case $GUI_EVENT_CLOSE EndSwitch EndSwitch WEnd Func ResetImage() If $bBigger Then $iMPx_p = $iResetPosX $iMPy_p = $iResetPosY ControlMove($hGUI_Image, "", $iPic_WebP, $iMPx_p, $iMPy_p) EndIf EndFunc Func LoadImage($sFileLoad) If $hImage_tmp Then _GDIPlus_ImageDispose($hImage_tmp) If $hImage Then _GDIPlus_ImageDispose($hImage) If $hImage_GDI Then _WinAPI_DeleteObject($hImage_GDI) If StringRight($sFileLoad, 5) = ".webp" Then If WebP_GetAmountOfAnimFrames($sFileLoad) > 0 Then Return MsgBox($MB_ICONERROR, "ERROR", "WebP animated image cannot be loaded!", 30, $hGUI) $hImage_tmp = WebP_BitmapCreateGDIp($sFileLoad) If @error Or $hImage_tmp = 0 Then Return MsgBox($MB_ICONERROR, "ERROR", "Unable to decode WebP image!", 30, $hGUI) EndIf Else $hImage_tmp = _GDIPlus_ImageLoadFromFile($sFileLoad) If @error Or $hImage_tmp = 0 Then Return MsgBox($MB_ICONERROR, "ERROR", "Unknown image format!", 30, $hGUI) EndIf EndIf $aPixelFormat = _GDIPlus_ImageGetPixelFormat($hImage_tmp) ;Local Const $aImageRawFormat = _GDIPlus_ImageGetRawFormat($hImage_tmp) If BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED) Then GUICtrlSetData($ipColorOriginal, BitmapCountColors($hImage_tmp)) Else GUICtrlSetData($ipColorOriginal, 0) EndIf ;~ If $hImage_tmp Then ConsoleWrite("Original color count: " & BitmapCountColors($hImage_tmp) & @CRLF) $aDim = _GDIPlus_ImageGetDimension($hImage_tmp) $hImage = _GDIPlus_BitmapCreateFromScan0($aDim[0], $aDim[1]) Local Const $hGfx = _GDIPlus_ImageGetGraphicsContext($hImage) If $aPixelFormat[0] = 2498570 Then _GDIPlus_GraphicsClear($hGfx, $bGUIBgColor) _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage_tmp, 0, 0, $aDim[0], $aDim[1]) _GDIPlus_GraphicsDispose($hGfx) $hImage_GDI = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) $bNew = True _WinAPI_LockWindowUpdate($hGUI) CompressAndDisplay($hImage, $aPixelFormat[1]) _WinAPI_LockWindowUpdate(0) EndFunc ;==>LoadImage Func CompressAndDisplay($hImage, $sFormat = "") Local $aDim = _GDIPlus_ImageGetDimension($hImage) If $hHBitmap Then _WinAPI_DeleteObject($hHBitmap) $pMemData = 0 $pMemData_Size = 0 Local $iPreset = GUICtrlRead($cbPreset) Switch $iPreset Case "Default" $iPreset = 0 Case "Picture" $iPreset = 1 Case "Photo" $iPreset = 2 Case "Graph" $iPreset = 3 Case "Last" $iPreset = 4 EndSwitch If IsDllStruct($tMem) Then WebP_FreeUp($tMem) $old_cursor = MouseGetCursor() GUISetCursor(15, 1, $hGUI) _GUICtrlStatusBar_SetBkColor($StatusBar, 192) Local $end, $fTimer = TimerInit() $tMem = WebP_CreateWebPAdvancedFromBitmap("", $hImage, _ BitAND(GUICtrlRead($chkbLossless), $GUI_CHECKED), _ GUICtrlRead($slQuality), _ GUICtrlRead($slMethod), _ GUICtrlRead($slSNS_Strength), _ GUICtrlRead($slFilter_Sharpness), _ GUICtrlRead($slFilter_Strength), _ GUICtrlRead($slPass), _ GUICtrlRead($slNear_Lossless), _ BitAND(GUICtrlRead($chkbAlpha_Compression), $GUI_CHECKED), _ GUICtrlRead($slAlpha_Filtering), _ GUICtrlRead($slAlpha_Quality), _ GUICtrlRead($ipTarget_Size), _ $iPreset, _ True) ;hold the compressed image in memory only, no save to HD! $end = TimerDiff($fTimer) ToolTip("") _GUICtrlStatusBar_SetBkColor($StatusBar, $iSBColor) GUISetCursor($old_cursor, 1, $hGUI) Local $iColorsWebp = 0 If IsDllStruct($tMem) Then _GUICtrlStatusBar_SetText($StatusBar, "WebP size: " & Round($tMem.memsize / 1024, 2) & " kb / encoded in " & Round($end, 2) & " ms.") $hHBitmap = WebP_BitmapCreateGDIpFromMem($tMem.pMemData, $tMem.memsize, 1, 0, 32, BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED)) If @error Then Return MsgBox($MB_ICONERROR, "ERROR", "Unable to compress image", 30, $hGUI) $iColorsWebp = @extended GUICtrlSetData($ipColorWebP, $iColorsWebp) If BitAND(GUICtrlRead($chkbCountColors), $GUI_CHECKED) And GUICtrlRead($ipColorOriginal) = "0" Then GUICtrlSetData($ipColorOriginal, BitmapCountColors($hImage_tmp)) ;~ ConsoleWrite("WebP image color count: " & @extended & @CRLF) Local $aTaskbar = WinGetPos("[CLASS:Shell_TrayWnd;INSTANCE:1]", ""), $tbw = 0, $tbh = 0 If $aTaskbar[2] > $aTaskbar[3] Then $tbh = $aTaskbar[3] ELse $tbw = $aTaskbar[2] EndIf Local Const $minw = 384, $minh = $minw * 10 / 16 Local $maxw = Min($aDim[0] + $dw, @DesktopWidth * 0.95), $maxh = Min($aDim[1] + $dh, @DesktopHeight * 0.95), $iNewW = 0, $iNewH = 0 If $aDim[0] + $dw > @DesktopWidth * 0.95 Or $aDim[1] + $dh > @DesktopHeight * 0.95 Then $bBigger = True Else $bBigger = False EndIf If $bNew Then $iNewW = Max($minw, $maxw) $iNewH = Max($minh, $maxh) WinMove($hGUI_Image, "", (@DesktopWidth - $iNewW - (@DesktopWidth - $iW > $iNewW ? $iW : 0)) / 2 - $tbw, (@DesktopHeight - $iNewH - $tbh) / 2, $iNewW, $iNewH) WinSetTitle($hGUI_Image, "", StringRegExpReplace($sFileLoad, ".+\\(.*)", "$1") & " / " & $aDim[0] & "x" & $aDim[1] & " px / " & $sFormat & " / " & Round(FileGetSize($sFileLoad) / 1024, 2) & " kb") $iNewH -= $dh ;_WinAPI_GetSystemMetrics($SM_CXBORDER) + _WinAPI_GetSystemMetrics($SM_CYSIZE) + _WinAPI_GetSystemMetrics($SM_CXPADDEDBORDER) * 2 $iMPx_p = ($iNewW - $aDim[0]) / 2 $iMPy_p = ($iNewH - $aDim[1] - 4) / 2 $iResetPosX = $iMPx_p $iResetPosY = $iMPy_p GUICtrlSetPos($iPic_WebP, $iMPx_p, $iMPy_p, $iNewW - 1, $iNewH - 1) $bNew = False EndIf _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_WebP, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap)) Local Const $iWC_State = WinGetState($hGUI_Image) If $iWC_State <> 7 Or $iWC_State <> 5 Then WinSetState($hGUI_Image, "", @SW_SHOW) WinActivate($hGUI_Image) EndIf WinActivate($hGUI) Else MsgBox($MB_ICONERROR, "ERROR", "DLL encode error " & $tMem, 30) EndIf EndFunc ;==>CompressAndDisplay Func Progress($progress, $ptr) ToolTip($progress & "%", MouseGetPos(0) - 40, MouseGetPos(1)) Return 1 EndFunc Func WM_HSCROLL($hWnd, $Msg, $wParam, $lParam) #forceref $hWnd, $Msg, $wParam Switch $lParam Case $hslAlpha_Filtering GUICtrlSetData($ipAlpha_Filtering, GUICtrlRead($slAlpha_Filtering)) Case $hslAlpha_Quality GUICtrlSetData($ipAlpha_Quality, GUICtrlRead($slAlpha_Quality)) Case $hslFilter_Sharpness GUICtrlSetData($ipFilter_Sharpness, GUICtrlRead($slFilter_Sharpness)) Case $hslFilter_Strength GUICtrlSetData($ipFilter_Strength, GUICtrlRead($slFilter_Strength)) Case $hslLevel GUICtrlSetData($ipLevel, GUICtrlRead($slLevel)) Case $hslMethod GUICtrlSetData($ipMethod, GUICtrlRead($slMethod)) Case $hslNear_Lossless GUICtrlSetData($ipNear_Lossless, GUICtrlRead($slNear_Lossless)) Case $hslPass GUICtrlSetData($ipPass, GUICtrlRead($slPass)) Case $hslQuality GUICtrlSetData($ipQuality, GUICtrlRead($slQuality)) Case $hslSNS_Strength GUICtrlSetData($ipSSN_Strength, GUICtrlRead($slSNS_Strength)) EndSwitch Return "GUI_RUNDEFMSG" EndFunc ;==>WM_HSCROLL Func WM_DROPFILES($hWnd, $iMsg, $wParam, $lParam) Local $i = 1 Local $aFileList = _WinAPI_DragQueryFileEx($wParam) Do If StringInStr(FileGetAttrib($aFileList[$i]), "D") Then _ArrayDelete($aFileList, $i) Else $i += 1 EndIf Until $i = UBound($aFileList) $aFileList[0] = UBound($aFileList) - 1 $sFileLoad = $aFileList[1] _WinAPI_DragFinish($wParam) LoadImage($sFileLoad) Return 0 EndFunc ;==>WM_DROPFILES# Func WM_LBUTTONDOWN($hWnd, $iMsg, $wParam, $lParam) _SendMessage($hWnd, $WM_SYSCOMMAND, $SC_DRAGMOVE, 0) EndFunc ;==>_WM_LBUTTONDOWN Func WM_SYSCOMMAND($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg, $ilParam Switch BitAND($iwParam, 0x0000FFFF) Case $idAbout GUICtrlSendToDummy($iDummy_About) EndSwitch Return "GUI_RUNDEFMSG" EndFunc ;==>WM_SYSCOMMAND Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam) #forceref $hWnd, $iMsg Switch $iwParam Case 1 GUICtrlSendToDummy($iDummy_Return) Return 0 Case $idResetPicPos ResetImage() Return 0 Case $idResetValues GUICtrlSetData($slAlpha_Filtering, 1) GUICtrlSetData($ipAlpha_Filtering, 1) GUICtrlSetData($slAlpha_Quality, 100) GUICtrlSetData($ipAlpha_Quality, 100) GUICtrlSetData($slFilter_Sharpness, 0) GUICtrlSetData($ipFilter_Sharpness, 0) GUICtrlSetData($slFilter_Strength, 60) GUICtrlSetData($ipFilter_Strength, 60) GUICtrlSetData($slLevel, 6) GUICtrlSetData($ipLevel, 6) GUICtrlSetData($slMethod, 4) GUICtrlSetData($ipMethod, 4) GUICtrlSetData($slNear_Lossless, 60) GUICtrlSetData($ipNear_Lossless, 60) GUICtrlSetData($slPass, 6) GUICtrlSetData($ipPass, 6) GUICtrlSetData($slQuality, 75) GUICtrlSetData($ipQuality, 75) GUICtrlSetData($slSNS_Strength, 50) GUICtrlSetData($ipSSN_Strength, 50) GUICtrlSetData($ipTarget_Size, 0) GUICtrlSetState($chkbAlpha_Compression, $GUI_CHECKED) GUICtrlSetState($chkbLossless, $GUI_UNCHECKED) _SendMessage($hcbPreset, $CB_SETCURSEL, 0) Return 0 EndSwitch Return "GUI_RUNDEFMSG" EndFunc ;==>WM_COMMAND Func WM_CONTEXTMENU($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $lParam Switch $hWnd Case $hGUI Local $hMenu $hMenu = _GUICtrlMenu_CreatePopup() _GUICtrlMenu_InsertMenuItem($hMenu, 0, "Reset values to default", $idResetValues) If $bBigger Then _GUICtrlMenu_InsertMenuItem($hMenu, 1, 0) _GUICtrlMenu_InsertMenuItem($hMenu, 2, "Reset image position", $idResetPicPos) EndIf _GUICtrlMenu_TrackPopupMenu($hMenu, $wParam) _GUICtrlMenu_DestroyMenu($hMenu) Return True EndSwitch Return $GUI_RUNDEFMSG EndFunc ;==>WM_CONTEXTMENU Func Max($a, $b) If $a > $b Then Return $a Return $b EndFunc Func Min($a, $b) If $a < $b Then Return $a Return $b EndFunc Func GDIPlus_About($iFontsize = 10, $dx = 0, $dy = 0, $iSpeed = 333, $sFont = "MV Boli") If @AutoItX64 = 0 Then Local $binSIDSound = _Chip_Sound() _SIDStartup() _SIDOpen($binSIDSound) EndIf Local Const $iWh = $iW / 2, $iHh = $iH / 2, $sTitle = "GDI+ About Window" Local Const $fPi = ACos(-1), $fRad = $fPi / 180, $fDeg = 180 / $fPi #Region text Local $sText = _ " WebP Advanced Encoder GUI ²" & _ " " & $ver & " beta " & _ " " & $build & " " & _ " " & _ " Coded by UEZ ;-) " & _ " " & _ "Credits to: " & _ " " & _ "* Google for the WebP API " & _ " and static libraries " & _ "* wakillon for TichySID " & _ " and Stat-Mat for the DLL " & _ "* Soren Lund for SID Tune " & _ "* Ward for Mem call code " & _ " " & _ "-------------------------- " & _ " " & _ "Greetings fly out to: " & _ " " & _ " All Autoit users " & _ " around the globe " & _ " " & _ " " & _ " Press ESC to exit. " & _ " " & _ " " & _ "-------------------------- " & _ " " & _ "NO ..--+++--.. WAR " & _ " .-' | `-. " & _ " +' | `+ " & _ " ' | ` " & _ " ' | ` " & _ ": | : " & _ ": +'|`+ : " & _ ". +' | `+ ; " & _ " + +' | `+ + " & _ " `. +' | `+ .' " & _ " `._ | _.' " & _ "Peace `--.._|_..--' :-) " #EndRegion $bExit = False $hGUI_About = GUICreate($sTitle, $iW, $iH, 0, 0, $WS_POPUP, $WS_EX_NOPARENTNOTIFY, $hGUI) _WinAPI_SetParent($hGUI_About, $hGUI) WinSetTrans($hGUI_About, "", 0xD8) GUISetState(@SW_SHOWNA, $hGUI_About) ;create canvas elements Local Const $hDC = _WinAPI_GetDC($hGUI_About) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) _GDIPlus_GraphicsSetSmoothingMode($hCanvas, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetPixelOffsetMode($hCanvas, $GDIP_PIXELOFFSETMODE_HIGHQUALITY) Local Const $hBrush_Clr = _GDIPlus_HatchBrushCreate(18, 0xF0B0B0E0, 0xF0F0F0FF), _ $hBrush_FPS = _GDIPlus_BrushCreateSolid(0xF0808080), _ $hFormat_FPS = _GDIPlus_StringFormatCreate(), _ $hFamily_FPS = _GDIPlus_FontFamilyCreate("Arial"), _ $hFont_FPS = _GDIPlus_FontCreate($hFamily_FPS, 8), _ $tLayout_FPS = _GDIPlus_RectFCreate(0, 0, 100, 24) $iFPS = 0 GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit_About") Local $iLen = StringLen($sText), $iColums = StringInStr($sText, "²"), $i, $u, $s, $r, $iChar_Space, $x, $y, $t = 0, $f, $b = 0, $a = 512, $iCharCol = 0x101030 $sText = StringReplace($sText, "²", " ") Local $aChars = StringSplit($sText, "", 2) Local $hFormat_char = _GDIPlus_StringFormatCreate(), $hFamily_char = _GDIPlus_FontFamilyCreate($sFont), $hFont_char = _GDIPlus_FontCreate($hFamily_char, $iFontsize, 1), _ $tLayout_char = _GDIPlus_RectFCreate(), $hBrush_char = _GDIPlus_BrushCreateSolid(0xFF000000 + $iCharCol) Local Const $iMilliSeconds = 5 AdlibRegister("CalcFPS", 1000) Do DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush_Clr, "float", 0, "float", 0, "float", $iW, "float", $iH) ;erase canvas background For $i = 0 To UBound($aChars) - 1 If $aChars[$i] <> " " Then $f = $t - $i / $iSpeed $s = $f > 2 ? 2 : $f $s = $s > 0 ? $s : 0 $r = (2 - $s) * $iColums * $iColums $iChar_Space = $s / 5.1 * $iColums $tLayout_char.x = $dx + $r / 2 * Sin($t + $i) + Mod($i, $iColums) * $iChar_Space $tLayout_char.y = $dy + $r / 3 * Cos($t + $i) + Int($i / $iColums) * $iChar_Space * 1.3333 DllCall($__g_hGDIPDll, "int", "GdipDrawString", "handle", $hCanvas, "wstr", $aChars[$i], "int", -1, "handle", $hFont_char, "struct*", $tLayout_char, "handle", $tLayout_char, "handle", $hBrush_char) EndIf Next $t += 0.025 DllCall($__g_hGDIPDll, "int", "GdipDrawString", "handle", $hCanvas, "wstr", "FPS: " & $iShowFPS, "int", -1, "handle", $hFont_FPS, "struct*", $tLayout_FPS, "handle", $hFormat_FPS, "handle", $hBrush_FPS) DllCall("gdi32.dll", "bool", "BitBlt", "handle", $hDC, "int", 0, "int", 0, "int", $iW, "int", $iH, "handle", $hDC_backbuffer, "int", 0, "int", 0, "dword", $SRCCOPY) $iFPS += 1 If $bExit Then ExitLoop If $r = 0 Then $b = 1 If $b Then $a -= 5 If $a < 256 Then DllCall($__g_hGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBrush_char, "dword", BitShift(Max(0, $a), -24) + $iCharCol) If $a <= -50 Then $b = 0 $a = 384 DllCall($__g_hGDIPDll, "int", "GdipSetSolidFillColor", "handle", $hBrush_char, "dword", 0xFF000000 + $iCharCol) $t = 0 EndIf EndIf DllCall($_KERNEL32DLL, "dword", "SleepEx", "dword", $iMilliSeconds, "bool", True) Until False AdlibUnRegister("CalcFPS") ;release resources _GDIPlus_FontDispose($hFont_char) _GDIPlus_FontFamilyDispose($hFamily_char) _GDIPlus_StringFormatDispose($hFormat_char) _GDIPlus_BrushDispose($hBrush_char) _GDIPlus_FontDispose($hFont_FPS) _GDIPlus_FontFamilyDispose($hFamily_FPS) _GDIPlus_StringFormatDispose($hFormat_FPS) _GDIPlus_BrushDispose($hBrush_Clr) _GDIPlus_BrushDispose($hBrush_FPS) _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($hGUI_About, $hDC) GUIDelete($hGUI_About) If @AutoItX64 = 0 Then _SIDStop() _SIDClose() _SIDShutdown() $binSIDSound = 0 EndIf EndFunc ;==>GDIPlus_About Func _Exit_About() $bExit = True EndFunc ;==>_Exit_About Func CalcFPS() ;display FPS $iShowFPS = $iFPS $iFPS = 0 EndFunc ;==>CalcFPS Func _GDIPlus_GraphicsGetDPIRatio($iDPIDef = 96) Local $hGfx = _GDIPlus_GraphicsCreateFromHWND(0) If @error Then Return SetError(1, @extended, 0) Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetDpiX", "handle", $hGfx, "float*", 0) If @error Then Return SetError(2, @extended, 0) Local $iDPI = $aResult[2] _GDIPlus_GraphicsDispose($hGfx) Local $aResults[2] = [$iDPIDef / $iDPI, $iDPI / $iDPIDef] Return $aResults EndFunc ;==>_GDIPlus_GraphicsGetDPIRatio Func _WinAPI_GetDpiForMonitor($dpiType = $MDT_DEFAULT, $iDPIDef = 96) Local $aMonitors = _WinAPI_EnumDisplayMonitors() Local $x, $y Local $aRet = DllCall("Shcore.dll", "long", "GetDpiForMonitor", "long", $aMonitors[1][0], "int", $dpiType, "uint*", $x, "uint*", $y) If @error Or Not IsArray($aRet) Then Return SetError(1, 0, 0) Local $aDPI[2] = [$iDPIDef / $aRet[3], $aRet[3] / $iDPIDef] Return $aDPI EndFunc ;==>_WinAPI_GetDpiForMonitor Func _WinAPI_SetDPIAwareness($hGUI = 0) Switch @OSBuild Case 6000 To 9199 If Not DllCall("user32.dll", "bool", "SetProcessDPIAware") Then Return SetError(1, 0, 0) Return 1 Case 9200 To 13999 _WinAPI_SetProcessDpiAwareness($PROCESS_PER_MONITOR_DPI_AWARE) If @error Then Return SetError(1, 0, 0) Return 1 Case @OSBuild > 13999 #cs Context_Unaware = ((DPI_AWARENESS_CONTEXT)(-1)), Context_SystemAware = ((DPI_AWARENESS_CONTEXT)(-2)), Context_PerMonitorAware = ((DPI_AWARENESS_CONTEXT)(-3)), Context_PerMonitorAwareV2 = ((DPI_AWARENESS_CONTEXT)(-4)), Context_UnawareGdiScaled = ((DPI_AWARENESS_CONTEXT)(-5)) #ce _WinAPI_SetProcessDpiAwarenessContext($Context_PerMonitorAwareV2, $hGUI) If @error Then Return SetError(3, @error, 0) Return 1 EndSwitch Return -1 EndFunc ;==>_WinAPI_SetDPIAwareness Func _WinAPI_SetProcessDpiAwareness($DPIAware) ;https://docs.microsoft.com/en-us/windows/desktop/api/shellscalingapi/nf-shellscalingapi-setprocessdpiawareness DllCall("Shcore.dll", "long", "SetProcessDpiAwareness", "int", $DPIAware) If @error Then Return SetError(1, 0, 0) Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwareness ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext Func _WinAPI_SetProcessDpiAwarenessContext($DPIAwareContext = $Context_PerMonitorAware, $hGUI = 0, $iMode = 1) ;https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setprocessdpiawarenesscontext $DPIAwareContext = ($DPIAwareContext < -5) ? -5 : ($DPIAwareContext > -1) ? -1 : $DPIAwareContext $iMode = ($iMode < 1) ? 1 : ($iMode > 3) ? 3 : $iMode Switch $iMode Case 1 Local $hDC = _WinAPI_GetDC($hGUI) Local $aResult1 = DllCall("user32.dll", "ptr", "GetDpiFromDpiAwarenessContext", "ptr", $hDC) If @error Or Not IsArray($aResult1) Then Return SetError(11, 0, 0) _WinAPI_ReleaseDC(0, $hDC) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult1[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(12, 0, 0) Case 2 ;~ If Not $hGUI Then $hGUI = WinGetHandle(AutoItWinGetTitle()) Local $aResult2 = DllCall("user32.dll", "int", "GetWindowDpiAwarenessContext", "ptr", $hGUI) If @error Or Not IsArray($aResult2) Then Return SetError(21, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetProcessDpiAwarenessContext", "int", $aResult2[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(22, 0, 0) Case 3 Local $aResult31 = DllCall("user32.dll", "ptr", "GetThreadDpiAwarenessContext") If @error Or Not IsArray($aResult31) Then Return SetError(31, 0, 0) Local $aResult32 = DllCall("user32.dll", "ptr", "GetAwarenessFromDpiAwarenessContext", "ptr", $aResult31[0]) If @error Or Not IsArray($aResult32) Then Return SetError(32, 0, 0) Local $aResult = DllCall("user32.dll", "Bool", "SetThreadDpiAwarenessContext", "int", $aResult32[0] + $DPIAwareContext) If @error Or Not IsArray($aResult) Then Return SetError(33, 0, 0) EndSwitch Return 1 EndFunc ;==>_WinAPI_SetProcessDpiAwarenessContext ;Code below was generated by: 'File to Base64 String' Code Generator v1.20 Build 2020-06-05 Func _Chip_Sound($bSaveBinary = False, $sSavePath = @ScriptDir) Local $Chip_Sound $Chip_Sound &= 'UFNJRAACAHwAABAAEAMAAQABAAAAAENvbW1vZG9yZSA2NAAAAAAAAAAAAAAAAAAAAAAAAAAAU/hyZW4gTHVuZCAoSmVmZikAAAAAAAAAAAAAAAAAAAAyMDA0IFZpcnV6L0NhbWVsb3QAAAAAAAAAAAAAAAAAAAAUAAAAAAAQTH0RTOoRTA0SrZaJkpWarS0oAykgCgUGBi8WCRIVGi0BAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFic4S19ziqG61PAOLU5xlr3nE0J0qeAbWpviLHvOJ4XoUcE3tDfEV/WcTgnQo4JuaG6Ir+s5nBOhRgTc0NwQXtZyOCZCjAi4oLggvKzkcEyEGBBwQHBAeFjI4JgIMCAuAQEBAQEBAQEBAQECAgICAgICAwMDAwMEBAQEBQUFBgYGBwcICAkJCgoLDA0NDg8QERITFBUXGBobHR8gIiQnKSsuMTQ3Oj5BRUlOUldcYmhudXyDi5Ocpa+5xNDd6vj9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzRkAAAAAACAaAAAAAABlGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqKkPjfMRuSUQCqq9BheNexG9BxeNfBG5KRCNIxCtJBCNMhaNZxK5LRCNTxG5MRCNVhG5NRCNXRGiACDBEaIHIMERog6pAZ0+EZ05EZ1lEakCnQ8RqQSdEhGpAJ04EZ0TEZ1NEZ08ESAtEkxcFKX7SKX8SKkACQCNGNSiDiCpE6IHIKkTogAgqRNohfxohftgpftIpfxIog4gJRKiByAlEqIAICUSTAYSvTsR8OJMyhSp/506EZ0lEbwTEbmWGJ1jEbm2GJ0QEakAnSMRnRQRnTsRnSgRnSkRuTYZnScRuVYZnSYRqQOdEhHgANAZuRYZjRfU' $Chip_Sound &= 'ufYYKfCN8RG51hiNaBGpAI1vEb04EcnA8CO5dhidBtSdPxC5VhidBdSdPhCpCZ0E1L1NEZ1OEakAnTgRYLxiEbmwGZ0G1J0/ELmTGUyWEqn/nToRTEMTKR+dDhH+PBHITC4T8OrJ/fAhsGipA50SEamAnSURjHoRvBMRuTYZnScRuVYZnSYRrHoR/jwRyEwuEyl/nRMR/jwRyEwuE71mEZ0PEb0+EdAJIMoUvU0RnU4RvTkQhfu9OhCF/Lw8EbH7yfuwn8mwsE/JgLDFyWCwh50kEf48Eb0OEZ05Ecix+8n/0Aj+TxGpAJ08Eb0+EdAQvTgRyRDwJ8kg8C/JUPBKYEwtEr0PEfCVyQLwCJADTMoUTJYUTCEU/jwRyEwuE71iEZ0lEakAnTgRYLxiEbmTGZ1jEakAnTgRYN4PEb05EfDCvQ8R8BhMyhS8YhG5sBmdPxC5kxmdPhCpAJ04EWC9ZRFJAZ1lEai5exGdDxHeORFMyhTwEsn+8AmpAJ0+EchMOxSp/p06EakAnT4RTEUUyMmwkDeMehE46bCdYhGouXYZnTgRMAWpAJ0+Eax6EUw7FLw8EfA2qf+dOhGdPhG9ORCF+706EIX8vDwRsfvJ+7CiyWCwur0+EfAPqf6dOhGpAJ0/EKn/nT4QTMoUvVARhfu9URGF/LxPEbH7MBmoua0anTkQuccanToQTCYUsfudTxGoTGkUyMn/8PIpf51NEf5PEUxpFL1lEUkBnWURqLl7EZ1mESDKFL04EclA0BSpAJ0SEZ0oEZ0pEZ04Eb1iEZ09EWDeFBFMCBWpAZ07Eb0UEdDwvBMRufYYKQ+dFBG8YxG5DhfJ/vAfkAyYOPl2F51jEahM4hSdZxEp9509ELl2F51kEf5jEbwlETATvSYRGHmwGZ0mEb0nEXmTGZ0nEb1nESkI0Dq9JBEYfU4RfWQRhfuouU4QGH0mEY14EbmuEH0nEY15Eb0SEfAryQLwJJBirXgRnQDUrXkRnQHU' $Chip_Sound &= 'TDEWvSYRnQDUvWQRGH0nEZ0B1EwxFkz0FaT7uU8QOPlOEIX7ua8Q+a4Qhfy8PRG5kxlKaQCdIxG5sBnwCaiIRvxm+4gQ+f4SEaX7nVIRpfydUxFMMRa9KBEYfVIRnSgRvSkRfVMRnSkRrXgRGH0oEZ0A1K15EX0pEZ0B1L0jEd4jEdBPvD0RuZMZGGkBnSMR/hIRTDEWvSgROP1SEZ0oEb0pEf1TEZ0pEa14ERh9KBGdANSteRF9KRGdAdS9IxHeIxHQD7w9EbmTGRhpAZ0jEd4SEeAA0FisaBHwU7kOGNAbuSAYjXYRjRbUuUQY8ECNaBGouQ4YjXcRTI0WrGgR8C65IBgYbW8RjW8RuTIYbXYRjXYRjRbUuQ4YzXcRzncR0A25RBiNaBGouQ4YjXcRvBAR8F653hfQI7nqF508EJ0D1CnwnTsQnQLUuQIY8EOdEBGoud4XnRERTPAWvBAR8DG56hcYfTsQnTsQnQLUufYXfTwQnTwQnQPUud4X3RER3hER0A25AhidEBGoud4XnRERvT8QnQbUvT4QnQXUvT0QPToRnQTUYAQE////////Cf5B/okZGRkYGP6JSYiIiP+JGfn4/kFBQUERERER/0FBQUERERER/0FBQUERERER/0FBQUERERER/0FBQUERERER/4n+Ef4RQf4T/hkZGRkZGRn+if4T/hP+iRkZGBgYGBgY/xH+Ff4AAAAAzwkHBgQDAM8NVFBUApgeHh4AAAAAAAAAAAAIAAMHDAADBwwIAAUIDAAFCAwIAAUJDAAFCQwIAAUKDAAFCgwIzwAAAAAAABgAEAcGBQQEAwDPAAwADAAyDQkHBgUEBAQIAAAAAAAAEBAAADAwABAgIAAEQMAIBiDgBhAQ8AAAAP8AAAD/AAAA/wACAwIABgcGCQoLCgAABwAAAAcAMACAgACAgIAAAACwANzAqAAQgFCgYIjAgIB4aAAA6AAAAOwABAAA/wD//wAAAAACAAICBgAI' $Chip_Sound &= 'AAoLCg0ODw4KCgAHBwcNBgkAAQcBAQEBtwECxwYHAcYGDQDhwQSnBgMFd4eHh/W3tSMldzs7OztzRTZze41FfWv1JUVDaXWZNVUAAgICBAsFERYCHygxOkMWC0VHRxZKR0wWFlRWWFpkZgABAQEABAAABAQFBQUFAAQEAAgIBAQIAAQEBAAAAAAAAAEDBAAAAAAJBQAAAAAHCQAHEQwRDBAAERERAAAAAAAQEBAQAAAAADAQAgICAhAwABAwMDAwMAAwMDAAAAAAAPHx8fEAAAAA8/EAAAAA8fMA8fPz8/PzAPPz8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAMDAwEDAQBBAQFAQEFBQEBAQEBAQEBAQwBAQEBAQzNzsBQAIAAgI1P8A5AEA/5AwqKCQgPuw+gD++hzKysoCXwUIAwRN+BBLRTD4AAAAAACAABiAgCAAAAkNBAQEBAQEBAQEBAQEBAQEBgYGDwYGBg8GBgYPBgYGDwEBBwgBAQcIAQEHCAEBBwgGBgYPBgYGDwYGBg8GBgYPBgYGDwYGBg8QExUTEBMVE/8BCowDBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBIAFBQUFGBmMAwQEBAQEBAQEBAQEBAQEBIARFBYUERQWFP8BCwIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDAIMAgwCDIwXFxcXEgQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBP8B4eQBGz1fkK3K5+vy+RQ2WHWeyuz8Ez1qi74aGhsbGxsbGxsbGxsbHBwcHBwcHBwdHR0dHW/+/4JgD7Ni+4FgG7Ni+7BgD7P7iWEbsWAPs/u0G/v/hGEA/gD+hQD+hwD+AIYAhAD+hQD+hwCGAP+IYCf8LPwi/Cf8Lvwi/Cn8Lvwl/Cn8Kvwl/Cf8Kvws' $Chip_Sound &= '/Cf//GAn/Cz8Ivwn/C78Ivwp/C78Jfwp/Cr8Jfwn/Cr8LPwn/4pgM7X7Y/5gM7X7Y/6LYDW1Yvtv/oxgMbX7Y/5gMbX7Y/6NYDW1+2P+i2A1tftr/v+CYA2zYvuBYA+zYvuwYA+z+4lhG7FgD7P7tBv7/4JgErNi+4FgHrNi+7BgErP7iWEesWASs/u0Hvv/gmAWs2L7gWAis2L7sGAWs/uJYSKxYBaz+7Qi+/+OZwD/kWAMtmb7/2H+hgD+AP+EYQD+AP6FAP6HAP4AhgCEAP6FAIYAhwCGAP+PYCf8LPwi/Cf8Lvwi/Cn8Lvwl/Cn8Kvwl/Cf8Kvws/Cf/iGAn/Cz8Ivwn/C78Ivwp/C78Jfwp/Cr8Jfwn/Cr8LPwn/4JgErNi+4FgFLNi+7BgFLP7iWEgsWAUs/u0IPv/kmAnt2L7Y/5gI7di+2P+YCK3Yvtj/mAet2L7Y/6TYBu3avty/rlg/v+bYDG+YvuSYCe3Yvtj/mAjt2L7Y/5gIrdi+2P+YB63Yvtj/pNgG7dy+2f+/5lgJ/ws/CL8J/wu/CL8Kfwu/CX8Kfwq/CX8J/wq/Cy9J//8YA+4aPt1/mv7vGP7b/7/l2MAZ/6VYAq6bvtr/rtn/rxj/pprAP+SYCe3Yvtj/mAjt2L7Y/6WYC63Yvtj/mAqt2L7Y/6TYCe3avty/rlg/v+bYCe+YvuSYCe3Yvtj/mAjt2L7Y/6WYC63Yvtj/mAqt2L7Y/6TYCe3cvtn/v+XYQCYYCL8J/wu/CL8KfwulwD8+5gq/CX8J/wq/Cz8J/+eYBjAYvvBY/vC+8Nn+8Rj+8X7xvtgSshi+8dgSsj+Sshi+8dgSsj+nxvJavvKYD9m+/+eYBjAYvvBY/vC+8Nn+8Rj+8X7y2H7zPtgSshi+8dgSsj+Sshi+8dgSsj+nz/KYvuXYwCHYQCQYwAAhWEA/w==' Local $bString = _WinAPI_Base64Decode($Chip_Sound) If @error Then Return SetError(1, 0, 0) $bString = Binary($bString) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\Commodore_64.sid", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_Chip_Sound Func _WebP_Icon($bSaveBinary = False, $sSavePath = @ScriptDir) Local $WebP_Icon $WebP_Icon &= 'iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAAlC+aJAAAMkElEQVR4XsRZe3BU1Rn/vnPvPpNsdsnCIgkkFogoElIpFAMZmUIC5SVpBcb6ACMNFAYUi5RRKUgFNWTEDgyKBEHoA4y1ZkKxHQYspfJ0SpGEplIeCXntJvtIsu+993yF3EDGMs3eO67hd3fuP/fuOb/f9zrfOReoV8TkGBFdrwvo7oXFi5bNmjN59pzJi55dZh4OX5y91P3CXQUDFeAxZu0HhSu8BUtbpyxu/eFz3nsyIRZWnsG3BM5VDR1HgMJPFA16PdizojZHxOaI9ssM2NLAZuvX9UiEbweMqTJub9MTkcKvualRFwJPS9DvFUHGtuZrDsz+5Usbc76b7XL7BCYAECQIBKBnzO1vnD+3qKAwX3FFL2KQiP7/UAgAH+4/WLx81urSSdljfX6PBMBMKfK16v6t7iudkXpZAkBIJAhQAMbg/Q2wY/PvSn72uGJKRNTmAYXXwgUlVWd2vvVRvn1wm68FqCvkIkHMGtU0wpQmiiMQdZBwyLIhhRcUmJbM/8lXl2vLyl5FRMWgGjzQ7pbuy7XlTPEvWTM1xp3tLgmRKVYgAg5AMgEov8QDiawOUcB7X11emWWaWXWwSlsI/any2MyiSau35+RPT/W6vEE/CIwBQl+Cc56UKpstmTs2/vnqqfR/X2gApq4KbXht3cySSeXHZk6Yamxp8ISDIAgK+z4FQ+bvEPzuhqVr8yY/rcM0vC0sjoDz5y6/VGrIyPY1XvODxBAZ3BUgCMCCIfC6PHOL80w2CHR0S4iTxGajJRiJ+L2AwABRaw0hIFkmYARArHs2BI6CgAgIqFEDsWgUwoGYyQACqQshOcaVhUQrdZk4gKxPIvvA1IzMjKx778scmn3jnpGZbh9o0Rm5DDIRAWn3BUMJIBBUV0Y5cgEAuDarA+MWq85i6e9ri507faK6JtpcD6EQGAyQPgRG5/YbOXpMmiPs8/hC' $WebP_Icon &= 'fo7EtLm2Kwdlla3ErSQhVeS72OuMNGCw0dtsWb/icPG0v54/MCfPWr6m6ERZyZevzD0zod+e0/smPvHI4Z2bjwu8v/0eEZhMRNpWNwBB5UKGIAOqEaBo5EYzmFNNn+xq+KCsee+2yic/mX0HgbGrX15AEqxZ89oTBWvLduUNzY21NQVJFjT5QVYpADip84Bie0hOTd31+ilXTS4PNn2tl+yJQoExRBHeLHvlyaefyhmbtWHXw6MmiK3XZdISS8hV5gAQMHVtF+NWh/HjnTXuf33vzOlTt6mzLvxPfHIuMSaOyslsvNyZnpmypXLy4Gy32ykhqVtkUH07zTlTU3OAW+y6+mrTR1t9J0+e6qJIvbTBjHUba1BG8hcnL61aeCQcSDOZmYaqpDaJ1VlfFMmkc2ze+PeKvcdvUURQhzHjhr24cPOBXUes9jQOHCihAgAkiAdOPNmqq73QZPYOm/HoRPUbKCWWuhqWVYf3Q9BrNBiBgBLqAY7I4hYfSklK/7Tyws+Xl2rZQPXEks4IeblFF2vOJqdYZDmhAhB5fBICJzSdPwPTp83qNqoWKNny6NTHzp5oMyWlAeMJ9YAMDIDiJACGA52xTsj4jtgzjsaaPnb8xNpqEJiZJTaEAHgcBQAoYDTiN2mhfWedGOQYEPADESSiCmkHIcE3Q0zijAHDuyGAZDLokqPyN5q14XqjNQ34XRHAZTKaU3gyOOvvWDxUF6Ljnx99MAfkmJero8ExQQLwpvcZYnjMOKg6WNlNSDv2V24dPyHbH2hDlTR4ojyAN6/OQOOMopxNb6/o6d7UQZZlAKi92Hw9UDN85NBQR1TT5oAnQICy4/ZIw0fb9Rn1v/ngkPqFjHMuCAIALFn8zKLnHRy80Qgg9nkOIILEIeT3vLCu8KnFM5wtYZXsFZ179vyxLvqX/KmjvW1+xtjdKaMCsA6f1H+Ic+22ccOyTeEQKJC4xDm/k7pMssL1s6Pnnln+o3VbCkORhmgUEFAt' $WebP_Icon &= '03j7Ae2ZQMzdLD1UICx9/QGTDU8fqxn3/QdEJn4tK9jN67aZd773YcmL89/5eHKy3eVpZgIySGQZ1R5IJDFPY+ThGeay3094ZN7IeUXFdVc7uodWcGuKz49fzM0dW7pv/vufFtoz3d4WiWlmr84DpE0DyhJrbQhlPSjtOzTlSFXFiCm7B4kDfpC38P77c62WNKer/h//PPHZmd2GgVD8/IiH8gtDwRu2186eA5A6AaIgAiodkVoNxIW2ZsloaJk2b9T0uba6q0211aVHr0HwP2CzwdDpMG3V+AHpaVLE7W1tjEVRW+RwAiSdrpssiyugtaNplJhqSmHUzEHdTKgcoUWopb5Dr++w9RemzMgXdUmIJs5D0Yg/FGx31nfKMjDGBC3ncwQkGMBkFoMhCAR9AFbOgbFeT6e3vrN95cZlvz00G3V1Ppes1ddEwImoy2y3IhJRQIW3JhARityRkfS3yvDba7+MeghZdy2Oc7z+6y3lv9jy092VMwXjZZ9LUDT0KRT2Ou5ITzlS4drxqyvtzaQ3qa5Cz61c9MbKd0t+fFCODrPaOScO1NfsRYX9AVf5piudToW9qg8cPT4qK92+/r1l5X+YheIljwsRsc/4i3pwZFiOVLTeYO9rItEAmr7Q9GgofXPbG+XLdx98LMkejvkRBAFUA5W71u9QxJGR0QRVey+9u7623amwjyegFw2bNm55+a0Xpj8OnZ2AGrM5FAYZQKcDowCAav9l1IOzFb46CR11pDMCgAoBvWuoqKj0e0kUjJw0KNDr9UOGZBoNBqfT6WptQyR1AmRR1Hnbry14ttiSosLh/23WykIiPYJw51hcFEVBnxJ8MGBMBkREQV8EQfDFAw+8yGpAjSJhxYcIRiIS3VVXMt6Yw8iIJDMGIXFEFBFFxRtR8+D14C0Rx2tcD8Z18+djC8o//Q+T2SwLFtJUfVNd/1/VVdXd8itvky6eX3eZupW3SbQCb/TZAhU32WF9fILAP01OToaH' $WebP_Icon &= 'h9/c3DxAMrHmm39twPejFy/kL06AOA8ywRSBxLBL8/Pz4OHA7e0tG3GS+PWY5wcR/f8UQpi1oF0HFhYWnJ/+Wr6RA0p3t5ymGxsbg4ODEri+vj4zM6M1tLKyAnx7e1vyjR3ARBKhs7i4eHZ25sBnia6vrycmJtQLfnBwoFYQrq6ueMbU1BQEm82G8Tn65Suqq6uDiHVXh/Py8pIn+/v7SwlpMBjYNE+B2dXVVbWau7u7k8vr4eEBffJQbSExMZEURHNzM+TCwkKebDQagYSGhnp5eTG4v78vdS0SIyMjr66uIPb19RHS1tYm6cAOxsrKyq2trdbWVgJxtb8Lv01ZX/6LRW0IYmJiMGZlZWEBS0pKCIyOjoaCYM94TkBAAMTAwEA1WF1dDbGsrIzEhoYGbRfu7+/XOhkSEoJxd3eXwbm5OVIbHx8npO634kc/iPKuT7N/FF//8uE3xk++NXzGFnx9fTHi1dnC0NAQEDIrIFOEjo+PeU5eXp7ZbAYzMjJCIP0vZG9vj0Rvb2+IJpOJjWqTnsXg4GBOaDX+RV4ueKtFyWoXzVMPvzNnzP05+cwcpx8XKT+JS+udZlBQkF0LNTU1AgIta1NTE/ilpSXwCBIppaWlUUbazZ+wsLDs7GxkUVRUVHx8fHJyMuGjo6NqNb1eL7Wd2NhY4Drdx6/cUh6bxJM/AhSiW+Xp7x88Ngrl5s5CVVWVFKmkpCRKk3ehkJmZiZGyore3l9edYoxxenqaaloq2aOjI9SGxWJBZ9jc3MT65Ofnt7e3R0REqNWoT7A/vEO97/KQLrv4e/DOR4LoPUjehDO5uLhIFigjrFar4FCRBmqXI41yIb6iogLM+fm5tAIoXEYclGBubi547nIgNzc34AUF+eDPLMqjn8XTEfHr8Pfnx0rHYPWzMZH+7xRKT0+XLPj4+AAvKioSEDiLcnJyMGZkZBC4trZGorZei4uLgaDHSQ4MDw8DRyNmB/z8/KS5Ozs7UhE3dZUU' $WebP_Icon &= 'dYoCg0jWiy8N4qtO1yedn7MFnU4nWTg9PSUL2H8EtgYqDqpdOrqoQ5iQkICxpaXF7i5bWloKXtuapMeDZmdngeClX+scKVSEzYTDyhburHh6emrtokB5/5L2y8PDQ2GPuJuxk2j/7BvTxcWFeuPSbs1SW6uvr5csoPygILg/nJycxMXFIQc40rR1p6Sk9PT0EKil5eVlbIVYh8bGRpwpJAX04tTUVOIRv9ra2vLy8oGBAefOOXJfRnNDk0DL6ejokA5z941kB8bGxv7722msAxF4B6D0K05KGJl3MJ01mXGS+F6BAzmbZQv3eQXkG4Xdi4RQ7jehbOCAgyP3P94Red6jcQCLAAAAAElFTkSuQmCC' Local $bString = _WinAPI_Base64Decode($WebP_Icon) If @error Then Return SetError(1, 0, 0) $bString = Binary($bString) If $bSaveBinary Then Local Const $hFile = FileOpen($sSavePath & "\WebP_logo_2010_64x64_Simo99.png", 18) If @error Then Return SetError(2, 0, $bString) FileWrite($hFile, $bString) FileClose($hFile) EndIf Return $bString EndFunc ;==>_WebP_Icon 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 #Region TichySID Func _SIDClose() Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDClose') If @error Then Return SetError(@error, 0, 0) Return $aRet[0] EndFunc ;==>_SIDClose Func _SIDOpen($Sid, $iSubsong = 1) Local $bSid If Not IsBinary($Sid) Then If Not FileExists($Sid) Then Return SetError(2, 0, 0) Local $hFileOpen = FileOpen($Sid, 0) If $hFileOpen = -1 Then Return SetError(-1, 0, 0) $bSid = FileRead($hFileOpen) FileClose($hFileOpen) Else $bSid = $Sid EndIf Local $tSid = DllStructCreate('byte[' & BinaryLen($bSid) & ']') DllStructSetData($tSid, 1, $bSid) Local $sType = BinaryToString(BinaryMid($bSid, 1, 4), 1) ConsoleWrite('-->-- Sid File Type : ' & $sType & @CRLF) Local $iVersion = Execute(BinaryMid($bSid, 5, 2)) ConsoleWrite('-->-- Sid File Version : ' & $iVersion & @CRLF) $iSubsongCount = Int(StringTrimLeft(BinaryMid($bSid, 15, 2), 2)) ConsoleWrite('-->-- SubsongCount : ' & $iSubsongCount & @CRLF) $iSubsong = $iSubsong - 1 If $iSubsong < 0 Then $iSubsong = 0 If $iSubsong > $iSubsongCount Then $iSubsong = 0 ConsoleWrite('-->-- Subsong : ' & $iSubsong & @CRLF) Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDOpen', 'ptr', DllStructGetPtr($tSid), 'int', DllStructGetSize($tSid), 'int', $SID_MEMORY, 'int', $SID_NON_DEFAULT, 'int', $iSubsong) If @error Then Return SetError(@error, 0, 0) $tSid = 0 $bSid = 0 Return $aRet[0] EndFunc ;==>_SIDOpen Func _SIDShutdown() MemoryDllClose($hTitchysidDll) $hTitchysidDll = 0 EndFunc ;==>_SIDShutdown Func _SIDStartup() $hTitchysidDll = MemoryDllOpen(TitchySIDdll()) If $hTitchysidDll = -1 Then Return SetError(1, 0, 0) Return SetError(0, 0, $hTitchysidDll) EndFunc ;==>_SIDStartup Func _SIDStop() Local $aRet = MemoryDllCall($hTitchysidDll, 'int', 'SIDStop') If @error Then Return SetError(@error, 0, 0) Return $aRet[0] EndFunc ;==>_SIDStop Func TitchySIDdll() ;only x86 :-( Local $sFileBin = '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' $sFileBin &= 'vrlCABCKRQAMiEYDM8CJRgAE/k4HZotNCIBmiU4IUOjoAFAIUOjiAArrBeh/AQCYZoN+CAF39CBeycIIAAB6g8QA/FZXi3UIi30ADA+2RgeIRf8AD7cEMGaJB6MAy0IBEA+3RgpIZsHAAEtHAgALDIUECwQAKg+IRwYABgARiEcHD7cHBQLDAIMPtlX/g8IAAgPyi00QK8oAZolPCFBRv8MBAEaJTwSDPwB0wAj/dwToXgDVAAclAMNOAAmJBwAL/zcIVuhbAAZZWFFQGFboUYAEgEZmg38ABAB1GWoAg+wAAmb/dwLoEf+BgIS3BddFABABQQGAWWoYWYPGFoMQxwrzpYCFwgwAAP8lADAAEP8lmgSAAswKAIGTV/yDc0GATsHpAvOlgAODMOED86SDHYsXVlcAvndDARCL/oEAx+QGAAC4yA0AAAD3ZssD+P8ARsuDfssQdQUlAbXLhE62XYBN6HAA/v//aHIDAAAAVugt8v//M9IA6xFmiw5miQ8BgIQCg8YCg8cECEKB+gEQcudfXg0D3dCAjoEkclBQUABo8EEAEGr/jQBGblDomAIAAADHRnqA3AAAgwSOioFMx0Z2W0qAARBqDI+GhsADAGogjUZ2UP92SG7oeYAK6EwAIIOgfnIAdfUHBngABgj+hqSBlT5qBI9khpaBDQyNwgECCC0RAAiLhpqAAzPSuQFCOPGD4A85RnIQdAfo+wAz6wdqAAXo9gEAAIC+oqIACQB0uUEND0ANLQcZDUADwQHbgAlqACzoqoABgFMEgZZWVyK/gTeAv6MCDwXoAotBdnUIgH0QAEB1I1dqClYADH9RAAyL+FdAAntBAvAFQQJ9QAKJRQxf6AR+94A1dQxXVugAUv3//4pFGPYARRQBdAWKRwdg/siIh6XBMUWH8xD8//9qQCBqAGgs8x2AUQEjF8ERR2oAC8B0DmoPUOgyIIAD/ocBI0F8FAAJQ1/+hsE2av//dlhq6BBACMEB2IFEwPKJQgZew8MJhzzCEcJVi8UGQQX4QevN9v8AaiJywTuAvqaBAXUHIsaCCgCKhscrdgJk6EPAK+iWQDVDbV7Qw/81PgBO6IEEZQEGq2EBDyk2ikUIOgBHBnQuPAByKkkAAXMlYyH+hyEO6JJpYCb+j0EBgL8iDw0gLzlgAoEeBADM/1QlCGJkDKIAEKIAFFWiABiiAByiACCiACRVogAoogAwogA0ogA4VaIAPKIAQKIARKIASPWiAEyiAFCgAKEPHwAfAH8fAB8AHwAfAB8AHwATAPQAMAAAAjEAAB5VYAAsYAA8YABKYABaVWAAamAAfmAAkGAAmKtgAAEAruAAvmAA1GAACuJgAPJgAAoyAABqGmAALGAARmAACQCcW+ALBQAQYQjgAcxoAlY/4AUgPH8TfxN/E2QTpQEAR2xvYmFsQWwgbG9jAKykAUZyAGVlAABrZXJuAGVsMzIuZGxsAAAAIwBDbG9zAGVIYW5kbGUAAFYAQ3JlYXRlFFRowABkYBsARXgEaXSlAcAARmluAGRSZXNvdXJjAGVBAO8BTG9hgeYBAACpAlNlhAUAUHJpb3JpdHkAALYCU2l6ZW8CZqcEtwJTbGVlAnDg71dhaXRGbwByU2luZ2xlTwBiamVjdAC2AIB3YXZlT3V0whIIAAC/5QFHZXRQAG9zaXRpb24ABADCpQJPcGVuAKLDpQFQYXVhBsTmAYByZXBhcmVIAAkaZZBDxXUBwAhldABEAMb4AHRhchABylEVAVVucLsDy5UBV4NgDTAGd2lubW0jFNFxHO0oVXEAzvAXIExUAAc0AIjwAKQwAMAFMRog8EIfAADRHqswH7AAnLAADnAAuHAAqtzwAeowAPMwAPswAKAEMwAADDAAFjAAAREFAgADAAQABQAABgB0aXRjaBB5c2lksgdTSUQAQ2hhbmdlU2/8bmfSAFITgACCEXAAIxExgQBsYXlxALAOdW3hEgFTdG9wLykPAA8A/w8ADwAPAA8ADwAPAA8ADwAbDwAIAGcAGWAWAKSTgAIAh7kAAD1gkgB+PgAA2CcAAAT8GjA3FgAA+BKAAAAlDwAAFACJqgpQhOYwA4UwAIJwAwOxlOE3pKZtPLEeAFsU+gzKCD4HAC4G7wT7Af0AgJ4AfwAqABkAWQAUJzg4OCcuOFYTMABxAAT0AAh0ABYAJTg4KiUzOBerMABxAAXwADhwAAl0AIQYJnAAJi84EjAAKhUwAAb0AAx0ABk1oXAANTQ4IjAAFTAACgf0AA10ADgPODiAEQ8QOB84I3IAIgD0ACQPGrIBLSsiLDIAISsdcgABKxEzAQ4rHnIAMjA4QTAAKDggMBtyAAIV8AA4cAAKdAAxNjhBMAApOBw2N3IAAxXwADhwAAt0AGvdMwDTi9kA0HrdTcDUK90d0WD8AP0BFfMADPYAaPYBRNUrStnwANj5ABHS+AHUT/IB/AD1HtEyRKywWLEuAjAzgHIgAGhwAQswABAwKTA/MEcwAHswjzClMBIxAFkxCTK8MvIyAIAzjTO+M/MzAA40XDShNCQ2AEo2dTadNqI2AKs2uDbINvI2AAc3Ejc9PJM8AME82jwqPUg9AE49kz34PQU+ACU+1z5MP3Y/sJ4/uj8ABkAmNGAAAgRwBiAwbDByMAB4MH4whDCKMACQMJYwnDCiMACoMK4wtDC6MIDAMMYwzDDSP2H/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ADwD/DwAPAA8ADwAPAA8ADwAPAP8PAA8ADwAPAA8ADwAPAA8A/w8ADwAPAA8ADwAPAA8ABAA=' $sFileBin = Binary(_WinAPI_Base64Decode($sFileBin)) $sFileBin = Binary(_LzntDecompress($sFileBin)) Return SetError(0, 0, $sFileBin) EndFunc ;==>TitchySIDdll Func _LzntDecompress($bBinary) $bBinary = Binary($bBinary) Local $tInput = DllStructCreate('byte[' & BinaryLen($bBinary) & ']') DllStructSetData($tInput, 1, $bBinary) Local $tBuffer = DllStructCreate('byte[' & 16 * DllStructGetSize($tInput) & ']') Local $a_Call = DllCall('ntdll.dll', 'int', 'RtlDecompressBuffer', 'ushort', 2, 'ptr', DllStructGetPtr($tBuffer), 'dword', DllStructGetSize($tBuffer), 'ptr', DllStructGetPtr($tInput), 'dword', DllStructGetSize($tInput), 'dword*', 0) If @error Or $a_Call[0] Then Return SetError(1, 0, '') Local $tOutput = DllStructCreate('byte[' & $a_Call[6] & ']', DllStructGetPtr($tBuffer)) Return SetError(0, 0, DllStructGetData($tOutput, 1)) EndFunc ;==>_LzntDecompress Func API_FreeLibrary($Module) Local $Ret = DllCall($_KERNEL32DLL, 'bool', 'FreeLibrary', 'handle', $Module) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_FreeLibrary Func API_GetProcAddress($Module, $Procname) If IsNumber($Procname) Then Local $Ret = DllCall($_KERNEL32DLL, 'ptr', 'GetProcAddress', 'handle', $Module, 'int', $Procname) Else Local $Ret = DllCall($_KERNEL32DLL, 'ptr', 'GetProcAddress', 'handle', $Module, 'str', $Procname) EndIf If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_GetProcAddress Func API_IsBadReadPtr($Ptr, $Len) Local $Ret = DllCall($_KERNEL32DLL, 'int', 'IsBadReadPtr', 'ptr', $Ptr, 'UINT_PTR', $Len) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_IsBadReadPtr Func API_LoadLibrary($Filename) Local $Ret = DllCall($_KERNEL32DLL, 'handle', 'LoadLibraryW', 'wstr', $Filename) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_LoadLibrary Func API_lstrlenA($Address) Local $Ret = DllCall($_KERNEL32DLL, 'int', 'lstrlenA', 'ptr', $Address) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_lstrlenA Func API_lstrlenW($Address) Local $Ret = DllCall($_KERNEL32DLL, 'int', 'lstrlenW', 'ptr', $Address) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_lstrlenW Func API_VirtualProtect($Address, $Size, $Protection) Local $Ret = DllCall($_KERNEL32DLL, 'bool', 'VirtualProtect', 'ptr', $Address, 'dword_ptr', $Size, 'dword', $Protection, 'dword*', 0) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_VirtualProtect Func API_ZeroMemory($Address, $Size) Local $Ret = DllCall($_KERNEL32DLL, 'none', 'RtlZeroMemory', 'ptr', $Address, 'dword_ptr', $Size) If @error Then Return SetError(@error, @extended, 0) Return $Ret[0] EndFunc ;==>API_ZeroMemory Func MemLib_BuildImportTable($CodeBase, $PEHeader) Local Const $IMAGE_DIRECTORY_ENTRY_IMPORT = 1 Local Const $SizeOfPtr = DllStructGetSize(DllStructCreate('ptr', 1)) Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY)) Local $ImportDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_IMPORT * $SizeOfDataDirectory Local $ImportDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $ImportDirectoryPtr) Local $ImportSize = DllStructGetData($ImportDirectory, 'Size') Local $ImportVirtualAddress = DllStructGetData($ImportDirectory, 'VirtualAddress') Local $SizeOfImportDir = DllStructGetSize(DllStructCreate($tagIMAGE_IMPORT_DESCRIPTOR)) Local $ImportList = '' If $ImportSize > 0 Then Local $ImportDescPtr = $CodeBase + $ImportVirtualAddress While 1 If API_IsBadReadPtr($ImportDescPtr, $SizeOfImportDir) Then ExitLoop Local $ImportDesc = DllStructCreate($tagIMAGE_IMPORT_DESCRIPTOR, $ImportDescPtr) Local $NameOffset = DllStructGetData($ImportDesc, 'Name') If $NameOffset = 0 Then ExitLoop Local $Name = Peek('str', $CodeBase + $NameOffset) Local $OriginalFirstThunk = DllStructGetData($ImportDesc, 'OriginalFirstThunk') Local $FirstThunk = DllStructGetData($ImportDesc, 'FirstThunk') Local $Handle = API_LoadLibrary($Name) If $Handle Then $ImportList &= $Handle & ',' Local $FuncRef = $CodeBase + $FirstThunk Local $ThunkRef = $CodeBase + $OriginalFirstThunk If $OriginalFirstThunk = 0 Then $ThunkRef = $FuncRef While 1 Local $Ref = Peek('ptr', $ThunkRef) If $Ref = 0 Then ExitLoop If BitAND(Peek('byte', $ThunkRef + $SizeOfPtr - 1), 0x80) Then Local $Ptr = API_GetProcAddress($Handle, BitAND($Ref, 0xffff)) Else Local $IMAGE_IMPORT_BY_NAME = DllStructCreate($tagIMAGE_IMPORT_BY_NAME, $CodeBase + $Ref) Local $NamePtr = DllStructGetPtr($IMAGE_IMPORT_BY_NAME, 2) Local $FuncName = Peek('str', $NamePtr) Local $Ptr = API_GetProcAddress($Handle, $FuncName) EndIf If $Ptr = 0 Then Return SetError(1, 0, False) Poke('ptr', $FuncRef, $Ptr) $ThunkRef += $SizeOfPtr $FuncRef += $SizeOfPtr WEnd Else Return SetError(1, 0, False) EndIf $ImportDescPtr += $SizeOfImportDir WEnd EndIf Return $ImportList EndFunc ;==>MemLib_BuildImportTable Func MemLib_CopySections($CodeBase, $PEHeader, $DllDataPtr) Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) Local $SizeOfFileHeader = DllStructGetPtr($IMAGE_NT_HEADER, 'Magic') - $PEHeader Local $SizeOfOptionalHeader = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfOptionalHeader') Local $NumberOfSections = DllStructGetData($IMAGE_NT_HEADER, 'NumberOfSections') Local $SectionAlignment = DllStructGetData($IMAGE_NT_HEADER, 'SectionAlignment') Local $SectionPtr = $PEHeader + $SizeOfFileHeader + $SizeOfOptionalHeader For $i = 1 To $NumberOfSections Local $Section = DllStructCreate($tagIMAGE_SECTION_HEADER, $SectionPtr) Local $VirtualAddress = DllStructGetData($Section, 'VirtualAddress') Local $SizeOfRawData = DllStructGetData($Section, 'SizeOfRawData') Local $PointerToRawData = DllStructGetData($Section, 'PointerToRawData') If $SizeOfRawData = 0 Then Local $Dest = _MemVirtualAlloc($CodeBase + $VirtualAddress, $SectionAlignment, $MEM_COMMIT, $PAGE_READWRITE) API_ZeroMemory($Dest, $SectionAlignment) Else Local $Dest = _MemVirtualAlloc($CodeBase + $VirtualAddress, $SizeOfRawData, $MEM_COMMIT, $PAGE_READWRITE) _MemMoveMemory($DllDataPtr + $PointerToRawData, $Dest, $SizeOfRawData) EndIf DllStructSetData($Section, 'VirtualSize', $Dest - $CodeBase) $SectionPtr += DllStructGetSize($Section) Next EndFunc ;==>MemLib_CopySections Func MemLib_FinalizeSections($CodeBase, $PEHeader) Local Const $IMAGE_SCN_MEM_EXECUTE = 0x20000000 Local Const $IMAGE_SCN_MEM_READ = 0x40000000 Local Const $IMAGE_SCN_MEM_WRITE = 0x80000000 Local Const $IMAGE_SCN_MEM_NOT_CACHED = 0x4000000 Local Const $IMAGE_SCN_CNT_INITIALIZED_DATA = 64 Local Const $IMAGE_SCN_CNT_UNINITIALIZED_DATA = 128 Local Const $PAGE_WRITECOPY = 0x0008 Local Const $PAGE_EXECUTE_WRITECOPY = 0x0080 Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) Local $SizeOfFileHeader = DllStructGetPtr($IMAGE_NT_HEADER, 'Magic') - $PEHeader Local $SizeOfOptionalHeader = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfOptionalHeader') Local $NumberOfSections = DllStructGetData($IMAGE_NT_HEADER, 'NumberOfSections') Local $SectionAlignment = DllStructGetData($IMAGE_NT_HEADER, 'SectionAlignment') Local $SectionPtr = $PEHeader + $SizeOfFileHeader + $SizeOfOptionalHeader For $i = 1 To $NumberOfSections Local $Section = DllStructCreate($tagIMAGE_SECTION_HEADER, $SectionPtr) Local $Characteristics = DllStructGetData($Section, 'Characteristics') Local $SizeOfRawData = DllStructGetData($Section, 'SizeOfRawData') Local $Executable = (BitAND($Characteristics, $IMAGE_SCN_MEM_EXECUTE) <> 0) Local $Readable = (BitAND($Characteristics, $IMAGE_SCN_MEM_READ) <> 0) Local $Writeable = (BitAND($Characteristics, $IMAGE_SCN_MEM_WRITE) <> 0) Local $ProtectList[8] = [$PAGE_NOACCESS, $PAGE_EXECUTE, $PAGE_READONLY, $PAGE_EXECUTE_READ, $PAGE_WRITECOPY, $PAGE_EXECUTE_WRITECOPY, $PAGE_READWRITE, $PAGE_EXECUTE_READWRITE] Local $Protect = $ProtectList[$Executable + $Readable * 2 + $Writeable * 4] If BitAND($Characteristics, $IMAGE_SCN_MEM_NOT_CACHED) Then $Protect = BitOR($Protect, $PAGE_NOCACHE) Local $Size = $SizeOfRawData If $Size = 0 Then If BitAND($Characteristics, $IMAGE_SCN_CNT_INITIALIZED_DATA) Then $Size = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfInitializedData') ElseIf BitAND($Characteristics, $IMAGE_SCN_CNT_UNINITIALIZED_DATA) Then $Size = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfUninitializedData') EndIf EndIf If $Size > 0 Then Local $PhysicalAddress = $CodeBase + DllStructGetData($Section, 'VirtualSize') API_VirtualProtect($PhysicalAddress, $Size, $Protect) EndIf $SectionPtr += DllStructGetSize($Section) Next EndFunc ;==>MemLib_FinalizeSections Func MemLib_FreeLibrary($ModulePtr) If Not MemLib_Vaild($ModulePtr) Then Return 0 Local $Module = DllStructCreate($tagModule, $ModulePtr) Local $CodeBase = DllStructGetData($Module, 'CodeBase') Local $DllEntry = DllStructGetData($Module, 'DllEntry') Local $Initialized = DllStructGetData($Module, 'Initialized') Local $ImportListPtr = DllStructGetData($Module, 'ImportList') Local $ExportListPtr = DllStructGetData($Module, 'ExportList') If $Initialized And $DllEntry Then Local $Success = MemoryFuncCall('bool', $DllEntry, 'ptr', $CodeBase, 'dword', 0, 'ptr', 0) DllStructSetData($Module, 'Initialized', 0) EndIf If $ExportListPtr Then _MemGlobalFree($ExportListPtr) If $ImportListPtr Then Local $ImportList = StringSplit(Peek('str', $ImportListPtr), ',') For $i = 1 To $ImportList[0] If $ImportList[$i] Then API_FreeLibrary($ImportList[$i]) Next _MemGlobalFree($ImportListPtr) EndIf If $CodeBase Then _MemVirtualFree($CodeBase, 0, $MEM_RELEASE) DllStructSetData($Module, 'CodeBase', 0) DllStructSetData($Module, 'ExportList', 0) _MemGlobalFree($ModulePtr) Return 1 EndFunc ;==>MemLib_FreeLibrary Func MemLib_GetExportList($CodeBase, $PEHeader) Local Const $IMAGE_DIRECTORY_ENTRY_EXPORT = 0 Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY)) Local $ExportDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_EXPORT * $SizeOfDataDirectory Local $ExportDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $ExportDirectoryPtr) Local $ExportSize = DllStructGetData($ExportDirectory, 'Size') Local $ExportVirtualAddress = DllStructGetData($ExportDirectory, 'VirtualAddress') Local $ExportList = '' If $ExportSize > 0 Then Local $IMAGE_EXPORT_DIRECTORY = DllStructCreate($tagIMAGE_EXPORT_DIRECTORY, $CodeBase + $ExportVirtualAddress) Local $NumberOfNames = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'NumberOfNames') Local $NumberOfFunctions = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'NumberOfFunctions') Local $AddressOfFunctions = DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfFunctions') If $NumberOfNames = 0 Or $NumberOfFunctions = 0 Then Return '' Local $NameRef = $CodeBase + DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfNames') Local $Ordinal = $CodeBase + DllStructGetData($IMAGE_EXPORT_DIRECTORY, 'AddressOfNameOrdinals') For $i = 1 To $NumberOfNames Local $Ref = Peek('dword', $NameRef) Local $Idx = Peek('word', $Ordinal) Local $FuncName = Peek('str', $CodeBase + $Ref) If $Idx <= $NumberOfFunctions Then Local $Addr = $CodeBase + Peek('dword', $CodeBase + $AddressOfFunctions + $Idx * 4) $ExportList &= $FuncName & Chr(1) & $Addr & Chr(1) EndIf $NameRef += 4 $Ordinal += 2 Next EndIf Return $ExportList EndFunc ;==>MemLib_GetExportList Func MemLib_GetProcAddress($ModulePtr, $FuncName) Local $ExportPtr = Peek('ptr', $ModulePtr) If Not $ExportPtr Then Return 0 Local $ExportList = Peek('str', $ExportPtr) Local $Match = StringRegExp($ExportList, '(?i)' & $FuncName & '\001([^\001]*)\001', 3) If Not @error Then Return Ptr($Match[0]) Return 0 EndFunc ;==>MemLib_GetProcAddress Func MemLib_LoadLibrary($DllBinary) $DllBinary = Binary($DllBinary) Local $DllData = DllStructCreate('byte[' & BinaryLen($DllBinary) & ']') Local $DllDataPtr = DllStructGetPtr($DllData) DllStructSetData($DllData, 1, $DllBinary) Local $IMAGE_DOS_HEADER = DllStructCreate($tagIMAGE_DOS_HEADER, $DllDataPtr) If DllStructGetData($IMAGE_DOS_HEADER, 'e_magic') <> 0x5A4D Then Return SetError(1, 0, 0) EndIf Local $PEHeader = $DllDataPtr + DllStructGetData($IMAGE_DOS_HEADER, 'e_lfanew') Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) If DllStructGetData($IMAGE_NT_HEADER, 'Signature') <> 0x4550 Then Return SetError(1, 0, 0) EndIf Switch DllStructGetData($IMAGE_NT_HEADER, 'Magic') Case 0x10B If @AutoItX64 Then Return SetError(2, 0, 0) Case 0x20B If Not @AutoItX64 Then Return SetError(2, 0, 0) EndSwitch Local $ImageBase = DllStructGetData($IMAGE_NT_HEADER, 'ImageBase') Local $SizeOfImage = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfImage') Local $SizeOfHeaders = DllStructGetData($IMAGE_NT_HEADER, 'SizeOfHeaders') Local $AddressOfEntryPoint = DllStructGetData($IMAGE_NT_HEADER, 'AddressOfEntryPoint') Local $ModulePtr = _MemGlobalAlloc(DllStructGetSize(DllStructCreate($tagModule)), $GPTR) If $ModulePtr = 0 Then Return SetError(3, 0, 0) Local $Module = DllStructCreate($tagModule, $ModulePtr) Local $CodeBase = _MemVirtualAlloc($ImageBase, $SizeOfImage, $MEM_RESERVE, $PAGE_READWRITE) If $CodeBase = 0 Then $CodeBase = _MemVirtualAlloc(0, $SizeOfImage, $MEM_RESERVE, $PAGE_READWRITE) If $CodeBase = 0 Then Return SetError(3, 0, 0) DllStructSetData($Module, 'CodeBase', $CodeBase) _MemVirtualAlloc($CodeBase, $SizeOfImage, $MEM_COMMIT, $PAGE_READWRITE) Local $Base = _MemVirtualAlloc($CodeBase, $SizeOfHeaders, $MEM_COMMIT, $PAGE_READWRITE) _MemMoveMemory($DllDataPtr, $Base, $SizeOfHeaders) MemLib_CopySections($CodeBase, $PEHeader, $DllDataPtr) Local $LocationDelta = $CodeBase - $ImageBase If $LocationDelta <> 0 Then MemLib_PerformBaseRelocation($CodeBase, $PEHeader, $LocationDelta) Local $ImportList = MemLib_BuildImportTable($CodeBase, $PEHeader) If @error Then MemLib_FreeLibrary($ModulePtr) Return SetError(2, 0, 0) EndIf Local $ExportList = MemLib_GetExportList($CodeBase, $PEHeader) Local $ImportListPtr = _MemGlobalAlloc(StringLen($ImportList) + 2, $GPTR) Local $ExportListPtr = _MemGlobalAlloc(StringLen($ExportList) + 2, $GPTR) DllStructSetData($Module, 'ImportList', $ImportListPtr) DllStructSetData($Module, 'ExportList', $ExportListPtr) If $ImportListPtr = 0 Or $ExportListPtr = 0 Then MemLib_FreeLibrary($ModulePtr) Return SetError(3, 0, 0) EndIf Poke('str', $ImportListPtr, $ImportList) Poke('str', $ExportListPtr, $ExportList) MemLib_FinalizeSections($CodeBase, $PEHeader) Local $DllEntry = $CodeBase + $AddressOfEntryPoint DllStructSetData($Module, 'DllEntry', $DllEntry) DllStructSetData($Module, 'Initialized', 0) If $AddressOfEntryPoint Then Local $Success = MemoryFuncCall('bool', $DllEntry, 'ptr', $CodeBase, 'dword', 1, 'ptr', 0) If Not $Success[0] Then MemLib_FreeLibrary($ModulePtr) Return SetError(4, 0, 0) EndIf DllStructSetData($Module, 'Initialized', 1) EndIf Return $ModulePtr EndFunc ;==>MemLib_LoadLibrary Func MemLib_PerformBaseRelocation($CodeBase, $PEHeader, $LocationDelta) Local Const $IMAGE_DIRECTORY_ENTRY_BASERELOC = 5 Local Const $IMAGE_REL_BASED_HIGHLOW = 3 Local Const $IMAGE_REL_BASED_DIR64 = 10 Local $IMAGE_NT_HEADER = DllStructCreate($tagIMAGE_NT_HEADER, $PEHeader) Local $SizeOfDataDirectory = DllStructGetSize(DllStructCreate($tagIMAGE_DATA_DIRECTORY)) Local $RelocDirectoryPtr = $PEHeader + DllStructGetSize($IMAGE_NT_HEADER) + $IMAGE_DIRECTORY_ENTRY_BASERELOC * $SizeOfDataDirectory Local $RelocDirectory = DllStructCreate($tagIMAGE_DATA_DIRECTORY, $RelocDirectoryPtr) Local $RelocSize = DllStructGetData($RelocDirectory, 'Size') Local $RelocVirtualAddress = DllStructGetData($RelocDirectory, 'VirtualAddress') If $RelocSize > 0 Then Local $Relocation = $CodeBase + $RelocVirtualAddress While 1 Local $IMAGE_BASE_RELOCATION = DllStructCreate($tagIMAGE_BASE_RELOCATION, $Relocation) Local $VirtualAddress = DllStructGetData($IMAGE_BASE_RELOCATION, 'VirtualAddress') Local $SizeOfBlock = DllStructGetData($IMAGE_BASE_RELOCATION, 'SizeOfBlock') If $VirtualAddress = 0 Then ExitLoop Local $Dest = $CodeBase + $VirtualAddress Local $Entries = ($SizeOfBlock - 8) / 2 Local $RelInfo = DllStructCreate('word[' & $Entries & ']', $Relocation + 8) For $i = 1 To $Entries Local $Info = DllStructGetData($RelInfo, 1, $i) Local $Type = BitShift($Info, 12) If $Type = $IMAGE_REL_BASED_HIGHLOW Or $Type = $IMAGE_REL_BASED_DIR64 Then Local $Addr = DllStructCreate('ptr', $Dest + BitAND($Info, 0xFFF)) DllStructSetData($Addr, 1, DllStructGetData($Addr, 1) + $LocationDelta) EndIf Next $Relocation += $SizeOfBlock WEnd EndIf EndFunc ;==>MemLib_PerformBaseRelocation Func MemLib_Vaild($ModulePtr) Local $ModuleSize = DllStructGetSize(DllStructCreate($tagModule)) If API_IsBadReadPtr($ModulePtr, $ModuleSize) Then Return False Local $Module = DllStructCreate($tagModule, $ModulePtr) Local $CodeBase = DllStructGetData($Module, 'CodeBase') If Not $CodeBase Then Return False Return True EndFunc ;==>MemLib_Vaild Func MemoryDllCall($Module, $RetType, $FuncName, $Type1 = '', $Param1 = 0, $Type2 = '', $Param2 = 0, $Type3 = '', $Param3 = 0, $Type4 = '', $Param4 = 0, $Type5 = '', $Param5 = 0, $Type6 = '', $Param6 = 0, $Type7 = '', $Param7 = 0, $Type8 = '', $Param8 = 0, $Type9 = '', $Param9 = 0, $Type10 = '', $Param10 = 0, $Type11 = '', $Param11 = 0, $Type12 = '', $Param12 = 0, $Type13 = '', $Param13 = 0, $Type14 = '', $Param14 = 0, $Type15 = '', $Param15 = 0, $Type16 = '', $Param16 = 0, $Type17 = '', $Param17 = 0, $Type18 = '', $Param18 = 0, $Type19 = '', $Param19 = 0, $Type20 = '', $Param20 = 0) Local $Ret, $OpenFlag = False Local Const $MaxParams = 20 If (@NumParams < 3) Or (@NumParams > $MaxParams * 2 + 3) Or (Mod(@NumParams, 2) = 0) Then Return SetError(4, 0, 0) If Not IsPtr($Module) Then $OpenFlag = True $Module = MemoryDllOpen($Module) If @error Then Return SetError(1, 0, 0) EndIf Local $Addr = MemLib_GetProcAddress($Module, $FuncName) If Not $Addr Then Return SetError(3, 0, 0) Poke('ptr', $_MFHookPtr + 1 + @AutoItX64, $Addr) Switch @NumParams Case 3 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi) Case 5 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1) Case 7 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2) Case 9 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3) Case 11 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4) Case 13 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5) Case Else Local $DllCallStr = 'DllCall ( $_KERNEL32DLL, $RetType, $_MFHookApi', $n = 1 For $i = 5 To @NumParams Step 2 $DllCallStr &= ', $Type' & $n & ', $Param' & $n $n += 1 Next $DllCallStr &= ' )' $Ret = Execute($DllCallStr) EndSwitch Local $Err = @error If $OpenFlag Then MemoryDllClose($Module) Return SetError($Err, 0, $Ret) EndFunc ;==>MemoryDllCall Func MemoryDllClose($Module) MemLib_FreeLibrary($Module) EndFunc ;==>MemoryDllClose Func MemoryDllOpen($DllBinary) If Not IsDllStruct($_MFHookBak) Then MemoryFuncInit() Local $Module = MemLib_LoadLibrary($DllBinary) If @error Then Return SetError(@error, 0, -1) Return $Module EndFunc ;==>MemoryDllOpen Func MemoryFuncCall($RetType, $Address, $Type1 = '', $Param1 = 0, $Type2 = '', $Param2 = 0, $Type3 = '', $Param3 = 0, $Type4 = '', $Param4 = 0, $Type5 = '', $Param5 = 0, $Type6 = '', $Param6 = 0, $Type7 = '', $Param7 = 0, $Type8 = '', $Param8 = 0, $Type9 = '', $Param9 = 0, $Type10 = '', $Param10 = 0, $Type11 = '', $Param11 = 0, $Type12 = '', $Param12 = 0, $Type13 = '', $Param13 = 0, $Type14 = '', $Param14 = 0, $Type15 = '', $Param15 = 0, $Type16 = '', $Param16 = 0, $Type17 = '', $Param17 = 0, $Type18 = '', $Param18 = 0, $Type19 = '', $Param19 = 0, $Type20 = '', $Param20 = 0) If Not IsDllStruct($_MFHookBak) Then MemoryFuncInit() Poke('ptr', $_MFHookPtr + 1 + @AutoItX64, $Address) Local $Ret Switch @NumParams Case 2 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi) Case 4 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1) Case 6 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2) Case 8 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3) Case 10 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4) Case 12 $Ret = DllCall($_KERNEL32DLL, $RetType, $_MFHookApi, $Type1, $Param1, $Type2, $Param2, $Type3, $Param3, $Type4, $Param4, $Type5, $Param5) Case Else Local $DllCallStr = 'DllCall($_KERNEL32DLL, $RetType, $_MFHookApi', $n = 1 For $i = 4 To @NumParams Step 2 $DllCallStr &= ', $Type' & $n & ', $Param' & $n $n += 1 Next $DllCallStr &= ')' $Ret = Execute($DllCallStr) EndSwitch Return SetError(@error, 0, $Ret) EndFunc ;==>MemoryFuncCall Func MemoryFuncInit() Local $KernelHandle = API_LoadLibrary('kernel32.dll') API_FreeLibrary($KernelHandle) Local $HookPtr = API_GetProcAddress($KernelHandle, $_MFHookApi) Local $HookSize = 7 + @AutoItX64 * 5 $_MFHookPtr = $HookPtr $_MFHookBak = DllStructCreate('byte[' & $HookSize & ']') If Not API_VirtualProtect($_MFHookPtr, $HookSize, $PAGE_EXECUTE_READWRITE) Then Return False DllStructSetData($_MFHookBak, 1, Peek('byte[' & $HookSize & ']', $_MFHookPtr)) If @AutoItX64 Then Poke('word', $_MFHookPtr, 0xB848) Poke('word', $_MFHookPtr + 10, 0xE0FF) Else Poke('byte', $_MFHookPtr, 0xB8) Poke('word', $_MFHookPtr + 5, 0xE0FF) EndIf Return True EndFunc ;==>MemoryFuncInit Func Peek($Type, $Ptr) If $Type = 'str' Then $Type = 'char[' & API_lstrlenA($Ptr) & ']' ElseIf $Type = 'wstr' Then $Type = 'wchar[' & API_lstrlenW($Ptr) & ']' EndIf Return DllStructGetData(DllStructCreate($Type, $Ptr), 1) EndFunc ;==>Peek Func Poke($Type, $Ptr, $Value) If $Type = 'str' Then $Type = 'char[' & (StringLen($Value) + 1) & ']' ElseIf $Type = 'wstr' Then $Type = 'wchar[' & (StringLen($Value) + 1) & ']' EndIf DllStructSetData(DllStructCreate($Type, $Ptr), 1, $Value) EndFunc ;==>Poke #EndRegion Download UDF, DLLs and examples on my 1Drv: WebP (to download all marked files, you must login first, otherwise 1by1 only)2 points
-
Write an eula for the end user; that they have to cover their eyes when executing the binary?2 points
-
How do you handle password in your code ?
cramaboule and one other reacted to Jos for a topic
Just to be clear: Whatever you do, the shell command requires the clear text password, so by definition no solution will be safe! 🙂2 points -
If you need/want to characterize floats beyond just being of datatype "double", you can pick ideas from this code: Local $a = [ _ [0xfff0000000000000, "-infinity"], _ ; 1 11111111111 0000000000000000000000000000000000000000000000000000 ⎫ [0xffefffffffffffff, "smallest negative normal"], _ ; 1 11111111110 1111111111111111111111111111111111111111111111111111 ⎪ [0x8010000000000000, "largest negative normal"], _ ; 1 00000000001 0000000000000000000000000000000000000000000000000000 ⎪ [0x8000000000000000, "negative zero"], _ ; 1 00000000000 0000000000000000000000000000000000000000000000000000 ⎪ [0x0000000000000000, "positive zero"], _ ; 0 00000000000 0000000000000000000000000000000000000000000000000000 ⎬ Numbers you can deal with [0x0010000000000000, "smallest positive normal"], _ ; 0 00000000001 0000000000000000000000000000000000000000000000000000 ⎪ [0x7fefffffffffffff, "largest positive normal"], _ ; 0 11111111110 1111111111111111111111111111111111111111111111111111 ⎪ [0x7ff0000000000000, "+infinity"], _ ; 0 11111111111 0000000000000000000000000000000000000000000000000000 ⎭ [0x800fffffffffffff, "smallest negative denormal"], _ ; 1 00000000000 1111111111111111111111111111111111111111111111111111 ⎫ [0x8000000000000001, "largest negative denormal"], _ ; 1 00000000000 0000000000000000000000000000000000000000000000000001 ⎬ Numbers best avoided unless [0x0000000000000001, "smallest positive denormal"], _ ; 0 00000000000 0000000000000000000000000000000000000000000000000001 ⎪ dealing with extra-small values [0x000fffffffffffff, "largest positive denormal"], _ ; 0 00000000000 1111111111111111111111111111111111111111111111111111 ⎭ [0xfff8000000000001, "-NAN (quiet, denormal)"], _ ; 1 11111111111 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎫ [0xfff0000000000001, "-NAN (signaling, denormal)"], _ ; 1 11111111111 00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎪ [0xfff4000000000001, "-NAN (signaling, normal)"], _ ; 1 11111111111 0100000000000000000000000000000000000000000000000000 ⎪ [0x7ff4000000000001, "+NAN (signaling, normal)"], _ ; 0 11111111111 0100000000000000000000000000000000000000000000000000 ⎬ You shouldn't get those [0x7ff8000000000001, "+NAN (quiet, denormal)"], _ ; 0 11111111111 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎪ [0x7ff0000000000001, "+NAN (signaling, denormal)"], _ ; 0 11111111111 00xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x >= 1 ⎭ [0xfff8000000000000, " NAN (indeterminate)"] _ ; 1 11111111111 1000000000000000000000000000000000000000000000000000 ◀ You made a big mistake ] ConsoleWrite("Ranges of double values" & @LF) Local $t = DllStructCreate("int64") Local $u = DllStructCreate("double", DllStructGetPtr($t)) Local $v For $n = 0 To UBound($a) - 1 DllStructSetData($t, 1, $a[$n][0]) $v = DllStructGetData($u, 1) ConsoleWrite(StringFormat("%s%23s\t%s\n", VarGetType($v), $v, $a[$n][1])) Next ConsoleWrite(@LF & "FP zeroes are signed !" & @LF) ConsoleWrite(" 0/3" & @TAB & (0/3) & @LF) ConsoleWrite("-0/-3" & @TAB & (-0/-3) & @LF) ConsoleWrite(" 0/-3" & @TAB & (0/-3) & @LF) ConsoleWrite("-0/3" & @TAB & (-0/3) & @LF) ConsoleWrite("Yet (hopefully)" & @LF) ConsoleWrite("0/-3 = 0/3" & @TAB & (0/-3 = 0/3) & @LF) ConsoleWrite("0/-3 = 0" & @TAB & (0/3 = 0) & @LF) ConsoleWrite(@LF & "Infinities compute (but if you get there, you are mostly stuck!)" & @LF) Local Const $PI = 3.141592653589793 ConsoleWrite("3/0" & @TAB & @TAB & (3/0) & @LF) ConsoleWrite("3/0 + 100" & @TAB & (3/0 + 100) & @LF) ConsoleWrite("(3/0) / 2" & @TAB & ((3/0) / 2) & @LF) ConsoleWrite("(3/0) ^ 2" & @TAB & ((3/0) ^ 2) & @LF) ConsoleWrite("-3/0" & @TAB & @TAB & (-3/0) & @LF) ConsoleWrite("-3/0 + 100" & @TAB & (-3/0 + 100) & @LF) ConsoleWrite("(-3/0) / 2" & @TAB & ((-3/0) / 2) & @LF) ConsoleWrite("(-3/0) ^ 2" & @TAB & ((-3/0) ^ 2) & @LF) ConsoleWrite("(-3/0) ^ 5" & @TAB & ((-3/0) ^ 5) & @LF) ConsoleWrite("Log(1/0)" & @TAB & Log(1/0) & @LF) ConsoleWrite("Exp(1/0)" & @TAB & Exp(1/0) & @LF) ConsoleWrite("Tan($Pi/2)" & @TAB & Tan($Pi/2) & @TAB & "<-- should be 'inf'" & @LF) ConsoleWrite("Tan(-$Pi/2)" & @TAB & Tan(-$Pi/2) & @TAB & "<-- should be '-inf'" & @LF) ConsoleWrite("ATan(1/0)" & @TAB & ATan(1/0) & @TAB & @TAB & "<-- Pi/2" & @LF) ConsoleWrite("ATan(-1/0)" & @TAB & ATan(-1/0) & @TAB & "<-- -Pi/2" & @LF) ConsoleWrite("1/(1/0)" & @TAB & @TAB & 1/(1/0) & @LF) ConsoleWrite("-1/(1/0)" & @TAB & -1/(1/0) & @LF) ConsoleWrite("1/(-1/0)" & @TAB & 1/(-1/0) & @LF) ConsoleWrite("-1/(-1/0)" & @TAB & -1/(-1/0) & @LF) ConsoleWrite("0^0)" & @TAB & @TAB & 0^0 & @TAB & @TAB & @TAB & "<-- NOT indeterminate in FP" & @LF) ConsoleWrite("(1/0)^0" & @TAB & @TAB & (1/0)^0 & @TAB & @TAB & @TAB & "<-- NOT indeterminate in FP" & @LF) ConsoleWrite(@LF & "Indeterminate forms" & @LF) Local $ind = [ _ ["0/0", 0/0], _ ["0*(1/0)", 0*(1/0)], _ ["0*(-1/0)", 0*(-1/0)], _ ["(1/0)-(1/0)", (1/0)-(1/0)], _ ["(-1/0)-(-1/0)", (-1/0)-(-1/0)], _ ["(1/0)+(-1/0)", (1/0)+(-1/0)], _ ["(-1/0)+(1/0)", (-1/0)+(1/0)], _ ["1^(1/0)", 1^(1/0)], _ ["1^(-1/0)", 1^(-1/0)], _ ["-1^(1/0)", -1^(1/0)], _ ["-1^(-1/0)", -1^(-1/0)], _ ["Cos(1/0)", Cos(1/0)], _ ["Sin(1/0)", Sin(1/0)], _ ["ACos(5)", ACos(5)], _ ["ASin(5)", ASin(5)], _ ["Sqrt(-1)", Sqrt(-1)], _ ["Log(-1)", Log(-1)] _ ] For $i = 0 To UBound($ind) - 1 ConsoleWrite(StringFormat("%-15s\t%s\t%f\n", $ind[$i][0], VarGetType($ind[$i][1]), $ind[$i][1])) Next ConsoleWrite(@LF & "NANs never compare !" & @LF) ConsoleWrite("0/0 > 0" & @TAB & @TAB & (0/0 > 0) & @LF) ConsoleWrite("0/0 = 0" & @TAB & @TAB & (0/0 = 0) & @LF) ConsoleWrite("0/0 < 0" & @TAB & @TAB & (0/0 < 0) & @LF) ConsoleWrite("0/0 > -0/0" & @TAB & (0/0 > -0/0) & @LF) ConsoleWrite("0/0 = -0/0" & @TAB & (0/0 = -0/0) & @LF) ConsoleWrite("0/0 < -0/0" & @TAB & (0/0 < -0/0) & @LF)2 points
-
S: #Region Example Usage ; Example 1: Check a binary executable file Local $filePathBinary = @WindowsDir & "\explorer.exe" Local $fileInfoBinary = _GetFileDataType($filePathBinary) If @error Then MsgBox(4096, "Error", "Could not determine file type: " & $fileInfoBinary) Else Local $isBinary = (@extended = 1) ? "Binary" : "Text" MsgBox(4096, "Result (Binary)", "Path: " & $filePathBinary & @CRLF & _ "File Type: " & $fileInfoBinary & @CRLF & "Classification: " & $isBinary) EndIf ; Example 2: Check a text file (this AutoIt script) Local $filePathText = @ScriptFullPath Local $fileInfoText = _GetFileDataType($filePathText) If @error Then MsgBox(4096, "Error", "Could not determine file type: " & $fileInfoText) Else Local $isBinary = (@extended = 1) ? "Binary" : "Text" MsgBox(4096, "Result (Text)", "Path: " & $filePathText & @CRLF & _ "File Type: " & $fileInfoText & @CRLF & "Classification: " & $isBinary) EndIf #EndRegion Example Usage ; ================================================================================================= ; Function: _CheckDataType ; Purpose: Determine the data type code of any AutoIt variable or string. ; Parameters: ; $vInput - Any AutoIt variable or literal to examine. ; $bShowDebug - Optional. When True, debug messages are printed to the console. ; Returns: Integer type code: ; 1 = String ; 2 = Int32 ; 3 = Int64 ; 4 = Double/Float ; 5 = Binary/Hex ; 6 = Boolean ; 7 = Array ; 8 = Map ; 9 = Pointer ; 10 = DLL Struct ; 11 = Window Handle ; 12 = Object ; 13 = Keyword ; 14 = Function ; 15 = UserFunction ; 16 = Unknown ; ================================================================================================= Func _CheckDataType($vInput, $bShowDebug = False) ; 1) AutoIt-specific objects If IsArray($vInput) Then Return _DebugResult(7, "Array", $vInput) If IsMap($vInput) Then Return _DebugResult(8, "Map", $vInput) If IsPtr($vInput) Then Return _DebugResult(9, "Pointer", $vInput) If IsDllStruct($vInput) Then Return _DebugResult(10, "DLL Struct", $vInput) If IsHWnd($vInput) Then Return _DebugResult(11, "Window Handle", $vInput) If IsObj($vInput) Then Return _DebugResult(12, "Object", $vInput) If IsKeyword($vInput) Then Return _DebugResult(13, "Keyword", $vInput) Local $sType = VarGetType($vInput) If IsFunc($vInput) Then If $sType = "UserFunction" Then Return _DebugResult(15, "UserFunction", $vInput) Else Return _DebugResult(14, "Function", $vInput) EndIf EndIf ; 2) Native numeric If $sType = "Int32" Then Return _DebugResult(2, "Int32", $vInput) If $sType = "Int64" Then Return _DebugResult(3, "Int64", $vInput) If $sType = "Double" Then Return _DebugResult(4, "Double/Float", $vInput) ; 3) Native binary & boolean If IsBinary($vInput) Then Return _DebugResult(5, "Binary/Hex", $vInput) If IsBool($vInput) Then Return _DebugResult(6, "Boolean", $vInput) ; 4) String analysis – strict-hex first, then numeric/boolean-like, then fallback If IsString($vInput) Then If $bShowDebug Then ConsoleWrite("- [DEBUG] String analysis..." & @CRLF) Local $s = StringStripWS($vInput, 8) ; 4.1) Hex with 0x prefix, even-length body If StringRegExp($s, "^0[xX][0-9A-Fa-f]+$") Then Local $hexBody = StringMid($s, 3) If Mod(StringLen($hexBody), 2) = 0 Then Return _DebugResult(5, "Hex string (0x prefix, strict)", $vInput) ElseIf $bShowDebug Then ConsoleWrite("- [DEBUG] Prefix hex odd length, skip" & @CRLF) EndIf EndIf ; 4.2) Bare hex (no prefix), even length, ; but skip if purely digits (prioritize numeric) If StringRegExp($s, "^[0-9A-Fa-f]+$") Then ; if only digits (no A-F letters), treat as numeric If StringRegExp($s, "^[0-9]+$") Then If $bShowDebug Then ConsoleWrite("- [DEBUG] Bare digits only, defer to numeric parse" & @CRLF) EndIf ElseIf Mod(StringLen($s), 2) = 0 Then Return _DebugResult(5, "Hex string (bare, strict)", $vInput) ElseIf $bShowDebug Then ConsoleWrite("- [DEBUG] Bare hex odd length, skip" & @CRLF) EndIf EndIf ; 4.3) Numeric parse (int32/int64/double) Local $numInfo = _ParseNumeric($s, $bShowDebug) If $numInfo[0] Then Return _DebugResult($numInfo[1], GetDataTypeName($numInfo[1]) & " (string)", $vInput) EndIf ; 4.4) Boolean-like strings Local $sl = StringLower($s) If $sl = "true" Or $sl = "false" Then Return _DebugResult(6, "Boolean-like string", $vInput) EndIf ; 4.5) Fallback string Return _DebugResult(1, "String", $vInput) EndIf ; 5) Unknown Return _DebugResult(16, "Unknown", $vInput) EndFunc ;==>_CheckDataType ; ================================================================================================= ; Function: _DebugResult ; Purpose: Internal helper to print debug messages and return a code. ; Parameters: ; $iCode - Integer code to return. ; $sText - Description text to display in debug. ; Returns: $iCode ; ================================================================================================= Func _DebugResult($iCode, $sText, $sInput) $sInput = StringReplace($sInput, @CRLF, '@CRLF') ConsoleWrite(StringFormat("- [DEBUG] Input '%s' (Len: %d) is: %s (Type=%d)" & @CRLF, $sInput, StringLen($sInput), $sText, $iCode)) Return $iCode EndFunc ;==>_DebugResult ; ================================================================================================= ; Function: _ParseNumeric ; Purpose: Internal numeric parser supporting US and EU formats. ; Parameters: ; $sInput - String to parse for numeric patterns. ; $bShowDebug - Optional. When True, debug messages are printed. ; Returns: A two-element array: [0] = True/False if numeric, ; [1] = type code (2=Int32,3=Int64,4=Double) ; ================================================================================================= Func _ParseNumeric($sInput, $bShowDebug = False) Local $res[2] = [False, 0] If $sInput = "" Then Return $res If StringRegExp($sInput, "^0[0-9]+$") Then Return $res Local $patUS = "^[+-]?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)?$" Local $patEU = "^[+-]?[0-9]{1,3}(\.[0-9]{3})*(,[0-9]+)?$" Local $patThousand = "^[+-]?[0-9]{1,3}([,\.][0-9]{3})+$" Local $patSimpleEU = "^[+-]?[0-9]+,[0-9]+$" Local $matched = False Local $numStr = $sInput Local $hasDec = False ; US format: 1,234.56 If StringRegExp($sInput, $patUS) Then $matched = True $numStr = StringReplace($sInput, ",", "") $hasDec = StringInStr($sInput, ".", 0) > 0 EndIf ; EU format: 1.234,56 If Not $matched And StringRegExp($sInput, $patEU) Then $matched = True $numStr = StringReplace(StringReplace($sInput, ".", ""), ",", ".") $hasDec = True EndIf ; Thousand separators only: 1,234 or 1.234 If Not $matched And StringRegExp($sInput, $patThousand) Then $matched = True $numStr = StringReplace(StringReplace($sInput, ",", ""), ".", "") EndIf ; Simple EU decimals: 123,45 If Not $matched And StringRegExp($sInput, $patSimpleEU) Then $matched = True $numStr = StringReplace($sInput, ",", ".") $hasDec = True EndIf If Not $matched Then Return $res Local $val = Number($numStr) ; Decide Double vs Int If $hasDec Or $val <> Int($val) Then Local $aResult[2] = [True, 4] Return $aResult EndIf ; Int32 vs Int64 If $val >= -2147483648 And $val <= 2147483647 Then Local $aResult[2] = [True, 2] Return $aResult Else Local $aResult[2] = [True, 3] Return $aResult EndIf EndFunc ;==>_ParseNumeric ; ================================================================================================= ; Function: GetDataTypeName ; Purpose: Map a numeric code to its human-readable type name. ; Parameters: ; $iCode - Integer type code (1–16). ; Returns: String name corresponding to that code. ; ================================================================================================= Func GetDataTypeName($i) Select Case $i = 1 Return "String" Case $i = 2 Return "Int32" Case $i = 3 Return "Int64" Case $i = 4 Return "Double/Float" Case $i = 5 Return "Binary/Hex" Case $i = 6 Return "Boolean" Case $i = 7 Return "Array" Case $i = 8 Return "Map" Case $i = 9 Return "Pointer" Case $i = 10 Return "DLL Struct" Case $i = 11 Return "Window Handle" Case $i = 12 Return "Object" Case $i = 13 Return "Keyword" Case $i = 14 Return "Function" Case $i = 15 Return "UserFunction" Case Else Return "Unknown" EndSelect EndFunc ;==>GetDataTypeName ; ------------------------------------------------------------------- ; Helper: is this ANY numeric type? (native or string) ; ------------------------------------------------------------------- Func _IsNumber($v) Local $c = _CheckDataType($v, False) Return ($c = 2 Or $c = 3 Or $c = 4) EndFunc ;==>_IsNumber ;=============================================================================== ; Function: _GetFileDataType – Determine File Types by Hex Signature ; Description: Determines file type & classification (binary/text) by: ; • Reading a file’s first 1KB and converting to hex ; • Matching against signature database (500+ entries) ; • Checking RIFF, ZIP, MP4/MOV, TAR, PE subtables ; • Applying advanced text analysis heuristics ; Parameters: $sInput – full file path OR raw hex signature string ; Return: On success: file type string; @extended=1 if binary else 0 ; On failure: SetError(1), @extended=0, returns error message ; Author: Dao Van Trong – TRONG.PRO ; Example: ; Local $sType = _GetFileDataType("C:\Windows\explorer.exe") ; If @error Then ConsoleWrite("Error: " & $sType & @CRLF) ; Else ConsoleWrite("Type: " & $sType & ", Binary? " & @extended & @CRLF) ;=============================================================================== Func _GetFileDataType($sInput) Local Static $aMaps = _CreateSignatureDatabase() Local Static $mSignatures = $aMaps[0] Local Static $mBinaryFlags = $aMaps[1] Local $sHexData = "" ; Handle input If FileExists($sInput) Then $sHexData = _ReadFileSignature($sInput) If @error Then Return SetError(1, 0, "Cannot read file: " & $sInput) ElseIf (StringLen($sInput) > 1) And (_CheckDataType($sInput, False) = 5) Then $sInput = StringStripWS($sInput, 8) $sHexData = StringUpper($sInput) Else Return SetError(1, 0, "Invalid input") EndIf If _CheckHexPrefix($sHexData) Then $sHexData = _RemoveHexPrefix($sHexData) ; Search for signatures in descending order of length (prioritizing longer, more specific signatures) Local $aLengths[12] = [64, 48, 32, 28, 24, 20, 16, 12, 10, 8, 6, 4] For $iLen In $aLengths If StringLen($sHexData) >= $iLen Then Local $sTestSig = StringLeft($sHexData, $iLen) If $mSignatures.Exists($sTestSig) Then Local $sFileType = $mSignatures[$sTestSig] Local $iBinaryFlag = $mBinaryFlags[$sTestSig] Return SetError(0, $iBinaryFlag, $sFileType) EndIf EndIf Next ; Check for special patterns (which may not be at offset 0) Local $sSpecialResult = _CheckSpecialPatterns($sHexData) If $sSpecialResult <> "" Then Return SetError(0, StringInStr($sSpecialResult, "|BIN|") ? 1 : 0, StringReplace($sSpecialResult, "|BIN|", "")) EndIf ; Advanced text content analysis Local $sTextType = _AdvancedTextAnalysis($sHexData) If $sTextType <> "" Then Local $isBinaryHeuristic = ($sTextType = "Binary Data") Return SetError(0, $isBinaryHeuristic, $sTextType) EndIf Return SetError(1, 0, "Could not determine file type") EndFunc ;==>_GetFileDataType Func _RemoveHexPrefix($sHex) ; Kiểm tra nếu chuỗi bắt đầu bằng "0x" hoặc "0X" If StringLeft($sHex, 2) = "0x" Or StringLeft($sHex, 2) = "0X" Then Return StringTrimLeft($sHex, 2) EndIf Return $sHex EndFunc ;==>_RemoveHexPrefix Func _CheckHexPrefix($str) If (StringLen($str) < 2) Then Return False $prefix = StringUpper(StringLeft($str, 2)) If $prefix == "0X" Then Return True Else Return False EndIf EndFunc ;==>_CheckHexPrefix ;=============================================================================== ; Function: _ReadFileSignature ; Description: Reads first 1KB of a file in binary mode and returns hex string ; Parameters: $sFilePath – full path to file ; Return: On success: uppercase hex string of data read ; On failure: SetError(1), return "" ;=============================================================================== Func _ReadFileSignature($sFilePath) Local $hFile = FileOpen($sFilePath, 16) ; Open in binary mode If $hFile = -1 Then Return SetError(1, 0, "") ; Read the first 1KB for comprehensive analysis Local $dData = FileRead($hFile, 1024) FileClose($hFile) If @error Then Return SetError(1, 0, "") Return StringUpper(Hex($dData)) EndFunc ;==>_ReadFileSignature ;================================================================================ ; Helper Function: Create the signature database (500+ file types) ;================================================================================ Func _CreateSignatureDatabase() Local $mSignatures[], $mBinaryFlags[] ; === ARCHIVE & COMPRESSION FORMATS === ; ZIP Family $mSignatures["504B0304"] = "ZIP Archive" $mBinaryFlags["504B0304"] = 1 $mSignatures["504B0506"] = "ZIP Archive (Empty)" $mBinaryFlags["504B0506"] = 1 $mSignatures["504B0708"] = "ZIP Archive (Spanned)" $mBinaryFlags["504B0708"] = 1 ; RAR Family $mSignatures["526172211A0700"] = "RAR Archive v1.5+" $mBinaryFlags["526172211A0700"] = 1 $mSignatures["526172211A070100"] = "RAR Archive v5.0+" $mBinaryFlags["526172211A070100"] = 1 ; 7-Zip Family $mSignatures["377ABCAF271C"] = "7-Zip Archive" $mBinaryFlags["377ABCAF271C"] = 1 ; Compression Formats $mSignatures["1F8B"] = "GZIP Compressed" $mBinaryFlags["1F8B"] = 1 $mSignatures["425A68"] = "BZIP2 Compressed" $mBinaryFlags["425A68"] = 1 $mSignatures["FD377A585A00"] = "XZ Compressed" $mBinaryFlags["FD377A585A00"] = 1 $mSignatures["5D00"] = "LZMA Compressed" $mBinaryFlags["5D00"] = 1 $mSignatures["28B52FFD"] = "Zstandard Compressed" $mBinaryFlags["28B52FFD"] = 1 $mSignatures["04224D18"] = "LZ4 Compressed" $mBinaryFlags["04224D18"] = 1 ; Archive Formats $mSignatures["213C617263683E"] = "Unix Archive" $mBinaryFlags["213C617263683E"] = 1 $mSignatures["EDABEEDB"] = "Debian Package" $mBinaryFlags["EDABEEDB"] = 1 $mSignatures["43414220"] = "Microsoft Cabinet" $mBinaryFlags["43414220"] = 1 $mSignatures["4D534346"] = "Microsoft Cabinet" $mBinaryFlags["4D534346"] = 1 $mSignatures["495321"] = "Inno Setup" $mBinaryFlags["495321"] = 1 $mSignatures["4E45534D1A01"] = "Nintendo NES ROM" $mBinaryFlags["4E45534D1A01"] = 1 ; === IMAGE FORMATS === ; JPEG Family $mSignatures["FFD8FFE0"] = "JPEG Image (JFIF)" $mBinaryFlags["FFD8FFE0"] = 1 $mSignatures["FFD8FFE1"] = "JPEG Image (EXIF)" $mBinaryFlags["FFD8FFE1"] = 1 $mSignatures["FFD8FFE2"] = "JPEG Image (Canon)" $mBinaryFlags["FFD8FFE2"] = 1 $mSignatures["FFD8FFE3"] = "JPEG Image (Samsung)" $mBinaryFlags["FFD8FFE3"] = 1 $mSignatures["FFD8FFE8"] = "JPEG Image (SPIFF)" $mBinaryFlags["FFD8FFE8"] = 1 $mSignatures["FFD8FFDB"] = "JPEG Image" $mBinaryFlags["FFD8FFDB"] = 1 $mSignatures["FFD8FFEE"] = "JPEG Image (Adobe)" $mBinaryFlags["FFD8FFEE"] = 1 ; PNG Family $mSignatures["89504E470D0A1A0A"] = "PNG Image" $mBinaryFlags["89504E470D0A1A0A"] = 1 ; GIF Family $mSignatures["474946383761"] = "GIF Image (87a)" $mBinaryFlags["474946383761"] = 1 $mSignatures["474946383961"] = "GIF Image (89a)" $mBinaryFlags["474946383961"] = 1 ; TIFF Family $mSignatures["49492A00"] = "TIFF Image (Little Endian)" $mBinaryFlags["49492A00"] = 1 $mSignatures["4D4D002A"] = "TIFF Image (Big Endian)" $mBinaryFlags["4D4D002A"] = 1 ; Bitmap Family $mSignatures["424D"] = "BMP Image" $mBinaryFlags["424D"] = 1 ; WebP (Lossy and Lossless) ; Note: WebP is a RIFF container, also checked in _CheckSpecialPatterns $mSignatures["52494646"] = "WebP Image" $mBinaryFlags["52494646"] = 1 ; Icon Formats $mSignatures["00000100"] = "Windows Icon (ICO)" $mBinaryFlags["00000100"] = 1 $mSignatures["00000200"] = "Windows Cursor (CUR)" $mBinaryFlags["00000200"] = 1 ; Advanced Image Formats $mSignatures["38425053"] = "Photoshop PSD" $mBinaryFlags["38425053"] = 1 $mSignatures["00000C6A502020"] = "JPEG2000" $mBinaryFlags["00000C6A502020"] = 1 $mSignatures["FF4FFF51"] = "JPEG2000" $mBinaryFlags["FF4FFF51"] = 1 $mSignatures["000000186674797068656963"] = "HEIF/HEIC Image" $mBinaryFlags["000000186674797068656963"] = 1 $mSignatures["0000002066747970617669663"] = "AVIF Image" $mBinaryFlags["0000002066747970617669663"] = 1 ; RAW Image Formats $mSignatures["49494E31"] = "Nikon NEF" $mBinaryFlags["49494E31"] = 1 $mSignatures["4352"] = "Canon CR2" $mBinaryFlags["4352"] = 1 $mSignatures["49494944"] = "Adobe DNG" $mBinaryFlags["49494944"] = 1 $mSignatures["46554A49"] = "Fuji RAF" $mBinaryFlags["46554A49"] = 1 $mSignatures["41524159"] = "Sony ARW" $mBinaryFlags["41524159"] = 1 ; === VIDEO FORMATS === ; MP4 Family (checked more deeply in _CheckSpecialPatterns) $mSignatures["0000002066747970"] = "MP4 Video" $mBinaryFlags["0000002066747970"] = 1 $mSignatures["000000186674797033677035"] = "MP4 Video (3GP5)" $mBinaryFlags["000000186674797033677035"] = 1 ; QuickTime (checked more deeply in _CheckSpecialPatterns) $mSignatures["0000001466747970717420"] = "QuickTime MOV" $mBinaryFlags["0000001466747970717420"] = 1 $mSignatures["6D6F6F76"] = "QuickTime MOV" $mBinaryFlags["6D6F6F76"] = 1 ; AVI (is a RIFF container, checked in _CheckSpecialPatterns) $mSignatures["52494646"] = "AVI Video" $mBinaryFlags["52494646"] = 1 ; Matroska $mSignatures["1A45DFA3"] = "Matroska MKV" $mBinaryFlags["1A45DFA3"] = 1 ; Flash Video $mSignatures["464C5601"] = "Flash FLV" $mBinaryFlags["464C5601"] = 1 ; Windows Media $mSignatures["3026B2758E66CF11"] = "Windows Media (ASF/WMV)" $mBinaryFlags["3026B2758E66CF11"] = 1 ; MPEG $mSignatures["000001BA"] = "MPEG Program Stream" $mBinaryFlags["000001BA"] = 1 $mSignatures["000001B3"] = "MPEG Elementary Stream" $mBinaryFlags["000001B3"] = 1 $mSignatures["47"] = "MPEG Transport Stream" $mBinaryFlags["47"] = 1 ; === AUDIO FORMATS === ; MP3 Family $mSignatures["494433"] = "MP3 Audio (ID3v2)" $mBinaryFlags["494433"] = 1 $mSignatures["FFFB"] = "MP3 Audio (MPEG-1 Layer 3)" $mBinaryFlags["FFFB"] = 1 $mSignatures["FFF3"] = "MP3 Audio (MPEG-2 Layer 3)" $mBinaryFlags["FFF3"] = 1 ; WAV (is a RIFF container, checked in _CheckSpecialPatterns) $mSignatures["52494646"] = "WAV Audio" $mBinaryFlags["52494646"] = 1 ; FLAC $mSignatures["664C6143"] = "FLAC Audio" $mBinaryFlags["664C6143"] = 1 ; OGG $mSignatures["4F676753"] = "OGG Audio/Video" $mBinaryFlags["4F676753"] = 1 ; AAC $mSignatures["FFF1"] = "AAC Audio (ADTS)" $mBinaryFlags["FFF1"] = 1 ; Apple Audio $mSignatures["4D344120"] = "M4A Audio" $mBinaryFlags["4D344120"] = 1 ; Other Audio $mSignatures["4D546864"] = "MIDI Audio" $mBinaryFlags["4D546864"] = 1 ; === DOCUMENT FORMATS === ; PDF $mSignatures["25504446"] = "PDF Document" $mBinaryFlags["25504446"] = 1 ; Microsoft Office Legacy $mSignatures["D0CF11E0A1B11AE1"] = "Microsoft Office Document (Legacy)" $mBinaryFlags["D0CF11E0A1B11AE1"] = 1 ; Microsoft Office Modern (Office Open XML) $mSignatures["504B030414000600"] = "Office Open XML (DOCX/XLSX/PPTX)" $mBinaryFlags["504B030414000600"] = 1 ; PostScript $mSignatures["25215053"] = "PostScript Document" $mBinaryFlags["25215053"] = 0 ; === EXECUTABLE FORMATS === ; Windows $mSignatures["4D5A"] = "Windows Executable (PE)" $mBinaryFlags["4D5A"] = 1 ; Linux $mSignatures["7F454C46"] = "Linux ELF Executable" $mBinaryFlags["7F454C46"] = 1 ; macOS $mSignatures["FEEDFACE"] = "macOS Mach-O 32-bit" $mBinaryFlags["FEEDFACE"] = 1 $mSignatures["FEEDFACF"] = "macOS Mach-O 64-bit" $mBinaryFlags["FEEDFACF"] = 1 ; Java $mSignatures["CAFEBABE"] = "Java Class File" $mBinaryFlags["CAFEBABE"] = 1 ; === DATABASE FORMATS === $mSignatures["53514C69746520666F726D61742033"] = "SQLite Database" $mBinaryFlags["53514C69746520666F726D61742033"] = 1 $mSignatures["00010000"] = "Microsoft Access Database" $mBinaryFlags["00010000"] = 1 ; === FONT FORMATS === $mSignatures["00010000"] = "TrueType Font" $mBinaryFlags["00010000"] = 1 $mSignatures["4F54544F"] = "OpenType Font" $mBinaryFlags["4F54544F"] = 1 $mSignatures["774F4646"] = "Web Open Font (WOFF)" $mBinaryFlags["774F4646"] = 1 $mSignatures["774F4632"] = "Web Open Font 2 (WOFF2)" $mBinaryFlags["774F4632"] = 1 ; === DISK IMAGES === $mSignatures["4344303031"] = "ISO 9660 CD Image" $mBinaryFlags["4344303031"] = 1 ; === TEXT FORMATS WITH SIGNATURES === ; RTF $mSignatures["7B5C72746631"] = "Rich Text Format" $mBinaryFlags["7B5C72746631"] = 0 ; XML/HTML variants $mSignatures["3C3F786D6C"] = "XML Document" $mBinaryFlags["3C3F786D6C"] = 0 $mSignatures["3C21444F43545950"] = "HTML Document" $mBinaryFlags["3C21444F43545950"] = 0 ; Script files with shebang $mSignatures["2321"] = "Shell/Script File" $mBinaryFlags["2321"] = 0 ; === ENCODING SIGNATURES (BOMs) === $mSignatures["EFBBBF"] = "UTF-8 with BOM" $mBinaryFlags["EFBBBF"] = 0 $mSignatures["FFFE"] = "UTF-16 Little Endian" $mBinaryFlags["FFFE"] = 0 $mSignatures["FEFF"] = "UTF-16 Big Endian" $mBinaryFlags["FEFF"] = 0 $mSignatures["FFFE0000"] = "UTF-32 Little Endian" $mBinaryFlags["FFFE0000"] = 0 $mSignatures["0000FEFF"] = "UTF-32 Big Endian" $mBinaryFlags["0000FEFF"] = 0 ; === SECURITY & CERTIFICATES === $mSignatures["2D2D2D2D2D424547494E"] = "PEM Certificate" $mBinaryFlags["2D2D2D2D2D424547494E"] = 0 $mSignatures["308"] = "DER Certificate" $mBinaryFlags["308"] = 1 Local $aResult[2] = [$mSignatures, $mBinaryFlags] Return $aResult EndFunc ;==>_CreateSignatureDatabase ;================================================================================ ; Helper Function: Check for special patterns (not starting at offset 0) ;================================================================================ Func _CheckSpecialPatterns($sHexData) ; RIFF-based formats need to be checked at offset 8 If StringLeft($sHexData, 8) = "52494646" Then ; RIFF Local $sSubType = StringMid($sHexData, 17, 8) ; Offset 8 Switch $sSubType Case "57415645" ; WAVE Return "|BIN|WAV Audio" Case "41564920" ; AVI Return "|BIN|AVI Video" Case "57454250" ; WEBP Return "|BIN|WebP Image" EndSwitch EndIf ; QuickTime/MP4 - check ftyp at offset 4 If StringMid($sHexData, 9, 8) = "66747970" Then ; ftyp Local $sBrand = StringMid($sHexData, 17, 8) ; Brand Switch $sBrand Case "69736F6D", "6D703431", "6D703432" ; isom, mp41, mp42 Return "|BIN|MP4 Video" Case "71742020" ; qt Return "|BIN|QuickTime MOV" Case "33677035", "33677034" ; 3gp5, 3gp4 Return "|BIN|3GPP Video" EndSwitch EndIf ; ZIP-based formats If StringLeft($sHexData, 8) = "504B0304" Then ; PK.. ; Look for specific files in ZIP to identify format If StringInStr($sHexData, "776F72642F") Then ; word/ Return "|BIN|Microsoft Word (DOCX)" ElseIf StringInStr($sHexData, "786C2F") Then ; xl/ Return "|BIN|Microsoft Excel (XLSX)" ElseIf StringInStr($sHexData, "7070742F") Then ; ppt/ Return "|BIN|Microsoft PowerPoint (PPTX)" ElseIf StringInStr($sHexData, "636F6E74656E742E786D6C") Then ; content.xml Return "|BIN|OpenOffice Document" ElseIf StringInStr($sHexData, "4D4554412D494E462F") Then ; META-INF/ Return "|BIN|Java JAR Archive" ElseIf StringInStr($sHexData, "416E64726F69644D616E69666573742E786D6C") Then ; AndroidManifest.xml Return "|BIN|Android APK" EndIf EndIf ; TAR detection at offset 257 If StringMid($sHexData, 513, 12) = "757374617200" Or StringMid($sHexData, 513, 12) = "757374617220" Then Return "|BIN|TAR Archive" EndIf ; EXE sub-type detection If StringLeft($sHexData, 4) = "4D5A" Then ; MZ header ; Look for PE signature If StringInStr($sHexData, "50450000") Then Return "|BIN|Windows PE Executable" EndIf EndIf Return "" EndFunc ;==>_CheckSpecialPatterns ;================================================================================ ; Helper Function: Convert Hex to Binary (takes a portion for testing) ;================================================================================ Func _HexToBinary($sHexData) ; Only take the first 1024 hex characters (512 bytes) for analysis Local $sTestHex = StringLeft($sHexData, 1024) Local $sBinary = "" ; Convert each hex pair into a character For $i = 1 To StringLen($sTestHex) Step 2 Local $sHexByte = StringMid($sTestHex, $i, 2) If StringLen($sHexByte) = 2 Then Local $iDecimal = Dec($sHexByte) $sBinary &= Chr($iDecimal) EndIf Next Return $sBinary EndFunc ;==>_HexToBinary ;================================================================================ ; Helper Function: Advanced text analysis ;================================================================================ Func _AdvancedTextAnalysis($sHexData) Local $sBinaryData = _HexToBinary($sHexData) If $sBinaryData = "" Then Return "" ; === BOM and Encoding Detection === Local $sEncoding = _DetectEncoding($sHexData) If $sEncoding <> "" Then Return $sEncoding ; === Content-based Detection === Local $sContentType = _DetectTextContent($sBinaryData) If $sContentType <> "" Then Return $sContentType ; === Heuristic Analysis === Local $sHeuristicType = _HeuristicTextAnalysis($sBinaryData) If $sHeuristicType <> "" Then Return $sHeuristicType Return "" EndFunc ;==>_AdvancedTextAnalysis ;================================================================================ ; Helper Function: Simple Min function ;================================================================================ Func __Min($a, $b) Return ($a < $b) ? $a : $b EndFunc ;==>__Min ;================================================================================ ; Helper Function: Detect encoding and text variants ;================================================================================ Func _DetectEncoding($sHexData) ; BOMs are already handled in the main database, this function can be expanded later ; if more complex logic is needed to guess encoding without a BOM. Return "" EndFunc ;==>_DetectEncoding ;================================================================================ ; Helper Function: Detect content type based on patterns ;================================================================================ Func _DetectTextContent($sContent) ; === Configuration Files === If StringRegExp($sContent, '(?m)^\s*\[[^\]]+\]') Then Return "INI Configuration File" If StringRegExp($sContent, '(?i)^server\s*=|^host\s*=|^port\s*=') Then Return "Configuration File" ; === Data Formats === If _IsAdvancedJSON($sContent) Then Return "JSON Data File" If _IsAdvancedCSV($sContent) Then Return "CSV Data File" If _IsTSV($sContent) Then Return "TSV (Tab Separated Values)" If _IsYAML($sContent) Then Return "YAML Configuration" If _IsTOML($sContent) Then Return "TOML Configuration" ; === Log Files === Local $sLogType = _DetectLogFormat($sContent) If $sLogType <> "" Then Return $sLogType ; === Programming Languages === Local $sCodeType = _DetectProgrammingLanguage($sContent) If $sCodeType <> "" Then Return $sCodeType ; === Markup Languages === Local $sMarkupType = _DetectMarkupLanguage($sContent) If $sMarkupType <> "" Then Return $sMarkupType ; === Specialized Text Formats === Local $sSpecialType = _DetectSpecializedFormats($sContent) If $sSpecialType <> "" Then Return $sSpecialType Return "" EndFunc ;==>_DetectTextContent ;================================================================================ ; Helper Function: Advanced JSON detection ;================================================================================ Func _IsAdvancedJSON($sContent) Local $sTrimmed = StringStripWS($sContent, 3) If $sTrimmed = "" Then Return False Local $bHasStructure = False If (StringLeft($sTrimmed, 1) = "{" And StringRight($sTrimmed, 1) = "}") Or _ (StringLeft($sTrimmed, 1) = "[" And StringRight($sTrimmed, 1) = "]") Then $bHasStructure = True EndIf If Not $bHasStructure Then Return False Local $aJSONPatterns[6] = [ _ '"[^"]*"\s*:\s*"[^"]*"', _ ; "key": "value" '"[^"]*"\s*:\s*\d+', _ ; "key": 123 '"[^"]*"\s*:\s*(true|false|null)', _ ; "key": true '"[^"]*"\s*:\s*\[', _ ; "key": [ '"[^"]*"\s*:\s*\{', _ ; "key": { '\[\s*("|\d|\{|\[)' _ ; Array starts with valid element ] Local $iMatches = 0 For $sPattern In $aJSONPatterns If StringRegExp($sContent, $sPattern) Then $iMatches += 1 Next Return ($iMatches >= 2) EndFunc ;==>_IsAdvancedJSON ;================================================================================ ; Helper Function: Advanced CSV detection ;================================================================================ Func _IsAdvancedCSV($sContent) Local $aLines = StringSplit(StringStripCR($sContent), @LF, 1) If $aLines[0] < 2 Then Return False Local $iCommaLines = 0 Local $iConsistentColumns = 0 Local $iPrevColCount = -1 Local $iLinesToCheck = __Min(10, $aLines[0]) For $i = 1 To $iLinesToCheck Local $sLine = StringStripWS($aLines[$i], 3) If $sLine = "" Or StringLeft($sLine, 1) = "#" Then ContinueLoop Local $iCommas = StringLen($sLine) - StringLen(StringReplace($sLine, ",", "")) If $iCommas >= 1 Then $iCommaLines += 1 Local $iCurrentCols = $iCommas + 1 If $iPrevColCount = -1 Then $iPrevColCount = $iCurrentCols $iConsistentColumns = 1 ElseIf $iPrevColCount = $iCurrentCols Then $iConsistentColumns += 1 EndIf EndIf Next If $iLinesToCheck = 0 Then Return False Local $fCommaRatio = $iCommaLines / $iLinesToCheck Local $fConsistencyRatio = $iConsistentColumns / $iLinesToCheck Return ($fCommaRatio >= 0.5 And $fConsistencyRatio >= 0.7) EndFunc ;==>_IsAdvancedCSV ;================================================================================ ; Helper Function: TSV detection ;================================================================================ Func _IsTSV($sContent) Local $aLines = StringSplit(StringStripCR($sContent), @LF, 1) If $aLines[0] < 2 Then Return False Local $iTabLines = 0 Local $iLinesToCheck = __Min(5, $aLines[0]) For $i = 1 To $iLinesToCheck Local $sLine = $aLines[$i] Local $iTabs = StringLen($sLine) - StringLen(StringReplace($sLine, @TAB, "")) If $iTabs >= 1 Then $iTabLines += 1 Next Return ($iLinesToCheck > 0 And $iTabLines / $iLinesToCheck >= 0.6) EndFunc ;==>_IsTSV ;================================================================================ ; Helper Function: YAML detection ;================================================================================ Func _IsYAML($sContent) Local $aYAMLPatterns[5] = [ _ '(?m)^---', _ ; Document separator '(?m)^\w+:\s+[^|\>]', _ ; Key with simple value '(?m)^\s+-\s+\w+', _ ; List items '(?m)^\s+\w+:\s+', _ ; Indented key-value '!!?\w+' _ ; Type tags ] Local $iMatches = 0 For $sPattern In $aYAMLPatterns If StringRegExp($sContent, $sPattern) Then $iMatches += 1 Next Return ($iMatches >= 2) EndFunc ;==>_IsYAML ;================================================================================ ; Helper Function: TOML detection ;================================================================================ Func _IsTOML($sContent) Local $aTOMLPatterns[5] = [ _ '(?m)^\[[\w\.\-]+\]', _ ; Sections '(?m)^\w+\s*=\s*"[^"]*"', _ ; String values '(?m)^\w+\s*=\s*\d+', _ ; Number values '(?m)^\w+\s*=\s*(true|false)', _ ; Boolean values '(?m)^\w+\s*=\s*\[\s*' _ ; Arrays ] Local $iMatches = 0 For $sPattern In $aTOMLPatterns If StringRegExp($sContent, $sPattern) Then $iMatches += 1 Next Return ($iMatches >= 2) EndFunc ;==>_IsTOML ;================================================================================ ; Helper Function: Detect log file formats ;================================================================================ Func _DetectLogFormat($sContent) If StringRegExp($sContent, '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s+-\s+-\s+\[') Then Return "Apache Access Log" If StringRegExp($sContent, '\[.*\]\s+\[(error|warn|info)\]\s+\[client') Then Return "Apache Error Log" If StringRegExp($sContent, '\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+\w+\s+\w+') Then Return "IIS Web Log" If StringInStr($sContent, "Event Type:") And StringInStr($sContent, "Event ID:") Then Return "Windows Event Log" If StringRegExp($sContent, '(?i)\d{4}[-/]\d{2}[-/]\d{2}.*?(ERROR|WARN|INFO|DEBUG|TRACE)') Then Return "Application Log" Return "" EndFunc ;==>_DetectLogFormat ;================================================================================ ; Helper Function: Detect programming languages ;================================================================================ Func _DetectProgrammingLanguage($sContent) If StringRegExp($sContent, '(?i)<\?php') Then Return "PHP Script" If StringRegExp($sContent, '(?i)(import.*from|export\s+(default\s+)?|(const|let)\s+\w+\s*=)') Then Return "JavaScript (ES6+)" If StringRegExp($sContent, '(?i)(def\s+\w+\s*\(|import\s+\w+|from\s+\w+\s+import)') Then Return "Python Script" If StringRegExp($sContent, '(?i)#include\s*<.*>|int\s+main\s*\(') Then If StringRegExp($sContent, '(?i)(class\s+\w+|public:|private:|protected:|\w+::\w+)') Then Return "C++ Source Code" Return "C Source Code" EndIf If StringRegExp($sContent, '(?i)(using\s+System|namespace\s+\w+|public\s+class\s+\w+)') Then Return "C# Source Code" If StringRegExp($sContent, '(?i)(import\s+java\.|public\s+class\s+\w+|package\s+[\w\.]+)') Then Return "Java Source Code" If StringRegExp($sContent, '(?i)^#!/bin/(bash|sh|zsh)') Then Return "Shell Script" ; --- FIX: Moved AutoIt check before PowerShell --- ; AutoIt (Check before PowerShell due to similar variable syntax '$') If StringRegExp($sContent, '(?i)(#include|Func\s+\w+\s*\(|Local\s+\$\w+|\$\w+\s*=)') Then Return "AutoIt Script" ; PowerShell If StringRegExp($sContent, '(?i)(param\s*\(|\$\w+\s*=|Get-\w+|Set-\w+)') Then Return "PowerShell Script" ; --- END FIX --- If StringRegExp($sContent, '(?i)(@echo\s+(off|on)|set\s+\w+=|goto\s+\w+)') Then Return "Windows Batch File" If StringRegExp($sContent, '(?i)(SELECT\s+.*\s+FROM|CREATE\s+TABLE|INSERT\s+INTO)') Then Return "SQL Script" Return "" EndFunc ;==>_DetectProgrammingLanguage ;================================================================================ ; Helper Function: Detect markup languages ;================================================================================ Func _DetectMarkupLanguage($sContent) If _IsAdvancedMarkdown($sContent) Then Return "Markdown Document" If StringRegExp($sContent, '(?i)\\documentclass\{|\\begin\{document\}') Then Return "LaTeX Document" If StringRegExp($sContent, '<\?xml.*\?>') Then If StringInStr($sContent, "<rss") Then Return "RSS Feed" If StringInStr($sContent, "<feed") Then Return "Atom Feed" Return "XML Document" EndIf If StringRegExp($sContent, '(?i)<!DOCTYPE\s+html|<html') Then Return "HTML Document" If StringRegExp($sContent, '(?i)<svg[^>]*>|xmlns="http://www\.w3\.org/2000/svg"') Then Return "SVG Vector Graphics" Return "" EndFunc ;==>_DetectMarkupLanguage ;================================================================================ ; Helper Function: Advanced Markdown detection ;================================================================================ Func _IsAdvancedMarkdown($sContent) Local $aMarkdownPatterns[8] = [ _ '(?m)^#{1,6}\s+.+', _ ; Headers '(?m)^\s*[-*+]\s+', _ ; Unordered lists '(?m)^\s*\d+\.\s+', _ ; Ordered lists '\*{1,2}[^*]+\*{1,2}', _ ; Emphasis '`[^`]+`', _ ; Inline code '(?m)^```', _ ; Fenced code blocks '\[.+\]\(.+\)', _ ; Links '(?m)^>\s+' _ ; Blockquotes ] Local $iMatches = 0 For $sPattern In $aMarkdownPatterns If StringRegExp($sContent, $sPattern) Then $iMatches += 1 Next Return ($iMatches >= 3) EndFunc ;==>_IsAdvancedMarkdown ;================================================================================ ; Helper Function: Detect specialized text formats ;================================================================================ Func _DetectSpecializedFormats($sContent) If StringRegExp($sContent, '(?m)^(From|To|Subject|Date|Message-ID):\s+') Then Return "Email Message (EML)" If StringRegExp($sContent, '(?i)BEGIN:VCARD') Then Return "vCard Contact" If StringRegExp($sContent, '(?i)BEGIN:VCALENDAR') Then Return "iCalendar Event" If StringRegExp($sContent, '(?m)^(diff |--- |\+\+\+ |@@ )') Then Return "Diff/Patch File" If StringRegExp($sContent, '(?i)(MIT License|Apache License|GNU General Public License)') Then Return "Software License" If StringRegExp($sContent, '(?i)("name"\s*:\s*"[^"]+"|"version"\s*:\s*"[^"]+"|"dependencies")') Then Return "package.json (Node.js)" If StringRegExp($sContent, '(?i)^(FROM\s+|RUN\s+|COPY\s+|WORKDIR\s+|EXPOSE\s+)') Then Return "Dockerfile" If StringRegExp($sContent, '(?i)(version:\s*["\' & "']3\.|services:|volumes:|networks:)") Then Return "Docker Compose YAML" If StringRegExp($sContent, '(?i)(apiVersion:\s*|kind:\s*(Deployment|Service|Pod))') Then Return "Kubernetes Manifest" If StringRegExp($sContent, '(?m)^\w+:\s*$|^\t') Then Return "Makefile" If StringRegExp($sContent, '(?m)^\*\..*|^!.*|^#.*ignore') Then Return "Ignore File (.gitignore style)" If StringRegExp($sContent, '(?m)^\d+\.\d+\.\d+\.\d+\s+\w+') Then Return "Hosts File" If StringRegExp($sContent, '(?m)^[A-Z0-9_]+\s*=\s*.+') Then Return "Environment File (.env)" If StringRegExp($sContent, '(?m)^[a-zA-Z0-9\._-]+\s*=\s*.+') Then Return "Java Properties File" If StringRegExp($sContent, "(?m)^WEBVTT") Then Return "WebVTT Subtitles" If StringRegExp($sContent, '(?m)^\d+\R\d{2}:\d{2}:\d{2},\d{3} --> \d{2}:\d{2}:\d{2},\d{3}') Then Return "SubRip Subtitles (.srt)" Return "" EndFunc ;==>_DetectSpecializedFormats ;================================================================================ ; Helper Function: Heuristic analysis to distinguish between Text and Binary ;================================================================================ Func _HeuristicTextAnalysis($sBinaryData) Local $iLen = StringLen($sBinaryData) If $iLen = 0 Then Return "" Local $iNonPrintable = 0 Local $iNulls = 0 ; Analyze the bytes in the string For $i = 1 To $iLen Local $iChar = Asc(StringMid($sBinaryData, $i, 1)) ; Count null bytes If $iChar = 0 Then $iNulls += 1 EndIf ; Count non-printable characters (outside ASCII 32-126 and common whitespace) If ($iChar < 32 And $iChar <> 9 And $iChar <> 10 And $iChar <> 13) Or ($iChar > 126 And $iChar < 160) Then $iNonPrintable += 1 EndIf Next ; --- HEURISTIC RULES --- ; Rule 1: If there are null bytes, it's almost certainly a binary file. ; Text files rarely contain NUL characters, except for UTF-16/32 (which are handled by BOM). If $iNulls > 0 Then Return "Binary Data" EndIf ; Rule 2: If the ratio of non-printable characters is too high, it's likely a binary file. ; Text files consist mainly of printable characters. Local $fNonPrintableRatio = $iNonPrintable / $iLen If $fNonPrintableRatio > 0.15 Then ; 15% threshold Return "Binary Data" EndIf ; If it passes the above checks, assume it's a plain text document. Return "Plain Text Document" EndFunc ;==>_HeuristicTextAnalysis !2 points
-
_WinAPI_DwmEnableBlurBehindWindow in Windows 11
ioa747 and one other reacted to WildByDesign for a topic
You're welcome. And thank you for the sharing your example as well with the buttons. Your example makes more sense for being able to play around with the example. I've never been very good with examples. I was working on another example earlier today using a slider to automatically change the color transparency in real-time and it's working well. So I think what I will do is combine my slider example with your example and should make for a good example in the end. Also, I was thinking of adding an input box (likely a color picker too) to change color. And with that, maybe a "Random Color" button as well.2 points -
Never say never 😉 It was too late and I forgot to set the correct stride value for 24bit capturing. I uploaded the x86 version which should work now. We’ll figure it out if it’s still not working.2 points
-
I'm 47 years old. Have my own business. I employ 4 people. Working with "bussiness psychologist" mostly on communication and management in bussines in relation to HR. So. No I do not think so. I think that, You simply haven't thought enough about the meaning of my statement. I know it's sometimes difficult, mainly because of my poor English. BTW. I see JOS and I are still trying to be polite to you. Please respect this.2 points
-
AutoIt COM speed with variants
WildByDesign and one other reacted to mLipok for a topic
The only thing is that you are creating time pressure on people who devote their time here on a NON PROFIT basis. Lets revert your question: Have you signed any agreement that obligates anyone to respond to your question within the required timeframe ? If not, I suggest you be more patient, understanding, and formulate your thoughts better, meaning to consider not only your own needs but also respect the time of others. And this is not just about communication in relation to AutoIt forum members, but also in your life in general. p.s. Please don't take my answer as offensive, but rather as advice from a kind person.2 points -
Made a quick test with 3.3.12.0 by replacing AutoIt3.exe only - same result.2 points
-
OK I've managed to get this working for the most part... bear with me. say we want to resolve: "Windows.Foundation.Collections.IVector`1<Microsoft.UI.Xaml.Controls.ColumnDefinition>" broadly speaking, this is what needs to happen. Create a MetaDataLocator - this is similar to how we're creating our delegates. It doesn't inherit from IUnknown, and has 1 method called "Locate"... but more on this in a bit! Call RoParseTypeName. This gives us an array of name elements i.e.: ["Windows.Foundation.Collections.IVector`1", "Microsoft.UI.Xaml.Controls.ColumnDefinition"] Use this info to call RoGetParameterizedTypeInstanceIID. As RoGetParameterizedTypeInstanceIID does its thing, it'll pump us for information - by you guessed it! calling our "Locate" function. we are provided with: a name of a typedef and a pointer to an IRoSimpleMetaDataBuilder interface. (I've written an interface library for this one). We need to dig in the metadata for that info, then call the correct method of the builder to send it on. A call to RoGetMetaDataFile will get us an pointer to a IMetadataImport2 interface. This is what we should use to find stuff. In our scenario, the first time "Locate" is called we're asked to resolve "Windows.Foundation.Collections.IVector`1" So we need to determine what this is.. (a paramatised interface). Therefore we should call builder.SetParameterizedInterface(PIID, NumParams). Next time around we get "Microsoft.UI.Xaml.Controls.RowDefinition". This is a class. So this time we should call builder.SetRuntimeClassSimpleDefault(ClassName, DefaultInterface, DefaultInterfaceIID). DefaultInterfaceIID is optional though can be left null. In this case Locate() would be called a third time asking us to resolve the default interface (Microsoft.UI.Xaml.Controls.IRowDefinition). Because this is a non-paramatised interface, we'd then call builder.SetWinRtInterface(IID). Once RoGetParameterizedTypeInstanceIID is satisfied it'll spit out what it thinks the IID is. If we call the wrong method on IRoSimpleMetaDataBuilder or provide bad info, then unsurprisingly we get an incorrect IID as a result! I'll do a bit of a tidy up, and pop some code up in a day or two2 points
-
AutoItHelp v3.3.16.1 with external CSS loading
ioa747 and one other reacted to argumentum for a topic
..ok. Back at it I don't like the current CSS as is in the help site. So, I made a "SciTE4AutoIt3 to CSS" script that outputs a nicer "color list" ( to give it a name, not an HTML guy ) #NoTrayIcon #include <StringConstants.au3> #include <SendMessage.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global $g_SciTE_hDirector = 0, $g_idMemo = 0, $g_hGUI = 0 If Not StringInStr($CmdLineRaw, "/ErrorStdOut") Or @Compiled Then Exit MsgBox($MB_TOPMOST, @ScriptName, "Run as script from SciTE4AutoIt3", 60) EndIf Exit main() Func main() Local $iW = 700, $iH = 350, $iErr, $sError = "" $g_hGUI = GUICreate(StringTrimRight(@ScriptName, 4), $iW, $iH) $g_idMemo = GUICtrlCreateEdit("", 2, 2, $iW - 4, $iH - 4, $WS_VSCROLL) GUICtrlSetFont($g_idMemo, 9, 400, 0, "Courier New") GUISetState(@SW_SHOW) Local $sFilename = _SciTE_ExportScriptToHTML(@ScriptFullPath, @TempDir & "\" & @ScriptName & ".htm") $iErr = @error Switch $iErr Case 1 $sError = 'File not created' Case 2 $sError = 'File did not rename back to original' Case 3 $sError = 'AutoIt Script Editor (SciTE4AutoIt3) is not loaded' EndSwitch Local $sData = FileRead($sFilename) FileDelete($sFilename) Local $sChunk = "", $aChunks = StringSplit($sData, "><") For $n = 1 To UBound($aChunks) - 1 If StringInStr($aChunks[$n], @CRLF & ".S") Then $sChunk = $aChunks[$n] ; this is where the CSS is at ExitLoop EndIf Next $aChunks = StringSplit($sChunk, "}{") Local $aCSS[UBound($aChunks) + 2][3] $aCSS[0][0] = 0 For $n = 2 To UBound($aChunks) - 1 Step 2 ; turn the CSS into an array $aChunks[$n] = StringStripWS(StringReplace($aChunks[$n], @CRLF, " "), 7) If $aChunks[$n] = "" Then ContinueLoop $aCSS[0][0] += 1 $aCSS[$aCSS[0][0]][0] = StringStripWS($aChunks[$n - 1], 8) $aCSS[$aCSS[0][0]][1] = $aChunks[$n] $aCSS[$aCSS[0][0]][2] = _SciTE_Colors_Description($aCSS[$aCSS[0][0]][0]) Next ReDim $aCSS[$aCSS[0][0] + 1][3] ; this builds the CSS values for the script examples in the CHM/HTM file Local $sCSS = '/*** SciTE colors ***/' & @CRLF For $n = 1 To $aCSS[0][0] Switch $aCSS[$n][0] Case "span" $sCSS &= '/* ' & $aCSS[$n][0] & " { " & $aCSS[$n][1] & " } " & $aCSS[$n][2] & " */" & @CRLF Case Else $sCSS &= $aCSS[$n][0] & " { " & _SciTE_Colors_RemoveFontSize($aCSS[$n][1]) & " } /* " & $aCSS[$n][2] & " */" & @CRLF EndSwitch Next $sCSS &= '/*** SciTE colors ***/' & @CRLF ;~ ConsoleWrite($sCSS) MemoWrite($sError = "" ? $sCSS : $sError) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() Return SetError($iErr, 0, $iErr) EndFunc ;==>main ; Write message to memo Func MemoWrite($sMessage = "", $iAppend = 1) GUICtrlSetData($g_idMemo, $sMessage & @CRLF, $iAppend) EndFunc ;==>MemoWrite Func _SciTE_Colors_RemoveFontSize($sStr) Local $n, $sReturn = "", $aArray = StringSplit($sStr, ";") For $n = 1 To UBound($aArray) - 1 If StringStripWS($aArray[$n], 8) = "" Then ContinueLoop If StringInStr($aArray[$n], "font-size") Then ContinueLoop $sReturn &= $aArray[$n] & ";" Next Return $sReturn EndFunc ;==>_SciTE_Colors_RemoveFontSize Func _SciTE_Colors_Description($sS0) Switch $sS0 ; /*** SciTE colors ***/ /** __SciTE4AutoIt3_Dark.SciTEConfig **/ Case ".S0" Return "White space" Case ".S1" Return "Comment line" Case ".S2" Return "Comment block" Case ".S3" Return "Number" Case ".S4" Return "Function" Case ".S5" Return "Keyword" Case ".S6" Return "Macro" Case ".S7" Return "String" Case ".S8" Return "Operator" Case ".S9" Return "Variable" Case ".S10" Return "Send keys in string" Case ".S11" Return "Pre-Processor" Case ".S12" Return "Special" Case ".S13" Return "Abbrev-Expand" Case ".S14" Return "COM Objects" Case ".S15" Return "Standard UDF's" EndSwitch Return "" EndFunc ;==>_SciTE_Colors_Description ; #FUNCTION# ==================================================================================================================== ; @error: ; 1 = File not created ; 2 = File did not rename back to original ; 3 = SciTE is not loaded ; ; Example: ;~ MsgBox(0, @ScriptName, "File: " & _SciTE_ExportScriptToHTML(@ScriptFullPath, @ScriptFullPath & ".htm") & _ ;~ @LF & @LF & 'Error: ' & @error & @LF & 'Extended: ' & @extended) ; =============================================================================================================================== Func _SciTE_ExportScriptToHTML($sSource, $sDestination) Local $iErr = 1, $iExt = 0, $sDestinationTemp = $sDestination & "~" & TimerInit() & ".htm" If Not _SciTE_GetDirector(True) Then Return SetError(3, 0, "") __SciTE_Send_Command(0, _SciTE_GetDirector(False), 'exportashtml:' & StringReplace($sDestinationTemp, '\', '\\')) If FileGetSize($sDestinationTemp) Then $iExt = Int(Not FileMove($sDestinationTemp, $sDestination, 9)) $iErr = ($iExt ? 2 : 0) EndIf Return SetError($iErr, $iExt, ($iErr ? $sDestinationTemp : $sDestination)) EndFunc ;==>_SciTE_ExportScriptToHTML Func _SciTE_GetDirector($bIsReset = False) Local Enum $SCITE_DIRECTOR = 1 If $bIsReset Or Not IsHWnd($g_SciTE_hDirector) Then $g_SciTE_hDirector = WinGetHandle('DirectorExtension') If @error Then $g_SciTE_hDirector = 0 EndIf Return $g_SciTE_hDirector EndFunc ;==>_SciTE_GetDirector Func __SciTE_Send_Command($hWnd, $hSciTE, $sMsg) Local $bReturn = False, $_WM_COPYDATA = 74, $tagCOPYDATASTRUCT = "ulong_ptr dwData;dword cbData;ptr lpData" If Not (StringStripWS($sMsg, $STR_STRIPALL) == '') Then $sMsg = ':' & Dec(StringTrimLeft($hWnd, StringLen('0x'))) & ':' & $sMsg Local Const $tBuffer = DllStructCreate('char cdata[' & StringLen($sMsg) + 1 & ']') DllStructSetData($tBuffer, 'cdata', $sMsg) Local Const $tCOPYDATASTRUCT = DllStructCreate($tagCOPYDATASTRUCT) DllStructSetData($tCOPYDATASTRUCT, 'dwData', 0) DllStructSetData($tCOPYDATASTRUCT, 'cbData', DllStructGetSize($tBuffer)) DllStructSetData($tCOPYDATASTRUCT, 'lpData', DllStructGetPtr($tBuffer)) _SendMessage($hSciTE, _ $_WM_COPYDATA, _ $hWnd, _ DllStructGetPtr($tCOPYDATASTRUCT)) $bReturn = Not @error EndIf Return $bReturn EndFunc ;==>__SciTE_Send_Command #cs Added for color export. #ce #pragma compile(LegalCopyright, © You) ; Added for color export. Func ForColorExports() Return "This is not meant to run. Added for color export." ; "cmd " ..typing that would expand to "RunWait('"' & @ComSpec & '" /c |', '', @SW_HIDE)" ; The .S13 ("Abbrev-Expand") will not be rendered in the code, thereby preventing the value from being exported. ; for more help go to https://www.autoitscript.com/autoit3/scite/docs/SciTE4AutoIt3/SciTE4AutoIt3-AbbreviationHowTo.html Local $oShell = ObjCreate("shell.application") ; Get the Windows Shell Object Local $oShellWindows = $oShell.Windows() ; Get the collection of open shell Windows Send("{SPACE}") EndFunc ;==>ForColorExports /*** SciTE colors ***/ .S0 { color: #80C0FF; } /* White space */ .S1 { font-style: italic; color: #60A060; } /* Comment line */ .S2 { font-style: italic; color: #60A060; } /* Comment block */ .S3 { color: #C0FFFF; } /* Number */ .S4 { color: #8080FF; } /* Function */ .S5 { color: #C080C0; } /* Keyword */ .S6 { color: #A0A000; } /* Macro */ .S7 { color: #F0E090; } /* String */ .S8 { color: #FF8000; } /* Operator */ .S9 { color: #D0D0D0; } /* Variable */ .S10 { color: #A0A0A0; } /* Send keys in string */ .S11 { color: #8996A8; } /* Pre-Processor */ .S12 { color: #FFAAB7; } /* Special */ .S14 { color: #993399; } /* COM Objects */ .S15 { color: #0080FF; } /* Standard UDF's */ /* span { font-family: 'Courier New'; color: #D0D0D0; font-size: 10pt; } */ /*** SciTE colors ***/ that is easier to see and edit, and with some help for what applies to what. ( you could test online too ) I'll have my test site updated soon(done) to reflect what's in the works. Given that the test site, is testing stuff, some times the prior CSS or JS may be used instead of the current. To clear the cache data, open "inspect data", go to network and tick "Disable cache". Reload the page and that should be all that's needed.2 points -
Controller-Worker-Task Manager Framework
WildByDesign and one other reacted to Trong for a topic
v2: Added AutoStart functionality ; =============================================================================================================================== ; SCRIPT: Controller-Worker-Task Manager Framework ; AUTHOR: Dao Van Trong - TRONG.PRO ; VERSION: 2.0 (Added AutoStart functionality) ; 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. ; 6. Auto-starting specified Workers and Tasks on launch. ; ; - 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. ; ; PERFORMANCE IMPROVEMENTS: ; - Optimized tray menu handling with reduced event processing overhead ; - Faster exit processing with immediate cleanup ; - Reduced Adlib function frequency for better responsiveness ; - Improved memory management and array operations ; ; NEW FEATURES: ; - On/Off declaration for MasterWorkers and MasterTasks ; - Au3Stripper compatibility with proper function protection ; - Enhanced configuration system ; - AutoStart option for Workers and Tasks ; =============================================================================================================================== #include <TrayConstants.au3> #include <Array.au3> #include <File.au3> #include <FileConstants.au3> ; Au3Stripper protection directives #Au3Stripper_Ignore_Funcs=Worker1Function,Worker2Function,Worker3Function,Worker4Function,Worker5Function,Worker6Function,Worker7Function,Worker8Function,Worker9Function,Worker10Function #Au3Stripper_Ignore_Funcs=TaskA_Function,TaskB_Function,TaskC_Function,TaskD_Function,TaskE_Function,TaskF_Function,TaskG_Function,TaskH_Function,TaskI_Function,TaskJ_Function #Au3Stripper_Ignore_Funcs=_CheckStatus_Adlib,_CheckForConfigChanges_Adlib,_WorkerHeartbeat_Adlib #Au3Stripper_Ignore_Variables=$g_aMasterWorkers,$g_aMasterTasks,$g_aWorkers,$g_aTasks,$g_aWorkerTrayItems,$g_aTaskTrayItems ; =============================================================================================================================== ; --- 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 = 15000 ; Increased for better performance Global $g_sLastConfigModDate = "" ; --- Registry & IPC --- Global Const $g_sRegBase = "HKCU\Software\ControllerWorkerApp" Global Const $g_iAdlibCheckInterval = 2000 ; Reduced frequency for better performance Global Const $g_iGracefulShutdownTimeout = 2000 ; Reduced for faster exit ; --- 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 ; --- Performance optimization flags --- Global $g_bShuttingDown = False Global $g_bConfigReloading = False ; --- MASTER DATA STRUCTURES (Hard-coded definitions) --- ; [InternalName, DisplayName, FunctionName, MenuType, Status(On/Off), AutoStart(On/Off)] Global Const $g_aMasterWorkers[10][6] = [ _ ["CheckResources", "Check Resources", "Worker1Function", $MENU_TYPE_MAIN, "On", "On"], _ ; AutoStart Enabled ["SyncFiles", "Sync Files", "Worker2Function", $MENU_TYPE_MAIN, "On", "Off"], _ ["MonitorNetwork", "Monitor Network", "Worker3Function", $MENU_TYPE_MAIN, "On", "On"], _ ; AutoStart Enabled ["BackupDB", "Backup DB", "Worker4Function", $MENU_TYPE_SUB, "On", "Off"], _ ["CleanupLogs", "Cleanup Logs", "Worker5Function", $MENU_TYPE_SUB, "On", "Off"], _ ["ProcessEmails", "Process Emails", "Worker6Function", $MENU_TYPE_SUB, "On", "Off"], _ ["AutoScreenshot", "Auto Screenshot", "Worker7Function", $MENU_TYPE_SUB, "Off", "Off"], _ ["MonitorTemp", "Monitor Temp", "Worker8Function", $MENU_TYPE_SUB, "Off", "Off"], _ ["CheckUpdates", "Check Updates", "Worker9Function", $MENU_TYPE_SUB, "On", "Off"], _ ["SecurityScan", "Security Scan", "Worker10Function", $MENU_TYPE_SUB, "Off", "Off"] _ ] ; [InternalName, DisplayName, FunctionName, MenuType, ExecutionMode, RunType, Status(On/Off), AutoStart(On/Off)] Global Const $g_aMasterTasks[10][8] = [ _ ["QuickCleanup", "Quick Cleanup", "TaskA_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_SUBAPP, "On", "Off"], _ ["GenerateReport", "Generate Report", "TaskB_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_SUBAPP, "On", "On"], _ ; AutoStart Enabled ["SendNotification", "Send Notification (Direct)", "TaskJ_Function", $MENU_TYPE_MAIN, $TASK_MODE_EXCLUSIVE, $TASK_RUN_TYPE_DIRECT, "On", "Off"], _ ["TaskC", "Run Task C (Direct)", "TaskC_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_DIRECT, "On", "Off"], _ ["TaskD", "Run Task D", "TaskD_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "Off", "Off"], _ ["TaskE", "Run Task E", "TaskE_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "Off", "Off"], _ ["TaskF", "Run Task F", "TaskF_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "On", "Off"], _ ["TaskG", "Run Task G", "TaskG_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "Off", "Off"], _ ["TaskH", "Run Task H", "TaskH_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "On", "Off"], _ ["TaskI", "Run Task I", "TaskI_Function", $MENU_TYPE_SUB, $TASK_MODE_CONCURRENT, $TASK_RUN_TYPE_SUBAPP, "Off", "Off"] _ ] ; --- 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 ; --- Performance optimization variables --- Global $g_iLastStatusCheck = 0 Global $g_iLastConfigCheck = 0 ; =============================================================================================================================== ; --- 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. Auto-starts any configured items. ; * 5. Registers Adlib functions for background monitoring. ; * 6. Starts the main event loop. ; */ Func _RunAsController() ; Performance optimization: Batch initialization _CleanupAllRegistryKeys() _LoadConfiguration() _CreateTrayMenu() ; Auto-start configured items _AutoStartItems() ; Optimized Adlib registration with performance flags $g_iLastStatusCheck = TimerInit() $g_iLastConfigCheck = TimerInit() 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. ; * ; * Enhanced version with On/Off status checking for master arrays. ; * If Configs.ini exists, it reads the settings and the disable lists. ; * If not, it uses the default configuration (all master items with "On" status enabled). ; * It then populates the dynamic $g_aWorkers and $g_aTasks arrays with only the enabled items. ; */ Func _LoadConfiguration() $g_bConfigReloading = True 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", 15000) $sDisabledWorkers = "," & IniRead($g_sConfigFile, "Workers", "Disable", "") & "," $sDisabledTasks = "," & IniRead($g_sConfigFile, "Tasks", "Disable", "") & "," Else $g_sLastConfigModDate = "" $sDisabledWorkers = "," $sDisabledTasks = "," EndIf ; Enhanced filtering: Check both INI disable list and master array On/Off status Local $iWorkerCount = 0, $iTaskCount = 0 For $i = 0 To UBound($g_aMasterWorkers) - 1 If $g_aMasterWorkers[$i][4] = "On" And Not StringInStr($sDisabledWorkers, "," & $g_aMasterWorkers[$i][0] & ",") Then $iWorkerCount += 1 EndIf Next For $i = 0 To UBound($g_aMasterTasks) - 1 If $g_aMasterTasks[$i][6] = "On" And Not StringInStr($sDisabledTasks, "," & $g_aMasterTasks[$i][0] & ",") Then $iTaskCount += 1 EndIf Next $g_iNumWorkers = $iWorkerCount $g_iNumTasks = $iTaskCount ; Performance optimization: Only create arrays if needed If $g_iNumWorkers > 0 Then Dim $g_aWorkers[$g_iNumWorkers][8] ; UPDATED: Increased size for AutoStart flag Local $iWorkerIdx = 0 For $i = 0 To UBound($g_aMasterWorkers) - 1 Local $sInternalName = $g_aMasterWorkers[$i][0] If $g_aMasterWorkers[$i][4] = "Off" Or 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] $g_aWorkers[$iWorkerIdx][7] = $g_aMasterWorkers[$i][5] ; NEW: Copy AutoStart flag $iWorkerIdx += 1 Next Else Dim $g_aWorkers[0][0] ; Empty array EndIf If $g_iNumTasks > 0 Then Dim $g_aTasks[$g_iNumTasks][8] ; UPDATED: Increased size for AutoStart flag Local $iTaskIdx = 0 For $i = 0 To UBound($g_aMasterTasks) - 1 Local $sInternalName = $g_aMasterTasks[$i][0] If $g_aMasterTasks[$i][6] = "Off" Or 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] $g_aTasks[$iTaskIdx][7] = $g_aMasterTasks[$i][7] ; NEW: Copy AutoStart flag $iTaskIdx += 1 Next Else Dim $g_aTasks[0][0] ; Empty array EndIf $g_bConfigReloading = False EndFunc ;==>_LoadConfiguration ;/** ; * @brief Creates the entire tray menu structure based on the loaded configuration. ; * ; * Enhanced version with better performance and empty array handling. ; */ Func _CreateTrayMenu() Opt("TrayMenuMode", 3) TraySetToolTip($g_sAppName) ; Performance optimization: Only create arrays if needed If $g_iNumWorkers > 0 Then ReDim $g_aWorkerTrayItems[$g_iNumWorkers] Local $hSubWorkersMenu = 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 Else ReDim $g_aWorkerTrayItems[0] EndIf TrayCreateItem("") If $g_iNumTasks > 0 Then ReDim $g_aTaskTrayItems[$g_iNumTasks] Local $hSubTasksMenu = 0 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 Else ReDim $g_aTaskTrayItems[0] EndIf TrayCreateItem("") $g_iTrayExit = TrayCreateItem("Exit") TraySetState(1) EndFunc ;==>_CreateTrayMenu ;/** ; * @brief The main event loop for the Controller. ; * ; * Enhanced with performance optimizations and faster exit handling. ; */ Func _ControllerMainLoop() While Not $g_bShuttingDown Local $iTrayMsg = TrayGetMsg() Switch $iTrayMsg Case 0 ; No message - continue Case $g_iTrayExit ; Immediate exit handling for better responsiveness $g_bShuttingDown = True _ExitController() Case Else ; Performance optimization: Early exit if reloading config If $g_bConfigReloading Then ContinueLoop 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(50) ; Reduced sleep for better responsiveness 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) If $g_bShuttingDown Or $g_bConfigReloading Then Return _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) If $g_bShuttingDown Or $g_bConfigReloading Then Return _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) If $g_iNumWorkers = 0 Or $iIndex < 0 Or $iIndex >= $g_iNumWorkers Then Return $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) If $g_iNumWorkers = 0 Or $iIndex < 0 Or $iIndex >= $g_iNumWorkers Then Return 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 $g_iNumWorkers = 0 Or $iIndex < 0 Or $iIndex >= $g_iNumWorkers Then Return 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) If $g_iNumWorkers = 0 Or $iIndex < 0 Or $iIndex >= $g_iNumWorkers Then Return 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) If $g_iNumTasks = 0 Or $iIndex < 0 Or $iIndex >= $g_iNumTasks Then Return 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 Automatically starts workers and tasks that are configured to run on startup. ; */ Func _AutoStartItems() _WriteLog("INFO: Checking for items to auto-start...") ; Auto-start workers If $g_iNumWorkers > 0 Then For $i = 0 To $g_iNumWorkers - 1 If $g_aWorkers[$i][7] = "On" Then _WriteLog("INFO: Auto-starting Worker '" & $g_aWorkers[$i][1] & "'...") _UpdateWorkerState($i, True) EndIf Next EndIf ; Auto-start tasks If $g_iNumTasks > 0 Then For $i = 0 To $g_iNumTasks - 1 If $g_aTasks[$i][7] = "On" Then _WriteLog("INFO: Auto-starting Task '" & $g_aTasks[$i][1] & "'...") _RunTask($i) EndIf Next EndIf EndFunc ;==>_AutoStartItems ;/** ; * @brief Optimized Adlib function to monitor the status of running workers and tasks. ; */ Func _CheckStatus_Adlib() ; Performance optimization: Skip if shutting down or reloading If $g_bShuttingDown Or $g_bConfigReloading Then Return ; Rate limiting for better performance If TimerDiff($g_iLastStatusCheck) < $g_iAdlibCheckInterval Then Return $g_iLastStatusCheck = TimerInit() ; Check workers only if we have any If $g_iNumWorkers > 0 Then 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 EndIf ; Check tasks only if we have any If $g_iNumTasks > 0 Then 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() EndIf 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() If $g_iNumTasks = 0 Then Return False 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() If $g_iNumTasks = 0 Then Return 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 Optimized Adlib function to check for modifications to the Configs.ini file. ; */ Func _CheckForConfigChanges_Adlib() ; Performance optimization: Skip if shutting down If $g_bShuttingDown Then Return ; Rate limiting for better performance If TimerDiff($g_iLastConfigCheck) < $g_iCheckConfigInterval Then Return $g_iLastConfigCheck = TimerInit() Local $sCurrentModDate = FileGetTime($g_sConfigFile, $FT_MODIFIED, $FT_STRING) If $sCurrentModDate <> $g_sLastConfigModDate And $sCurrentModDate <> "" Then _WriteLog("INFO: Configuration file change detected. Reloading...") $g_bConfigReloading = True _UnregisterAllMasterAdlibs() _StopAllWorkers() TraySetState(2) _LoadConfiguration() _CreateTrayMenu() ; Re-register Adlib functions after config reload AdlibRegister("_CheckStatus_Adlib", $g_iAdlibCheckInterval) AdlibRegister("_CheckForConfigChanges_Adlib", $g_iCheckConfigInterval) _WriteLog("INFO: Configuration reloaded and menu recreated.") EndIf EndFunc ;==>_CheckForConfigChanges_Adlib ;/** ; * @brief Stops all currently active workers with performance optimization. ; */ Func _StopAllWorkers() If $g_iNumWorkers = 0 Then Return _WriteLog("INFO: Stopping all workers...") ; Performance optimization: Parallel shutdown approach Local $aWorkerPIDs[$g_iNumWorkers] Local $aWorkerRegKeys[$g_iNumWorkers] ; First pass: Send exit signals to all workers For $i = 0 To $g_iNumWorkers - 1 If $g_aWorkers[$i][4] And $g_aWorkers[$i][3] > 0 And ProcessExists($g_aWorkers[$i][3]) Then $aWorkerPIDs[$i] = $g_aWorkers[$i][3] $aWorkerRegKeys[$i] = $g_sRegBase & "\" & $g_aWorkers[$i][0] RegWrite($aWorkerRegKeys[$i], "Signal", "REG_SZ", "exit") If @error Then _WriteLog("ERROR: Failed to write exit signal for " & $g_aWorkers[$i][0]) Else $aWorkerPIDs[$i] = 0 EndIf Next ; Wait for graceful shutdown Sleep(500) ; Second pass: Force close any remaining processes For $i = 0 To $g_iNumWorkers - 1 If $aWorkerPIDs[$i] > 0 Then If ProcessExists($aWorkerPIDs[$i]) Then _WriteLog("WARN: Force closing Worker PID " & $aWorkerPIDs[$i]) ProcessClose($aWorkerPIDs[$i]) EndIf RegDelete($aWorkerRegKeys[$i]) $g_aWorkers[$i][3] = 0 $g_aWorkers[$i][4] = False $g_aWorkers[$i][5] = $STATUS_STOPPED EndIf 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. ; * Enhanced with faster shutdown process. ; */ Func _ExitController() $g_bShuttingDown = True _WriteLog("INFO: Controller shutting down...") ; Immediate cleanup for faster exit _UnregisterAllMasterAdlibs() _StopAllWorkers() _CleanupAllRegistryKeys() _WriteLog("INFO: Controller shutdown complete.") Exit EndFunc ;==>_ExitController ;/** ; * @brief Enhanced function to unregister all possible Adlib callbacks. ; * Now includes protection for Au3Stripper and handles empty arrays. ; */ Func _UnregisterAllMasterAdlibs() AdlibUnRegister("_CheckStatus_Adlib") AdlibUnRegister("_CheckForConfigChanges_Adlib") ; Unregister all master worker functions (protected from Au3Stripper) 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("WARN: Registry key cleanup - base key may not exist: " & $g_sRegBase) EndFunc ;==>_CleanupAllRegistryKeys ;/** ; * @brief Enhanced function to find array index with bounds checking. ; * @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) Local $iUBound = UBound($aTrayItems) If $iUBound = 0 Then Return -1 For $i = 0 To $iUBound - 1 If $aTrayItems[$i] = $nID Then Return $i Next Return -1 EndFunc ;==>_GetIndexFromTrayID ;/** ; * @brief Enhanced logging function with better performance and error handling. ; * @param $sMessage The message to log. ; */ Func _WriteLog($sMessage) Local $sTimeStamp = @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC Local $sFormattedMessage = $sTimeStamp & " - " & $sMessage & @CRLF ConsoleWrite($sFormattedMessage) ; Performance optimization: Non-blocking file write Local $hFile = FileOpen($g_sLogFile, $FO_APPEND + $FO_UTF8_NOBOM) If $hFile <> -1 Then FileWrite($hFile, $sFormattedMessage) FileClose($hFile) EndIf 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 ; Performance optimization: Longer intervals for worker processes AdlibRegister($sFunction, 1000) AdlibRegister("_WorkerHeartbeat_Adlib", 3000) ; Reduced frequency While 1 Sleep(200) ; Slightly longer sleep for worker processes WEnd EndFunc ;==>_RunAsWorker ;/** ; * @brief Enhanced Adlib function for workers to monitor the Controller and exit signals. ; */ Func _WorkerHeartbeat_Adlib() ; Check if controller is still running If $g_iControllerPID > 0 And Not ProcessExists($g_iControllerPID) Then _WorkerExitGracefully() Return EndIf ; Check for exit signal from registry Local $sSignal = RegRead($g_sWorkerRegKey, "Signal") If @error Then _WorkerExitGracefully() Return EndIf If $sSignal = "exit" Then _WorkerExitGracefully() EndIf EndFunc ;==>_WorkerHeartbeat_Adlib ;/** ; * @brief Enhanced cleanup function for Workers before exit. ; */ Func _WorkerExitGracefully() AdlibUnRegister("_WorkerHeartbeat_Adlib") ; Find and unregister the specific worker function 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) ; --- These functions are protected by Au3Stripper directives ; =============================================================================================================================== Func Worker1Function() _WriteLog("Worker 'Check Resources' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker1Function Func Worker2Function() _WriteLog("Worker 'Sync Files' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker2Function Func Worker3Function() _WriteLog("Worker 'Monitor Network' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker3Function Func Worker4Function() _WriteLog("Worker 'Backup DB' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker4Function Func Worker5Function() _WriteLog("Worker 'Cleanup Logs' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker5Function Func Worker6Function() _WriteLog("Worker 'Process Emails' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker6Function Func Worker7Function() _WriteLog("Worker 'Auto Screenshot' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker7Function Func Worker8Function() _WriteLog("Worker 'Monitor Temp' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker8Function Func Worker9Function() _WriteLog("Worker 'Check Updates' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker9Function Func Worker10Function() _WriteLog("Worker 'Security Scan' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>Worker10Function Func TaskA_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(2000) EndFunc ;==>TaskA_Function Func TaskB_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(3000) EndFunc ;==>TaskB_Function Func TaskC_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here EndFunc ;==>TaskC_Function Func TaskD_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskD_Function Func TaskE_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskE_Function Func TaskF_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskF_Function Func TaskG_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskG_Function Func TaskH_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskH_Function Func TaskI_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskI_Function Func TaskJ_Function($sName) _WriteLog("Task '" & $sName & "' is running...") ; This is PlaceHoder - Your Code Replace Here Sleep(1000) EndFunc ;==>TaskJ_Function Eg: Configs.ini ; ====================================================================== ; Configuration file for the Controller-Worker-Task Manager ; ; Instructions: ; - To enable an option, remove the semicolon (;) from the beginning of the line. ; - Changes made to this file will be automatically detected and ; applied by the program without requiring a restart. ; ====================================================================== [Settings] ; The application name that will be displayed in the system tray tooltip. AppName=My Custom Automation Suite ; The interval (in milliseconds) for checking this configuration file for changes. ; The default value in the script is 15000 (which is 15 seconds). CheckConfigInterval=15000 [Workers] ; List the InternalName of the Workers you want to DISABLE, separated by commas (with no spaces). ; Even if a Worker is set to "On" in the script's master array, listing it here ; will prevent it from being loaded and appearing in the tray menu. ; ; Example: Disable=SyncFiles,CleanupLogs ; ; Available Workers (InternalName from the script): ; CheckResources, SyncFiles, MonitorNetwork, BackupDB, CleanupLogs, ProcessEmails, ; AutoScreenshot, MonitorTemp, CheckUpdates, SecurityScan ; ; This example will disable the "Backup DB" and "Process Emails" workers. Disable=BackupDB,ProcessEmails [Tasks] ; List the InternalName of the Tasks you want to DISABLE, separated by commas. ; Similar to Workers, any Task listed here will be disabled. ; ; Available Tasks (InternalName from the script): ; QuickCleanup, GenerateReport, SendNotification, TaskC, TaskD, TaskE, ; TaskF, TaskG, TaskH, TaskI ; ; This example will disable "Run Task F" and "Run Task H". Disable=TaskF,TaskH2 points -
BETA: SciTE v5x & lua Dynamic_include and "Smart" AutoComplete for Vars/UDFs/Abbrevs
WildByDesign and one other reacted to Jos for a topic
It checks for the environment variables "SCITE_USERHOME" and then "SCITE_HOME" and when they are not defined assumes a portable version is used so will default to the directory the AU3STRIPPER program is located in.2 points -
@pixelsearch let me think tomorrow about it. I changed a lot of internal functions from str to wstr to support unicode filenames and all examples must be touched otherwise crash. Currently I'm writing on an example in Freebasic (WebP Encoder GUI) how to use the DLL. Freebasic WebP DLL source code (my written DLL stuff, Google WebP dll will be linked as static library to my DLL) and other stuff can be found on my OneDrive, if you want to have a look under the hood.2 points
-
Hour AM/PM ( yes, one more of these )
Danyfirex and one other reacted to argumentum for a topic
; #FUNCTION# ==================================================================================================================== ; Name...........: HourAmPm ; Description....: Converts a time in 24-hour format to AM/PM format. ; Syntax.........: HourAmPm( $sDateTime [, $sAmPm = "AM|PM" [, $iTrimRight = 0]] ) ; Parameters.....: $sDateTime - The time (with date or not) string with "HH:" in it. ; $sAmPm - [optional] The AM/PM representation (default is "AM|PM"). ; $iTrimRight - [optional] The number of characters to trim from the right of the result (default is 0). ; $iNoDate - [optional] Whether to omit the date from the output. Defaults to False. ; Return values .: Success: Returns the formatted date and time in AM/PM format. ; Failure: None. ; Author ........: argumentum ; Modified ......: ; Remarks .......: This function takes a 24-hour time string, converts it to AM or PM format, and returns the result with optional trimming. ; Related .......: ; Link ..........: https://www.autoitscript.com/forum/index.php?showtopic=213061 ; Example .......: MsgBox(64, "Converted Time", HourAmPm("12/31/1999 18:59:59")) ; =============================================================================================================================== Func HourAmPm($sDateTime, $sAmPm = Default, $iTrimRight = Default, $iNoDate = Default) Local $aAmPm = StringSplit((StringInStr($sAmPm, "|") ? $sAmPm : "AM|PM"), "|"), $sFormat = $aAmPm[2] Local $iHourPos = StringInStr($sDateTime, ":"), $sHour = StringMid($sDateTime, $iHourPos - 2, 2) Local $sDate = StringLeft($sDateTime, $iHourPos - 3), $sTime = StringTrimLeft($sDateTime, $iHourPos - 1) If $sHour < 12 Then $sFormat = $aAmPm[1] ; https://www.autoitscript.com/forum/index.php?showtopic=213061 $sHour = Mod($sHour, 12) If Not $sHour Then $sHour = 12 Return StringTrimRight((Int($iNoDate) ? "" : $sDate) & StringRight('0' & $sHour, 2) & $sTime, Int($iTrimRight)) & " " & $sFormat EndFunc ;==>HourAmPm ...am always looking for these ( because am disorganized ) and when I find them they are more than needed so, I decided to simplify it and flexibly-cate** it. All that's needed is the hour, the rest of the date-time string should be anything as long as there is a "HH:" in it. ; Examples: ConsoleWrite('- ' & HourAmPm("18:59") & @CRLF) ; - 06:59 PM ConsoleWrite('- ' & HourAmPm("18:59:59.999") & @CRLF) ; - 06:59:59.999 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999") & @CRLF) ; - 1999/12/31 06:59:59.999 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999", Default, 7) & @CRLF) ; - 1999/12/31 06:59 PM ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59", Default, 3) & @CRLF) ; - 1999/12/31 06:59 PM ConsoleWrite('- ' & HourAmPm("12/31/1999 18:59", "a|p") & @CRLF) ; - 12/31/1999 06:59 p ConsoleWrite('- ' & HourAmPm("1999/12/31 18:59:59.999", Default, 7, True) & @CRLF) ; - 06:59 PM Don't remember seeing this approach anywhere so I decided to share it **flexibly-cate [verb] To make it flexible2 points