Leaderboard
Popular Content
Showing content with the highest reputation on 08/05/2024 in all areas
-
Quick Clipboard Translation
Danyfirex reacted to pixelsearch for a topic
Hi everybody The script Google Translation with GUI works fine, especially when the text to translate is long and plenty of languages can be used for translation. But today, I also needed a shorter version, where I could translate in a snap (in a click) what is found in the clipboard, for example while browsing on web pages that are not written in my native language. So I scripted what follows, based on : 1) a minimal GUI (no title, popup, resizable, topmost) 2) a label control, draggable ($GUI_WS_EX_PARENTDRAG) with same size as the GUI client size, so the GUI can be dragged anywhere (and stay on top) while dragging the label control, great ! 3) a context menu associated to the label control. 4) an ini file wich will be created after we launch the script once. It will contain the gui coords when the script was exited, the background color of the label control, the language of the translated text etc... The 1st time we run the script, the GUI appears like this : We resize it, move it near the buttons of our Browser (for example), we change the color of the background through the context menu (not changed for now, let's keep it yellow), we choose our native language (context menu). There are other options in the context menu, i.e. an InputBox if we want to type a couple of words to translate them quickly, an option to modify the transparency of the GUI, an option to minimize the GUI and finally an option to exit the script. For example, I didn't know what "caveat" means so I selected the 3 lines (see pic below), clicked "Translate" in the context menu and the translation appears in a MsgBox whose buttons got special captions (note the "Copy Text" button) as scripted a few hours ago in this thread As you see, the goal isn't to translate plenty of lines (it won't fit in a MsgBox and "Google Translation with GUI" is much more appropriate to do that) but just to translate a few sentences found here and there, no matter the original language, and to translate them quickly in a user-friendly way. If your native language is not amongst the 6 languages already hard coded (english, french, german, italian, portuguese, spanish) and you would like to add it the script, then it's doable by modifying one line in the script, which is : Local $aLangTo[][2] = [["en","English"],["fr","French"],["de","German"],["it","Italian"],["pt","Portuguese"],["es","Spanish"]] The script requires the file "Json.au3" scripted by @AspirinJunkie (link found at 3rd line in the script), many thanks to him ; Version 13b (August 1, 2024) ; requires AutoIt 3.3.16.1 (which includes Maps, as Json.au3 requires Maps for some translations) #include "Json.au3" ; by @AspirinJunkie, download from https://github.com/Sylvan86/autoit-json-udf #include <FileConstants.au3> #include <GUIConstantsEx.au3> #include <Misc.au3> #include <MsgBoxConstants.au3> #include <StaticConstants.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration Opt("GUICloseOnESC", 0) ;1=ESC closes (default), 0=ESC won't close Global $hGUI, $bContextMenu = True Global $g_aCaption, $g_sTitle ; 2 global variables for _TimerProc() Example() ;============================================== Func Example() ; If a user wants to add/remove a "Language To" , then modify THE following line, that's all. Local $aLangTo[][2] = [["en","English"],["fr","French"],["de","German"],["it","Italian"],["pt","Portuguese"],["es","Spanish"]] Local $iMaxLangTo = Ubound($aLangTo) Local $sIniFile = StringTrimRight(@ScriptFullPath, 4) & ".ini" ; ".au3" | ".a3x" | ".exe" => ".ini" Local $aIni = _ReadIniFile($sIniFile) Local $iBkColor = $aIni[6], $iTrans = $aIni[7], $sLangTo = $aIni[8] ; "en" or "fr" or ... (or "" if ini file doesn't exist) $hGUI = GUICreate("Clipboard Translation", $aIni[4], $aIni[5], -1, -1, BitOr($WS_POPUP, $WS_SIZEBOX), $WS_EX_TOPMOST) WinSetTrans($hGUI, "", $iTrans) Local $idLabel = GUICtrlCreateLabel("Translate", 0, 0, $aIni[4], $aIni[5], BitOr($SS_CENTERIMAGE, $SS_CENTER), $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, $iBkColor) Local $idContextMenu = GUICtrlCreateContextMenu($idLabel) Local $idTranslate = GUICtrlCreateMenuItem("Translate", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) ; separator Local $idMenuTo = GUICtrlCreateMenu("To", $idContextMenu) ; create the languages menuradioitem IMMEDIATELY after this line, in a loop. Local $bIsChecked For $i = 0 To $iMaxLangTo - 1 GUICtrlCreateMenuItem($aLangTo[$i][1], $idMenuTo, -1, 1) ; 1 = create a menuradioitem If $sLangTo = $aLangTo[$i][0] Then GUICtrlSetState(-1, $GUI_CHECKED) $bIsChecked = True EndIf Next If Not $bIsChecked Then GUICtrlSetState($idMenuTo + 1, $GUI_CHECKED) $sLangTo = $aLangTo[0][0] EndIf Local $idInputBox = GUICtrlCreateMenuItem("InputBox", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) Local $idSelectColor = GUICtrlCreateMenuItem("Back Color", $idContextMenu) Local $idTransparency = GUICtrlCreateMenuItem("Transparency", $idContextMenu) GUICtrlCreateMenuItem("", $idContextMenu) Local $idMinimize = GUICtrlCreateMenuItem("Minimize", $idContextMenu) Local $idQuit = GUICtrlCreateMenuItem("Quit", $idContextMenu) WinMove($hGUI, "", $aIni[0], $aIni[1], $aIni[2], $aIni[3]) GUISetState(@SW_SHOW) GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU") ; deactivate context menu while setting transparency Local $nMsg While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $idQuit ; context menu ($GUI_EVENT_CLOSE not usable in this script because no GUI close button and GUICloseOnESC, 0) _WriteIniFile($sIniFile, $iBkColor, $iTrans, $sLangTo) ExitLoop Case $idInputBox ; context menu Local $sTextInput = InputBox("InputBox", "Enter a string to translate", "", " M", _ ; M means Mandatory 220, 140, Default, Default, 0, $hGui) If @error <> 1 Then ; 3 possible reasons for @error = 1 : click on InputBox close X button OR push Cancel button OR Esc key. ClipPut(StringStripWS($sTextInput, 1 + 2)) ; 1 = strip leading white space, 2 = strip trailing white space. CONTINUECASE ; translate (see Case JUST below : do not insert any other Case between them or ContinueCase will fail !) EndIf Case $idTranslate ; context menu GUICtrlSetState($idTranslate, $GUI_DISABLE) ; prevent accidental double click on the context menuitem (possible ?) GUICtrlSetData($idLabel, "Processing...") _Translate($sLangTo, $idLabel) GUICtrlSetData($idLabel, "Translate") GUICtrlSetState($idTranslate, $GUI_ENABLE) Case $idMenuTo + 1 To $idMenuTo + $iMaxLangTo ; context menu (any "Language To" menuitem) $sLangTo = $aLangTo[$nMsg - $idMenuTo - 1][0] ; will be saved to .ini file (ex. "en" or "fr" or etc...) Case $idSelectColor ; context menu Local $iChooseColor = _ChooseColor(2, $iBkColor, 2, $hGUI) ; both 2's mean RGB hex (output & input) If $iChooseColor <> -1 Then $iBkColor = $iChooseColor GUICtrlSetBkColor($idLabel, $iBkColor) EndIf Case $idTransparency ; context menu $bContextMenu = False $iTrans = _Transparency($iTrans) $bContextMenu = True Case $idMinimize ; context menu WinSetState($hGUI, "", @SW_MINIMIZE) EndSwitch WEnd GUIDelete($hGUI) EndFunc ;==>Example ;============================================== Func WM_CONTEXTMENU($hwnd, $iMsg, $wParam, $lParam) If Not $bContextMenu Then Return 0 Return $GUI_RUNDEFMSG EndFunc ;==>WM_CONTEXTMENU ;============================================== Func _Transparency($iTrans) ; Calculate coords so $hGUI2 is always created near $hGUI Local $aPos = WinGetPos($hGUI), $iLeft = $aPos[0], $iTop = $aPos[1], $iRight = $iLeft + $aPos[2], $iBottom = $iTop + $aPos[3] Local $iLeft2, $iTop2, $iWidth2 = 220, $iHeight2 = 30 ; $hGUI2 (30 is good for future slider thumb size, tested) $iLeft2 = ($iLeft + $iWidth2 + 10 < @DesktopWidth) ? $iLeft : $iRight - ($iWidth2 + 10) $iTop2 = ($iBottom + 20 + $iHeight2 + 20 < @DesktopHeight) ? $iBottom + 10 : $iTop - 10 - ($iHeight2 + 20) Local $hGUI2 = GUICreate("Transparency " & $iTrans, $iWidth2, $iHeight2, $iLeft2, $iTop2, _ BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX), BitOr($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST)) Local $idSlider = GUICtrlCreateSlider(0, 0, $iWidth2, $iHeight2) GUICtrlSetLimit(-1, 255, 100) ; set max/min value (never set minimal value at 0, or $hGUI won't be clickable when transparency 0 !) GUICtrlSetData(-1, $iTrans) GUISetState(@SW_SHOW, $hGUI2) Local $iTrans_Old = $iTrans While 2 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch $iTrans = GUICtrlRead($idSlider) If $iTrans <> $iTrans_Old Then WinSetTrans($hGUI, "", $iTrans) WinSetTitle($hGUI2, "", "Transparency " & $iTrans) $iTrans_Old = $iTrans EndIf WEnd GUIDelete($hGUI2) Return $iTrans EndFunc ;==>_Transparency ;============================================== Func _Translate($sLangTo, $idLabel) Local $sLangFrom = "auto" Local $iMaxInputLength = 5460 ; this value allows any encoded string to be < 65536 length, even if each character is a Unicode character ; requiring 4 bytes. In this case, each character will be coded on 12 bytes in the string "%..%..%..%.." ; 5460 * 12 = 65520 bytes (which is < 65536) Local $bTruncated = (StringLen(ClipGet()) > $iMaxInputLength) ? True : False Local $sEncoded = _URIEncode(StringLeft(ClipGet(), $iMaxInputLength)) If StringLen($sEncoded) = 0 Then GUICtrlSetData ($idLabel, "Done") MsgBox($MB_TOPMOST, "Clipboard is empty", "Nothing to translate", 0, $hGUI) Return EndIf Local $sLangUsed, $sTranslated = _GoogleAPITranslate($sEncoded, $sLangFrom, $sLangTo, $sLangUsed) GUICtrlSetData ($idLabel, "Done") If $sLangUsed Then ; translation has succeeded and $sLangUsed always contains the code that Google used for its last translation Dim $g_aCaption[2] = ["Copy text", "Ok"] ; 2 buttons $g_sTitle = "Clipboard translated From " & _ (($sLangFrom = "auto") ? ("auto (" & $sLangUsed & ")") : ($sLangFrom)) & _ " To " & $sLangTo & _ ($bTruncated ? " (truncated)" : "") Local $iChoice = _MsgBox(BitOr($MB_OKCANCEL, $MB_DEFBUTTON2, $MB_TOPMOST), $g_sTitle, _ $sTranslated, 0, $hGUI) ; think of $MB_YESNO too (2 buttons without Esc allowed) If $iChoice = 1 Then ; button "Copy text" ClipPut($sTranslated) EndIf Else ; translation failed as $sLangUsed is still empty MsgBox($MB_TOPMOST, "Error", _ "Something went wrong during translation" & @crlf & _ "(Internet connection ok ?)", 0, $hGUI) EndIf EndFunc ;==>_Translate ;============================================== Func _GoogleAPITranslate(Const ByRef $sEncoded, $sFrom, $sTo, ByRef $sLangUsed) Local $oLocalCOMErrorHandler = ObjEvent("AutoIt.Error", "_ErrFuncLocal") ; format and send request With ObjCreate("WinHttp.WinHttpRequest.5.1") ; thanks AspirinJunkie for correct syntax of the Object methods below. .Open("POST", "https://translate.googleapis.com/translate_a/single", False) .SetRequestHeader("Content-Type", "application/x-www-form-urlencoded") .Send(StringFormat("client=gtx&sl=%s&tl=%s&dt=t&q=%s", $sFrom, $sTo, $sEncoded)) Local $sResponse = .ResponseText EndWith ; ConsoleWrite(BinaryToString(StringToBinary("$sResponse: " & $sResponse, $SB_UTF8), $SB_ANSI) & @crlf) Local $vResponse = _JSON_Parse($sResponse) ; process return Local $sOutput = "" If VarGetType($vResponse) = 'Array' Then Local $aData = $vResponse[0] If VarGetType($aData) = 'Array' Then For $i = 0 To UBound($aData) -1 $sOutput &= ($aData[$i])[0] Next EndIf $sLangUsed = $vResponse[2] ; ex. "en" , "de" , ... to display which language Google used for translation, when $sFrom = "auto" EndIf Return $sOutput EndFunc ;==>_GoogleAPITranslate ;============================================== Func _URIEncode(Const ByRef $sData) ; code below from Prog@ndy (minor changes) : https://www.autoitscript.com/forum/topic/95850-url-encoding/?do=findComment&comment=689060 ; maybe Chr(32) should always be encoded as "%20" and not "+" to be compatible with all browsers (?) we'll see... Local $aData = StringSplit(BinaryToString(StringToBinary($sData, $SB_UTF8), $SB_ANSI), "") ; "" => each character returns as an element Local $nChar, $sEncoded = "" For $i = 1 To $aData[0] $nChar = Asc($aData[$i]) Switch $nChar Case 45, 46, 48 To 57, 65 To 90, 95, 97 To 122, 126 $sEncoded &= $aData[$i] Case 32 $sEncoded &= "+" Case Else $sEncoded &= "%" & Hex($nChar, 2) EndSwitch Next Return $sEncoded EndFunc ;==>_URIEncode ;============================================== Func _ErrFuncLocal($oError) ; https://www.autoitscript.com/forum/topic/191401-com-error-handling-in-a-udf-best-practice/?do=findComment&comment=1373102 MsgBox($MB_TOPMOST, @ScriptName & " (" & $oError.scriptline & ") : ==> Local COM error handler - COM Error intercepted !", _ @Tab & "err.number is: " & @Tab & @Tab & "0x" & Hex($oError.number) & @crlf & _ @Tab & "err.windescription:" & @Tab & @Tab & StringStripWS($oError.windescription, 2) & @crlf & _ @Tab & "err.description is: " & @Tab & @Tab & StringStripWS($oError.description, 2) & @crlf & _ @Tab & "err.source is: " & @Tab & @Tab & $oError.source & @crlf & _ @Tab & "err.helpfile is: " & @Tab & @Tab & $oError.helpfile & @crlf & _ @Tab & "err.helpcontext is: " & @Tab & @Tab & $oError.helpcontext & @crlf & _ @Tab & "err.lastdllerror is: " & @Tab & @Tab & $oError.lastdllerror & @crlf & _ @Tab & "err.scriptline is: " & @Tab & @Tab & $oError.scriptline & @crlf & _ @Tab & "err.retcode is: " & @Tab & @Tab & "0x" & Hex($oError.retcode), 0, $hGUI) EndFunc ;==>_ErrFuncLocal ;=========================================== Func _MsgBox($iFlag, $g_sTitle, ByRef $sText, $iTimeOut = 0, $hWnd = 0) Local $hTimerProc = DllCallbackRegister('_TimerProc', 'none', 'hwnd;uint;uint_ptr;dword') Local $iTimerID = _WinAPI_SetTimer(0, 0, 10, DllCallbackGetPtr($hTimerProc)) Local $iChoice = MsgBox($iFlag, $g_sTitle, $sText, $iTimeOut, $hWnd) _WinAPI_KillTimer(0, $iTimerID) DllCallbackFree($hTimerProc) Return $iChoice EndFunc ;==>_MsgBox ;=========================================== Func _TimerProc($hWnd, $iMsg, $iTimerID, $iTime) If WinActive($g_sTitle) Then _WinAPI_KillTimer(0, $iTimerID) If Ubound($g_aCaption) > 3 Then ReDim $g_aCaption[3] For $i = 0 To Ubound($g_aCaption) - 1 ControlSetText($g_sTitle, "", "Button" & ($i + 1), $g_aCaption[$i]) Next EndIf EndFunc ;==>_TimerProc ;============================================== Func _ReadIniFile($sIniFile) If FileExists($sIniFile) Then Local $aIni = FileReadToArray($sIniFile) If @extended <> 9 Then MsgBox($MB_TOPMOST, "_FileReadToArray: extended = " & @extended, _ "Ini file should have exactly 9 lines, not " & @extended & @crlf & _ "(this message is normal if you just upgraded the script to a new version)" & @crlf & _ "" & @crlf & _ "Incompatible .ini file will be deleted now, please run the script again.") FileDelete($sIniFile) Exit EndIf Else ; ini file doesn't exist Local $aIni[9] $aIni[0] = @DesktopWidth / 2 - 50 ; GUI X position $aIni[1] = @DesktopHeight / 2 - 50 ; GUI Y position $aIni[2] = 106 ; GUI Width $aIni[3] = 106 ; GUI Height $aIni[4] = 100 ; GUI Width (client) $aIni[5] = 100 ; GUI Height (client) $aIni[6] = 0xFFFF00 ; yellow (background color of label control) $aIni[7] = 255 ; opaque (GUI transparency) $aIni[8] = "" ; code of Language To (it will become for example "en" or "fr" or etc...) EndIf Return $aIni EndFunc ;==>_ReadIniFile ;============================================== Func _WriteIniFile($sIniFile, $iBkColor, $iTrans, $sLangTo) Local $hIni = FileOpen($sIniFile, $FO_OVERWRITE) If $hIni = -1 Then MsgBox($MB_TOPMOST, "FileOpen error", $sIniFile, 0, $hGUI) Else Local $aPos = WinGetPos($hGUI) Local $aCli = WinGetClientSize($hGUI) FileWrite($hIni, _ $aPos[0] & @crlf & _ $aPos[1] & @crlf & _ $aPos[2] & @crlf & _ $aPos[3] & @crlf & _ $aCli[0] & @crlf & _ $aCli[1] & @crlf & _ $iBkColor & @crlf & _ $iTrans & @crlf & _ $sLangTo) ; There are 9 lines in the ini file (no need of a last @crlf , though it is allowed but not mandatory) FileClose($hIni) EndIf EndFunc ;==>_WriteIniFile1 point -
MsgBox with altered buttons captions
argumentum reacted to pixelsearch for a topic
@funkey always great to hear from you. Thanks for sharing your alternate way to do it. @lIlIIlIllIIIIlI Yes, MsgBox is a blocking function with predefined captions & return values. That's why we can't get the handle of its window when displayed, in a simple way by using WinGetHandle ( "title" [, "text"] ) So if we want to use it with altered captions (instead of creating our own dialogue GUI) then we have to find ways to do it. Gladly with the help of these great people on the Forum, they show us it's possible. @argumentum thanks for the link1 point -
INI file [GUI_Settings] GuiXPos=638 GuiYPos=187 GuiWidth=640 GuiHeight=640 GuiTitle=My Custom GUI GuiIcon=C:\Windows\SysWOW64\shell32.dll, 239 GuiFont=12, 400, 0, Comic Sans MS RuningCnt=2 [GUI_Messages] 1=Move and resize the window, then reopen to check if it saves its position 2=Is everything alright? 3=to start again delete the ini file $ini = _Map_GetfromIni($MyIni) $value = $ini.Section.Key $Title = $ini.GUI_Settings.GuiTitle avoid spaces and dots in section names, and keys e.g. if it was 'GUI Settings' $Title = $ini["GUI Settings"].GuiTitle ; https://www.autoitscript.com/forum/topic/212138-maps-getset-from-to-ini-file/?do=findComment&comment=1535856 #NoTrayIcon #include <GUIConstants.au3> #include <WinAPIShellEx.au3> #include <Array.au3> Opt("ExpandVarStrings", 1) ;0=don't expand, 1=do expand Global $MyIni = SetIni(StringTrimRight(@ScriptFullPath, 4) & ".ini") Global $ini = _Map_GetfromIni($MyIni) OnAutoItExitRegister("SaveToExit") _WinAPI_SetCurrentProcessExplicitAppUserModelID(_WinAPI_CreateGUID()) ; ensure a unique ID Global $hGUI = GUICreate($ini.GUI_Settings.GuiTitle _ , $ini.GUI_Settings.GuiWidth _ , $ini.GUI_Settings.GuiHeight _ , $ini.GUI_Settings.GuiXPos _ , $ini.GUI_Settings.GuiYPos _ , BitOR($GUI_SS_DEFAULT_GUI, $WS_SIZEBOX, $WS_THICKFRAME)) ; check for the icon $aIcon = StringSplit($ini.GUI_Settings.GuiIcon, ", ", 1) GUISetIcon($aIcon[1], ($aIcon[0] = 2 ? Int($aIcon[2]) : "")) ; check for the font $aFont = StringSplit($ini.GUI_Settings.GuiFont, ", ", 1) If $aFont[0] = 4 Then GUISetFont($aFont[1], $aFont[2], $aFont[3], $aFont[4]) Global $Label1 = GUICtrlCreateLabel($ini.GUI_Messages[$ini.GUI_Settings.RuningCnt], 10, 15, $ini.GUI_Settings.GuiWidth - 20, 25) GUICtrlSetResizing(-1, $GUI_DOCKHEIGHT) GUISetState(@SW_SHOW) ;more accuracy GUI reposition WinMove($hGUI, "", Default, Default, $ini.GUI_Settings.GuiWidth, $ini.GUI_Settings.GuiHeight) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd ;-------------------------------------------------------------------------------------------------------------------------------- Func SaveToExit() ; save postion by exit Local $aWpos = WinGetPos($hGUI) $ini.GUI_Settings.GuiXPos = $aWpos[0] $ini.GUI_Settings.GuiYPos = $aWpos[1] $ini.GUI_Settings.GuiWidth = $aWpos[2] $ini.GUI_Settings.GuiHeight = $aWpos[3] $ini.GUI_Settings.RuningCnt += 1 _Map_SaveToIni($ini, $MyIni) EndFunc ;==>SaveToExit ;-------------------------------------------------------------------------------------------------------------------------------- Func SetIni($sIniFile) ; Make a ini file if not exist ;Local $sIniFile = FileGetShortName(StringTrimRight(@ScriptFullPath, 4) & ".ini") If Not FileExists($sIniFile) Then Local $mIni[], $mSection[] $mSection.GuiXPos = -1 $mSection.GuiYPos = -1 $mSection.GuiWidth = @DesktopWidth / 3 $mSection.GuiHeight = @DesktopWidth / 3 $mSection.GuiTitle = "My Custom GUI" $mSection.GuiIcon = @SystemDir & "\shell32.dll, 239" $mSection.GuiFont = "12, 400, 0, Comic Sans MS" $mSection.RuningCnt = 1 $mIni["GUI_Settings"] = $mSection ; add Section as GUI_Settings map to ini map Local $mMessage[] $mMessage[1] = "Move and resize the window, then reopen to check if it saves its position" $mMessage[2] = "Is everything alright?" $mMessage[3] = "to start again delete the ini file" $mIni["GUI_Messages"] = $mMessage ; add Section as GUI_Messages map to ini map _Map_SaveToIni($mIni, $sIniFile) Sleep(300) ShellExecute($sIniFile) EndIf Return $sIniFile EndFunc ;==>SetIni ; #FUNCTION# -------------------------------------------------------------------------------------------------------------------- ; Name...........: _Map_GetfromIni ; Description....: Reads an INI file and returns a map of section names to their respective key-value pairs. ; Syntax.........: _Map_GetfromIni($sFilePath) ; Parameters.....: $sFilePath - The path to the INI file to read. ; Return values..: A map of maps where each section is a map of key-value pairs collection. ; Author ........: ioa747 ; Notes .........: $ini = _Map_GetfromIni($sIniPath) ; value = $ini.Section.Key ; Link ..........: ; Dependencies...: ;-------------------------------------------------------------------------------------------------------------------------------- Func _Map_GetfromIni($sFilePath) Local $aSectionName, $Data, $mNewMap[] ;check if FileExists If Not FileExists($sFilePath) Then Return SetError(13, 0, -1) ; an array of all section names in the INI file. $aSectionName = IniReadSectionNames($sFilePath) For $R = 1 To $aSectionName[0] ; Read the INI section $aSectionName[$R]. This will return a 2 dimensional array. Local $aKey = IniReadSection($sFilePath, $aSectionName[$R]) Local $mKey[] ; Check if an error occurred. If Not @error Then ; Enumerate through the array displaying the keys and their respective values. For $i = 1 To $aKey[0][0] ;ConsoleWrite($i & ") " & $aKey[$i][0] & ":" & $aKey[$i][1] & @CRLF) $mKey[$aKey[$i][0]] = $aKey[$i][1] Next EndIf $mNewMap[$aSectionName[$R]] = $mKey Next Return $mNewMap EndFunc ;==>_Map_GetfromIni ;-------------------------------------------------------------------------------------------------------------------------------- Func _Map_SaveToIni(ByRef $mMap, $sFilePath) Local $aSectionName, $mKey, $aKey, $Data $aSectionName = MapKeys($mMap) $mKey = $mMap[$aSectionName[0]] $aKey = MapKeys($mKey) For $R = 0 To UBound($aSectionName) - 1 $mKey = $mMap[$aSectionName[$R]] $aKey = MapKeys($mKey) Local $iRowsCnt = UBound($aKey) Local $aSection[$iRowsCnt + 1][2] $aSection[0][0] = $iRowsCnt For $i = 0 To $iRowsCnt - 1 $Data = $mKey[$aKey[$i]] ;ConsoleWrite($i & ") " & $aKey[$i] & ":" & $Data & @CRLF) $aSection[$i + 1][0] = $aKey[$i] $aSection[$i + 1][1] = $Data Next ; Write the array to the section labelled $aSectionName[$R]. IniWriteSection($sFilePath, $aSectionName[$R], $aSection) Next ;_ArrayDisplay($aSection, "$aSection") EndFunc ;==>_Map_SaveToIni ;----------------------------------------------------------------------------------------1 point
-
ConsoleWrite and ANSI Escape Sequences Work -- in Windows Terminal
argumentum reacted to CarlD for a topic
Another way -- no file required. BUT: does not work if text includes newlines! Edit: Here's a workaround for text that includes newlines. In the final analysis, the "TYPE temp_file" method is more compact and straight-forward. #include <Process.au3> #include <StringConstants.au3> _ConsoleWriteANSI("This is Line #1." & @CRLF) _ConsoleWriteANSI("This is Line #2." & @CRLF, 33, 104) _ConsoleWriteANSI("This is Line #3a," & @CRLF & "and this is Line #3b" & @CRLF, 41, 52) _ConsoleWriteANSI("This is Line #4." & @CRLF, 105, 35) Func _ConsoleWriteANSI($sTxt, $iFg1 = 33, $iBg1 = 1, $iFg0 = 22, $iBg0 = 0) ; Write colorful text to the console ("ECHO" method) ; Reserved chars ^&|()<> must be "escaped" with ^ ; Default color - Bright Yellow on Black background Local $aLines, $iNL = 0, $sDummy = Chr(254) & Chr(15) & Chr(255) Local $aResvChar = StringSplit("^&|()<>", ""); "^" must come first! While StringRight($sTxt, 2) = @CRLF $sTxt = StringTrimRight($sTxt, 2) $iNL += 1 WEnd $sTxt = Chr(27) & "[" & $iFg1 & "m" & Chr(27) & _ "[" & $iBg1 & "m" & $sTxt & Chr(27) & "[" & $iFg0 & "m" & _ Chr(27) & "[" & $iBg0 & "m" For $i = 1 To $aResvChar[0] $sTxt = StringReplace($sTxt, $aResvChar[$i], "^" & $aResvChar[$i]) Next If StringInStr($sTxt, @CR) Or StringInStr($sTxt, @LF) Then $sTxt = StringReplace($sTxt, @CRLF, $sDummy) $sTxt = StringReplace($sTxt, @CR, $sDummy) $sTxt = StringReplace($sTxt, @LF, $sDummy) $sTxt = StringReplace($sTxt, $sDummy, @CRLF) While StringLeft($sTxt, 2) = @CRLF ConsoleWrite(@CRLF) $sTxt = StringTrimLeft($sTxt, 2) WEnd $aLines = StringSplit($sTxt, @CRLF, $STR_ENTIRESPLIT) For $i = 1 To $aLines[0] _RunDos("echo " & $aLines[$i]) Next Else _RunDos("echo " & $sTxt) EndIf If $iNL > 1 Then For $i = 2 To $iNL ConsoleWrite(@CRLF) Next EndIf EndFunc ;==>_ConsoleWriteANSI1 point