Jump to content

ioa747

Active Members
  • Posts

    1,744
  • Joined

  • Last visited

  • Days Won

    40

Everything posted by ioa747

  1. This works for me too, with Firefox as the default browser and Win10 22H2. Local $sTxt = "" $sTxt &= "https://www.youtube.com/watch?v=GygBY01Qbnk" & @CRLF $sTxt &= "https://www.youtube.com/watch?v=LrAtBtQnvCE&list=RDLrAtBtQnvCE" & @CRLF $sTxt &= "https://www.youtube.com/watch?v=fe5Jk7YT_JE&list=RDfe5Jk7YT_JE" & @CRLF $sTxt &= "https://www.youtube.com/watch?v=44tiZ7IP7zA" $aLines = StringSplit($sTxt, @CRLF, 1) For $i = 1 To $aLines[0] ConsoleWrite("$aLines[$i]=" & $aLines[$i] & @CRLF) ShellExecute($aLines[$i]) Next
  2. #include <Array.au3> $ini = _MapIni("test4.ini") ConsoleWrite("$ini.test.t0:" & $ini.test.t0 & @CRLF) ConsoleWrite("$ini.test.daemon_mount:" & $ini.test.daemon_mount & @CRLF) ConsoleWrite("$ini.test2.z2:" & $ini.test2.z2 & @CRLF) ; $iStripWS [optional] default is 3. This is the flag for StringStripWS(). Set to zero to disable. Func _MapIni($sFilePath, $iStripWS = 3) Local $sFileTxt = FileRead($sFilePath) If @error Then Return SetError(1, 0, "") ; Put a @CRLF in start, and convert all @LF, @CR to @CRLF $sFileTxt = @CRLF & StringRegExpReplace($sFileTxt, "(\r\n|\n)", @CRLF) ; split String in (@CRLF & "[") Local $aPart = StringSplit($sFileTxt, @CRLF & "[", 1) If $aPart[0] < 2 Then Return SetError(2, 0, "") Local $aSections[$aPart[0]][2] $aSections[0][0] = $aPart[0] - 1 Local $mMaps[] For $j = 2 To $aPart[0] ; normal first line is the (name & ]) Local $iPos = StringInStr($aPart[$j], "]", 0, -1) If Not $iPos > 0 Or @error Then Return SetError(3, 0, "") ; find the name and the Dimension Local $sName = StringLeft($aPart[$j], $iPos - 1) ; remove leading CRLF or LF from front & back Local $sString = StringRegExpReplace(StringTrimLeft($aPart[$j], $iPos + 2), '(^[\r\n]+|[\r\n]+$)', '') Local $a = StringSplit($sString, @CRLF, 3) Local $out, $m[] For $i = UBound($a) - 1 To 0 Step -1 $a[$i] = StringRegExpReplace($a[$i], "\h*;.*", "") If $a[$i] = "" Then _ArrayDelete($a, $i) $out = $a[$i] If StringRegExp($out, '@.*?@') Then $tmp = StringRegExp($out, '(@.*?@)', 1)[0] $out = StringReplace($out, $tmp, Execute(StringTrimRight($tmp, 1))) EndIf If StringRegExp($out, '\$.*?\$') Then $tmp = StringRegExp($out, '(\$.*?\$)', 1)[0] $out = StringReplace($out, $tmp, Execute(StringTrimRight($tmp, 1))) EndIf If StringRegExp($out, "%.*?%") Then $out = EnvGet(StringRegExp($out, "%(.*?)%", 1)[0]) & StringRegExpReplace($out, "%.*?%", "") EndIf $a[$i] = $out Next For $i = 0 To UBound($a) - 1 Local $result = StringRegExp($a[$i], '^(.*?)=(.*)$', 3) If IsArray($result) Then $m[$result[0]] = StringStripWS($result[1], $iStripWS) Next $mMaps[$sName] = $m Next Return $mMaps EndFunc ;==>_MapIni test4.ini [test] ; ligne commentaire t0= /l=$bdmount$ "ÁisoÁ" ;en thÚorie =w ; ici =w: mais seule la 1ere lettre compte ; de plus =w inutile (mount sur le 1er disque virtuel ?) t1="x y" ; "commentaire" comment2 t2="x y" t3='"x y"' t4=x y t5=""x y"" ;com bdmount="w:" path_log=e:\Mes documents\HCFR\logs\ ;vrai sauf pour bootime o¨ path_log est redÚfini Ó e:\sna10\xfert\ pour ecrire boot_time.log daemon_mount= /l=$bdmount$ "ÁisoÁ" ;en thÚorie =w ; ici =w: mais seule la 1ere lettre compte ; de plus =w inutile (mount sur le 1er disque virtuel ?) fichier_resultats=@Tempdir@\result.log ; fichier resultats des actions effectuÚes ""=pas de sauve [test2] z1="d:" z2="""zz""" ;"test2"
  3. Here is my approach, taking into account @argumentum concerns about using ';' why not use a rarer character ? like: 👉, 💬, 🚩, ⁉, ⚠, ℹ, ♠, ⋮, ⅈ, © Local $sFile = @ScriptDir & "\test2.ini" Local $sMyComment ; Declare a variable to hold the comment ; Read the INI section labelled 'EXEMPLES'. This will return a 2 dimensional array. Local $aArray = IniReadSection($sFile, "EXEMPLES") If Not @error Then For $i = 1 To $aArray[0][0] Local $sResult = IniReadWithComment($sMyComment, $sFile, "EXEMPLES", $aArray[$i][0]) ConsoleWrite($aArray[$i][0] & " = " & $sResult & @CRLF) If $sMyComment Then ConsoleWrite(@TAB & "Comment: " & $sMyComment & @CRLF) Next EndIf Func IniReadWithComment(ByRef $sComment, $filename, $section, $key, $defaut = "") Opt("ExpandEnvStrings", 1) ;0=don't expand, 1=do expand Opt("ExpandVarStrings", 1) ;0=don't expand, 1=do expand Local $sValue = IniRead($filename, $section, $key, $defaut) Local $sCleanValue, $sRetValue Local $aPart = StringSplit($sValue, "👉", 1) If $aPart[0] = 2 Then $sCleanValue = StringStripWS($aPart[1], 3) $sComment = StringStripWS($aPart[2], 3) $sRetValue = $sCleanValue Else $sRetValue = $aPart[1] EndIf Opt("ExpandEnvStrings", 0) ;0=don't expand, 1=do expand Opt("ExpandVarStrings", 0) ;0=don't expand, 1=do expand Return $sRetValue EndFunc ;==>IniReadWithComment_ByRef test2.ini [EXEMPLES] bdmount="w:" path_log=e:\Mes documents\HCFR\logs\ 👉 vrai sauf pour bootime où path_log est redéfini à e:\sna10\xfert\ pour ecrire boot_time.log daemon_mount= /l=$bdmount$ "µisoµ" 👉 en théorie =w ; ici =w: mais seule la 1ere lettre compte ; de plus =w inutile (mount sur le 1er disque virtuel ?) fichier_resultats=@Tempdir@\result.log 👉 fichier resultats des actions effectuées ""=pas de sauve Time=@HOUR@:@MIN@:@SEC@ 👉 curent time File=$sFile$ 👉 this .ini file SCITE=%SCITE_USERHOME% 👉 On installation this variable is set to "%LOCALAPPDATA%\AutoIt v3\SciTE" for Vista and above and to "%USERPROFILE%\AutoIt v3\SciTE" for WinXP.
  4. 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 much
  5. It's like you put them in a blender and mixed them well. Let's start from this. Func _ShowStep($msg, $sLineNo = @ScriptLineNumber) GUICtrlSetData($LineLabel, "Line: " & $sLineNo & " -" & $msg) EndFunc ;==>_ShowStep What does the help say about this? GUICtrlSetData ( controlID, data [, default] ) --- Modifies the data for a control. but you have no control so we will send it to the console Func _ShowStep($msg, $sLineNo = @ScriptLineNumber) ; GUICtrlSetData($LineLabel, "Line: " & $sLineNo & " -" & $msg) ConsoleWrite("Line: " & $sLineNo & " -" & $msg & @CRLF) EndFunc ;==>_ShowStep so you don't even need the ;~ Global $LineLabel one #RequireAdmin is enough, delete the second one these are not needed both, DirCreate('C:\Dnload\Macrium') are enough, because if it does it, automatically, 'C:\Dnload' also exists ;~ If Not FileExists('C:\Dnload') Then ;~ DirCreate('C:\Dnload') ;~ EndIf If Not FileExists('C:\Dnload\Macrium') Then DirCreate('C:\Dnload\Macrium') EndIf
  6. go to 'Administrative language settings' and look under 'Current language for non-Unicode programs' if it says Portuguese. If it says Portuguese , and even then it doesn't read them correctly, then... I don't know any other solution. except #include <File.au3> #include <Array.au3> Local $aFiles = AllToUTF8(@ScriptDir, "*.ini", 1) Func AllToUTF8($dir, $sMask = "*", $iRecur = $FLTAR_NORECUR) If StringRight($dir, 1) <> "\" Then $dir &= "\" $aList = _FileListToArrayRec($dir, $sMask, 1, $iRecur, $FLTAR_NOSORT, $FLTAR_FULLPATH) If Not IsArray($aList) Then MsgBox($MB_SYSTEMMODAL, "Ooops!", "No .ini files found") Return SetError(1, 0, 0) Else For $i = 1 To $aList[0] Local $sTxt = FileRead($aList[$i]) Local $sNewName, $iN = "" Do $sNewName = StringTrimRight($aList[$i], 4) & ".old" & $iN If FileExists($sNewName) Then $iN += 1 Until Not FileExists($sNewName) FileMove($aList[$i], $sNewName) FileWrite($aList[$i], $sTxt) Next MsgBox($MB_SYSTEMMODAL, "Job Complete!", "All " & $aList[0] & " .ini files converted to UTF-8") EndIf EndFunc ;==>AllToUTF8 Edit: Just keep in mind that with the flag 1 in AllToUTF8(@ScriptDir, "*.ini", 1), it will do the conversion, in all .ini in all subfolders
  7. when you open the ini file in notepad, what does it say in the bottom right? UTF-8 or ANSI? if it says ANSI, save it as UTF-8, and try reading it again with AutoIt
  8. Since you have Opt('GUIOnEventMode', 1) GUIGetMsg() does not read it at all (In my example I do not want to use #include "GIFAnimation.au3" and I disabled it for that - because I haven't read/analyzed it yet) The basic changes you need to make are declare the event in the $hGUI Global $hGUI = GUICreate('', $aGIFDimension[0], $aGIFDimension[1], -1, -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_DragMe") ; *** <--- 1 disable the event from $cButton ;~ GUICtrlSetOnEvent(-1, "_DragMe") ; *** <--- 2 disabling the entire ;~ Switch GUIGetMsg() ; *** <--- 3 from the main loop and in _DragMe() clean the part ;~ Switch GUIGetMsg() ; *** <--- 4 and leave only the $cInfo = GUIGetCursorInfo($hGUI) If $cInfo[4] = $cButton Then ... EndIf ; https://www.autoitscript.com/forum/topic/213062-move-gui-with-gif-animation-by-button/#findComment-1545090 #AutoIt3Wrapper_Au3Check_Parameters=-w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #NoTrayIcon #include <Constants.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> ;~ #include "GIFAnimation.au3" Opt('GUIOnEventMode', 1) Global Const $SC_DRAGMOVE = 0xF012 ; Flag to show if GUI was moved Global $fMoved = False Global $sFile = @ScriptDir & "\gif.gif" HotKeySet('{ESC}', '_Exit') ; Get dimension of the GIF ;~ Global $aGIFDimension = _GIF_GetDimension($sFile) Global $hGUI = GUICreate('', 600, 300, -1, -1, $WS_POPUP) ;, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST)) GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_DragMe") ; *** <--- 1 ;~ _WinAPI_SetLayeredWindowAttributes($hGUI, 0xABCDEF) Global $cButton = GUICtrlCreateButton('Drag me', 225, 100, 100, 100) ;~ GUICtrlSetOnEvent(-1, "_DragMe") ; *** <--- 2 Global $bButtonQuit = GUICtrlCreateButton("EXIT", 225, 200, 100, 20) GUICtrlSetOnEvent(-1, "_Exit") ; GIF job ;~ Global $hGIF = _GUICtrlCreateGIF($sFile, "", 120, -75) ; Additional processing of some windows messages (for example) ;~ GUIRegisterMsg(133, "_Refresh") ; WM_NCPAINT ;~ GUIRegisterMsg(15, "_ValidateGIFs") ; WM_PAINT Global $iPlay = 1 ; Make GUI transparent ;~ GUISetBkColor(345) ; some random color ;~ _WinAPI_SetLayeredWindowAttributes($hGui, 345, 255) ; making the GUI transparent ;~ _WinAPI_SetParent($hGui, 0) GUISetState(@SW_SHOW, $hGUI) ; Loop till end While 1 Sleep(500) ;~ Switch GUIGetMsg() ; *** <--- 3 ;~ Case $GUI_EVENT_PRIMARYDOWN ;~ ; Check mouse is over button ;~ $cInfo = GUIGetCursorInfo($hGUI) ;~ If $cInfo[4] = $cButton Then ;~ ; Clear the flag ;~ $fMoved = False ;~ ; Get initial positions of mouse and GUI ;~ $aInit_Pos = MouseGetPos() ;~ $aWin_Pos = WinGetPos($hGUI) ;~ ; Wait until mouse button released ;~ Do ;~ ; Check if mouse still pressed ;~ $cInfo = GUIGetCursorInfo($hGUI) ;~ ; Get current mouse position ;~ $aCurr_Pos = MouseGetPos() ;~ ; How far has mouse moved ;~ $iDiff_X = $aInit_Pos[0] - $aCurr_Pos[0] ;~ $iDiff_Y = $aInit_Pos[1] - $aCurr_Pos[1] ;~ ; Move GUI ;~ WinMove($hGUI, "", $aWin_Pos[0] - $iDiff_X, $aWin_Pos[1] - $iDiff_Y) ;~ Until Not $cInfo[2] ;~ ; See if mouse moved while it was pressed - allow for 5 pixel margin ;~ If (Abs($aCurr_Pos[0] - $aInit_Pos[0]) > 5) Or (Abs($aCurr_Pos[1] - $aInit_Pos[1]) > 5) Then ;~ ; If moved then set flag ;~ $fMoved = True ;~ EndIf ;~ EndIf ;~ EndSwitch WEnd Func _Exit() Exit EndFunc ;==>_Exit Func _DragMe() ;~ _GIF_PauseAnimation($sFile) ;~ Switch GUIGetMsg() ; *** <--- 4 ;~ Case $GUI_EVENT_PRIMARYDOWN ; Check mouse is over button $cInfo = GUIGetCursorInfo($hGUI) If $cInfo[4] = $cButton Then ; Clear the flag $fMoved = False ConsoleWrite("$fMoved=" & $fMoved & @CRLF) ; Get initial positions of mouse and GUI $aInit_Pos = MouseGetPos() $aWin_Pos = WinGetPos($hGUI) ; Wait until mouse button released Do ; Check if mouse still pressed $cInfo = GUIGetCursorInfo($hGUI) ; Get current mouse position $aCurr_Pos = MouseGetPos() ; How far has mouse moved $iDiff_X = $aInit_Pos[0] - $aCurr_Pos[0] $iDiff_Y = $aInit_Pos[1] - $aCurr_Pos[1] ; Move GUI WinMove($hGUI, "", $aWin_Pos[0] - $iDiff_X, $aWin_Pos[1] - $iDiff_Y) Until Not $cInfo[2] ; See if mouse moved while it was pressed - allow for 5 pixel margin If (Abs($aCurr_Pos[0] - $aInit_Pos[0]) > 5) Or (Abs($aCurr_Pos[1] - $aInit_Pos[1]) > 5) Then ; If moved then set flag $fMoved = True EndIf EndIf ;~ EndSwitch EndFunc ;==>_DragMe Func _Refresh($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ;~ _GIF_RefreshGIF($hGIF) EndFunc ;==>_Refresh Func _ValidateGIFs($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam, $lParam ;~ _GIF_ValidateGIF($hGIF) EndFunc ;==>_ValidateGIFs
  9. Practical! Thank you for sharing it. ideas - thoughts
  10. Check the link below tennispong Edit: or in the local help on GUICtrlCreatePic the second example
  11. maybe for such an action ( installation ) you need #RequireAdmin
  12. I also put an alternative one in case it suits you better I didn't encounter any problems with either the original or the alternative one #include <WindowsConstants.au3> #include <ListViewConstants.au3> #include <GUIConstantsEx.au3> #include <ColorConstants.au3> #include <GuiListView.au3> Local $Form1 = GUICreate("Test", 1024, 768, -1, -1, BitOR($WS_MAXIMIZEBOX, $WS_TABSTOP, $WS_EX_TOPMOST)) ;$WS_OVERLAPPEDWINDOW,$WS_CLIPCHILDREN GUISetBkColor(0xFFFFFF) Local $iLVStyle = BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $LVS_NOSORTHEADER) Local $iLVExtStyle = BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT) Local $hListView = GUICtrlCreateListView("", 166, 281, 840, 455, $iLVStyle, $iLVExtStyle) ;~ Local $hListView = GUICtrlCreateListView("#| NAME| PASSWORD| MAIL| CODE", 166, 281, 840, 455, $iLVStyle, $iLVExtStyle) GUICtrlSetFont($hListView, 12, 400, 0, "MS Sans Serif") GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKRIGHT + $GUI_DOCKTOP + $GUI_DOCKBOTTOM) _GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_SORTDESCENDING, $LVS_SORTASCENDING)) _GUICtrlListView_AddColumn($hListView, "#", 40) _GUICtrlListView_AddColumn($hListView, " NAME", 890) _GUICtrlListView_AddColumn($hListView, " PASSWORD", 890) _GUICtrlListView_AddColumn($hListView, " MAIL", 890) _GUICtrlListView_AddColumn($hListView, " CODE", 890) ;~ _GUICtrlListView_SetColumnWidth($hListView, 0, 40) ;~ _GUICtrlListView_SetColumnWidth($hListView, 1, 890) ;~ _GUICtrlListView_SetColumnWidth($hListView, 2, 890) ;~ _GUICtrlListView_SetColumnWidth($hListView, 3, 890) ;~ _GUICtrlListView_SetColumnWidth($hListView, 4, 890) _GUICtrlListView_SetBkColor($hListView, $CLR_BLACK) _GUICtrlListView_SetTextColor($hListView, $CLR_WHITE) _GUICtrlListView_SetTextBkColor($hListView, $CLR_BLACK) GUICtrlSetFont($hListView, 12, 700, 0, "MS Sans Serif") Local $OkButton = GUICtrlCreateButton("ADD DATA", 821, 21, 140, 38, $WS_BORDER) GUICtrlSetFont(-1, 18, 400, 0, "Impact") Local $Button206 = GUICtrlCreateButton("EXIT", 834, 77, 115, 38, $WS_BORDER) GUICtrlSetFont(-1, 18, 400, 0, "Impact") GUISetState(@SW_SHOW) While True Local $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE, $Button206 Exit Case $OkButton _FillList() EndSwitch WEnd Func _FillList() Local $iRead = FileRead(@ScriptDir & "\Data\NAME DATA.ini") Local $iRead2 = FileRead(@ScriptDir & "\Data\PASSWORD DATA.ini") Local $iRead3 = FileRead(@ScriptDir & "\Data\MAIL DATA.ini") Local $iRead4 = FileRead(@ScriptDir & "\Data\CODE DATA.ini") Local $aString = StringSplit(StringStripCR($iRead), @LF) Local $aString2 = StringSplit(StringStripCR($iRead2), @LF) Local $aString3 = StringSplit(StringStripCR($iRead3), @LF) Local $aString4 = StringSplit(StringStripCR($iRead4), @LF) For $i = 1 To $aString[0] If $aString[$i] = "" Then ContinueLoop For $i = 1 To $aString2[0] If $aString2[$i] = "" Then ContinueLoop For $i = 1 To $aString3[0] If $aString3[$i] = "" Then ContinueLoop For $i = 1 To $aString4[0] If $aString4[$i] = "" Then ContinueLoop GUICtrlCreateListViewItem($i & "|" & _ StringRegExpReplace($aString[$i], "^.*\\", "") & "|" & _ StringRegExpReplace($aString2[$i], "(^.*\).*", "\1") & "|" & _ StringRegExpReplace($aString3[$i], "(^.*\).*", "\1") & "|" & _ StringRegExpReplace($aString4[$i], "(^.*\).*", "\1"), $hListView) Next Next Next Next Local $iLV_Width = 0 For $i = 0 To 4 GUICtrlSendMsg($hListView, $LVM_SETCOLUMNWIDTH, $i, $LVSCW_AUTOSIZE_USEHEADER) $iLV_Width += GUICtrlSendMsg($hListView, $LVM_GETCOLUMNWIDTH, $i, 0) Next EndFunc ;==>_FillList
  13. and imagine that I tried it, and it didn't work. But now with the certainty that you said it, and with a second glance it cleared up, and it worked Thank you very much for the support. update to version: 0.3
  14. I took option 2 [my array ]1D or [my array ]2D I couldn't trick _ArrayFromString into creating a 2D array with one row and had to create a new function. Thank you very much for the suggestion and the enlightenment. update to version: 0.2
  15. _SectionsArrays A library for reading, writing, and managing 1D or 2D arrays, stored in a single text file using a section-based format. It provides functions to easily handle data, update existing sections, or add new ones. ; ; https://www.autoitscript.com/forum/topic/213059-_sectionsarrays/ ;--------------------------------------------------------------------------------------- ; Title...........: _SectionsArrays ; Description.....: A library for reading, writing, and managing 1D or 2D arrays, ; stored in a single text file using a section-based format. ; It provides functions to easily handle data, update existing sections, or add new ones. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.3 ; Note............: Testet in Win10 22H2 ;--------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <Array.au3> #include <GUIConstantsEx.au3> #include <GuiListView.au3> #include <WindowsConstants.au3> Example() Func Example() Local $sArraysFilepath = @ScriptDir & "\arrays.txt" If Not FileExists($sArraysFilepath) Then _MakeArrays($sArraysFilepath) If @error Then ConsoleWrite("_MakeArrays @error=" & @error & @CRLF) Local $aSections = _ArraysFromFile($sArraysFilepath) If @error Then ConsoleWrite("_ArraysFromFile @error=" & @error & @CRLF) ShellExecute($sArraysFilepath) Sleep(500) _ArraysDisplay($aSections, "Array Sections") EndFunc ;==>Example Func _MakeArrays($sFilePath) ; Make examples arrays ; Prepare Sections array Local $aSections[1][2] $aSections[0][0] = 0 Local $Info ; "Monthly zoo Report" array Local $Array[][] = [ _ ["Month", "Bears", "Dolphins", "Whales"], _ ["jan", 8, 150, 80], _ ["feb", 54, 77, 54], _ ["mar", 93, 32, 10], _ ["apr", 116, 11, 76], _ ["may", 137, 6, 93], _ ["jun", 184, 1, 72]] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "Monthly zoo Report", $Array) ConsoleWrite("add $Info=" & $Info & @CRLF) ; "Base Items" array Local $aArray_Base[2][2] = [["Item 0 - 0", "Item 0 - 1"], ["Item 1 - 0", "Item 1 - 1"]] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "Base Items", $aArray_Base) ConsoleWrite("add $aArray_Base=" & $Info & @CRLF) ; "item Index" array Local $aIndex[10] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ; Add array to Sections array $Info = _AddArrayToArrays($aSections, "item Index", $aIndex) ConsoleWrite("add $aIndex=" & $Info & @CRLF) ; "item Index2" array Local $aIndex2[1][10] = [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]] $Info = _AddArrayToArrays($aSections, "item Index2", $aIndex2) ConsoleWrite("add $aIndex2=" & $Info & @CRLF) ; Save arrays to file _ArraysToFile($sFilePath, $aSections) EndFunc ;==>_MakeArrays ;-------------------------------------------------------------------------------------------------------------------------------- ; Help functions (A library for reading, writing, and managing 1D or 2D arrays, stored in a single text file using a section-based format.) ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysDisplay(ByRef $aItems, $sTitle = "") ; Creates a GUI window to display and browse the contents of multiple arrays. Local $hGUI = GUICreate($sTitle, 300, 200, -1, -1, $WS_OVERLAPPEDWINDOW) Local $idListview = GUICtrlCreateListView("Sections | Arrays", 0, 0, 300, 200, $LVS_SINGLESEL) GUICtrlSetFont(-1, 10) _GUICtrlListView_SetExtendedListViewStyle($idListview, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT)) _GUICtrlListView_SetColumnWidth($idListview, 0, 170) _GUICtrlListView_SetColumnWidth($idListview, 1, 120) GUISetState(@SW_SHOW) Local $aIdItems[UBound($aItems, 1)] If @error Then Return SetError(@error, 0, 0) $aIdItems[0] = $aItems[0][0] For $i = 1 To $aIdItems[0] Local $sLabel = "error" Local $aArray = $aItems[$i][1] If IsArray($aArray) Then Local $iDimension = UBound($aArray, $UBOUND_DIMENSIONS) ; The dimension of the array e.g. 1/2/3 dimensional. Local $sDim = "" For $d = 1 To $iDimension $sDim &= "[" & UBound($aArray, $d) & "]" Next $sLabel = "Array" & $sDim EndIf $aIdItems[$i] = GUICtrlCreateListViewItem($aItems[$i][0] & " | {" & $sLabel & "}", $idListview) Next Local $iMsg While 1 $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_RESIZED Local $iWH = WinGetClientSize($hGUI) GUICtrlSetPos($idListview, 0, 0, $iWH[0], $iWH[1]) Case $aIdItems[1] To $aIdItems[$aIdItems[0]] Local $id = $iMsg - $aIdItems[1] + 1 $aArray = $aItems[$id][1] _ArrayDisplay($aArray, $aItems[$id][0]) EndSwitch WEnd GUIDelete() EndFunc ;==>_ArraysDisplay ;-------------------------------------------------------------------------------------------------------------------------------- Func _AddArrayToArrays(ByRef $aArrays, $sName, $aNewArray) ; Adds a new array to the main array structure, or updates an existing one. Local $iCurrentSections = $aArrays[0][0] ; Check if the section name already exists For $i = 1 To $iCurrentSections If $aArrays[$i][0] = $sName Then ; Section exists, update the array $aArrays[$i][1] = $aNewArray Return True EndIf Next ; Section does not exist, add a new one ReDim $aArrays[$iCurrentSections + 2][2] ; Add the new section name and the array $aArrays[$iCurrentSections + 1][0] = $sName $aArrays[$iCurrentSections + 1][1] = $aNewArray ; Update the total number of sections count $aArrays[0][0] = $iCurrentSections + 1 Return True EndFunc ;==>_AddArrayToArrays ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysToFile($sFilePath, $aArrays, $sDelim_Col = "|") ; Saves a multi-array structure back to a text file. Local $sOutput = "" Local $iNumSections = $aArrays[0][0] ; Loop through each section For $i = 1 To $iNumSections Local $sSectionName = $aArrays[$i][0] Local $aCurrentArray = $aArrays[$i][1] ; Get the array dimension Local $iDimension = UBound($aCurrentArray, $UBOUND_DIMENSIONS) ; Append the section name with the dimension to the output string $sOutput &= "[" & $sSectionName & "]" & $iDimension & "D" & @CRLF ; Convert the array to a string Local $sArrayString = _ArrayToString($aCurrentArray, $sDelim_Col) ; Append the array string to the output, followed by a newline $sOutput &= $sArrayString & @CRLF & @CRLF Next Local $hFile = FileOpen($sFilePath, $FO_OVERWRITE + $FO_UTF8_NOBOM) If $hFile = -1 Then Return SetError(1, 0, False) EndIf FileWrite($hFile, $sOutput) FileClose($hFile) Return True EndFunc ;==>_ArraysToFile ;-------------------------------------------------------------------------------------------------------------------------------- Func _RemoveArraySection(ByRef $aArrays, $sName) ; Removes a section and its corresponding array from the main array structure. Local $iCurrentSections = $aArrays[0][0] ; Check if the section name exists For $i = 1 To $iCurrentSections If $aArrays[$i][0] = $sName Then _ArrayDelete($aArrays, $i) $aArrays[0][0] = $iCurrentSections - 1 ReDim $aArrays[$iCurrentSections][2] Return True EndIf Next Return False ; Section not found EndFunc ;==>_RemoveArraySection ;-------------------------------------------------------------------------------------------------------------------------------- Func _ArraysFromFile($sFilePath, $sDelim_Col = "|") ; Reads a text file containing multiple sections and converts them into a 2D array structure. Local $sFileTxt = FileRead($sFilePath) If @error Then Return SetError(1, 0, "") ; Put a @CRLF in start, and convert all @LF, @CR to @CRLF $sFileTxt = @CRLF & StringRegExpReplace($sFileTxt, "(\r\n|\n)", @CRLF) ; split String in (@CRLF & "[") Local $aPart = StringSplit($sFileTxt, @CRLF & "[", 1) If $aPart[0] < 2 Then Return SetError(2, 0, "") Local $aSections[$aPart[0]][2] $aSections[0][0] = $aPart[0] - 1 For $i = 2 To $aPart[0] ; normal first line is the (name & ]) Local $iPos = StringInStr($aPart[$i], "]", 0, -1) If Not $iPos > 0 Or @error Then Return SetError(3, 0, "") ; find the name and the Dimension Local $sName = StringLeft($aPart[$i], $iPos - 1) Local $iDimension = 0 + Number(StringMid($aPart[$i], $iPos + 1, 1)) If Not ($iDimension = 1 Or $iDimension = 2) Then Return SetError(4, 0, "") ; remove leading CRLF or LF from front & back Local $sString = StringRegExpReplace(StringTrimLeft($aPart[$i], $iPos + 2), '(^[\r\n]+|[\r\n]+$)', '') Local $aArrayFromText ; $iDimension - 1 to $bForce2D => true $aArrayFromText = _ArrayFromString($sString, $sDelim_Col, Default, $iDimension - 1) $aSections[$i - 1][0] = $sName $aSections[$i - 1][1] = $aArrayFromText Next Return $aSections EndFunc ;==>_ArraysFromFile ;-------------------------------------------------------------------------------------------------------------------------------- Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
  16. try with Run ( @ComSpec & " /k ..." ) or direct with Local $sCommandLine = @ComSpec & " /k " & $sCommandToRun & " & pause" Run($sCommandLine, "", @SW_SHOW)
  17. the issue is that it already exists in the starting point , and when I put it in it again, gave me an invalid json That's why I left it outside. (for validation I use notepad++, with a 'JSON Tools' plugin that has)
  18. I know you solved it, just for a deeper understanding, on how (I'm a rookie too) ; with string manipulation, ; the convenient point is the intermediate '},' ; which you can add before it for terminal.background ; or after it for window.customTitleBarVisibility, window.titleBarStyle Local $sTxt = '{"workbench.colorCustomizations": {"editor.background": "#00000060"}, "workbench.startupEditor": "none", "breadcrumbs.enabled": false, "window.controlsStyle": "custom", "workbench.activityBar.location": "hidden"}' ConsoleWrite($sTxt & @CRLF) Local $sNewEntry, $sNewTxt ; add terminal.background to workbench.colorCustomizations $sNewEntry = ', "terminal.background": "#00000000"' $sNewTxt = StringReplace($sTxt, '},', $sNewEntry & '},') ; * and the replace part ; add the other 2 settings ,I don't understand who the third one is, but it shouldn't have the same name. $sNewEntry = ' "window.customTitleBarVisibility": "auto","window.titleBarStyle": "custom",' $sNewTxt = StringReplace($sNewTxt, '},', '},' & $sNewEntry) ; * and the replace part ConsoleWrite($sNewTxt & @CRLF)
  19. New release 0.11 Basic changes • Now the clock is updated with a timer and not in the main loop, or with AdlibRegister, so that it does not freeze with the tray menu or the settings GUIs • The movement of the hands is done in an analog manner and does not jump from minute to minute or hour to hour. • Now moving the clock can also be done with a long press on the center of the clock. • You don't need an additional image because it does it by itself, but it can also accept an external image. • I put a settings GUI for selecting clock colors. (if the changes concern the background image, they will be applied after deleting the background image) • Ability to change the size of the clock, through the ini file I made it Swiss update in the first post Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
  20. Dummy approach #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <Misc.au3> Opt("GUICloseOnESC", 0) ;1=ESC closes, 0=ESC won't close Example() Func Example() Local $hGUI = GUICreate("Example", 300, 200, -1, -1, -1, $WS_EX_TOOLWINDOW) Local $idDummy = GUICtrlCreateDummy() Local $idExit = GUICtrlCreateButton("Exit", 160, 150, 85, 25) GUISetState(@SW_SHOW, $hGUI) Local $bGreen = False While 1 $aCoords = WinGetPos($hGUI) If Not @error Then _MouseTrap($aCoords[0], $aCoords[1], $aCoords[0] + $aCoords[2], $aCoords[1] + $aCoords[3]) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE GUICtrlSendToDummy($idDummy) Case $idExit $bGreen = True GUICtrlSendToDummy($idDummy) Case $idDummy If $bGreen Then ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example
  21. I had an interesting accident. (I thing) #include <ButtonConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <Misc.au3> _ColorsSelection() Func _ColorsSelection() Local $hGUI = GUICreate("Colors Selection", 500, 500, -1, -1, -1) GUISetFont(10) GUICtrlCreateLabel("Red", 10, 10, 101, 17, 0x0002) GUICtrlCreateLabel("Green", 10, 140, 101, 17, 0x0002) Local $Button1 = GUICtrlCreateButton("", 120, 5, 50, 25, 0xFF0000) ; instead of 0x8000 I paste 0xFF0000 GUICtrlSetBkColor(-1, 0xFF0000) Local $Button2 = GUICtrlCreateButton("", 120, 135, 50, 25, 0xFF0000) ; instead of 0x8000 I paste 0xFF0000 GUICtrlSetBkColor(-1, 0x00FF00) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $Button1 ConsoleWrite("$Button1=" & $Button1 & @CRLF) Case $Button2 ConsoleWrite("$Button2=" & $Button2 & @CRLF) EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>_ColorsSelection
  22. [Case <value> [To <value>] [,<value> [To <value>] ...] It doesn't say anything about 'οr' $Var = 4 Switch $Var Case 1 ConsoleWrite("1") Case 2 To 3 ConsoleWrite("2 or 3") Case 4, 5 ConsoleWrite("4 or 5") Case Else ConsoleWrite("Else") EndSwitch
  23. For $unused In $colNetAdapter $num += 1 Next Edit: #include <Array.au3> $aResult = _zz() _ArrayDisplay($aResult) Func _zz() Local Const $wbemFlagReturnImmediately = 0x10 Local Const $wbemFlagForwardOnly = 0x20 Local $objWMIService = ObjGet("winmgmts:\\" & @ComputerName & "\root\CIMV2") Local $sQueryNetAdapter = 'select * from Win32_NetworkAdapter' Local $colNetAdapter = $objWMIService.ExecQuery($sQueryNetAdapter, "WQL", $wbemFlagReturnImmediately + $wbemFlagForwardOnly) Local $storearray[100][2] $ind = 0 For $netadapt In $colNetAdapter $storearray[$ind][0] = $netadapt.Manufacturer $storearray[$ind][1] = $netadapt.ProductName $ind = $ind + 1 Next ReDim $storearray[$ind][2] Return $storearray EndFunc ;==>_zz
  24. I played around a bit, and ended up with this analog clock. ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: AnalogClockGdi.au3 ; Description.....: A simple AutoIt script creating a digital analog clock GUI. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.1 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <StaticConstants.au3> Global $hGUI, $hGraphic ; main GUI Global $hGUIBack, $hGraphicBack ; background GUI Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter _GDIPlus_Startup() _CreateClock(600) Func _DrawClock($iWidth, $iX = -1, $iY = -1) Local $iHeight = $iWidth $hGUI = GUICreate("Analog Clock", $iWidth, $iHeight, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED, $hGUIBack) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUI, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hPenSeconds = _GDIPlus_PenCreate(0xFFFF0000, 2) $hPenMinutes = _GDIPlus_PenCreate(0xFF0000FF, 8) $hPenHours = _GDIPlus_PenCreate(0xFF00FF00, 12) $hBrushCenter = _GDIPlus_BrushCreateSolid(0xFF000000) Local $sTime, $Tick = -1 While True If $Tick <> @SEC Then $sTime = @HOUR & ":" & @MIN & ":" & @SEC ConsoleWrite("- " & $sTime & @CRLF) $Tick = @SEC _RedrawClock($iWidth) EndIf Switch GUIGetMsg() Case -3 ; $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd _GDIPlus_GraphicsDispose($hGraphicBack) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() EndFunc ;==>_DrawClock Func _RedrawClock($iWidth) Local $iHeight = $iWidth Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.5 Local $hTransparentBrush = _GDIPlus_BrushCreateSolid(0xFF00FFFF) _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iWidth, $iHeight, $hTransparentBrush) _GDIPlus_BrushDispose($hTransparentBrush) Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) - 90 _DrawHand($hGraphic, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) - 90 _DrawHand($hGraphic, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 _DrawHand($hGraphic, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphic, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) EndFunc ;==>_RedrawClock Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand Func _CreateClock($iWidth, $iX = -1, $iY = -1) Local $iHeight = $iWidth $hGUIBack = GUICreate("Clock Background", $iWidth, $iHeight, $iX, $iY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUIBack, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) ; Get the graphic context for the background GUI $hGraphicBack = _GDIPlus_GraphicsCreateFromHWND($hGUIBack) _GDIPlus_GraphicsSetSmoothingMode($hGraphicBack, $GDIP_SMOOTHINGMODE_HIGHQUALITY) Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.5 Local $iTextRadius = $iClockRadius * 0.90 ; Adjust this value for number placement (closer to edge) For $i = 1 To 12 Local $sDigit = $i Local $fAngleDegrees = ($i * 30) - 90 Local $fAngleRadians = _Radian($fAngleDegrees) Local $iTextX = $iCenterX + ($iTextRadius * Cos($fAngleRadians)) Local $iTextY = $iCenterY + ($iTextRadius * Sin($fAngleRadians)) Local $iDigitWidth = 36 ; Estimate based on font size 30 Local $iDigitHeight = 30 ; Estimate based on font size 30 ; Draw the number - 0xFFFFFFFF = White color for numbers (ARGB) _GDIPlus_GraphicsDrawString($hGraphicBack, $sDigit, $iTextX - ($iDigitWidth / 2), $iTextY - ($iDigitHeight / 2), "Arial", 30, Default, 0xFFFFFFFF) Next _DrawClock($iWidth, $iX, $iY) EndFunc ;==>_DrawStaticClockBackground Which I "tweaked" a bit, and ended up with this ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: Analog_Clock.au3 ; Description.....: A simple AutoIt script creating a digital analog clock GUI with alarm functionality. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.1 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <StaticConstants.au3> #include <TrayConstants.au3> #include <Misc.au3> Opt("TrayMenuMode", 3) ; 0=append, 1=no default menu, 2=no automatic check, 4=menuitemID not return Global $hGuiParent, $hGUIBack, $idBackTheme ; Parent GUI & background GUI Global $hGUI, $hGraphic ; main clock GUI Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter Global $mAlarm = _GetClockSetting(StringTrimRight(@ScriptFullPath, 4) & ".ini") _GDIPlus_Startup() _CreateClock($mAlarm.width, $mAlarm.x, $mAlarm.y) ;--------------------------------------------------------------------------------------- Func _DrawClock($iWidth, $iX = -1, $iY = -1) Local $hDLL = DllOpen("user32.dll") ; for _IsPressed ; Tray Menou Local $idMove = TrayCreateItem("Move") Local $idSetAlarm = TrayCreateItem("Alarm Setting") Local $idAlarmActive = TrayCreateItem("Alarm Enable/Disable") TrayItemSetState($idAlarmActive, ($mAlarm.active = "1" ? $TRAY_CHECKED : $TRAY_UNCHECKED)) Local $idClockSetting = TrayCreateItem("Clock Setting") TrayCreateItem("") ; separator ----------------------- Local $idClose = TrayCreateItem("Close") TraySetClick($TRAY_CLICK_SECONDARYUP) TraySetIcon("mmcndmgr.dll", -15) TraySetToolTip("Analog Clock") TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu. ; Clock GUI $hGUI = GUICreate("Analog Clock", $iWidth, $iWidth, $iX, $iY, $WS_POPUP, $WS_EX_LAYERED, $hGuiParent) GUISetBkColor(0x00FFFF) ; 0x00FFFF _WinAPI_SetLayeredWindowAttributes($hGUI, 0x00FFFF) ; 0x00FFFF GUISetState(@SW_SHOW) $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI) $hPenSeconds = _GDIPlus_PenCreate(0xFFFF0000, 2) ; 0xFFFF0000 $hPenMinutes = _GDIPlus_PenCreate(0xFF0000FF, 8) ; 0xFF0000FF $hPenHours = _GDIPlus_PenCreate(0xFF008000, 12) ; 0xFF00FF00 $hBrushCenter = _GDIPlus_BrushCreateSolid(0xFF000000) ; 0xFF000000 Local $Tick = -1, $Tack = -1 While True If $Tick <> @SEC Then $Tick = @SEC _RedrawClock($iWidth) EndIf If $Tack <> @MIN Then $Tack = @MIN _CheckAlarm() EndIf Switch TrayGetMsg() Case $idClose ExitLoop Case $idMove WinActivate($hGuiParent) While 1 Local $aMpos = MouseGetPos() WinMove($hGuiParent, '', $aMpos[0], $aMpos[1]) ToolTip("click to drop it", $aMpos[0] + 30, $aMpos[1] - 10) If _IsPressed("01", $hDLL) Then ExitLoop ; 01 Left mouse button Sleep(10) WEnd ToolTip("") $mAlarm.x = $aMpos[0] $mAlarm.y = $aMpos[1] IniWrite($mAlarm.file, "ClockSetting", "x", $aMpos[0]) IniWrite($mAlarm.file, "ClockSetting", "y", $aMpos[1]) Case $idAlarmActive If BitAND(TrayItemGetState($idAlarmActive), $TRAY_CHECKED) Then ; If $TRAY_CHECKED TrayItemSetState($idAlarmActive, $TRAY_UNCHECKED) IniWrite($mAlarm.file, "ClockSetting", "active", "0") $mAlarm.active = "0" Else ; If $TRAY_UNCHECKED TrayItemSetState($idAlarmActive, $TRAY_CHECKED) IniWrite($mAlarm.file, "ClockSetting", "active", "1") $mAlarm.active = "1" EndIf Case $idSetAlarm _SetAlarm() Case $idClockSetting ShellExecute($mAlarm.file) Case $TRAY_EVENT_PRIMARYDOUBLE WinActivate($hGuiParent) EndSwitch WEnd DllClose($hDLL) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() EndFunc ;==>_DrawClock ;--------------------------------------------------------------------------------------- Func _RedrawClock($iWidth) Local $iHeight = $iWidth Local $iCenterX = $iWidth / 2 Local $iCenterY = $iHeight / 2 Local $iClockRadius = $iWidth * 0.45 Local $hTransparentBrush = _GDIPlus_BrushCreateSolid(0xFF00FFFF) ;0xFF00FFFF _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $iWidth, $iHeight, $hTransparentBrush) _GDIPlus_BrushDispose($hTransparentBrush) Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) - 90 _DrawHand($hGraphic, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) - 90 _DrawHand($hGraphic, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 _DrawHand($hGraphic, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphic, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) EndFunc ;==>_RedrawClock ;--------------------------------------------------------------------------------------- Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand ;--------------------------------------------------------------------------------------- Func _CreateClock($iWidth, $iX = -1, $iY = -1) $hGuiParent = GUICreate("GuiParent", 10, 10, $iX, $iY, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TRANSPARENT)) $hGUIBack = GUICreate("GUIBack", $iWidth, $iWidth, 10 - ($iWidth / 2), 10 - ($iWidth / 2), $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_MDICHILD), $hGuiParent) $idBackTheme = GUICtrlCreatePic(@ScriptDir & "\Clock-600.gif", 0, 0, $iWidth, $iWidth) GUISetState(@SW_SHOW, $hGUIBack) GUISetState(@SW_SHOW, $hGuiParent) Local $aPos = WinGetPos($hGuiParent) _DrawClock($iWidth, $aPos[0] - ($iWidth / 2) + 5, $aPos[1] - ($iWidth / 2) + 5) EndFunc ;==>_CreateClock ;--------------------------------------------------------------------------------------- Func _GetClockSetting($sIniPath) If Not FileExists($sIniPath) Then ; make one Local $sTxt = "" ; Write Example data to the ini file $sTxt &= "[ClockSetting]" & @CRLF $sTxt &= "file=" & $sIniPath & @CRLF $sTxt &= "width=600" & @CRLF $sTxt &= "x=-1" & @CRLF $sTxt &= "y=-1" & @CRLF $sTxt &= "sound=C:\Windows\Media\ringout.wav" & @CRLF $sTxt &= "day=1,2,3,4,5" & @CRLF $sTxt &= "active=1" & @CRLF $sTxt &= "time=17:30" & @CRLF FileWrite($sIniPath, $sTxt) EndIf ; Read the INI section labelled 'ClockSetting'. This will return a 2 dimensional array. Local $aArray = IniReadSection($sIniPath, "ClockSetting") Local $mMap[] If Not @error Then For $i = 1 To $aArray[0][0] $mMap[$aArray[$i][0]] = $aArray[$i][1] Next EndIf Return $mMap EndFunc ;==>_GetClockSetting ;--------------------------------------------------------------------------------------- Func _CheckAlarm() If $mAlarm.active <> "1" Then Return Local $iPos = StringInStr($mAlarm.day, @WDAY) If Not @error And $iPos > 0 Then If $mAlarm.time = @HOUR & ":" & @MIN Then ShellExecute($mAlarm.sound) EndIf EndFunc ;==>_CheckAlarm ;--------------------------------------------------------------------------------------- Func _SetAlarm() Local Const $MARGIN = 10 Local $hGUI = GUICreate("Set Alarm", 300, 260, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) GUICtrlCreateLabel("Select Days:", $MARGIN, $MARGIN, 100, 20) GUICtrlSetFont(-1, 9, 800) Local $a_idDays[7] Local $aDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Local $iY = $MARGIN + 25 For $i = 0 To UBound($aDays) - 1 $a_idDays[$i] = GUICtrlCreateCheckbox($aDays[$i], 10, $iY, 90, 20) Local $iPos = StringInStr($mAlarm.day, $i + 1) If Not @error And $iPos > 0 Then GUICtrlSetState(-1, $GUI_CHECKED) $iY += (20 + 2) Next GUICtrlCreateLabel("Set Time (HH:MM):", 170, $MARGIN, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputTime = GUICtrlCreateInput($mAlarm.time, 180, 35, 80, 20) GUICtrlSetFont(-1, 10) Local $idInfo = GUICtrlCreateLabel("", 100, 65, 190, 100) GUICtrlSetFont(-1, 10) $iY += $MARGIN GUICtrlCreateLabel("Select Sound File:", $MARGIN, $iY, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputSoundFile = GUICtrlCreateInput($mAlarm.sound, $MARGIN, $iY + 25, 240, 20) Local $idBtnBrowse = GUICtrlCreateButton("...", 260, $iY + 25, 30, 20) Local $idBtnSetAlarm = GUICtrlCreateButton("Set Alarm", 190, 170, 100, 20 + 5) GUICtrlSetFont(-1, 10, 800) GUISetState(@SW_SHOW) While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idBtnBrowse Local $sSoundFile = FileOpenDialog("Select Alarm Sound", @WorkingDir, "Sound Files (*.mp3;*.wav)|All Files (*.*)") If Not @error Then GUICtrlSetData($idInputSoundFile, $sSoundFile) Case $idBtnSetAlarm Local $sTime , $sSoundPath, $sDays = "", $sInfo = "" GUICtrlSetData($idInfo, "") For $i = 0 To UBound($a_idDays) - 1 If GUICtrlRead($a_idDays[$i]) = $GUI_CHECKED Then $sDays &= $i + 1 & "," Next $sDays = StringTrimRight($sDays, 1) ; remove last "," If $sDays = "" Then $sInfo &= "⚠ Please select at least one day." & @CRLF $sTime = GUICtrlRead($idInputTime) If Not StringRegExp($sTime, "^\d{2}:\d{2}$") Then $sInfo &= "⚠ Please enter time in HH:MM format (e.g., 07:30)." & @CRLF $sSoundPath = GUICtrlRead($idInputSoundFile) If $sSoundPath = "" Then $sInfo &= "⚠ Please select an sound file." GUICtrlSetData($idInfo, $sInfo) If $sInfo <> "" Then ContinueCase ; checks if everything is valid $mAlarm.day = $sDays $mAlarm.time = $sTime $mAlarm.sound = $sSoundPath IniWrite($mAlarm.file, "ClockSetting", "day", $sDays) IniWrite($mAlarm.file, "ClockSetting", "time", $sTime) IniWrite($mAlarm.file, "ClockSetting", "sound", $sSoundPath) ExitLoop EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>_SetAlarm ...but I didn't stop there and ended up with this Release 0.12 ; https://www.autoitscript.com/forum/topic/213036-%F0%9F%95%91-analog-clock/ ;---------------------------------------------------------------------------------------- ; Title...........: Analog_Clock.au3 ; Description.....: Analog clock GUI with alarm functionality. ; AutoIt Version..: 3.3.16.1 Author: ioa747 Script Version: 0.12 ; Note............: Testet in Win10 22H2 ;---------------------------------------------------------------------------------------- #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #include <GDIPlus.au3> #include <WinAPI.au3> #include <WindowsConstants.au3> #include <Math.au3> #include <Array.au3> #include <GUIConstantsEx.au3> #include <TrayConstants.au3> #include <Misc.au3> #include <Timers.au3> Opt("TrayMenuMode", 3) ; 0=append, 1=no default menu, 2=no automatic check, 4=menuitemID not return ; Global Constants Global Const $AC_SRC_ALPHA = 0x01 Global Const $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT = 5 Global Const $GDIP_STRINGFORMAT_ALIGNMENT_CENTER = 1 Global Const $GDIP_STRINGFORMAT_LINEALIGNMENT_CENTER = 1 ; Global Variables Global $hGUIClock Global $hImageBuffer, $hGraphicBuffer Global $hClockImage = 0 Global $hPenSeconds, $hPenMinutes, $hPenHours, $hBrushCenter Global $iClockWidth = 600, $iClockHeight = 600 Global $mClock = _GetClockSetting(StringTrimRight(@ScriptFullPath, 4) & ".ini") _GDIPlus_Startup() ; Try to load a clock background image _GetClockImage($mClock.Image) ; Start the Clock GUI _CreateClock($mClock.Width, $mClock.X, $mClock.Y) Exit ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; Try to load the clock background image Func _GetClockImage($sImagePath = Default) ; The Default clock background image If $sImagePath = Default Or $sImagePath = "Default" Then $sImagePath = StringTrimRight(@ScriptFullPath, 4) & ".png" If Not FileExists($sImagePath) Then ConsoleWrite("WARNING: ClockImage not found or could not be loaded initially. fallback to Default" & @CRLF) ; Set $sImagePath to Default $sImagePath = StringTrimRight(@ScriptFullPath, 4) & ".png" EndIf ; If there isn't one, make one. If Not FileExists($sImagePath) Then ConsoleWrite("WARNING: Default Image not found or could not be loaded initially. Generating new image..." & @CRLF) Local $bOk = _CreateAndSaveClockImage($iClockWidth, $sImagePath) If $bOk Then ConsoleWrite("INFO: Default Image generated successfully. Attempting to load it now." & @CRLF) Else ConsoleWrite("ERROR: Failed to generate Default Image Will go to exit." & @CRLF) Exit EndIf EndIf $hClockImage = _GDIPlus_ImageLoadFromFile($sImagePath) ; Check if loaded image is a valid pointer and file has content If IsPtr($hClockImage) And FileGetSize($sImagePath) > 0 Then ConsoleWrite("INFO: Loaded ClockImage." & @CRLF) Else ConsoleWrite("ERROR: Failed to Loaded the ClockImage. Will go to exit." & @CRLF) Exit EndIf EndFunc ;==>_GetClockImage ; Clock GUI - Initialization and Main Loop Func _CreateClock($iWidth, $iX = -1, $iY = -1) ; Tray Menu ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $idMove = TrayCreateItem("Move") Local $idAlarmActive = TrayCreateItem("Alarm Enable/Disable") TrayItemSetState($idAlarmActive, ($mClock.Alarm = "1" ? $TRAY_CHECKED : $TRAY_UNCHECKED)) Local $iSettings = TrayCreateMenu("Settings") Local $idSetAlarm = TrayCreateItem("Alarm Setting", $iSettings) Local $idSetColors = TrayCreateItem("Colors Setting", $iSettings) Local $idIniFile = TrayCreateItem("Ini file", $iSettings) Local $idRestart = TrayCreateItem("Restart", $iSettings) TrayCreateItem("") ; separator ----------------------- Local $idClose = TrayCreateItem("Close") TraySetClick($TRAY_CLICK_SECONDARYUP) TraySetIcon("mmcndmgr.dll", -15) TraySetToolTip("Analog Clock") TraySetState($TRAY_ICONSTATE_SHOW) ; Show the tray menu. ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Local $hDLL = DllOpen("user32.dll") ; for _IsPressed $iClockWidth = $iWidth $iClockHeight = $iWidth ; The clock GUI $hGUIClock = GUICreate("Analog Clock", $iClockWidth, $iClockHeight, $iX, $iY, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOOLWINDOW)) Local $idMouseLab = GUICtrlCreateLabel("", $iWidth / 2 - 5, $iWidth / 2 - 5, 10, 10) GUISetState(@SW_SHOW) $hImageBuffer = _GDIPlus_BitmapCreateFromScan0($iClockWidth, $iClockHeight) $hGraphicBuffer = _GDIPlus_ImageGetGraphicsContext($hImageBuffer) _GDIPlus_GraphicsSetSmoothingMode($hGraphicBuffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ; Colors from inifile RGB to ARGB Local $sColorSeconds = "0xFF" & StringTrimLeft($mClock.ColorSeconds, 2) Local $sColorMinutes = "0xFF" & StringTrimLeft($mClock.ColorMinutes, 2) Local $sColorHours = "0xFF" & StringTrimLeft($mClock.ColorHours, 2) Local $sColorCenter = "0xFF" & StringTrimLeft($mClock.ColorCenter, 2) ; hands Width Local $iWSeconds = ($iWidth * 0.005 < 2 ? 2 : $iWidth * 0.005) Local $iWMinutes = ($iWidth * 0.015 < 4 ? 4 : $iWidth * 0.015) Local $iWHours = ($iWidth * 0.020 < 6 ? 6 : $iWidth * 0.020) ; Initialize pens and brush for drawing hands and center circle $hPenSeconds = _GDIPlus_PenCreate($sColorSeconds, $iWSeconds) ; 0xFFFF0000 $hPenMinutes = _GDIPlus_PenCreate($sColorMinutes, $iWMinutes) ; 0xFF40C880 $hPenHours = _GDIPlus_PenCreate($sColorHours, $iWHours) ; 0xFF0080C0 $hBrushCenter = _GDIPlus_BrushCreateSolid($sColorCenter) ; 0xFF000000 ; SetTimer so it doesn't freeze with the tray menu _Timer_SetTimer($hGUIClock, 250, "_RedrawClock") Local $bRestart, $aMpos, $iCnt = 0, $Tick = -1 ;******************************************** While 1 ; Check Alarm If $Tick <> @MIN Then $Tick = @MIN _CheckAlarm() _ActivityTimeout($mClock.ActivityTimeout) EndIf ; GUI Msg $idMouseLab Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $GUI_EVENT_PRIMARYDOWN ; long press Left mouse button in bullet, to move the clock Local $a = GUIGetCursorInfo() If $a[4] = $idMouseLab Then While _IsPressed("01", $hDLL) ; 01 Left mouse button $iCnt += 1 If $iCnt > 60 Then $aMpos = MouseGetPos() WinMove($hGUIClock, '', $aMpos[0] - $iWidth / 2, $aMpos[1] - $iWidth / 2) ToolTip("Move it", $aMpos[0] + 30, $aMpos[1] - 10) EndIf Sleep(10) WEnd If $iCnt > 60 Then ToolTip("") $mClock.X = $aMpos[0] - $iWidth / 2 $mClock.Y = $aMpos[1] - $iWidth / 2 IniWrite($mClock.IniFile, "ClockSetting", "X", $mClock.X) IniWrite($mClock.IniFile, "ClockSetting", "Y", $mClock.Y) EndIf $iCnt = 0 EndIf EndSwitch ; Tray Msg Switch TrayGetMsg() Case $idClose ExitLoop Case $idMove ; move the clock WinActivate($hGUIClock) While 1 $aMpos = MouseGetPos() WinMove($hGUIClock, '', $aMpos[0] - $iWidth / 2, $aMpos[1] - $iWidth / 2) ToolTip("click to drop it", $aMpos[0] + 30, $aMpos[1] - 10) If _IsPressed("01", $hDLL) Then ExitLoop ; 01 Left mouse button Sleep(10) WEnd ToolTip("") $mClock.X = $aMpos[0] - $iWidth / 2 $mClock.Y = $aMpos[1] - $iWidth / 2 IniWrite($mClock.IniFile, "ClockSetting", "X", $mClock.X) IniWrite($mClock.IniFile, "ClockSetting", "Y", $mClock.Y) Case $idAlarmActive ; Alarm Enable/Disable If BitAND(TrayItemGetState($idAlarmActive), $TRAY_CHECKED) Then ; If $TRAY_CHECKED TrayItemSetState($idAlarmActive, $TRAY_UNCHECKED) IniWrite($mClock.IniFile, "ClockSetting", "Alarm", "0") $mClock.Alarm = "0" Else ; If $TRAY_UNCHECKED TrayItemSetState($idAlarmActive, $TRAY_CHECKED) IniWrite($mClock.IniFile, "ClockSetting", "Alarm", "1") $mClock.Alarm = "1" EndIf Case $idSetAlarm ; Alarm Setting _SetAlarm() Case $idSetColors ; Colors Setting _SetColors() Case $idIniFile ; Ini File (open ini file) ShellExecute($mClock.IniFile) Case $idRestart ; Restart the clock $bRestart = True ExitLoop Case $TRAY_EVENT_PRIMARYDOUBLE ; double click activate clock WinActivate($hGUIClock) EndSwitch WEnd ;******************************************** ; Clean up resources _Timer_KillAllTimers($hGUIClock) _GDIPlus_PenDispose($hPenSeconds) _GDIPlus_PenDispose($hPenMinutes) _GDIPlus_PenDispose($hPenHours) _GDIPlus_BrushDispose($hBrushCenter) _GDIPlus_GraphicsDispose($hGraphicBuffer) _GDIPlus_ImageDispose($hImageBuffer) _GDIPlus_ImageDispose($hClockImage) _GDIPlus_Shutdown() DllClose($hDLL) GUIDelete($hGUIClock) If $bRestart Then Local $Cmd = StringRight(@ScriptFullPath, 4) = ".exe" ? '"' & @ScriptFullPath & '"' : '"' & @AutoItExe & '" "' & @ScriptFullPath & '"' Exit Run($Cmd) EndIf EndFunc ;==>_CreateClock ; Helper Function to Draw a Hand Func _DrawHand($hGraphic, $hPen, $iX1, $iY1, $iLength, $fAngleDegrees) Local $fAngleRadians = _Radian($fAngleDegrees) Local $iX2 = $iX1 + ($iLength * Cos($fAngleRadians)) Local $iY2 = $iY1 + ($iLength * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphic, $iX1, $iY1, $iX2, $iY2, $hPen) EndFunc ;==>_DrawHand ; Redraw Clock Function (CallBack by timer) Func _RedrawClock($hWnd, $iMsg, $iIDTimer, $iTime) #forceref $hWnd, $iMsg, $iIDTimer, $iTime Local $iCurrentHour = @HOUR Local $iCurrentMinute = @MIN Local $iCurrentSecond = @SEC Local $iCenterX = $iClockWidth / 2 Local $iCenterY = $iClockHeight / 2 Local $iClockRadius = $iClockWidth / 2 _GDIPlus_GraphicsClear($hGraphicBuffer, 0x00000000) _GDIPlus_GraphicsDrawImageRect($hGraphicBuffer, $hClockImage, 0, 0, $iClockWidth, $iClockHeight) ; Calculate angles for smooth hand movement Local $iDisplayHour = $iCurrentHour If $iDisplayHour > 12 Then $iDisplayHour -= 12 Local $fAngleHours = ($iDisplayHour * 30) + ($iCurrentMinute * 0.5) - 90 _DrawHand($hGraphicBuffer, $hPenHours, $iCenterX, $iCenterY, $iClockRadius * 0.5, $fAngleHours) Local $fAngleMinutes = ($iCurrentMinute * 6) + ($iCurrentSecond * 0.1) - 90 _DrawHand($hGraphicBuffer, $hPenMinutes, $iCenterX, $iCenterY, $iClockRadius * 0.7, $fAngleMinutes) Local $fAngleSeconds = ($iCurrentSecond * 6) - 90 ; + ($iCurrentMillisecond * 0.006) ; - 90 _DrawHand($hGraphicBuffer, $hPenSeconds, $iCenterX, $iCenterY, $iClockRadius * 0.8, $fAngleSeconds) ; Draw center bullet Local $iBulletRadius = 10 _GDIPlus_GraphicsFillEllipse($hGraphicBuffer, $iCenterX - $iBulletRadius, $iCenterY - $iBulletRadius, $iBulletRadius * 2, $iBulletRadius * 2, $hBrushCenter) ; Create HBITMAP and display Local $hHBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImageBuffer) If IsPtr($hHBitmap) Then _WinAPI_BitmapDisplayTransparentInGUI($hHBitmap, $hWnd) EndFunc ;==>_RedrawClock ; Custom _WinAPI_BitmapDisplayTransparentInGUI Function (by UEZ) Func _WinAPI_BitmapDisplayTransparentInGUI(ByRef $hHBitmap, ByRef $hGUI, $bReleaseGDI = True) If Not BitAND(GUIGetStyle($hGUI)[1], $WS_EX_LAYERED) Then Return SetError(1, 0, 0) Local $tSize = DllStructCreate($tagSIZE), $tSource = DllStructCreate($tagPOINT), $tBlend = DllStructCreate($tagBLENDFUNCTION) Local Const $hScrDC = _WinAPI_GetDC(0) Local Const $hMemDC = _WinAPI_CreateCompatibleDC($hScrDC) Local Const $hOldBitmap = _WinAPI_SelectObject($hMemDC, $hHBitmap) Local $tBitmapInfo = DllStructCreate($tagBITMAP) _WinAPI_GetObject($hHBitmap, DllStructGetSize($tBitmapInfo), DllStructGetPtr($tBitmapInfo)) $tSize.X = $tBitmapInfo.bmWidth $tSize.Y = $tBitmapInfo.bmHeight $tBlend.Alpha = 0xFF $tBlend.Format = $AC_SRC_ALPHA _WinAPI_UpdateLayeredWindow($hGUI, $hScrDC, 0, DllStructGetPtr($tSize), $hMemDC, DllStructGetPtr($tSource), 0, DllStructGetPtr($tBlend), $ULW_ALPHA) _WinAPI_SelectObject($hMemDC, $hOldBitmap) _WinAPI_DeleteDC($hMemDC) _WinAPI_ReleaseDC(0, $hScrDC) If $bReleaseGDI Then _WinAPI_DeleteObject($hHBitmap) Return True EndFunc ;==>_WinAPI_BitmapDisplayTransparentInGUI ; This function draws a clock dial and saves it as a PNG. Func _CreateAndSaveClockImage($iWidth, $sFilePath) Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($iWidth, $iWidth) Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) _GDIPlus_GraphicsSetTextRenderingHint($hGraphics, $GDIP_TEXTRENDERINGHINT_CLEARTYPEGRIDFIT) Local $iCenterX = $iWidth / 2 Local $iCenterY = $iWidth / 2 Local $iRadius = $iWidth / 2 ; Clear with transparent background (ARGB: A=00) _GDIPlus_GraphicsClear($hGraphics, 0x00000000) ; Colors from inifile RGB to ARGB Local $sColorOutline = "0xFF" & StringTrimLeft($mClock.ColorOutline, 2) Local $sColorTextHour = "0xFF" & StringTrimLeft($mClock.ColorTextHour, 2) Local $sColorTextMin = "0xFF" & StringTrimLeft($mClock.ColorTextMin, 2) ; Colors and Pens/Brushes Local $hPenOutline = _GDIPlus_PenCreate($sColorOutline, 5) ; 0xFFEEEEEE Local $hPenHourMark = _GDIPlus_PenCreate($sColorOutline, 5) Local $hPenMinuteMark = _GDIPlus_PenCreate($sColorOutline, 2) Local $hBrushTextMin = _GDIPlus_BrushCreateSolid($sColorTextMin) Local $hBrushTextHour = _GDIPlus_BrushCreateSolid($sColorTextHour) ; String Format for drawing and measuring text (centered) Local $hStringFormatCenter = _GDIPlus_StringFormatCreate() ; Check if string format object was successfully created If Not IsPtr($hStringFormatCenter) Or $hStringFormatCenter = 0 Then ConsoleWrite("ERROR: Failed to create GDI+ StringFormat object." & @CRLF) ; Clean up other resources before returning failure _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return False EndIf _GDIPlus_StringFormatSetAlign($hStringFormatCenter, $GDIP_STRINGFORMAT_ALIGNMENT_CENTER) _GDIPlus_StringFormatSetLineAlign($hStringFormatCenter, $GDIP_STRINGFORMAT_LINEALIGNMENT_CENTER) ; Draw outer circle Local $iOutlinePadding = 5 _GDIPlus_GraphicsDrawEllipse($hGraphics, $iOutlinePadding, $iOutlinePadding, $iWidth - (2 * $iOutlinePadding), $iWidth - (2 * $iOutlinePadding), $hPenOutline) ; Draw hour and minute marks For $i = 0 To 59 Local $fAngleDegrees = ($i * 6) - 90 Local $fAngleRadians = _Radian($fAngleDegrees) Local $iStartX, $iStartY, $iEndX, $iEndY Local $iMarkLength If Mod($i, 5) = 0 Then ; Hour marks (every 5 minutes) $iMarkLength = $iRadius * 0.06 $iStartX = $iCenterX + (($iRadius - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iStartY = $iCenterY + (($iRadius - ($iRadius * 0.02)) * Sin($fAngleRadians)) $iEndX = $iCenterX + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iEndY = $iCenterY + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphics, $iStartX, $iStartY, $iEndX, $iEndY, $hPenHourMark) Else ; Minute marks $iMarkLength = $iRadius * 0.04 $iStartX = $iCenterX + (($iRadius - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iStartY = $iCenterY + (($iRadius - ($iRadius * 0.02)) * Sin($fAngleRadians)) $iEndX = $iCenterX + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Cos($fAngleRadians)) $iEndY = $iCenterY + (($iRadius - $iMarkLength - ($iRadius * 0.02)) * Sin($fAngleRadians)) _GDIPlus_GraphicsDrawLine($hGraphics, $iStartX, $iStartY, $iEndX, $iEndY, $hPenMinuteMark) EndIf Next ; Draw numbers (Hours and Minutes) Local $iHourTextRadius = $iRadius * 0.66 ; Radius for hour numbers (adjust this to move them closer/further from center) Local $iMinuteTextRadius = $iRadius * 0.86 ; Radius for minute numbers ; Define font families Local $sFontName = "Times New Roman" Local $hFontFamily = _GDIPlus_FontFamilyCreate($sFontName) ; Critical check for font family handle If Not IsPtr($hFontFamily) Or $hFontFamily = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontFamilyCreate returned an invalid handle for '" & $sFontName & "'. @error is: " & @error & @CRLF) ; Clean up current resources before returning failure _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_StringFormatDispose($hStringFormatCenter) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return False EndIf For $i = 1 To 12 ; Hour Numbers (1-12) Local $sHourDigit = $i Local $fHourAngleDegrees = ($i * 30) - 90 Local $fHourAngleRadians = _Radian($fHourAngleDegrees) Local $iHourFontSize = 50 Local $hHourFont = _GDIPlus_FontCreate($hFontFamily, $iHourFontSize, 1) ; 1 = Bold typeface ; Check for font handle If Not IsPtr($hHourFont) Or $hHourFont = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontCreate failed for hour font. Skipping text drawing." & @CRLF) ContinueLoop ; Skip drawing this text if font creation failed EndIf ; Calculate the approximate position for the text bounding box (large enough to contain text) Local $fApproxTextSize = $iHourFontSize * 1.5 Local $tHourLayoutRect = _GDIPlus_RectFCreate($iCenterX - $fApproxTextSize, $iCenterY - $fApproxTextSize, $fApproxTextSize * 2, $fApproxTextSize * 2) ; Measure text to get its exact dimensions Local $aHourMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, $sHourDigit, $hHourFont, $tHourLayoutRect, $hStringFormatCenter) Local $fHourTextWidth = 0, $fHourTextHeight = 0 If Not @error And IsArray($aHourMeasure) And DllStructGetData($aHourMeasure[0], "Width") > 0 And DllStructGetData($aHourMeasure[0], "Height") > 0 Then $fHourTextWidth = DllStructGetData($aHourMeasure[0], "Width") $fHourTextHeight = DllStructGetData($aHourMeasure[0], "Height") Else ; Fallback: Simple estimation if measurement fails $fHourTextWidth = $iHourFontSize * 0.6 * StringLen($sHourDigit) $fHourTextHeight = $iHourFontSize * 1.0 ConsoleWrite("WARNING: Failed to measure hour text '" & $sHourDigit & "'. Fallback: Using estimation." & @CRLF) EndIf ; Calculate the FINAL position for the text, taking into account text dimensions and desired radius Local $iHourTextX = $iCenterX + ($iHourTextRadius * Cos($fHourAngleRadians)) - ($fHourTextWidth / 2) Local $iHourTextY = $iCenterY + ($iHourTextRadius * Sin($fHourAngleRadians)) - ($fHourTextHeight / 2) ; Create a layout rectangle specific for drawing the text at the calculated position Local $tDrawHourLayout = _GDIPlus_RectFCreate($iHourTextX, $iHourTextY, $fHourTextWidth, $fHourTextHeight) ; Draw the string using _GDIPlus_GraphicsDrawStringEx _GDIPlus_GraphicsDrawStringEx($hGraphics, $sHourDigit, $hHourFont, $tDrawHourLayout, $hStringFormatCenter, $hBrushTextHour) _GDIPlus_FontDispose($hHourFont) ; Minute Numbers (5, 10, ..., 60) Local $sMinuteDigit = $i * 5 If $sMinuteDigit = 60 Then $sMinuteDigit = "00" Local $fMinuteAngleDegrees = ($i * 30) - 90 Local $fMinuteAngleRadians = _Radian($fMinuteAngleDegrees) Local $iMinuteFontSize = 20 Local $hMinuteFont = _GDIPlus_FontCreate($hFontFamily, $iMinuteFontSize, 1) ; 1 = Bold typeface ; Check for font handle If Not IsPtr($hMinuteFont) Or $hMinuteFont = 0 Then ConsoleWrite("ERROR: _GDIPlus_FontCreate failed for minute font. Skipping text drawing." & @CRLF) ContinueLoop ; Skip drawing this text if font creation failed EndIf Local $fApproxMinuteTextSize = $iMinuteFontSize * 1.5 Local $tMinuteLayoutRect = _GDIPlus_RectFCreate($iCenterX - $fApproxMinuteTextSize, $iCenterY - $fApproxMinuteTextSize, $fApproxMinuteTextSize * 2, $fApproxMinuteTextSize * 2) ; Measure text Local $aMinuteMeasure = _GDIPlus_GraphicsMeasureString($hGraphics, $sMinuteDigit, $hMinuteFont, $tMinuteLayoutRect, $hStringFormatCenter) Local $fMinuteTextWidth = 0, $fMinuteTextHeight = 0 If Not @error And IsArray($aMinuteMeasure) And DllStructGetData($aMinuteMeasure[0], "Width") > 0 And DllStructGetData($aMinuteMeasure[0], "Height") > 0 Then $fMinuteTextWidth = DllStructGetData($aMinuteMeasure[0], "Width") $fMinuteTextHeight = DllStructGetData($aMinuteMeasure[0], "Height") Else ; Fallback: Simple estimation if measurement fails $fMinuteTextWidth = $iMinuteFontSize * 0.6 * StringLen($sMinuteDigit) $fMinuteTextHeight = $iMinuteFontSize * 1.0 ConsoleWrite("WARNING: Failed to measure minute text '" & $sMinuteDigit & "'. Fallback: Using estimation." & @CRLF) EndIf Local $iMinuteTextX = $iCenterX + ($iMinuteTextRadius * Cos($fMinuteAngleRadians)) - ($fMinuteTextWidth / 2) Local $iMinuteTextY = $iCenterY + ($iMinuteTextRadius * Sin($fMinuteAngleRadians)) - ($fMinuteTextHeight / 2) Local $tDrawMinuteLayout = _GDIPlus_RectFCreate($iMinuteTextX, $iMinuteTextY, $fMinuteTextWidth, $fMinuteTextHeight) ; Draw the string using _GDIPlus_GraphicsDrawStringEx _GDIPlus_GraphicsDrawStringEx($hGraphics, $sMinuteDigit, $hMinuteFont, $tDrawMinuteLayout, $hStringFormatCenter, $hBrushTextMin) _GDIPlus_FontDispose($hMinuteFont) Next _GDIPlus_FontFamilyDispose($hFontFamily) ; Dispose font family after the loop ; Save the bitmap to a PNG file Local $bSuccess = _GDIPlus_ImageSaveToFile($hBitmap, $sFilePath) ConsoleWrite("DEBUG: _GDIPlus_ImageSaveToFile $bSuccess=" & $bSuccess & ", @error=" & @error & @CRLF) ; Add check for file exist and size after saving If FileExists($sFilePath) And FileGetSize($sFilePath) > 0 Then Sleep(200) ; Give some time for file system to release the file Else ConsoleWrite("ERROR: File save verification failed for '" & $sFilePath & "'. Success: " & $bSuccess & ", Exists: " & FileExists($sFilePath) & ", Size: " & FileGetSize($sFilePath) & @CRLF) $bSuccess = False EndIf ; Clean up resources _GDIPlus_PenDispose($hPenOutline) _GDIPlus_PenDispose($hPenHourMark) _GDIPlus_PenDispose($hPenMinuteMark) _GDIPlus_BrushDispose($hBrushTextHour) _GDIPlus_BrushDispose($hBrushTextMin) _GDIPlus_StringFormatDispose($hStringFormatCenter) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_ImageDispose($hBitmap) Return $bSuccess EndFunc ;==>_CreateAndSaveClockImage ; Make, and read ini to map Func _GetClockSetting($sIniPath) If Not FileExists($sIniPath) Then ; make one Local $sTxt = "" ; Write Example data to the ini file $sTxt &= "[ClockSetting]" & @CRLF $sTxt &= "IniFile=" & $sIniPath & @CRLF $sTxt &= "Image=Default" & @CRLF $sTxt &= "Width=600" & @CRLF $sTxt &= "X=-1" & @CRLF $sTxt &= "Y=-1" & @CRLF $sTxt &= "ColorSeconds=0xFF0000" & @CRLF $sTxt &= "ColorMinutes=0x40C880" & @CRLF $sTxt &= "ColorHours=0x0080C0" & @CRLF $sTxt &= "ColorCenter=0x000000" & @CRLF $sTxt &= "ColorTextHour=0xFFFFFF" & @CRLF $sTxt &= "ColorTextMin=0xFFFFFF" & @CRLF $sTxt &= "ColorOutline=0xFFFFFF" & @CRLF $sTxt &= "Alarm=1" & @CRLF $sTxt &= "AlarmSound=C:\Windows\Media\ringout.wav" & @CRLF $sTxt &= "AlarmDays=2,3,4,5,6" & @CRLF $sTxt &= "AlarmTime=17:30" & @CRLF $sTxt &= "ActivityTimeout=3" & @CRLF FileWrite($sIniPath, $sTxt) EndIf ; Read the INI section labelled 'ClockSetting'. This will return a 2 dimensional array. Local $aArray = IniReadSection($sIniPath, "ClockSetting") Local $mMap[] If Not @error Then For $i = 1 To $aArray[0][0] $mMap[$aArray[$i][0]] = $aArray[$i][1] Next EndIf ; Default colors If $mMap.ColorSeconds = "" Then $mMap.ColorSeconds = "0xFF0000" If $mMap.ColorMinutes = "" Then $mMap.ColorMinutes = "0x40C880" If $mMap.ColorHours = "" Then $mMap.ColorHours = "0x0080C0" If $mMap.ColorCenter = "" Then $mMap.ColorCenter = "0x000000" If $mMap.ColorTextHour = "" Then $mMap.ColorTextHour = "0xFFFFFF" If $mMap.ColorTextMin = "" Then $mMap.ColorTextMin = "0xFFFFFF" If $mMap.ColorOutline = "" Then $mMap.ColorOutline = "0xFFFFFF" Return $mMap EndFunc ;==>_GetClockSetting ; Check Alarm time Func _CheckAlarm() If $mClock.Alarm <> "1" Then Return Local $iPos = StringInStr($mClock.AlarmDays, @WDAY) If Not @error And $iPos > 0 Then If $mClock.AlarmTime = @HOUR & ":" & @MIN Then ShellExecute($mClock.AlarmSound) EndIf EndFunc ;==>_CheckAlarm ; Set Alarm GUI Func _SetAlarm() Local Const $MARGIN = 10 Local $hGUIAlarm = GUICreate("Set Alarm", 300, 260, -1, -1, -1, BitOR($WS_EX_TOPMOST, $WS_EX_TOOLWINDOW)) GUICtrlCreateLabel("Select Days:", $MARGIN, $MARGIN, 100, 20) GUICtrlSetFont(-1, 9, 800) Local $a_idDays[7] Local $aDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Local $iY = $MARGIN + 25 For $i = 0 To UBound($aDays) - 1 $a_idDays[$i] = GUICtrlCreateCheckbox($aDays[$i], 10, $iY, 90, 20) Local $iPos = StringInStr($mClock.AlarmDays, $i + 1) If Not @error And $iPos > 0 Then GUICtrlSetState(-1, $GUI_CHECKED) $iY += (20 + 2) Next GUICtrlCreateLabel("Set Time (HH:MM):", 170, $MARGIN, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputTime = GUICtrlCreateInput($mClock.AlarmTime, 180, 35, 80, 20) GUICtrlSetFont(-1, 10) Local $idInfo = GUICtrlCreateLabel("", 100, 65, 190, 100) GUICtrlSetFont(-1, 10) $iY += $MARGIN GUICtrlCreateLabel("Select Sound File:", $MARGIN, $iY, 150, 20) GUICtrlSetFont(-1, 9, 800) ; Bold Local $idInputSoundFile = GUICtrlCreateInput($mClock.AlarmSound, $MARGIN, $iY + 25, 240, 20) Local $idBtnBrowse = GUICtrlCreateButton("...", 260, $iY + 25, 30, 20) Local $idBtnSetAlarm = GUICtrlCreateButton("Set Alarm", 190, 170, 100, 20 + 5) GUICtrlSetFont(-1, 10, 800) GUISetState(@SW_SHOW) While 1 Local $iMsg = GUIGetMsg() Switch $iMsg Case $GUI_EVENT_CLOSE ExitLoop Case $idBtnBrowse Local $sSoundFile = FileOpenDialog("Select Alarm Sound", @WorkingDir, "Sound Files (*.mp3;*.wav)|All Files (*.*)") If Not @error Then GUICtrlSetData($idInputSoundFile, $sSoundFile) Case $idBtnSetAlarm Local $sTime, $sSoundPath, $sDays = "", $sInfo = "" GUICtrlSetData($idInfo, "") For $i = 0 To UBound($a_idDays) - 1 If GUICtrlRead($a_idDays[$i]) = $GUI_CHECKED Then $sDays &= $i + 1 & "," Next $sDays = StringTrimRight($sDays, 1) ; remove last "," If $sDays = "" Then $sInfo &= "⚠ Please select at least one day." & @CRLF $sTime = GUICtrlRead($idInputTime) If Not StringRegExp($sTime, "^\d{2}:\d{2}$") Then $sInfo &= "⚠ Please enter time in HH:MM format (e.g., 07:30)." & @CRLF $sSoundPath = "" & GUICtrlRead($idInputSoundFile) If $sSoundPath = "" Then $sInfo &= "⚠ Please select an sound file." GUICtrlSetData($idInfo, $sInfo) If $sInfo <> "" Then ContinueCase ; checks if everything is valid $mClock.AlarmDays = $sDays $mClock.AlarmTime = $sTime $mClock.AlarmSound = $sSoundPath IniWrite($mClock.IniFile, "ClockSetting", "AlarmDays", $sDays) IniWrite($mClock.IniFile, "ClockSetting", "AlarmTime", $sTime) IniWrite($mClock.IniFile, "ClockSetting", "AlarmSound", $sSoundPath) ExitLoop EndSwitch WEnd GUIDelete($hGUIAlarm) EndFunc ;==>_SetAlarm ; Set Colors GUI Func _SetColors() Local $hGUIColors = GUICreate("Set Colors", 180, 250, -1, -1, -1, $WS_EX_TOOLWINDOW) GUISetFont(10) GUICtrlCreateLabel("Seconds hand", 10, 10, 101, 17, 0x0002) GUICtrlCreateLabel("Minutes hand", 10, 40, 101, 17, 0x0002) GUICtrlCreateLabel("Hours hand", 10, 70, 101, 17, 0x0002) GUICtrlCreateLabel("Center Pin", 10, 100, 101, 17, 0x0002) GUICtrlCreateLabel("Hours Didits", 10, 130, 101, 17, 0x0002) GUICtrlCreateLabel("Minutes Didits", 10, 160, 101, 17, 0x0002) GUICtrlCreateLabel("Image Outline", 10, 190, 101, 17, 0x0002) Local $aNames[8] = [7, "ColorSeconds", "ColorMinutes", "ColorHours", "ColorCenter", "ColorTextHour", "ColorTextMin", "ColorOutline"] Local $iY = 5 Local $aColors[8][3] $aColors[0][0] = 7 For $i = 1 To $aColors[0][0] $aColors[$i][0] = GUICtrlCreateButton("", 120, $iY, 50, 25, 0x8000) $aColors[$i][1] = $mClock[$aNames[$i]] GUICtrlSetBkColor(-1, $aColors[$i][1]) If $i < 5 Then GUICtrlSetTip(-1, "This will be in effect after restart the clock") If $i > 4 Then GUICtrlSetTip(-1, "This will be in effect after deleting the existing clock image") $iY += 30 Next Local $idSetColors = GUICtrlCreateButton("Set Colors", 70, $iY, 100, 25) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") GUISetState(@SW_SHOW) Local $nMsg, $iChooseColor While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE ExitLoop Case $aColors[1][0] To $aColors[7][0] ;ConsoleWrite("$nMsg=" & $nMsg & @CRLF) Local $id = $nMsg - 10 $iChooseColor = _ChooseColor(2, $aColors[$id][1], 2, $hGUIColors) If $iChooseColor <> -1 Then $aColors[$id][1] = $iChooseColor GUICtrlSetBkColor($aColors[$id][0], $aColors[$id][1]) EndIf Case $idSetColors For $i = 1 To $aColors[0][0] $mClock[$aNames[$i]] = $aColors[$i][1] IniWrite($mClock.IniFile, "ClockSetting", $aNames[$i], $aColors[$i][1]) Next ExitLoop EndSwitch WEnd GUIDelete($hGUIColors) EndFunc ;==>_SetColors Func _ActivityTimeout($iTimeout = 3) Local Static $iMinute, $iMouseX Local $aMpos = MouseGetPos() If $iMouseX <> $aMpos[0] Then $iMouseX = $aMpos[0] $iMinute = 0 Return EndIf $iMinute +=1 If $iMinute = $iTimeout Then $iMinute = 0 WinActivate($hGUIClock) ConsoleWrite("INFO: Activity Timeout triggered." & @CRLF) EndIf EndFunc Extra background image Please, every comment is appreciated! leave your comments and experiences here! Thank you very much
×
×
  • Create New...