Jump to content

Search the Community

Showing results for tags 'ansi'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General
    • Announcements and Site News
    • Administration
  • AutoIt v3
    • AutoIt Help and Support
    • AutoIt Technical Discussion
    • AutoIt Example Scripts
  • Scripting and Development
    • Developer General Discussion
    • Language Specific Discussion
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Categories

  • AutoIt Team
    • Beta
    • MVP
  • AutoIt
    • Automation
    • Databases and web connections
    • Data compression
    • Encryption and hash
    • Games
    • GUI Additions
    • Hardware
    • Information gathering
    • Internet protocol suite
    • Maths
    • Media
    • PDF
    • Security
    • Social Media and other Website API
    • Windows
  • Scripting and Development
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Member Title


Location


WWW


Interests

Found 7 results

  1. "vintage" terminal This is a funny old style terminal simulator capable to understand and interpretate ANSI escape sequences. It allows printing of text in various colors and are also allowed styles like underline, italic, blink and flash You can print in any position of the screen by using some dedicated functions or by simply printing whole strings with embedded appropriate ANSI escape sequences. You can use it as a simil-terminal that fit within a whole window, or as an embeddable GUI control you can place within your GUI. Even if i've enjoyed on building this, I've to say that it has still some flaws that keep it very far from the "perfection". For example: it's quite slow in printing; shows visible flicker during the print and some others minor flaws, but I hope to receive suggestions on how to improve the whole thing To use this udf you need to save along with this also the stringsize.au3 script by @melba. You can get it from here. Many thanks to: @Melba23 for the stringsize.au3 @jchd for his very powerful RegExp pattern jchd's pattern also adapted by @mikell @KaFu and @ProgAndy for the _GUICtrlGetFont() function vdt.udf #include <GuiRichEdit.au3> #include <GUIConstants.au3> #include <WinAPISys.au3> ; for _WinAPI_SetTimer ; _WinAPI_KillTimer ; the following include is by @melba23 ; get it here -> https://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/ #include <stringsize.au3> ; _StringSize() ; the _GUICtrlGetFont() by KaFu, Prog@ndy ; included at the bottom of this script OnAutoItExitRegister("_EndVintage") ; Default 'screen' dimension in chars (columns and rows) Global $__g_iColumns = 80 ; width of screen (nr. of chars per line) Global $__g_iRows = 24 ; height of screen (nr. of lines) Global $__g_iTabStop = 8 ; Horizontal tab stop step (Historically tab stops where every 8th character) #cs Default Font parameters (a monospaced font is MANDATORY!) "The only monospaced TrueType fonts shipped by Microsoft are Courier New, which shipped with Windows 3.1, and Lucida Sans Typewriter, which was included in the TrueType Font Pack. All other TrueType fonts included with Windows 3.1 and the TrueType Font Pack are proportional fonts." https://support.microsoft.com/en-us/help/90057/microsoft-supplied-monospaced-truetype-fonts #ce Global $__g_sFontName = "Courier New" Global $__g_fFontSize = 12 Global $__g_iFontWeight = 400 ; normal Global $__g_iCharSet = 0 ; see --> _GUICtrlRichEdit_SetFont() Global $__g_hTimerProc = DllCallbackRegister('__SwitchScreen', 'none', 'hwnd;uint;uint_ptr;dword') Global $__g_iTimerID ; see --> _WinAPI_KillTimer() ; the screen text buffer Global $__g_sBuffer = "" ; GUI and 'screen layers' handles Global $__g_hParentGui, $__g_hMainGui, $__g_ahScreen[3] ; initialize cursor position Global $__g_iCursorPosX = 1 ; actual cursor horizontal position Global $__g_iCursorPosY = 1 ; actual cursor vertical position Global $__g_iCursorPushX = $__g_iCursorPosX ; temp X storage (for a later pull) Global $__g_iCursorPushY = $__g_iCursorPosY ; temp Y storage (for a later pull) ; ANSI Control Sequence Introducer Global Const $__g_sCSI = Chr(27) & "[" ; Unicode shapes associated to control codes [ChrW()] Global $__g_aControlChars[32] = [ _ 0, 9786, 9787, 9829, 9830, 9827, 9824, 8226, 9688, 9675, 9689, 9794, 9792, 9834, 9835, 9788, _ 9658, 9668, 8597, 8252, 182, 167, 9644, 8616, 8593, 8595, 8594, 8592, 8735, 8596, 9650, 9660] ; possible text attributes: Global Enum Step * 2 $Bold, $Italic, $Underline, $Concealed, $Inverse, $Blink, $Flash, $VisCtrls ; see the _VDT_Style() function for how to set or unset a text styles ; the BITs of the following byte are used as flags, -> see the _VDT_Style() function for how to set or unset a text styles Global $__g_dbStyles = 0 ; 0 x 0 0 0 0 0 0 0 0 ; 8 bits as flags 1=true(on), 0=false(off) ; ^ ^ ^ ^ ^ ^ ^ ^ ; | | | | | | | | ; | | | | | | | +-> Bold bit value 1 ; | | | | | | +---> Italic bit value 2 ; | | | | | +-----> Underline bit value 4 ; | | | | +-------> Concealed bit value 8 ; | | | +---------> Inverse bit value 16 ; | | +-----------> Blink bit value 32 ; | +-------------> Flash bit value 64 ; +---------------> VisCtrls bit value 128 (visualize control chars) ; used by the _GUICtrlRichEdit_SetCharAttributes function to set or unset an attribute on text Global $__g_aAttribute[2] = ['-', '+'] ; [0] -> '-' -> False ; [1] -> "+" -> True ; Color names (indexes for the $__g_aColor array) Global Enum $Black, $Red, $Green, $Yellow, $Blue, $Magenta, $Cyan, $White, $BrightBlack, _ $BrightRed, $BrightGreen, $BrightYellow, $BrightBlue, $BrightMagenta, $BrightCyan, $BrightWhite ; Set ANSI 16 colors values (0 to 15 basic 16 colors) Global $__g_aColor[256] ; [16] $__g_aColor[$Black] = 0x000000 ; 00 = Black bk $__g_aColor[$Red] = 0x0000AA ; 01 = Red rd $__g_aColor[$Green] = 0x00AA00 ; 02 = Green gn $__g_aColor[$Yellow] = 0x00AAAA ; 03 = Yellow yl $__g_aColor[$Blue] = 0xAA0000 ; 04 = Blue bu $__g_aColor[$Magenta] = 0xAA00AA ; 05 = Magenta mg $__g_aColor[$Cyan] = 0xAAAA00 ; 06 = Cyan cy $__g_aColor[$White] = 0xAAAAAA ; 07 = White wt $__g_aColor[$BrightBlack] = 0x555555 ; 08 = Bright Black BK $__g_aColor[$BrightRed] = 0x0000FF ; 09 = Bright Red RD $__g_aColor[$BrightGreen] = 0x00FF00 ; 10 = Bright Green GN $__g_aColor[$BrightYellow] = 0x00FFFF ; 11 = Bright Yellow YE $__g_aColor[$BrightBlue] = 0xFF0000 ; 12 = Bright Blue BU $__g_aColor[$BrightMagenta] = 0xFF00FF ; 13 = Bright Magenta MG $__g_aColor[$BrightCyan] = 0xFFFF00 ; 14 = Bright Cyan CY $__g_aColor[$BrightWhite] = 0xFFFFFF ; 15 = Bright White WT ; Set ANSI 256 colors palette __SetupANSIPalette() ; (generates the remaining colors in addition to those here above (16 to 255) ; default text colors Global $__g_iDefaultForeground = $White Global $__g_iDefaultBackground = $Black Global $__g_iActiveFGColor = $__g_iDefaultForeground ; actual Foreground color Global $__g_iActiveBGColor = $__g_iDefaultBackground ; actual Background color ; ensure creation of only one TextMode 'control' Global $__g_bControlExists = False Func __SetupANSIPalette() ; Set ANSI colors values (16 to 231) Local $aSteps[7] = [16, '00', '5F', '87', 'AF', 'D7', 'FF'] For $i0 = 1 To 6 For $i1 = 1 To 6 For $i2 = 1 To 6 $__g_aColor[$aSteps[0]] = Dec($aSteps[$i2] & $aSteps[$i1] & $aSteps[$i0]) $aSteps[0] += 1 Next Next Next ; Set ANSI colors values (232 to 255) grey scale For $i0 = 8 To 238 Step 10 $__g_aColor[$aSteps[0]] = Dec(Hex($i0, 2) & Hex($i0, 2) & Hex($i0, 2)) $aSteps[0] += 1 Next EndFunc ;==>__SetupANSIPalette ; HotKeySet("{ESC}", "_EndByESC") ; press 'esc' to end ; #FUNCTION# ==================================================================================================================== ; Name ..........: _VDT_GUICreate ; Description ...: creates a GUI containing a full GUI window Video Terminal ; Syntax ........: _VDT_GUICreate([$sTitle = "Vintage Terminal"[, $iColumns = $__g_iColumns[, $iRows = $__g_iRows[, $fFontSize = $__g_fFontSize[, $sFontName = $__g_sFontName[, $iDefaultForeground = $__g_iDefaultForeground[, $iDefaultBackground = $__g_iDefaultBackground[, $nStyle = -1[, $nExStyle = -1]]]]]]]]]) ; ; Parameters ....: $sTitle - [optional] String of title for the window ; $iColumns - [optional] Number of wanted columns. Default is 80. ; $iRows - [optional] Number of wanted rows. Default is 24. ; $fFontSize - [optional] Font size. Default is 12. ; $sFontName - [optional] Font name. Default is Courier New. (a monospaced font is mandatory!!) ; $iDefaultForeground - [optional] Foreground color. Default is $__g_iDefaultForeground (if changed it becomes the new default) ; $iDefaultBackground - [optional] Background color. Default is $__g_iDefaultBackground (if changed it becomes the new default) ; $nStyle - [optional] defines the style of the window ; $nExStyle - [optional] defines the extended style of the window ; ; Return values .: a 3-element array containing the following information: ; [0] hWnd of the created window ; [1] Width of the window ; [2] Height of the window ; Author ........: Chimp ; Modified ......: ; Remarks .......: the overall dimension of the window is determined by the following parameters: ; number of columns ($iColumns); number of rows ($iRows); Size of font ($fFontSize) ; So there are not width and height parameter for the GUI, since it depends and is determined by the 3 above values ; Also, if the required font dimension is not available for this font, the most similar available dimension is used instead. ; The overall resulting dimensions are however notified to the caller into the returned array. ; ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _VDT_GUICreate($sTitle = Default, $iColumns = $__g_iColumns, $iRows = $__g_iRows, $fFontSize = $__g_fFontSize, $sFontName = $__g_sFontName, $iDefaultForeground = $__g_iDefaultForeground, $iDefaultBackground = $__g_iDefaultBackground, $nStyle = -1, $nExStyle = -1) ; check if already created If $__g_bControlExists = True Then Return __VDT_Check_Defaults($iColumns, $iRows, $fFontSize, $sFontName, $iDefaultForeground, $iDefaultBackground) ; fill the buffer with empty values (spaces) and returns dimensions Local $aWinDim = __VDT_CreateBuffer($__g_iColumns, $__g_iRows) ; create the text buffer and returns Width and Height dimensions Local $iWidth = $aWinDim[2], $iHeight = $aWinDim[3] ; Screen dimensions ; create a GUI $sTitle = ($sTitle = Default) ? "Vintage Terminal" : $sTitle $nExStyle = -1 ? $WS_EX_COMPOSITED : BitOR($nExStyle, $WS_EX_COMPOSITED) ; $WS_EX_COMPOSITED is always included $__g_hMainGui = GUICreate($sTitle, $iWidth, $iHeight, -1, -1, $nStyle, $nExStyle) __VDT_CreateLayers($__g_hMainGui, 0, 0, $iWidth, $iHeight) GUISetState(@SW_HIDE, $__g_hMainGui) $__g_bControlExists = True ; only one terminal is allowed Local $aArray[3] = [$__g_hMainGui, $iWidth, $iHeight] Return $aArray EndFunc ;==>_VDT_GUICreate ; nearly same as above, but instead of creating a GUI, ; this creates only the control to be placed on an already existent parent GUI ; #FUNCTION# ==================================================================================================================== ; Name ..........: _VDT_GUICtrl_Create ; Description ...: This creates only the 'Video Terminal Control' and places it on an already existent parent GUI ; Syntax ........: _VDT_GUICtrl_Create($hWnd[, $iLeft = 0[, $iTop = 0[, $iColumns = Default[, $iRows = Default[, $fFontSize = [, $sFontName = Default[, $iDefaultForeground = Default[, $iDefaultBackground = Default]]]]]]]]) ; Parameters ....: $hWnd - A handle value. the handle of the parent window ; $iLeft - [optional] An integer value. Default is 0. Left position where to place the control on the GUI ; $iTop - [optional] An integer value. Default is 0. Top position " ; $iColumns - [optional] An integer value. The number of wanted columns (default is the global variable $__g_iColumns) 80 ; $iRows - [optional] An integer value. The number of wanted rows (default is the global variable $__g_iRows) 24 ; $fFontSize - [optional] A floating value. Default is $__g_sFontSize -> 12 ; $sFontName - [optional] A string value. Default is $__g_sFontName -> "Courier New" ; $iDefaultForeground - [optional] An integer value. Default is $__g_iDefaultForeground ; $iDefaultBackground - [optional] An integer value. Default is $__g_iDefaultBackground ; Return values .: a 3-element array containing the following information: ; [0] an array of handles of the created layers ; [1] Width of the control ; [2] Height of the control ; Author ........: Chimp ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _VDT_GUICtrl_Create($hWnd, $iLeft = 0, $iTop = 0, $iColumns = Default, $iRows = Default, $fFontSize = Default, $sFontName = Default, $iDefaultForeground = Default, $iDefaultBackground = Default) If $__g_bControlExists = True Then Return $__g_hParentGui = $hWnd ; force the $WS_EX_COMPOSITED ExStyle on the parent GUI GUISetStyle(-1, BitOR(GUIGetStyle($hWnd)[1], $WS_EX_COMPOSITED), $hWnd) __VDT_Check_Defaults($iColumns, $iRows, $fFontSize, $sFontName, $iDefaultForeground, $iDefaultBackground) ; fill the buffer with empty values (spaces) and returns dimensions Local $aWinDim = __VDT_CreateBuffer($__g_iColumns, $__g_iRows) Local $iWidth = $aWinDim[2], $iHeight = $aWinDim[3] ; Screen dimensions __VDT_CreateLayers($hWnd, $iLeft, $iTop, $iWidth, $iHeight) $__g_bControlExists = True ; returns the handles of the layers and the size of the newly created control Local $aArray[3] = [$__g_ahScreen, $iWidth, $iHeight] Return $aArray EndFunc ;==>_VDT_GUICtrl_Create ; replace default values with the new required if needed Func __VDT_Check_Defaults($iColumns, $iRows, $fFontSize, $sFontName, $iDefaultForeground, $iDefaultBackground) ; if default values are changed then set also global variables accordingly $__g_iColumns = (($iColumns = Default) Or (String($iColumns) = "")) ? $__g_iColumns : Number($iColumns) $__g_iRows = (($iRows = Default) Or (String($iRows) = "")) ? $__g_iRows : Number($iRows) $__g_fFontSize = (($fFontSize = Default) Or (String($fFontSize) = "")) ? $__g_fFontSize : Number($fFontSize) $__g_sFontName = (($sFontName = Default) Or (String($sFontName) = "")) ? $__g_sFontName : $sFontName $__g_iDefaultForeground = (($iDefaultForeground = Default) Or (String($iDefaultForeground) = "")) ? $__g_iDefaultForeground : Number($iDefaultForeground) $__g_iDefaultBackground = (($iDefaultBackground = Default) Or (String($iDefaultBackground) = "")) ? $__g_iDefaultBackground : Number($iDefaultBackground) $__g_iActiveFGColor = $__g_iDefaultForeground $__g_iActiveBGColor = $__g_iDefaultBackground EndFunc ;==>__VDT_Check_Defaults ; Create sceen buffer and get dimensions Func __VDT_CreateBuffer($iColumns, $iRows) $__g_sBuffer = _StringReplay(_StringReplay(" ", $iColumns) & @CRLF, $iRows - 1) & _StringReplay(" ", $iColumns) ; a string of width * height blank spaces + @crlf ; ; _StringSize by @Melba23 (determine the size of the screen according to the font parameters) ; -------- Return _StringSize($__g_sBuffer, $__g_fFontSize, $__g_iFontWeight, 0, $__g_sFontName) EndFunc ;==>__VDT_CreateBuffer Func __VDT_CreateLayers($_hGUI, $iLeft, $iTop, $iWidth, $iHeight) ; a transparent layer above the rich edit to protect it from clicks and to allow the dragging of the GUI $__g_ahScreen[2] = GUICtrlCreateLabel("", $iLeft, $iTop, $iWidth, $iHeight, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; This is like a glass over the underlying RichEdit GUICtrlSetCursor(-1, 2) ; Cursor is an arrow (instead of the default I-beam) GUICtrlSetFont(-1, $__g_fFontSize, $__g_iFontWeight, 0, $__g_sFontName) ; by KaFu, Prog@ndy (get actual font size) ; ---- -------- $__g_fFontSize = Number(_GUICtrlGetFont($__g_ahScreen[2])[0]) ; 2 rich-edit screens (they will be shown alternately to make the Blink and Flash effects) $__g_ahScreen[0] = HWnd(_GUICtrlRichEdit_Create($_hGUI, "", $iLeft, $iTop, $iWidth + 4, $iHeight + 4, BitXOR($ES_READONLY, $ES_MULTILINE))) ; layer 0 _GUICtrlRichEdit_SetRECT($__g_ahScreen[0], 1, 1, $iWidth + 1, $iHeight + 1, True) _GUICtrlRichEdit_SetSel($__g_ahScreen[0], 0, -1, True) _GUICtrlRichEdit_SetFont($__g_ahScreen[0], $__g_fFontSize, $__g_sFontName) ; $__g_ahScreen[1] = HWnd(_GUICtrlRichEdit_Create($_hGUI, "", $iLeft, $iTop, $iWidth + 4, $iHeight + 4, BitXOR($ES_READONLY, $ES_MULTILINE))) ; layer 1 _GUICtrlRichEdit_SetRECT($__g_ahScreen[1], 1, 1, $iWidth + 1, $iHeight + 1, True) _GUICtrlRichEdit_SetSel($__g_ahScreen[1], 0, -1, True) _GUICtrlRichEdit_SetFont($__g_ahScreen[1], $__g_fFontSize, $__g_sFontName) ; Initialize and clear the screen _VDT_CLS() ; activate the switching ot the 2 RichEdit 'screens' _VDT_SetTimer() EndFunc ;==>__VDT_CreateLayers ; From Htab Vtab (1 based) to absolute position within the screen buffer Func __GetAbsPos($iHtab = 1, $iVtab = 1, $iScreenWidth = $__g_iColumns) Return ($iVtab - 1) * ($iScreenWidth + 1) + $iHtab EndFunc ;==>__GetAbsPos ; From Absolute To Htab Vtab (1 based) Func __GetTabsPos($iAbsolutePos = 1, $iScreenWidth = $__g_iColumns) Local $aXY[2] $aXY[0] = Mod($iAbsolutePos - 1, $iScreenWidth) + 1 ; Horizontal position within the Screen (column) $iHtab $aXY[1] = Int(($iAbsolutePos - 1) / $iScreenWidth) + 1 ; Vertical position within the Screen (row) $iVtab Return $aXY EndFunc ;==>__GetTabsPos ; retrieve chars from the screen starting from coordinates x,y ; default retrieve only one char Func _VDT_PeekChars($iX, $iY, $iZ = 1) Return StringMid(_GUICtrlRichEdit_GetText($__g_ahScreen[0]), __GetAbsPos($iX, $iY), $iZ) EndFunc ;==>_VDT_PeekChars ; repeat a char or a string along a Vertical line starting from x,y and with a length of $iZ Func _VDT_Vline($iX, $iY, $iZ = 1, $sChr = "|") $sChr &= Chr(30) _VDT_Print(_StringReplay($sChr, $iZ), $iX, $iY) EndFunc ;==>_VDT_Vline ; repeat a char or a string along an Horizontal line starting from x,y and with a length of $iZ Func _VDT_Hline($iX, $iY, $iZ = 1, $sChr = "-") _VDT_Print(StringLeft(_StringReplay($sChr, $iZ), $iZ), $iX, $iY) EndFunc ;==>_VDT_Hline ; print a rectangle. Topleft at X,Y, horizontal length is X1, vertical height is Y1 ; X1 and Y1 are dimensions of the edge and not of the inner body of the rectangle ; so the inner space is effectively X1 - 2 and Y1 - 2 starting at X + 1 and Y + 1 ; Chars in $sShapedAs are the symbols used to draw the rectangle, and respectively: ; TopLeft - Top - TopRight - Left - Right - BottomLeft - Bottom - BottomRight. Func _VDT_Rectangle($iX, $iY, $iX1, $iY1, $sShapedAs = -1, $bTransparent = False) If $sShapedAs = -1 Or $sShapedAs = Default Then $sShapedAs = "+-+||+-+" Local $sSpace = $bTransparent ? Chr(31) : " " _VDT_Print( _ StringMid($sShapedAs, 1, 1) & _ ; top-left corner _StringReplay(StringMid($sShapedAs, 2, 1), $iX1 - 2) & _ ; top border StringMid($sShapedAs, 3, 1), $iX, $iY) ; top-right corner ; left border, body* and right border *(if transparent is true then body is not printed) _VDT_Vline($iX, $iY + 1, $iY1 - 2, StringMid($sShapedAs, 4, 1) & _StringReplay($sSpace, $iX1 - 2) & StringMid($sShapedAs, 5, 1)) _VDT_Print( _ StringMid($sShapedAs, 6, 1) & _ ; bottom-left corner _StringReplay(StringMid($sShapedAs, 7, 1), $iX1 - 2) & _ ; bottom border StringMid($sShapedAs, 8, 1), $iX, $iY + $iY1 - 1) ; bottom-right corner EndFunc ;==>_VDT_Rectangle ; don't show drawing activity (draw behind the shenes) Func _VDT_PauseRedraw() ; _VDT_KillTimer() ; also suspend screen switcher ; _GUICtrlRichEdit_PauseRedraw($__g_ahScreen[0]) _GUICtrlRichEdit_PauseRedraw($__g_ahScreen[1]) WinSetState(HWnd($__g_ahScreen[0]), '', @SW_SHOW) EndFunc ;==>_VDT_PauseRedraw ; show what's been drawn Func _VDT_ResumeRedraw() ;_GUICtrlRichEdit_ResumeRedraw($__g_ahScreen[0]) _GUICtrlRichEdit_ResumeRedraw($__g_ahScreen[1]) ; _VDT_SetTimer() EndFunc ;==>_VDT_ResumeRedraw ; Disable Flash/Blink effect Func _VDT_PauseSwitching() _VDT_KillTimer() ; also suspend screen switcher WinSetState(HWnd($__g_ahScreen[0]), '', @SW_SHOW) EndFunc ;==>_VDT_PauseSwitching ; Enable Flash/Blink effect Func _VDT_ResumeSwitching() $__g_iTimerID = _WinAPI_SetTimer(0, 0, 500, DllCallbackGetPtr($__g_hTimerProc)) EndFunc ;==>_VDT_ResumeSwitching ; enables the screens switching Func _VDT_SetTimer() $__g_iTimerID = _WinAPI_SetTimer(0, 0, 500, DllCallbackGetPtr($__g_hTimerProc)) EndFunc ;==>_VDT_SetTimer ; stops the screens switching Func _VDT_KillTimer() _WinAPI_KillTimer(0, $__g_iTimerID) EndFunc ;==>_VDT_KillTimer ; #FUNCTION# ==================================================================================================================== ; Name ..........: _VDT_Print ; Description ...: Main printing function ; Syntax ........: _VDT_Print([$sString = ""[, $iHtab = $__g_iCursorPosX[, $iVtab = $__g_iCursorPosY[, $iForegroundColor = $__g_iActiveFGColor[, $iBackgroundColor = $__g_iActiveBGColor]]]]]) ; Parameters ....: $sString - [optional] a string value. Default is "". String can include ANSI sequences and ctrl chars ; $iHtab - [optional] column where to start printing ; $iVtab - [optional] row where to start printnting ; $iForegroundColor - [optional] wanted foreground color ; $iBackgroundColor - [optional] Wanted bckground color ; $bWrap - [optional] Default is True, printed Text wrapsaround ; if is False, the text that exceeds the right margin is simply discarded ; Return values .: None ; Author ........: Chimp ; Modified ......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _VDT_Print($sString = "", $iHtab = $__g_iCursorPosX, $iVtab = $__g_iCursorPosY, $iForegroundColor = $__g_iActiveFGColor, $iBackgroundColor = $__g_iActiveBGColor, $bWrap = True) If $iHtab = Default Then $iHtab = $__g_iCursorPosX If $iVtab = Default Then $iVtab = $__g_iCursorPosY Local $iStartingHtab = $iHtab Local $sANSI_Escape Local $aParameters[1] Local $iNumParams ; step 1 - split string on ansi escape sequences and/or on control chars (if any) ; ------------------------------------------------------------------------------- ; credits ; ------- ; RegExp pattern by @jchd (Thanks to @jchd) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1386039 ; ----- ; pattern also adapted by @mikell (Thanks to @mikell) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1387160 ; ------- Local $aStringChunks = StringRegExp($sString, "(?x)(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )(?| \x1B(?&ANSI_Escape) | [\x01-\x1A\x1C-\x1F] | \x1B(?!(?&ANSI_Escape)) | (?:[^\x01-\x1F] (?!(?&ANSI_Escape)))+ )", 3) ; remove escape sequences from the string (Thanks to @jchd again) ; $sString = StringRegExpReplace($sString, "(?x) (\x1B \[ (?:\s*\d*\s*;?)* [[:alpha:]])", "") ; step 2 - parse the resulting $aStringChunks array For $iChunk = 0 To UBound($aStringChunks) - 1 ; check presence of escape sequences or control chars $sANSI_Escape = StringReplace($aStringChunks[$iChunk], " ", "") ; clean unneeded (and disturbing)spaces If StringLeft($sANSI_Escape, 2) = $__g_sCSI Then ; it is a CSI (Control Sequence Introducer) ; get ansi escape sequence parameters $aParameters = StringSplit(StringMid(StringTrimRight($sANSI_Escape, 1), 3), ";") ; extract the parameters of this sequence $iNumParams = $aParameters[0] ; keep number of parameters $aParameters[0] = StringRight($sANSI_Escape, 1) ; gat the final character (put it in [0]) ; ; ANSI Escape squence interpreter (http://man7.org/linux/man-pages/man4/console_codes.4.html) ; https://en.wikipedia.org/wiki/ANSI_escape_code ; ------------------------------------------------------------------------------------------------- Select Case $aParameters[0] == "a" ; HPR Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "d" ; VPA Move cursor to the indicated row, current column. $iHtab = Number($aParameters[1]) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "e" ; VPR Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab Case $aParameters[0] == "f" ; HVP Move cursor to the indicated row, column. ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "g" ; TBC Without parameter: clear tab stop at current position. ; ? Case $aParameters[0] == "h" ; SM Set Mode ; ? Case $aParameters[0] == "l" ; RM Reset Mode ; ? Case $aParameters[0] == "m" ; SGR Set attributes. For $iParam = 1 To $iNumParams ; UBound($aParameters) - 1 Switch Number($aParameters[$iParam]) Case 0 ; reset all attributes to their defaults _VDT_SetActiveColors() ; _VDT_SetAttribute($Normal) _VDT_Style($Bold, False) ; $Bold = False _VDT_Style($Italic, False) ; $Italic = False _VDT_Style($Underline, False) ; $Underline = False _VDT_Style($Concealed, False) ; $Concealed = False _VDT_Style($Inverse, False) ; $Inverse = False _VDT_Style($Flash, False) ; $Flash = False _VDT_Style($Blink, False) ; $Blink = False $iBackgroundColor = _VDT_SetActiveBackColor($__g_iDefaultBackground) $iForegroundColor = _VDT_SetActiveForeColor($__g_iDefaultForeground) Case 1 ; set Bold (or increased intensity) _VDT_Style($Bold, True) Case 2 ; set Faint (decreased intensity) ; _VDT_Style($Bold, False) ; ; Case 3 ; set Italic _VDT_Style($Italic, True) Case 4 ; set underscore _VDT_Style($Underline, True) Case 5 ; set blink _VDT_Style($Blink, True) Case 6 ; Rapid Blink (used as "Flash" effect here instead) ; https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters ; http://www.pinon-hebert.fr/Knowledge/index.php/Codes_ANSI _VDT_Style($Flash, True) ; (emphasized blink) ; use "25" as blink and/or flash off Case 7 ; set reverse video _VDT_Style($Inverse, True) Case 8 ; concealed (foreground becomes = background) _VDT_Style($Concealed, True) Case 22 ; bold off _VDT_Style($Bold, False) Case 23 ; Italic off _VDT_Style($Italic, False) Case 24 ; underline off _VDT_Style($Underline, False) Case 25 ; blink off _VDT_Style($Blink, False) Case 26 ; flash off (custom) _VDT_Style($Flash, False) ; Case 27 ; reverse video off _VDT_Style($Inverse, False) Case 28 ; concealed off _VDT_Style($Concealed, False) Case 30 To 37 ; set foreground color $iForegroundColor = _VDT_SetActiveForeColor(Number($aParameters[$iParam]) - 30) Case 38 ; set default foreground color ; 38;5;# foreground based on index (0-255) ; 38;2;#;#;# foreground based on RGB If ($iParam + 1) < $iNumParams Then ; there are at least other 2 parameters $iParam += 1 Switch Number($aParameters[$iParam]) ; peek next (sub)Parameter Case 5 ; color based on index (0-255) $iParam += 1 ; color_index = $aParameters[$iParam] $iForegroundColor = _VDT_SetActiveForeColor(Number($aParameters[$iParam])) ; 0-255 Case 2 If ($iParam + 2) < $iNumParams Then ; there are at least other 3 parameters $iParam += 3 ; Blue_component = Number($aParameters[$iParam] $iForegroundColor = Hex($aParameters[$iParam], 2) $iParam -= 1 ; Green_component = Number($aParameters[$iParam] $iForegroundColor &= Hex($aParameters[$iParam], 2) $iParam -= 1 ; Red_component = Number($aParameters[$iParam] $iForegroundColor &= Hex($aParameters[$iParam], 2) $iForegroundColor = _VDT_SetActiveForeColor(Dec($iForegroundColor)) Else ; wrong number of parameters, 3 are needed for 'Case 2' EndIf EndSwitch Else ; wrong number of parameters, set color to black ; .... or (better choice ?) leave colors unchanged EndIf Case 39 ; set default foreground (using current intensity) Case 40 To 47 ; set background color $iBackgroundColor = _VDT_SetActiveBackColor(Number($aParameters[$iParam]) - 40) Case 48 ; 48;5;# background based on index (0-255) ; 48;2;#;#;# background based on RGB If ($iParam + 1) < $iNumParams Then ; there are at least other 2 parameters $iParam += 1 Switch Number($aParameters[$iParam]) ; peek next (sub)Parameter Case 5 ; color based on index (0-255) $iParam += 1 ; color_index = $aParameters[$iParam] $iBackgroundColor = _VDT_SetActiveBackColor(Number($aParameters[$iParam])) ; 0-255 Case 2 If ($iParam + 2) < $iNumParams Then ; there are at least other 3 parameters $iParam += 3 ; Blue_component = Number($aParameters[$iParam] $iBackgroundColor = Hex($aParameters[$iParam], 2) $iParam -= 1 ; Green_component = Number($aParameters[$iParam] $iBackgroundColor &= Hex($aParameters[$iParam], 2) $iParam -= 1 ; Red_component = Number($aParameters[$iParam] $iBackgroundColor &= Hex($aParameters[$iParam], 2) $iBackgroundColor = _VDT_SetActiveBackColor(Dec($iBackgroundColor)) Else ; wrong number of parameters, 3 are needed for 'Case 2' EndIf EndSwitch Else ; wrong number of parameters, set color to black ; .... or (better choice ?) leave colors unchanged EndIf Case 49 ; set default background (using current intensity) Case 90 To 97 ; set foreground bright color $iForegroundColor = _VDT_SetActiveForeColor(Number($aParameters[$iParam]) - 82) Case 100 To 107 ; ; set background bright color $iBackgroundColor = _VDT_SetActiveBackColor(Number($aParameters[$iParam]) - 92) EndSwitch Next Case $aParameters[0] == "n" ; DSR Status report #cs Ps = 6 -> Report Cursor Position (CPR) [row;column]. Result is CSI r ; c R #ce #cs If $aParameters[1] = 6 Then Return ($__g_sCSI & $__g_iCursorPosY & "," & $__g_iCursorPosX & "R") EndIf #ce Case $aParameters[0] == "q" ; DECLL Set keyboard LEDs. ; ESC [ 0 q: clear all LEDs ; ESC [ 1 q: set Scroll Lock LED ; ESC [ 2 q: set Num Lock LED ; ESC [ 3 q: set Caps Lock LED Case $aParameters[0] == "r" ; DECSTBM Set scrolling region; parameters are top and bottom row. Case $aParameters[0] == "s" ; Save cursor location. _StoreCursor() Case $aParameters[0] == "u" ; Restore cursor location. _RecallCursor() $iHtab = $__g_iCursorPosX $iVtab = $__g_iCursorPosY Case $aParameters[0] == "`" ; HPA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "@" ; ICH Insert the indicated # of blank characters. Case $aParameters[0] == "A" ; CUU Move cursor up the indicated # of rows. $iVtab -= Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab Case $aParameters[0] == "B" ; CUD Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab Case $aParameters[0] == "C" ; CUF Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "D" ; CUB Move cursor left the indicated # of columns. $iHtab -= Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "E" ; CNL Move cursor down the indicated # of rows, to column 1. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab $iHtab = 1 $__g_iCursorPosX = $iHtab Case $aParameters[0] == "F" ; CPL Move cursor up the indicated # of rows, to column 1. $iVtab -= Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab $iHtab = 1 $__g_iCursorPosX = $iHtab Case $aParameters[0] == "G" ; CHA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "H" ; CUP Move cursor to the indicated row, column (origin at 1,1). ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $__g_iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $__g_iCursorPosX = $iHtab Case $aParameters[0] == "J" ; ED Erase display (default: from cursor to end of display). ReDim $aParameters[2] ; mandatory 1 parameters Switch Number($aParameters[1]) Case 0 ; Pn=0: erases from active position to end of display. __Sub_Print(_StringReplay(" ", $__g_iColumns - $iHtab + 1), $iHtab, $iVtab, $__g_iDefaultForeground, $__g_iDefaultBackground) If $iVtab < $__g_iRows Then For $y = $iVtab + 1 To $__g_iRows __Sub_Print(_StringReplay(" ", $__g_iColumns), 1, $y, $__g_iDefaultForeground, $__g_iDefaultBackground) Next EndIf Case 1 ; Pn=1: erases from the beginning of display to active position. __Sub_Print(_StringReplay(" ", $iHtab), 1, $iVtab, $__g_iDefaultForeground, $__g_iDefaultBackground) If $iVtab > 1 Then For $y = 1 To $iVtab - 1 __Sub_Print(_StringReplay(" ", $__g_iColumns), 1, $y, $__g_iDefaultForeground, $__g_iDefaultBackground) Next EndIf Case 2 ; Pn=2: erases entire display and move cursor to the top-left. _VDT_CLS() $iHtab = 1 $iVtab = 1 EndSwitch Case $aParameters[0] == "K" ; EL Erase line (default: from cursor to end of line). __Sub_Print(_StringReplay(" ", $__g_iColumns - $iHtab + 1), $iHtab, $iVtab, $__g_iActiveFGColor, $__g_iActiveBGColor) Case $aParameters[0] == "L" ; IL Insert the indicated # of blank lines. Case $aParameters[0] == "M" ; DL Delete the indicated # of lines. Case $aParameters[0] == "P" ; DCH Delete the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $__g_iActiveFGColor, $__g_iActiveBGColor) Case $aParameters[0] == "X" ; ECH Erase the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $__g_iDefaultForeground, $__g_iDefaultBackground) EndSelect ; ; is it a single Control character ? (http://jkorpela.fi/chars/c0.html) ElseIf StringLen($sANSI_Escape) = 1 And (AscW($sANSI_Escape) >= 0 And AscW($sANSI_Escape) <= 31) Then ; https://docs.microsoft.com/en-us/host-integration-server/core/character-tables2 ; https://ascii.cl/control-characters.htm ; http://jkorpela.fi/chars/c0.html ; control character interpreter ; --------------------------------------------------------------------------------------- ; managed control codes are: chr(07) 0x07 Bell, rings the bell... (Plays Windows' default beep) ; chr(08) 0x08 move cursor 1 char to the left (Backspace) ; chr(09) 0x09 Horizontal tab, move to next tab stop (8 16 24 32 40.....) ; chr(10) 0x0A Line Feed, move cursor down 1 line (carrage return not performed here) ; chr(11) 0x0B Vertical tab (the opposite of a line feed as on an RS232 terminal) ; chr(12) 0xOC Form Feed, page eject ; chr(13) 0xOD Carriage Return (line feed not performed here) ; chr(24) 0x18 backspace with deletion (Cancel) ; chr(30) 0x1E (custom) Line feed + partial Carriage Return (CR returns only to previous hTab) ; chr(31) 0x1F (custom) move cursor 1 char to the right If _VDT_Style($VisCtrls) Then ; visualize control codes ; If (Asc($sANSI_Escape) < Chr(7)) Or (Asc($sANSI_Escape) > Chr(13)) Then __Sub_Print(ChrW($__g_aControlChars[AscW($sANSI_Escape)]), $iHtab, $iVtab, $__g_iActiveFGColor, $__g_iActiveBGColor, $bWrap) ; EndIf EndIf $aParameters[0] = $sANSI_Escape Switch Asc($sANSI_Escape) ; Select Case 1 Case 2 Case 3 Case 4 Case 5 Case 6 Case 7 ; Bell, rings the bell Beep(900, 150) Case 8 ; Backspace $iHtab -= 1 $__g_iCursorPosX = $iHtab Case 9 ; Horizontal tab (Historically tab stops were every 8th character) If $iHtab >= 0 Then $iHtab = $iHtab + (Mod($iHtab, $__g_iTabStop) * -1) + $__g_iTabStop Else $iHtab = $iHtab + (Mod(Abs($iHtab) - 1, $__g_iTabStop) + 1) EndIf $__g_iCursorPosX = $iHtab Case 10 ; Line Feed @LF (move cursor down by 1 line) $iVtab += 1 $__g_iCursorPosY = $iVtab Case 11 ; Vertical tab (move cusros up by 1 line) $iVtab -= 1 $__g_iCursorPosY = $iVtab Case 12 ; Form Feed Case 13 ; Carriage Return @CR (move cursor to the beginning of this line) $iHtab = 1 $__g_iCursorPosX = $iHtab Case 14 Case 15 Case 16 Case 17 Case 18 Case 19 Case 20 Case 21 Case 22 Case 23 Case 24 ; backspace with deletion (Cancel) $iHtab -= 1 __Sub_Print(" ", $iHtab, $iVtab, $__g_iActiveFGColor, $__g_iActiveBGColor) $__g_iCursorPosX = $iHtab Case 25 Case 26 Case 27 Case 28 Case 29 Case 30 ; (custom) LF + a partial CR (Carriage Return stops below previous HTab) $iVtab += 1 $iHtab = $iStartingHtab $__g_iCursorPosX = $iHtab $__g_iCursorPosY = $iVtab Case 31 ; move cursor to the right by 1 char -> $iHtab += 1 $__g_iCursorPosX = $iHtab EndSwitch Else ; print the text __Sub_Print(StringReplace($aStringChunks[$iChunk], ChrW(0), ""), $iHtab, $iVtab, $iForegroundColor, $iBackgroundColor, $bWrap) $iHtab = $__g_iCursorPosX $iVtab = $__g_iCursorPosY EndIf Next EndFunc ;==>_VDT_Print ; manage the portion of text and/or the wraparound of the text to be placed on the terminal Func __Sub_Print($sString = "", $iHtab = $__g_iCursorPosX, $iVtab = $__g_iCursorPosY, $iForegroundColor = $__g_iActiveFGColor, $iBackgroundColor = $__g_iActiveBGColor, $bWrap = True) Local $sExceeding = "" Local $iStringFullLen = StringLen($sString) Local $iStringLen = $iStringFullLen If Not $iStringLen Then Return ; no string to print Local $iStringEnd = $iHtab + $iStringLen - 1 $__g_iCursorPosX = $iHtab + $iStringLen $__g_iCursorPosY = $iVtab ; ----------------------------------------------------------------------- ; if $bWrap = False keep only the text portion that fall into the screen ; if $bWrap = True then the part on excess is wrapped to next line(s) ; (parts of text falling outside the screen will be managed by recursion) ; ----------------------------------------------------------------------- If (Not $bWrap) And ( _ ; check if the string exceeds the right edge $iHtab > $__g_iColumns) Then Return ; If _ ; check if all the string falls outside the printable area $iVtab > $__g_iRows Or _ ; below the bottom $iVtab < 1 Or _ ; over the top edge $iStringEnd < 1 _ ; last char of string is still on the left of the left edge Then Return ; adjust string if only a part has to be Printed ; (a) string begins on the left of the left edge If $iHtab < 1 Then ; remove the part outside on the left ...|..........| $sString = StringRight($sString, $iStringEnd) ; case st|ring $iStringLen = StringLen($sString) $iHtab = 1 EndIf ; (b) string begins in the screen but is wider of the screen | str|ing ; +---------+... If $iStringEnd > $__g_iColumns Then ; removes the exceeding part on the right ; to wordwrap by recursion we keep exceeding part for later use $sExceeding = StringRight($sString, $iStringEnd - $__g_iColumns) $sString = StringTrimRight($sString, $iStringEnd - $__g_iColumns) $iStringLen = StringLen($sString) EndIf ; --------------------------------------------------------------- Local $iAnchor = __GetAbsPos($iHtab, $iVtab) - 1 Local $iActive = $iAnchor + $iStringLen __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) ; Screen 0 normal text (common to all) Select ; evaluate what to print on the second screen based on the various styles set Case _VDT_Style($Blink) ; Print only on layer 1 ; it alternates On and Off. If _VDT_Style($Flash) Then ; blink + flash __PokeText(1, _StringReplay(" ", StringLen($sString)), $iAnchor, $iActive, $iBackgroundColor, $iForegroundColor) ; clear the portion on screen 1 Else ; only blink __PokeText(1, _StringReplay(" ", StringLen($sString)), $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) ; clear the portion on screen 1 EndIf Case _VDT_Style($Flash) ; only flash. Alternate foreground with background on each of both screens __PokeText(1, $sString, $iAnchor, $iActive, $iBackgroundColor, $iForegroundColor) Case Else ; normal text __PokeText(1, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) EndSelect ; *** recurse if part of the string have to be wrapped on next line *** If $bWrap And $sExceeding <> "" Then $iHtab = 1 $iVtab += 1 $__g_iCursorPosX = $iHtab $__g_iCursorPosY = $iVtab __Sub_Print($sExceeding, $iHtab, $iVtab, $iForegroundColor, $iBackgroundColor) ; ===>> recursive call EndIf EndFunc ;==>__Sub_Print ; Place string on the "screen" buffer (on the RichEdit controls) Func __PokeText($iLayer, $sString, $iAnchor, $iActive, $iForeColor, $iBackColor) ; Automatically set or unset the reverse effect based on the _VDT_Style($Inverse) boolean value Local $aForeBack[2] = [$iForeColor, $iBackColor] $iForeColor = $aForeBack[_VDT_Style($Inverse)] $iBackColor = $aForeBack[Not _VDT_Style($Inverse)] ; select the part of the screen buffer to be replaced with the incoming $sString _GUICtrlRichEdit_SetSel($__g_ahScreen[$iLayer], $iAnchor, $iActive, False) _GUICtrlRichEdit_ReplaceText($__g_ahScreen[$iLayer], $sString, False) ; reselect again the just replaced text so to set styles _GUICtrlRichEdit_SetSel($__g_ahScreen[$iLayer], $iAnchor, $iActive, False) ; set styles for the incoming text _GUICtrlRichEdit_SetFont($__g_ahScreen[$iLayer], $__g_fFontSize, $__g_sFontName, $__g_iCharSet) ; font Local $iLocalBackColor = __PeekColor($iBackColor) Local $iLocalForeColor = __PeekColor($iForeColor) ; bold is managed as higher-light (true bold creates problems) If _VDT_Style($Bold) Then If $iLocalForeColor <= 0xAAAAAA Then $iLocalForeColor = $iLocalForeColor + 0x555555 Else EndIf EndIf _GUICtrlRichEdit_SetCharBkColor($__g_ahScreen[$iLayer], $iLocalBackColor) ; foreground color If _VDT_Style($Concealed) Then ; if $Concealed is true then print with forecolor same as backcolor to 'hide' this text _GUICtrlRichEdit_SetCharColor($__g_ahScreen[$iLayer], $iLocalBackColor) Else _GUICtrlRichEdit_SetCharColor($__g_ahScreen[$iLayer], $iLocalForeColor) EndIf ; set or unset italic, underline, according to the state of the respective variables ; (since bold creates problems, is managed as HighLight here above) _GUICtrlRichEdit_SetCharAttributes($__g_ahScreen[$iLayer], _ ; $__g_aAttribute[_VDT_Style($Bold)] & 'bo' & _ ; bold creates problems $__g_aAttribute[_VDT_Style($Italic)] & 'it' & _ ; italic $__g_aAttribute[_VDT_Style($Underline)] & 'un') ; underline _GUICtrlRichEdit_Deselect($__g_ahScreen[$iLayer]) EndFunc ;==>__PokeText ; svae the cursor position Func _StoreCursor($sAction = "Push") Local Static $__g_iCursorPushX = $__g_iCursorPosX Local Static $__g_iCursorPushY = $__g_iCursorPosY If $sAction = "Push" Then $__g_iCursorPushX = $__g_iCursorPosX $__g_iCursorPushY = $__g_iCursorPosY EndIf Local $aXY[2] = [$__g_iCursorPushX, $__g_iCursorPushY] Return $aXY EndFunc ;==>_StoreCursor ; restore the cursor position Func _RecallCursor() Local $aXY = _StoreCursor("Pull") $__g_iCursorPosX = $aXY[0] $__g_iCursorPosY = $aXY[1] EndFunc ;==>_RecallCursor ; if you pass a number 0-255 it returns a predefined color from the $__g_aColor[] array. ; if the number is > 255 and <= 0xFFFFFF it returns the same number, while if the passed ; number is out of range it return 0 ($Black)and sets @error Func __PeekColor($iColor) $iColor = Number($iColor) If $iColor >= 0 And $iColor < UBound($__g_aColor) Then Return $__g_aColor[$iColor] ; predefined colors (0-255) ElseIf _IsRGB($iColor) Then Return $iColor ; value is <= 0xFFFFFF (256 - 0xFFFFFF) Else Return SetError(1, 0, 0) ; if out of range return Black and set error EndIf EndFunc ;==>__PeekColor ; clear the screen (fill screen buffer with spaces) ; (for 'crazy' effects you could also select another char instead of the space and custom colors) Func _VDT_CLS($sFillChr = " ", $iForegroundColor = $__g_iActiveFGColor, $iBackgroundColor = $__g_iActiveBGColor) ; clear the screen For $iScreen = 0 To 1 ; act on both screens 0 and 1 If $sFillChr = " " Then ; fill screens with blanks _GUICtrlRichEdit_SetText($__g_ahScreen[$iScreen], $__g_sBuffer) Else ; fill screens with custom char _GUICtrlRichEdit_SetText($__g_ahScreen[$iScreen], StringReplace($__g_sBuffer, " ", $sFillChr)) EndIf _GUICtrlRichEdit_SetSel($__g_ahScreen[$iScreen], 0, -1, True) ; select whole screen ; set RichEdit styles _GUICtrlRichEdit_SetFont($__g_ahScreen[$iScreen], $__g_fFontSize, $__g_sFontName, $__g_iCharSet) ; Set Font _GUICtrlRichEdit_SetCharColor($__g_ahScreen[$iScreen], __PeekColor($iForegroundColor)) ; Set Foreground default color _GUICtrlRichEdit_SetCharBkColor($__g_ahScreen[$iScreen], __PeekColor($iBackgroundColor)) ; Set Background default color _GUICtrlRichEdit_SetSel($__g_ahScreen[$iScreen], 0, 0, False) Next ; put cursor at home $__g_iCursorPosX = 1 ; $iHtab $__g_iCursorPosY = 1 ; $iVtab EndFunc ;==>_VDT_CLS ; Set new active fore/back colors ; Default: -> restore default color ; Empty string: -> if "" or out of range leave active color unchanged Func _VDT_SetActiveColors($iForeColor = Default, $iBackColor = Default) #cs If $iForeColor = Default Then $iForeColor = $__g_iDefaultForeground If $iForeColor < $Black Or $iForeColor > 255 Or String($iForeColor) = "" Then $iForeColor = $__g_iActiveFGColor If $iBackColor = Default Then $iBackColor = $__g_iDefaultBackground If $iBackColor < $Black Or $iBackColor > 255 Or String($iBackColor) = "" Then $iBackColor = $__g_iActiveBGColor #ce $__g_iActiveFGColor = _VDT_SetActiveForeColor($iForeColor) ; $__g_iDefaultForeground = __PeekColor($iForeColor) $__g_iActiveBGColor = _VDT_SetActiveBackColor($iBackColor) ; $__g_iDefaultBackground = __PeekColor($iBackColor) Local $aDefaultColors = [$__g_iActiveFGColor, $__g_iActiveBGColor] Return $aDefaultColors EndFunc ;==>_VDT_SetActiveColors ; Set new active foreground color Func _VDT_SetActiveForeColor($iForeColor = $__g_iActiveFGColor) If $iForeColor = Default Or $iForeColor = "" Then $iForeColor = $__g_iDefaultBackground EndIf If @error Then ; leave foreground color unchanged $iForeColor = $__g_iActiveBGColor EndIf $__g_iActiveFGColor = $iForeColor Return $__g_iActiveFGColor EndFunc ;==>_VDT_SetActiveForeColor ; Set new active background color Func _VDT_SetActiveBackColor($iBackColor = $__g_iActiveBGColor) If $iBackColor = Default Or $iBackColor = "" Then $iBackColor = $__g_iDefaultBackground EndIf If @error Then ; leave background color unchanged $iBackColor = $__g_iActiveBGColor EndIf $__g_iActiveBGColor = $iBackColor Return $__g_iActiveBGColor EndFunc ;==>_VDT_SetActiveBackColor ; if you pass the second parameter as True or False it Set or Unset the passed style. ; passing only first parameter (without the second), it returns True or False according to the actual setting of the passed style Func _VDT_Style($iStyle, $vAction = Null) If $vAction = Null Then Return BitAND($__g_dbStyles, $iStyle) <> 0 If $vAction = True Then $__g_dbStyles = BitOR($__g_dbStyles, $iStyle) If $vAction = False Then $__g_dbStyles = BitAND($__g_dbStyles, BitNOT($iStyle)) Return $__g_dbStyles EndFunc ;==>_VDT_Style ; check if is within color ranges Func _IsRGB($iColor) Return $iColor >= 0x000000 And $iColor <= 0xFFFFFF EndFunc ;==>_IsRGB ; move the TextMode GUI Func _VDT_GUIMoveTo($iX = 5, $iY = 5, $_hGUI = $__g_hMainGui) If IsHWnd($_hGUI) Then WinMove($_hGUI, "", $iX, $iY) EndFunc ;==>_VDT_GUIMoveTo ; psition cursor to indicated coordinates Func _VDT_SetCursorPos($iHtab, $iVtab) $__g_iCursorPosX = $iHtab $__g_iCursorPosY = $iVtab EndFunc ;==>_VDT_SetCursorPos ; if ESC and active GUI is this then exit Func _EndByESC() ; If WinActive("[ACTIVE]") = $__g_hMainGui Or WinActive("[ACTIVE]") = $__g_hParentGui Then _EndVintage() EndFunc ;==>_EndByESC ; This function alternates the visualization of the 2 screens Func __SwitchScreen($hWnd, $iMsg, $__g_iTimerID, $iTime) #forceref $hWnd, $iMsg, $__g_iTimerID, $iTime Local Static $bStatus = True $bStatus = Not $bStatus If $bStatus Then WinSetState(HWnd($__g_ahScreen[0]), '', @SW_HIDE) ; $iVisibleLayer = 1 Else WinSetState(HWnd($__g_ahScreen[0]), '', @SW_SHOWNOACTIVATE) ; $iVisibleLayer = 0 EndIf EndFunc ;==>__SwitchScreen ; https://www.autoitscript.com/forum/topic/121847-convert-text-string-from-codepage-437-or-850-to-1252/ Func _StringToCodepage($ansi, $codepage) #cs Local $struct = DllStructCreate("byte[" & StringLen($ansi) * 2 + 4 & "]") ;platz für UTF16 $string = _WinAPI_MultiByteToWideCharEx($ansi, DllStructGetPtr($struct), Number($codepage), $MB_PRECOMPOSED) ; $MB_USEGLYPHCHARS) ;Ansi-String in Codepage umwandeln Return BinaryToString(DllStructGetData($struct, 1), 2) #ce Return _WinAPI_MultiByteToWideChar($ansi, $codepage, 0, True) EndFunc ;==>_StringToCodepage Func _EndVintage() _WinAPI_KillTimer(0, $__g_iTimerID) DllCallbackFree($__g_hTimerProc) _GUICtrlRichEdit_Destroy($__g_ahScreen[0]) _GUICtrlRichEdit_Destroy($__g_ahScreen[1]) Exit EndFunc ;==>_EndVintage ; ----------------------------------- ; below are some companion functions ; ----------------------------------- ; returns one or more chars replicated n times ; Example: ConsoleWrite(_StringReplay('*', 5) & @CRLF) Func _StringReplay($sChars = "", $iRepeats = 0) $sChars = String($sChars) $iRepeats = Int(Abs(Number($iRepeats))) Return StringReplace(StringFormat('%' & $iRepeats & 's', ""), " ", $sChars) EndFunc ;==>_StringReplay ; passing a (long) string and a value it returns that string ; formatted in a column large as the value Func _StringColumn($sString, $x = 19) For $i = $x To StringLen($sString) Step $x $i = StringInStr($sString, " ", 0, -1, $i) If $i = 0 Then Return SetError(1, 0, "") $sString = StringReplace($sString, $i, Chr(30)) Next If StringRight($sString, 1) = Chr(30) Then $sString = StringTrimRight($sString, 1) Return _CSI_cursorSavePosition() & StringReplace($sString, Chr(30), _CSI_cursorRestorePosition() & @LF & _CSI_cursorSavePosition()) EndFunc ;==>_StringColumn ; passing a string and a value it returns that string with a len as required Func _StringSetLen($sString, $iWantedLen = 1, $sFillChr = " ") If $iWantedLen = 0 Then Return "" Local $iLen = StringLen($sString) Local $iKeepLeft = $iWantedLen > 0 ; else keep the right $iWantedLen = Abs($iWantedLen) If $iLen >= $iWantedLen Then If $iKeepLeft Then Return StringLeft($sString, $iWantedLen) Else Return StringRight($sString, $iWantedLen) EndIf Else If $iKeepLeft Then Return $sString & _StringReplay($sFillChr, $iWantedLen - $iLen) Else Return _StringReplay($sFillChr, $iWantedLen - $iLen) & $sString EndIf EndIf EndFunc ;==>_StringSetLen ; replace spaces with chr(31) ; in TextMode chr(31) moves cursor one char to the right without erasing ; so spaces behave as 'transparent' chars. (original string is unaffected) Func _StringTransparent($sString, $chr = Chr(31)) Return StringReplace($sString, " ", $chr) EndFunc ;==>_StringTransparent ; rotate a string by a nr of chars ; negative number rotate left <-- , positive number rotate right --> Func _StringRotate($sString, $sStep = 1) Local $Len = StringLen($sString) Local $bROL = $sStep < 0 $sStep = Mod(Abs($sStep), $Len) If $bROL Then Return StringRight($sString, $Len - $sStep) & StringLeft($sString, $sStep) Else Return StringRight($sString, $sStep) & StringLeft($sString, $Len - $sStep) EndIf EndFunc ;==>_StringRotate ; place a string in the middle of a given space Func _StringCenter($sString, $iSpace) Local $iLen = StringLen($sString) $iHloc = Int($iSpace / 2) - Int($iLen / 2) If $iHloc < 0 Then Return StringMid($sString, Abs($iHloc) + 1, $iSpace) Else Return _StringReplay(" ", $iHloc) & $sString EndIf EndFunc ;==>_StringCenter ; returns the number of occurence of a substring within the string Func _StringInStringCount($sString, $sSubstring) StringReplace($sString, $sSubstring, $sSubstring) Return @extended EndFunc ;==>_StringInStringCount ; plot a char (or a string) along a circle Func _plotCircle($chr, $xm, $ym, $r, $iForeColor = $BrightWhite, $iBackColor = $Black) Local $x = -$r, $y = 0, $err = 2 - 2 * $r ; /* II. Quadrant */ While ($x < 0) _VDT_Print($chr, $xm - $x, $ym + $y, $iForeColor, $iBackColor) ; /* I. Quadrant */ _VDT_Print($chr, $xm - $y, $ym - $x, $iForeColor, $iBackColor) ; /* II. Quadrant */ _VDT_Print($chr, $xm + $x, $ym - $y, $iForeColor, $iBackColor) ; /* III. Quadrant */ _VDT_Print($chr, $xm + $y, $ym + $x, $iForeColor, $iBackColor) ; /* IV. Quadrant */ $r = $err If ($r <= $y) Then $y += 1 $err += $y * 2 + 1 EndIf If ($r > $x Or $err > $y) Then $x += 1 $err += $x * 2 + 1 EndIf WEnd EndFunc ;==>_plotCircle ; some links about ANSI escape sequences: ; http://invisible-island.net/xterm/ctlseqs/ctlseqs.html ; https://www.npmjs.com/package/ansi-escape-sequences ; http://wiki.call-cc.org/eggref/4/ansi-escape-sequences ; ; https://github.com/sindresorhus/ansi-escapes <--- mnemonic functions ; https://github.com/chalk/ansi-styles <-- javascript encoder ; https://github.com/chalk/chalk ; ; https://misc.flogisoft.com/bash/tip_colors_and_formatting <-- for testing ; http://www.termsys.demon.co.uk/vtansi.htm ; ------------------------------------------------------ ; Following functions are ANSI Escape sequences encoders ; (CSI means Control Sequence Introducer) ; those can be used to 'embed' ansi escape sequences ; in a string or also te be sent to the terminal to ; set or unset some "rendition" ; ------------------------------------------------------ ; Set the forgraund and background colors Func _CSI_Colors($iForeColor = $__g_iActiveFGColor, $iBackColor = $__g_iActiveBGColor) Local $sAnsi = "" If $iForeColor = Default Then $iForeColor = $__g_iDefaultForeground ElseIf String($iForeColor) = "" Then $iForeColor = $__g_iActiveFGColor EndIf If $iBackColor = Default Then $iBackColor = $__g_iDefaultBackground ElseIf String($iBackColor) = "" Then $iBackColor = $__g_iActiveBGColor EndIf Local $sAnsiFG = _CSI_ForeColor($iForeColor, False) Local $sAnsiBG = _CSI_BackColor($iBackColor, False) If $sAnsiFG <> "" And $sAnsiBG <> "" Then $sAnsi = $__g_sCSI & $sAnsiFG & ";" & $sAnsiBG & "m" ElseIf String($sAnsiFG) = "" Then If $sAnsiBG <> "" Then $sAnsi = $__g_sCSI & $sAnsiBG & "m" Else $sAnsi = $__g_sCSI & $sAnsiFG & "m" EndIf Return $sAnsi EndFunc ;==>_CSI_Colors ; Set only the forgraund color Func _CSI_ForeColor($iForeColor = $__g_iActiveFGColor, $bEncodeAnsi = True) Local $sAnsi = "" If $iForeColor = Default Then $iForeColor = $__g_iDefaultForeground ElseIf String($iForeColor) = "" Then $iForeColor = $__g_iActiveFGColor EndIf If $iForeColor >= 0 And $iForeColor <= 7 Then $sAnsi &= String($iForeColor + 30) ElseIf $iForeColor >= 8 And $iForeColor <= 15 Then $sAnsi &= String($iForeColor + 82) EndIf If $bEncodeAnsi Then $sAnsi = Chr(27) & "[" & $sAnsi & "m" Return $sAnsi EndFunc ;==>_CSI_ForeColor ; Set only the background color Func _CSI_BackColor($iBackColor = $__g_iActiveBGColor, $bEncodeAnsi = True) If $iBackColor = Default Then $iBackColor = $__g_iDefaultBackground ElseIf String($iBackColor) = "" Then $iBackColor = $__g_iActiveBGColor EndIf Local $sAnsi = "" If $iBackColor >= 0 And $iBackColor <= 7 Then $sAnsi = String($iBackColor + 40) ElseIf $iBackColor >= 8 And $iBackColor <= 15 Then $sAnsi = String($iBackColor + 92) EndIf If $bEncodeAnsi Then $sAnsi = Chr(27) & "[" & $sAnsi & "m" Return $sAnsi EndFunc ;==>_CSI_BackColor ; Set/unset the bold attribute (use true or false to set/unset) Func _CSI_Bold($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "1m" Case $bSet = False $sAnsi = $__g_sCSI & "22m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Bold ; Set/unset the italic attribute (use true or false to set/unset) Func _CSI_Italic($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "3m" Case $bSet = False $sAnsi = $__g_sCSI & "23m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Italic ; Set/unset the underline attribute (use true or false to set/unset) Func _CSI_Underline($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "4m" Case $bSet = False $sAnsi = $__g_sCSI & "24m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Underline ; Set/unset the blink attribute (use true or false to set/unset) Func _CSI_Blink($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "5m" Case $bSet = False $sAnsi = $__g_sCSI & "25m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Blink ; Set/unset the flash attribute (use true or false to set/unset) ; note: this is a custom "rendition" ; ------ Func _CSI_Flash($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "6m" Case $bSet = False $sAnsi = $__g_sCSI & "26m" ; custom EndSelect Return $sAnsi EndFunc ;==>_CSI_Flash ; Set/unset the reverse attribute (use true or false to set/unset) Func _CSI_Reverse($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "7m" Case $bSet = False $sAnsi = $__g_sCSI & "27m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Reverse ; Set/unset the concealed attribute (use true or false to set/unset) Func _CSI_Concealed($bSet = True) ; True - False Local $sAnsi = "" Select Case $bSet = True $sAnsi = $__g_sCSI & "8m" Case $bSet = False $sAnsi = $__g_sCSI & "28m" EndSelect Return $sAnsi EndFunc ;==>_CSI_Concealed Func _CSI_ResetStyles() Local $sAnsi = $__g_sCSI & "0m" Return $sAnsi EndFunc ;==>_CSI_ResetStyles ; Set the absolute position of the cursor. x0 y0 is the top left of the screen. (x1 y1) Func _CSI_cursorTo($x = "", $y = "") Local $sAnsi = "" If Not IsNumber($x) Then Return "" If Not IsNumber($y) Then $ansi = $__g_sCSI & $x & "G" Else $ansi = $__g_sCSI & $y & ";" & $x & "H" EndIf Return $ansi EndFunc ;==>_CSI_cursorTo ; Set the position of the cursor relative to its current position. Func _CSI_cursorMove($x = "", $y = "") Local $sAnsi = "" If Not IsNumber($x) Then Return "" If $x < 0 Then $sAnsi = $__g_sCSI & $x & "D" ElseIf $x > 0 Then $sAnsi = $__g_sCSI & $x & "C" EndIf If $y < 0 Then $sAnsi &= $__g_sCSI & $y & "A" ElseIf $y > 0 Then $sAnsi &= $__g_sCSI & $y & "B" EndIf Return $sAnsi EndFunc ;==>_CSI_cursorMove ; Move cursor up a specific amount of rows. Default is 1. Func _CSI_cursorUp($count = 1) Local $ansi = "" $count = Int($count) $ansi = $__g_sCSI & $count & "A" Return $ansi EndFunc ;==>_CSI_cursorUp ; Move cursor down a specific amount of rows. Default is 1. Func _CSI_cursorDown($count = 1) Local $ansi = "" $count = Int($count) $ansi = $__g_sCSI & $count & "B" Return $ansi EndFunc ;==>_CSI_cursorDown ; Move cursor forward a specific amount of rows. Default is 1. Func _CSI_cursorForward($count = 1) Local $ansi = "" $count = Int($count) $ansi = $__g_sCSI & $count & "C" Return $ansi EndFunc ;==>_CSI_cursorForward ; Move cursor backward a specific amount of rows. Default is 1. Func _CSI_cursorBackward($count = 1) Local $ansi = "" $count = Int($count) $ansi = $__g_sCSI & $count & "D" Return $ansi EndFunc ;==>_CSI_cursorBackward ; Move cursor to the specified column (same line) : left side. Func _CSI_cursorColumn($count = 1) Local $ansi = "" $count = Int($count) + ($count = 0) $ansi = $__g_sCSI & $count & "G" Return $ansi EndFunc ;==>_CSI_cursorColumn ; Save cursor position. Func _CSI_cursorSavePosition() Local $ansi = $__g_sCSI & "s" Return $ansi EndFunc ;==>_CSI_cursorSavePosition ; Restore saved cursor position. Func _CSI_cursorRestorePosition() Local $ansi = $__g_sCSI & "u" Return $ansi EndFunc ;==>_CSI_cursorRestorePosition ; Get cursor position. Func _CSI_cursorGetPosition() Local $ansi = $__g_sCSI & "6n" Return $ansi EndFunc ;==>_CSI_cursorGetPosition ; Move cursor to the next line. Func _CSI_cursorNextLine() Local $ansi = $__g_sCSI & "E" Return $ansi EndFunc ;==>_CSI_cursorNextLine ; Move cursor to the previous line. Func _CSI_cursorPrevLine() Local $ansi = $__g_sCSI & "F" Return $ansi EndFunc ;==>_CSI_cursorPrevLine ; Hide cursor. Func _CSI_cursorHide() EndFunc ;==>_CSI_cursorHide ; Show cursor. Func _CSI_cursorShow() EndFunc ;==>_CSI_cursorShow ; Erase from the current cursor position up the specified amount of rows. Func _CSI_eraseLines($count) Local $ansi = "" For $i = 0 To $count $ansi &= _CSI_eraseLine() & $i < $count - 1 ? _CSI_cursorUp() : "" Next If $count Then $ansi &= _CSI_cursorColumn() Return $ansi EndFunc ;==>_CSI_eraseLines ; Erase from the current cursor position to the end of the current line. Func _CSI_eraseEndLine() Local $ansi = $__g_sCSI & "K" Return $ansi EndFunc ;==>_CSI_eraseEndLine ; Erase from the current cursor position to the start of the current line. Func _CSI_eraseStartLine() Local $ansi = $__g_sCSI & "1K" Return $ansi EndFunc ;==>_CSI_eraseStartLine ; Erase the entire current line. Func _CSI_eraseLine() Local $ansi = $__g_sCSI & "2K" Return $ansi EndFunc ;==>_CSI_eraseLine ; Erase the screen from the current line down to the bottom of the screen. Func _CSI_eraseDown() Local $ansi = $__g_sCSI & "J" Return $ansi EndFunc ;==>_CSI_eraseDown ; Erase the screen from the current line up to the top of the screen. Func _CSI_eraseUp() Local $ansi = $__g_sCSI & "1J" Return $ansi EndFunc ;==>_CSI_eraseUp ; Erase the screen and move the cursor to the top left position. Func _CSI_eraseScreen() Local $ansi = $__g_sCSI & "2J" Return $ansi EndFunc ;==>_CSI_eraseScreen ; Scroll display up one line. Func _CSI_scrollUp() Local $ansi = $__g_sCSI & "S" Return $ansi EndFunc ;==>_CSI_scrollUp ; Scroll display down one line. Func _CSI_scrollDown() Local $ansi = $__g_sCSI & "T" Return $ansi EndFunc ;==>_CSI_scrollDown ; Clear the terminal screen. Func _CSI_clearScreen() Local $ansi = $__g_sCSI & "2J" Return $ansi EndFunc ;==>_CSI_clearScreen ; Output a beeping sound. Func _CSI_beep() Return Chr(7) EndFunc ;==>_CSI_beep ; Create a clickable link. Func _CSI_link($text, $url) ; ToDo EndFunc ;==>_CSI_link ; Display an image. ; Currently only supported on iTerm2 >=3 Func _CSI_image($input, $options) ; ToDo EndFunc ;==>_CSI_image ; === The End === ; #FUNCTION# ==================================================================================================================== ; https://www.autoitscript.com/forum/topic/124526-_guictrlgetfont/ ; Name...........: _GUICtrlGetFont ; Description ...: Gets the font of a GUI Control ; Syntax.........: _GUICtrlGetFont( [$hWnd] ) ; Parameters ....: $hWnd - [optional] ControlID or Handle of the control. Default is last created GUICtrl... (-1) ; ; Return values .: Success - Array[5] with options of font: ; [0] - FontSize (~ approximation) ; [1] - Font weight (400 = normal). ; [2] - italic:2 underlined:4 strike:8 char format (styles added together, 2+4 = italic and underlined). ; [3] - The name of the font to use. ; [4] - Font quality to select (PROOF_QUALITY=2 is default in AutoIt). ; ; Failure - Array[5] with empty fields, @error set to nonzero ; ; Author ........: KaFu, Prog@ndy ; ; Comments.......: The FontSize returned is an approximation of the actual fontsize used for the control. ; The height of the font returned by GetObject is the height of the font's character cell or character in logical units. ; The character height value (also known as the em height) is the character cell height value minus the internal-leading value. ; The font mapper interprets the value specified in lfHeight. The result returned by the font mapper is not easily reversible ; The FontSize calculated below is an approximation of the actual size used for the analyzed control, qualified enough to use ; in another call to the font mapper resulting in the same font size as the the original font. ; MSDN.. ........: Windows Font Mapping: http://msdn.microsoft.com/en-us/library/ms969909(loband).aspx ; =============================================================================================================================== Func _GUICtrlGetFont($hWnd = -1) Local $aReturn[5], $hObjOrg If Not IsHWnd($hWnd) Then $hWnd = GUICtrlGetHandle($hWnd) If Not IsHWnd($hWnd) Then Return SetError(1, 0, $aReturn) Local $hFONT = _SendMessage($hWnd, $WM_GETFONT) If Not $hFONT Then Return SetError(2, 0, $aReturn) Local $hDC = _WinAPI_GetDC($hWnd) $hObjOrg = _WinAPI_SelectObject($hDC, $hFONT) Local $tFONT = DllStructCreate($tagLOGFONT) Local $aRet = DllCall('gdi32.dll', 'int', 'GetObjectW', 'ptr', $hFONT, 'int', DllStructGetSize($tFONT), 'ptr', DllStructGetPtr($tFONT)) If @error Or $aRet[0] = 0 Then _WinAPI_SelectObject($hDC, $hObjOrg) _WinAPI_ReleaseDC($hWnd, $hDC) Return SetError(3, 0, $aReturn) EndIf ; Need to extract FontFacename separately => DllStructGetData($tFONT, 'FaceName') is only valid if FontFacename has been set explicitly! $aRet = DllCall("gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", 0, "ptr", 0) Local $nCount = $aRet[0] Local $tBuffer = DllStructCreate("wchar[" & $aRet[0] & "]") Local $pBuffer = DllStructGetPtr($tBuffer) $aRet = DllCall("Gdi32.dll", "int", "GetTextFaceW", "handle", $hDC, "int", $nCount, "ptr", $pBuffer) If @error Then _WinAPI_SelectObject($hDC, $hObjOrg) _WinAPI_ReleaseDC($hWnd, $hDC) Return SetError(4, 0, $aReturn) EndIf $aReturn[3] = DllStructGetData($tBuffer, 1) ; FontFacename $aReturn[0] = Round(((-1 * DllStructGetData($tFONT, 'Height')) * 72 / _WinAPI_GetDeviceCaps($hDC, 90)), 1) ; $LOGPIXELSY = 90 => DPI aware ; 0.25 = Magic Number, don't ask... _WinAPI_SelectObject($hDC, $hObjOrg) _WinAPI_ReleaseDC($hWnd, $hDC) $aReturn[1] = DllStructGetData($tFONT, 'Weight') $aReturn[2] = 2 * (True = DllStructGetData($tFONT, 'Italic')) + 4 * (True = DllStructGetData($tFONT, 'Underline')) + 8 * (True = DllStructGetData($tFONT, 'StrikeOut')) $aReturn[4] = DllStructGetData($tFONT, 'Quality') Return $aReturn EndFunc ;==>_GUICtrlGetFont Here are 2 simple scripts as example of use (save scripts along with the 2 above udf) First script allows you to view a lot of ANSI files from this site: http://artscene.textfiles.com/ #include <String.au3> #include "vdt.au3" _Example() Func _Example() $hMainGui = GUICreate("Demo ANSI Terminal 80 cols x 24 rows", 900, 600) ; Create the ANSI Video Terminal Local $avVDT = _VDT_GUICtrl_Create($hMainGui, 5, 5, Default, Default, 9) GUICtrlSetTip(-1, 'here the "text" is rendered according to the directives' & @CRLF & 'specified by the ANSI escape sequences') ; Create the "Groups" List Local $hGroups = GUICtrlCreateList("", $avVDT[1] + 10, 5, 160, 160) GUICtrlSetBkColor(-1, 0x00FF00) GUICtrlSetTip(-1, 'here are the "groups" of the ansi files' & @CRLF & 'as from the site "http://artscene.textfiles.com/ansi/"' & @CRLF & 'click here to see the list of files') ; Create the "Titles" List Local $hTitles = GUICtrlCreateList("", $avVDT[1] + 175, 5, 160, 160) GUICtrlSetBkColor(-1, 0xFFFF00) GUICtrlSetTip(-1, 'these are the ANSI files' & @CRLF & 'click here for a little preview') ; Create the "Send to terminal" Button Local $hButton = GUICtrlCreateButton("<--", $avVDT[1] + 10, 160, 40, 205) GUICtrlSetTip(-1, 'Click here to render the ANSI file') ; Create the preview in a Browser control Local $hPreview = GUICtrlCreateLabel('', $avVDT[1] + 55, 160, 260, 205) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; This is like a glass over the underlying Object GUICtrlSetCursor(-1, 2) ; Cursor is an arrow (instead of the default I-beam) GUICtrlSetTip(-1, 'Preview PIC from "http://artscene.textfiles.com/ansi/"') Local $oIE = ObjCreate("Shell.Explorer.2") GUICtrlCreateObj($oIE, $avVDT[1] + 55, 160, 280, 205) ; this render $oIE usable $oIE.navigate('about:blank') ; Create an edit control to show the raw ANSI encoded text file Local $hTextViewer = GUICtrlCreateEdit("", 5, $avVDT[2] + 10, 890, 600 - $avVDT[2] - 50, BitOR($GUI_SS_DEFAULT_EDIT, $ES_MULTILINE, $ES_READONLY)) GUICtrlSetFont(-1, "Courier New") GUICtrlSetTip(-1, 'just out of curiosity...' & @CRLF & 'This is the raw ANSI file') ; Create some other controls Local $hWelcome = GUICtrlCreateButton("Show welcome screen", 5, 565, 200, 30) Local $hClearScr = GUICtrlCreateButton("Clear the screen", 210, 565, 200, 30) Local $hCP437 = GUICtrlCreateCheckbox("convert to codepage 437", 420, 565, 150, 30) GUICtrlSetState(-1, 1) Local $hShowCtrls = GUICtrlCreateCheckbox("show control chars", 580, 565, 150, 30) ; Create the "load from file" button Local $hLoadButton = GUICtrlCreateButton("Load a file", 735, 565, 160, 30) GUICtrlSetTip(-1, 'Click here to load an ANSI file') ; Fill the Groups list ; groups from the site "http://artscene.textfiles.com/ansi/" Local $aGroups[] = ['artwork', 'bbs', 'welcomes', 'holiday', 'logos', 'scene', 'unsorted'] Local $aAnsiArt, $sANSI_File For $i = 0 To UBound($aGroups) - 1 GUICtrlSetData($hGroups, $aGroups[$i]) Next GUISetState(@SW_SHOW, $hMainGui) ; _VDT_Style($VisCtrls, True) _WelcomeScreen() ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $hGroups ConsoleWrite("Click on " & GUICtrlRead($hGroups) & @CRLF) GUICtrlSetData($hTitles, "") ; clear the title list $aAnsiArt = _StringBetween(BinaryToString(InetRead("http://artscene.textfiles.com/ansi/" & GUICtrlRead($hGroups) & "/")), '><A HREF="', '">') For $i = 0 To UBound($aAnsiArt) - 1 GUICtrlSetData($hTitles, $aAnsiArt[$i]) Next Case $hTitles $oIE.navigate('about:blank') While Not String($oIE.readyState) = 'complete' ; wait for about:blank Sleep(100) WEnd $oIE.Document.Write('<img style="width:100%;" src="http://artscene.textfiles.com/ansi/' & GUICtrlRead($hGroups) & '/.png/' & GUICtrlRead($hTitles) & '.png' & '">') $oIE.document.close() ; close the write stream $sANSI_File = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/" & GUICtrlRead($hGroups) & "/" & GUICtrlRead($hTitles))) ; If GUICtrlRead($hCP437) = 1 Then $sANSI_File = _StringToCodepage($sANSI_File, 437) GUICtrlSetData($hTextViewer, (GUICtrlRead($hCP437) = 1) ? _StringToCodepage($sANSI_File, 437) : $sANSI_File) Case $hButton _VDT_KillTimer() GUICtrlSetData($hTextViewer, (GUICtrlRead($hCP437) = 1) ? _StringToCodepage($sANSI_File, 437) : $sANSI_File) _VDT_Style($VisCtrls, (GUICtrlRead($hShowCtrls) = 1)) _vdt_Print(_CSI_eraseScreen()) ; send the erase screen ANSI sequence to the terminal _vdt_Print((GUICtrlRead($hCP437) = 1) ? _StringToCodepage($sANSI_File, 437) : $sANSI_File) _VDT_SetTimer() Case $hWelcome _WelcomeScreen() Case $hClearScr _vdt_Print(_CSI_eraseScreen()) Case $hLoadButton $sANSI_Path = FileOpenDialog("Choose an ANSI file", @ScriptDir & "\", "txt file (*.ans;*.txt)") If Not @error Then $sANSI_File = BinaryToString(FileRead($sANSI_Path)) $oIE.navigate('about:blank') While Not String($oIE.readyState) = 'complete' ; wait for about:blank Sleep(100) WEnd $oIE.Document.Write('<img src="."><p><span style="color: #ff0000;"><em>sorry, no preview for this file</em>' & _ '</span></p><p><span style="font-size:10px; color: #339966;"><strong>' & $sANSI_Path & '</strong></span></p>') $oIE.document.close() ; close the write stream ControlClick("", "", $hButton) EndIf EndSwitch WEnd EndFunc ;==>_Example Func _WelcomeScreen() Local $sClipArt = Chr(27) & "[s" & _ " \|||/�[u" & @LF & "�[s" & _ " (o o)�[u" & @LF & "�[s" & _ ",~~~oo0~~~~~~(_)~~~~~~~~~~~,�[u" & @LF & "�[s" & _ "| |�[u" & @LF & "�[s" & _ "| |�[u" & @LF & "�[s" & _ "| |�[u" & @LF & "�[s" & _ "| |�[u" & @LF & "�[s" & _ "| |�[u" & @LF & "�[s" & _ "'~~~~~~~~~~~~~~~~~~~~oo0~~~'�[u" & @LF & "�[s" & _ " |__|__|�[u" & @LF & "�[s" & _ " || ||�[u" & @LF & "�[s" & _ " oo0 0oo" _vdt_Print(_CSI_eraseScreen()) _VDT_SetCursorPos(5, 3) ; set the upper left corner for the clipart _vdt_Print($sClipArt, 5, 3, $BrightCyan) _vdt_Print(_CSI_ForeColor($Red) & "Hello! Welcome to this", 7, 6) _vdt_Print('little "Terminal" demo.', 7, 7) _vdt_Print("It allows you to view", 7, 8) _vdt_Print("some ANSI art files....", 7, 9) _vdt_Print(_CSI_Blink(True) & " ..... enjoy .." & _CSI_Blink(False) & _CSI_ForeColor(Default), 7, 10) Sleep(500) _vdt_Print(_CSI_ForeColor($BrightGreen) & _CSI_cursorTo(40, 2) & _CSI_cursorSavePosition() & 'Click on this green ListBox ' & _CSI_Blink(True)) For $i = 1 To 10 _vdt_Print("-") Next _vdt_Print(">" & _CSI_cursorRestorePosition() & @LF & _CSI_Blink(False)) _vdt_Print('those are the ANSI art Groups') Sleep(500) _vdt_Print(_CSI_cursorTo(43, 6) & _CSI_cursorSavePosition() & _CSI_ForeColor($BrightYellow) & "On the yellow ListBox on the right") _vdt_Print(_CSI_cursorRestorePosition() & @LF & 'will be listed the ANSI files') _vdt_Print(_CSI_cursorRestorePosition() & @LF & @LF & 'belonging to the clicked group') Sleep(500) _vdt_Print("This button --------------------->", 45, 18, $BrightWhite) ; use immediate psitioning and coloring _vdt_Print( _CSI_ForeColor($BrightWhite)) ; set new fixed default foreground color _vdt_Print("will render the selected ANSI file", 45, 19) _vdt_Print('to this "' & _CSI_Flash(True) & 'terminal' & _CSI_Flash(False) & '"', 45, 20) Sleep(500) _vdt_Print(_CSI_cursorTo(39, 12) & _CSI_cursorSavePosition() & "The right panel shows a little preview *") _vdt_Print(_CSI_cursorRestorePosition() & @LF & _CSI_cursorSavePosition() & 'of the selected ANSI file') _vdt_Print(_CSI_cursorRestorePosition() & @LF & "* http://artscene.textfiles.com/ansi/...") Sleep(500) Local $sMsg = "Here below is shown the raw ANSI file content" For $i = 1 To StringLen($sMsg) ; .... a little trivial text effect _vdt_Print(StringRight($sMsg, $i), 23, 24) Sleep(10) Next EndFunc ;==>_WelcomeScreen the second example script shows some 'live' data as rates, weather forecast, moon phase and some other examples. #include 'vdt.au3' Local $aButtons = [ _ ['', 'Colors sample'], _ ['', 'rate'], _ ['', 'rate gr.'], _ ['', 'Random num/color'], _ ['', 'rate (cp 437)'], _ ['', 'rate gr. (cp 437)'], _ ['', 'Weather Report'], _ ['', 'Moon Phase'], _ ['', 'various'], _ ['', 'a fruit'], _ ['', 'Hide/Show'], _ ['', 'Exit'] _ ] Local $Columns = Round(Sqrt(UBound($aButtons))) Local $Rows = Ceiling(UBound($aButtons) / $Columns) Local $ButtonWidth = 100, $ButtonHeight = 40 ; create a generic gui with some examples buttons $hMainGui = GUICreate("Examples", $ButtonWidth * $Columns, $ButtonHeight * $Rows, 20, 20) For $i = 0 To UBound($aButtons) - 1 $aButtons[$i][0] = GUICtrlCreateButton($aButtons[$i][1], (__GetTabsPos($i + 1, $Columns)[0] - 1) * $ButtonWidth, (__GetTabsPos($i + 1, $Columns)[1] - 1) * $ButtonHeight, $ButtonWidth, $ButtonHeight) Next ; Terminal parameters Local $iCols = 132 ; nr of columns Local $iRows = 40 ; nr. of rows Local $FontSize = 9 ; font size ; create a detached window containing a "Vintage terminal" (it's created hidden by default) ; possible parameters: Title, Columns, Rows, FontSize, FontName(*), DefaultForeground, DefaultBackground, Style, ExStyle ; (*) choosed font must be a monospaced font. Local $vGUI = _VDT_GUICreate('Terminal Demo (' & $iCols & 'x' & $iRows & ')', $iCols, $iRows, $FontSize, '', $BrightWhite, $Black, $WS_CAPTION) Local $hTerminal = $vGUI[0] ; handle of the terminal gui GUISetState(@SW_SHOW, $hMainGui) ; show the Gui with the example buttons GUISetState(@SW_SHOWNOACTIVATE, $hTerminal) ; show the Terminal ; set user agent. Will be used by the InetRead() function ; this is interpreted by some sites as 'send me data as ANSI encoded' HttpSetUserAgent("curl/7.37.0") Local $bVisible = True ; a very simple welcome message with embedded escape ansi sequences Local $sWelcome = _CSI_Reverse(True) & "Hello !" & _CSI_Reverse(False) & @CRLF & @CRLF & _ _CSI_ForeColor($Green) & "Hi, you are welcome to this simple" & @CRLF & _ "'vintage' monitor. This is a basic" & @CRLF & _ "demonstration to show only some of the" & @CRLF & _ "features available." & @CRLF & _ "Use the buttons on the '" & _CSI_ForeColor($BrightMagenta) & "Example GUI" & _CSI_ForeColor($Green) & "' to" & @CRLF & _ "send me some demo strings..." & @CRLF & @CRLF & _ "Hope you " & _CSI_Flash(True) & _CSI_ForeColor($Cyan) & "have fun" & _CSI_ForeColor($Green) & _CSI_Flash(False) & " !!" & @CRLF & @CRLF & @TAB & @TAB & _ "Best regards..... " & _CSI_Underline(True) & _CSI_Italic(True) & _CSI_ForeColor($BrightGreen) & "Chimp" & _CSI_ResetStyles() ; send the welcome message to the terminal _vdt_Print(_CSI_cursorTo($iCols / 2 - 3, 1) & $sWelcome) ; Main loop - waiting clicks on buttons While 1 $idMsg = GUIGetMsg() Select Case $idMsg = $aButtons[0][0] ; color example ; send the ANSI escape sequence to clear the screen _vdt_Print(_CSI_clearScreen()) ; http://easyos.net/articles/bsd/freebsd/output_control_in_freebsd_console ; print a file containing ANSI color samples _vdt_Print(_GetAnsiData("http://easyos.net/content/download/2604/11965/file/color-samples.txt")) Case $idMsg = $aButtons[1][0] _vdt_Print(_CSI_clearScreen()) _vdt_Print(_GetAnsiData("http://eur.rate.sx")) ; rate ("http://rate.sx/") Case $idMsg = $aButtons[2][0] _vdt_Print(_CSI_clearScreen()) _vdt_Print(_GetAnsiData("http://rate.sx/eth")) ; rate graph Case $idMsg = $aButtons[3][0] ; screen generated by internal functions _vdt_Print(_CSI_clearScreen()) _vdt_Print("Below are 576 random numbers ranging from -50 to 200", 2, 1) ; column 2, row 1 _vdt_Print("Legend: " & _CSI_ForeColor($BrightRed) & _CSI_Flash(True) & "-50 to -25" & _CSI_Flash(False) & _CSI_ForeColor($Red) & " " & _ "-24 to -1 " & _CSI_ForeColor($Green) & "0 to 100 " & _CSI_ForeColor($Yellow) & "101 to 150 " & _csi_BackColor($BrightGreen) & _CSI_ForeColor($Black) & "151 to 200" & _ _csi_BackColor(Default) , 2, 3) For $iRow = 5 To 40 For $iCol = 0 To 15 $iValue = Random(-50, 200) Switch $iValue Case -50 To -25 $Forecolor = $BrightRed _VDT_Style($Flash, True) Case -24 To -1 $Forecolor = $Red Case 0 To 100 $Forecolor = $Green Case 101 To 150 $Forecolor = $Yellow Case Else $Forecolor = $BrightGreen _VDT_Style($Inverse, True) EndSwitch _vdt_Print(StringRight(" " & StringFormat("%.2f", $iValue), 6), $iCol * 8 + 2, $iRow, $Forecolor) _VDT_Style($Flash, False) _VDT_Style($Inverse, False) Next Next Case $idMsg = $aButtons[4][0] _vdt_Print(_CSI_clearScreen()) _vdt_Print(_StringToCodepage(_GetAnsiData("http://eur.rate.sx"), 437)) Case $idMsg = $aButtons[5][0] _vdt_Print(_CSI_clearScreen()) _vdt_Print(_StringToCodepage(_GetAnsiData("http://rate.sx/eth"), 437)) Case $idMsg = $aButtons[6][0] ; weather-forecast _VDT_PauseSwitching() ; temporary disable flash/blink effect to speed up printing a bit _vdt_Print(_CSI_clearScreen()) ; https://winaero.com/blog/get-weather-forecast-linux-console/ ; add wanted location at the end of the link if you like ; example _vdt_Print(_GetAnsiData("http://wttr.in/Imperia")) _vdt_Print(_GetAnsiData("http://wttr.in")) _VDT_ResumeSwitching() ; enable flash/blink effect again Case $idMsg = $aButtons[7][0] _VDT_PauseSwitching() _vdt_Print(_CSI_clearScreen()) _vdt_Print(_GetAnsiData("http://wttr.in/Moon")) ; Moon Phase _VDT_ResumeSwitching() Case $idMsg = $aButtons[8][0] _VDT_PauseSwitching() _vdt_Print(_CSI_clearScreen()) _vdt_Print(_GetAnsiData("http://git.io/unix")) ; TEST _vdt_Print(@CRLF & @CRLF & "Below is the qrcode of the string " & _CSI_Underline(True) & _CSI_Italic(True) & "www.autoitscript.com" & _CSI_ResetStyles() & @crlf& @crlf) _vdt_Print(_GetAnsiData("http://qrenco.de/www.autoitscript.com")) ;matrix _VDT_ResumeSwitching() Case $idMsg = $aButtons[9][0] ; _VDT_PauseSwitching() _vdt_Print(_CSI_clearScreen()) ; see http://www.robvanderwoude.com/ansi.php ;_vdt_Print(_StringToCodepage(FileRead("C:\TEMP\AN_APPLE.ANS"),437)) ; if you downloaded the txt file use this _vdt_Print(_StringToCodepage(BinaryToString(InetRead('http://www.robvanderwoude.com/files/apple_ansi.txt')), 437)) _VDT_ResumeSwitching() Case $idMsg = $aButtons[10][0] ; show/hide terminal window $bVisible = Not ($bVisible) ; alternate True/False If $bVisible Then GUISetState(@SW_SHOWNOACTIVATE, $hTerminal) Else GUISetState(@SW_HIDE, $hTerminal) EndIf Case $idMsg = $aButtons[11][0] GUIDelete() ExitLoop EndSelect WEnd Func _GetAnsiData($sURL) Local $sSource = InetRead($sURL, 9) ; 9 ; Convert the binary to a string. 4 = UTF8. $sSource = BinaryToString($sSource, 4) $sSource = StringReplace($sSource, @LF, @CRLF) Return $sSource EndFunc ;==>_GetAnsiData Hope you have fun.
  2. Hi, this is a followup from this previous post (https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/ I'm trying to make an ANSI file viewer. Some basic functions, even if still with some issues, let me do some early tests. I use a Rich Edit control as the "blackboard" where to print colored chars coming from the ANSI file (downloaded from the net), and in this "pre alpha" testing, I'm facing on a "basic" problem, that is: the chars are viewed with a wrong code page. I think that should be printed using the 437 codepage, but even trying to convert the string using the way found here (https://www.autoitscript.com/forum/topic/121847-convert-text-string-from-codepage-437-or-850-to-1252/), the result seems even worst. How can I display correctly the chars from the ANSI file so to produce the image, as the one shown in the InternetExplorer preview picture instead of that with altered chars shown in the rich edit control? Any idea on the direction to take? Thanks on advance. (to test the script, save both files in the same directory) #include '.\TextMode_udf.au3' #include <ie.au3> $oIe = _IECreate() ; just to see the original picture $hGUI = GUICreate("Ansi viewer", 700, 420, -1, -1, -1, $WS_EX_COMPOSITED) GUISetBkColor(0xFFFFFF) ; $Button1 = GUICtrlCreateButton("Test beastie ANSI", 590, 20, 100, 60) $Button2 = GUICtrlCreateButton("Test face_2 ANSI", 590, 100, 100, 60) $Button3 = GUICtrlCreateButton("Test flower ANSI", 590, 180, 100, 60) $Button4 = GUICtrlCreateButton("Test belinda ANSI", 590, 260, 100, 60) $Button5 = GUICtrlCreateButton("Test bambi 'text'", 590, 340, 100, 60) $Button6 = GUICtrlCreateButton("Clear screen", 15, 370, 555, 30) ; ; create a richedit _TextMode_GUICtrl_Create($hGUI, 10, 15, 80, 25, 9, "consolas") ; "Lucida console" ; "Terminal" ; "Courier new" GUISetState(@SW_SHOW, HWnd($hGUI)) ; While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $Button1 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/beastie.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/beastie.ans")) _Test($sMessage) Case $Button2 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/face_2.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/face_2.ans")) _Test($sMessage) Case $Button3 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/flower.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/flower.ans")) _Test($sMessage) Case $Button4 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/belinda.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/belinda.ans")) _Test($sMessage) Case $Button5 _IENavigate($oIe,"http://artscene.textfiles.com/vt100/bambi.vt", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/vt100/bambi.vt")) _Test($sMessage) Case $Button6 _TextMode_CLS() EndSwitch WEnd _IEQuit($oIe) Exit ; Func _Test($sMessage) ; $sMessage = _StringToCodepage($sMessage, 437) _TextMode_Print($sMessage); parse the ANSI string and print result to the RichEdit EndFunc ;==>_Test ; https://www.autoitscript.com/forum/topic/121847-convert-text-string-from-codepage-437-or-850-to-1252/ Func _StringToCodepage($ansi, $codepage) Local $struct = DllStructCreate("byte[" & StringLen($ansi) * 2 + 4 & "]") ;platz für UTF16 $string = _WinAPI_MultiByteToWideCharEx($ansi, DllStructGetPtr($struct), Number($codepage), $MB_PRECOMPOSED) ; $MB_USEGLYPHCHARS) ;Ansi-String in Codepage umwandeln Return BinaryToString(DllStructGetData($struct, 1), 2) EndFunc ;==>_StringToCodepage save this as "TextMode_udf.au3" (pre alpha code) ; the following include is by @melba23 ; get it here -> https://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/ ; #include <stringsize.au3> ; for the moment is not used here since I'm using a fixed width control just for testing #include <array.au3> #include <GuiRichEdit.au3> #include <GUIConstants.au3> ; ===== !! PRE ALPHA CODE FOR EARLY TESTING !! ===== ; 'paper' dimension in chars (columns and lines) Global $iHwidth = 80 ; width of screen (nr. of chars per line) Global $iVheight = 24 ; height of screen (nr. of lines) ; Font and size (a monospaced font is MANDATORY!) Global $iFontSize = 12, $sFontName = "Consolas" ; "Terminal" ; "Perfect DOS VGA 437 Win" ; "Courier New" ; "Lucida Sans Typewriter" ; "Lucida Console" ; Global $iTabStop = 8 ; Horizontal tab stops (Historically tab stops where every 8th character) Global $iCharSet = 2 ; see --> _GUICtrlRichEdit_SetFont() #cs the character set - one of: $ANSI_CHARSET - 0 $BALTIC_CHARSET - 186 $CHINESEBIG5_CHARSET - 136 $DEFAULT_CHARSET - 1 $EASTEUROPE_CHARSET - 238 $GB2312_CHARSET - 134 $GREEK_CHARSET - 161 $HANGEUL_CHARSET - 129 $MAC_CHARSET - 77 $OEM_CHARSET - 255 $RUSSIAN_CHARSET - 204 $SHIFTJIS_CHARSET - 128 $SYMBOL_CHARSET - 2 $TURKISH_CHARSET - 162 $VIETNAMESE_CHARSET - 163 #ce ; ; the screen text buffer Global $sBuffer = "" Global $_hVintageGui, $hScreen[2] ; initialize cursor position Global $iCursorPosX = 1 ; horizontal position Global $iCursorPosY = 1 ; vertical position Global $iCursorPushX = $iCursorPosX ; Save X (for a later pull) Global $iCursorPushY = $iCursorPosY ; Save Y (for a later pull) Global $iVisibleLayer = 0 ; there are 2 screens (0 and 1) ; possible text modes. ; To set a text mode use _TextMode_Mode($mode). Without a parameter it returns current mode Global Enum $Normal, $Inverse, $Blink, $Flash ; Text attributes (to be set each for himself True/False) Global $Bold = False Global $Italic = False Global $Underline = False Global $aAttribute[2] = ['-', '+'] ; False = - True = + ; Color names Global Enum $Black, $Red, $Green, $Yellow, $Blue, $Magenta, $Cyan, $White, _ $BrightBlack, $BrightRed, $BrightGreen, $BrightYellow, $BrightBlue, $BrightMagenta, $BrightCyan, $BrightWhite ; Set ANSI color values (GRB color values from here: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) Global $aColor[16] $aColor[$Black] = 0x000000 ; 00 = Black bk .......0 $aColor[$Red] = 0x000080 ; 01 = Red rd .....128 $aColor[$Green] = 0x008000 ; 02 = Green gn ...32768 $aColor[$Yellow] = 0x008080 ; 03 = Yellow yl ...32896 $aColor[$Blue] = 0x800000 ; 04 = Blue bu .8388608 $aColor[$Magenta] = 0x800080 ; 05 = Magenta mg .8388736 $aColor[$Cyan] = 0x808000 ; 06 = Cyan cy .8421376 $aColor[$White] = 0xC0C0C0 ; 07 = White wt 12632256 $aColor[$BrightBlack] = 0x808080 ; 08 = Bright Black BK .8421504 $aColor[$BrightRed] = 0x0000FF ; 09 = Bright Red RD .....255 $aColor[$BrightGreen] = 0x00FF00 ; 10 = Bright Green GN ...65280 $aColor[$BrightYellow] = 0x00FFFF ; 11 = Bright Yellow YE ...65535 $aColor[$BrightBlue] = 0xFF0000 ; 12 = Bright Blue BU 16711680 $aColor[$BrightMagenta] = 0xFF00FF ; 13 = Bright Magenta MG 16711935 $aColor[$BrightCyan] = 0xFFFF00 ; 14 = Bright Cyan CY 16776960 $aColor[$BrightWhite] = 0xFFFFFF ; 15 = Bright White WT 16777215 ; default text colors Global Static $iDefaultForeground = $BrightWhite Global Static $iDefaultBackground = $Black Global $iActiveFGColor = $iDefaultForeground Global $iActiveBGColor = $iDefaultBackground ; ensure creation of only one TextMode 'control' Global $bControlExists = False HotKeySet("{ESC}", "_EndANSI") ; press 'esc' to end ; create a control to be placed on a parent GUI Func _TextMode_GUICtrl_Create($hWnd, $iLeft = 0, $iTop = 0, $i_Hwidth = $iHwidth, $i_Vheight = $iVheight, $i_FontSize = $iFontSize, $s_FontName = $sFontName, $i_DefaultForeground = $iDefaultForeground, $i_DefaultBackground = $iDefaultBackground) If $bControlExists = True Then Return ; if default values are changed then set also global variables accordingly $iHwidth = $i_Hwidth $iVheight = $i_Vheight $sFontName = $s_FontName $iFontSize = $i_FontSize $iDefaultForeground = $i_DefaultForeground $iDefaultBackground = $i_DefaultBackground ; fill the buffer $sBuffer = _StringReplay(_StringReplay(" ", $i_Hwidth) & @CRLF, $i_Vheight - 1) & _StringReplay(" ", $i_Hwidth) ; a string of width * height blank spaces + @crlf #cs ; determine the size of the screen according to the font parameters (by @Melba23) Local $aWinDim = _StringSize($sBuffer, $i_FontSize, 400, 0, $s_FontName) $aWinDim[2] += _StringSize(" ", $i_FontSize, 400, 0, $s_FontName)[2] Local $iWidth = $aWinDim[2], $iHeight = $aWinDim[3] ; Screen dimensions #ce Local $iWidth = 567, $iHeight = 354 ; Screen dimensions (fixed here just for the test) ; a transparent layer above the rich edit to protect it from clicks and to allow dragging of the GUI Local $hGlass = GUICtrlCreateLabel("", $iLeft, $iTop, $iWidth, $iHeight, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; This is like a glass over the underlying RichEdit GUICtrlSetCursor(-1, 2) ; Cursor is an arrow (instead of the default I-beam) $hScreen[0] = HWnd(_GUICtrlRichEdit_Create($hWnd, "", $iLeft, $iTop, $iWidth, $iHeight, BitXOR($ES_READONLY, $ES_MULTILINE))) ; DllCall('user32.dll', 'uint_ptr', 'SetTimer', 'hwnd', 0, 'uint_ptr', 0, 'uint', 500, 'ptr', DllCallbackGetPtr(DllCallbackRegister('__SwitchScreen', 'none', 'hwnd;uint;uint_ptr;dword'))) _TextMode_CLS() ; Initialize and clear the screen $bControlExists = True Return $hScreen EndFunc ;==>_TextMode_GUICtrl_Create ; From Htab Vtab (1 based) to absolute within the screen buffer Func __GetAbsPos($iHtab = 1, $iVtab = 1, $iScreenWidth = $iHwidth) Return ($iVtab - 1) * ($iScreenWidth + 1) + $iHtab EndFunc ;==>__GetAbsPos ; From Absolute To Htab Vtab (1 based) Func __GetTabsPos($iAbsolutePos = 1, $iScreenWidth = $iHwidth) Local $aXY[2] $aXY[0] = Mod($iAbsolutePos - 1, $iScreenWidth) + 1 ; Horizontal position within the Screen (column) $iHtab $aXY[1] = Int(($iAbsolutePos - 1) / $iScreenWidth) + 1 ; Vertical position within the Screen (row) $iVtab Return $aXY EndFunc ;==>__GetTabsPos ; don't show drawing activity (draw behind the shenes) Func _TextMode_PauseRedraw() _GUICtrlRichEdit_PauseRedraw($hScreen[0]) EndFunc ;==>_TextMode_PauseRedraw ; show what's been drawn Func _TextMode_ResumeRedraw() _GUICtrlRichEdit_ResumeRedraw($hScreen[0]) EndFunc ;==>_TextMode_ResumeRedraw ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TextMode_Print ; Description ...: Main printing function ; Syntax ........: _TextMode_Print([$sString = ""[, $iHtab = $iCursorPosX[, $iVtab = $iCursorPosY[, $iForegroundColor = $iActiveFGColor[, ; $iBackgroundColor = $iActiveBGColor]]]]]) ; Parameters ....: $sString - [optional] a string value. Default is "". ; $iHtab - [optional] column where to start printing ; $iVtab - [optional] row where to start printnting ; $iForegroundColor - [optional] wanted foreground color ; $iBackgroundColor - [optional] Wanted bckground color ; =============================================================================================================================== Func _TextMode_Print($sString = "", $iHtab = $iCursorPosX, $iVtab = $iCursorPosY, $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) If $iHtab = Default Then $iHtab = $iCursorPosX If $iVtab = Default Then $iVtab = $iCursorPosY ; Local $aString = __StringSplitKeepTokens($sString) ; break the string to find the control characters Local $iStartingHtab = $iHtab ; Local $iActiveFGColor = $iForegroundColor ; Local $iActiveBGColor = $iBackgroundColor Local $sANSI_Escape Local $aParameters[1] ; split string on ansi escape sequences and control codes (if any) ; ---------------------------------------------------------------- ; Main RegExp pattern by @jchd (Thanks to @jchd) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1386039 ; pattern also modified by @mikell (Thanks to @mikell) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1387160 Local $aStringChunks = StringRegExp($sString, "(?x)(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )(?| \x1B(?&ANSI_Escape) | [\x01-\x1A\x1C-\x1F] | \x1B(?!(?&ANSI_Escape)) | (?:[^\x01-\x1F] (?!(?&ANSI_Escape)))+ )", 3) ; _ArrayDisplay($aStringChunks, "Debug") For $iChunk = 0 To UBound($aStringChunks) - 1 ; check presence of escape sequences or control chars $sANSI_Escape = StringReplace($aStringChunks[$iChunk], " ", "") ; clean unneeded (and disturbing)spaces If StringLeft($sANSI_Escape, 2) = Chr(27) & "[" Then ; it is a CSI (Control Sequence Introducer) ; ConsoleWrite("Debug: CSI -> " & $sANSI_Escape & @CRLF) ; get ansi escape sequence parameters $aParameters = StringSplit(StringMid(StringTrimRight($sANSI_Escape, 1), 3), ";") ; extract the parameters of this sequence $aParameters[0] = StringRight($sANSI_Escape, 1) ; gat the final character (put it in [0]) ; _ArrayDisplay($aParameters, "Debug") ; ; ANSI Escape squence interpreter ; ------------------------------- Select Case $aParameters[0] == "a" ; HPR Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "d" ; VPA Move cursor to the indicated row, current column. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "e" ; VPR Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "f" ; HVP Move cursor to the indicated row, column. ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "g" ; TBC Without parameter: clear tab stop at current position. ; ? Case $aParameters[0] == "h" ; SM Set Mode ; ? Case $aParameters[0] == "l" ; RM Reset Mode ; ? Case $aParameters[0] == "m" ; SGR Set attributes. ; _ArrayDisplay($aParameters,"Debug") For $iParam = 1 To UBound($aParameters) - 1 Switch Number($aParameters[$iParam]) Case 0 ; reset all attributes to their defaults _TextMode_SetDefaultColors() _TextMode_SetMode($Normal) $Bold = False $Italic = False $Underline = False Case 1 ; set bold $Bold = True Case 4 ; set underscore $Underline = True Case 5 ; set blink _TextMode_SetMode($Blink) Case 7 ; set reverse video _TextMode_SetMode($Inverse) Case 8 ; concealed (foreground becomes background) _TextMode_SetMode($Inverse) Case 22 ; bold off $Bold = False Case 24 ; underline off $Underline = False Case 25 ; blink off _TextMode_SetMode($Normal) Case 27 ; reverse video off _TextMode_SetMode($Normal) Case 28 ; concealed off _TextMode_SetMode($Normal) Case 30 To 37 ; set foreground color $iForegroundColor = _TextMode_SetActiveForeColor(Number($aParameters[$iParam]) - 30) Case 38 ; set default foreground color ; 38;2;# foreground based on index (0-255) ; 38;5;#;#;# foreground based on RGB Case 39 ; set default foreground (using current intensity) Case 40 To 47 ; set background color $iBackgroundColor = _TextMode_SetActiveBackColor(Number($aParameters[$iParam]) - 40) Case 48 ; 48;2;# background based on index (0-255) ; 48;5;#;#;# background based on RGB Case 49 ; set default background (using current intensity) Case 90 To 97 ; set foreground bright color $iForegroundColor = _TextMode_SetActiveForeColor(Number($aParameters[$iParam]) - 82) Case 100 To 107 ; ; set background bright color $iBackgroundColor = _TextMode_SetActiveBackColor(Number($aParameters[$iParam]) - 92) EndSwitch Next Case $aParameters[0] == "n" ; DSR Status report ; ? Case $aParameters[0] == "q" ; DECLL Set keyboard LEDs. ; ESC [ 0 q: clear all LEDs ; ESC [ 1 q: set Scroll Lock LED ; ESC [ 2 q: set Num Lock LED ; ESC [ 3 q: set Caps Lock LED Case $aParameters[0] == "r" ; DECSTBM Set scrolling region; parameters are top and bottom row. Case $aParameters[0] == "s" ; ? Save cursor location. _PushCursor() Case $aParameters[0] == "u" ; ? Restore cursor location. _PullCursor() $iHtab = $iCursorPosX $iVtab = $iCursorPosY Case $aParameters[0] == "`" ; HPA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "@" ; ICH Insert the indicated # of blank characters. Case $aParameters[0] == "A" ; CUU Move cursor up the indicated # of rows. ; ConsoleWrite("Debug: " & Number($aParameters[1]) - ($aParameters[1] = 0) & @CRLF) $iVtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "B" ; CUD Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "C" ; CUF Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "D" ; CUB Move cursor left the indicated # of columns. $iHtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "E" ; CNL Move cursor down the indicated # of rows, to column 1. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] == "F" ; CPL Move cursor up the indicated # of rows, to column 1. $iVtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] == "G" ; CHA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "H" ; CUP Move cursor to the indicated row, column (origin at 1,1). ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "J" ; ED Erase display (default: from cursor to end of display). ReDim $aParameters[2] ; mandatory 1 parameters Switch Number($aParameters[1]) Case 0 ; Pn=0: erases from active position to end of display. __Sub_Print(_StringReplay(" ", $iHwidth - $iHtab + 1), $iHtab, $iVtab, $iDefaultForeground, $iDefaultBackground) If $iVtab < $iVheight Then For $y = $iVtab + 1 To $iVheight __Sub_Print(_StringReplay(" ", $iHwidth), 1, $y, $iDefaultForeground, $iDefaultBackground) Next EndIf Case 1 ; Pn=1: erases from the beginning of display to active position. __Sub_Print(_StringReplay(" ", $iHtab), 1, $iVtab, $iDefaultForeground, $iDefaultBackground) If $iVtab > 1 Then For $y = 1 To $iVtab - 1 __Sub_Print(_StringReplay(" ", $iHwidth), 1, $y, $iDefaultForeground, $iDefaultBackground) Next EndIf Case 2 ; Pn=2: erases entire display and move cursor to the top-left. _TextMode_CLS() $iHtab = 1 $iVtab = 1 EndSwitch Case $aParameters[0] == "K" ; EL Erase line (default: from cursor to end of line). __Sub_Print(_StringReplay(" ", $iHwidth - $iHtab + 1), $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) Case $aParameters[0] == "L" ; IL Insert the indicated # of blank lines. Case $aParameters[0] == "M" ; DL Delete the indicated # of lines. Case $aParameters[0] == "P" ; DCH Delete the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) Case $aParameters[0] == "X" ; ECH Erase the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $iDefaultForeground, $iDefaultBackground) EndSelect ; ; is it a single Control character ? (http://jkorpela.fi/chars/c0.html) ElseIf StringLen($sANSI_Escape) = 1 And (AscW($sANSI_Escape) >= 0 And AscW($sANSI_Escape) <= 0x1F) Then ; and 1 = 2 ; ConsoleWrite("Debug: ctrl -> " & @TAB & "[" & Ascw($sANSI_Escape) & "]" & @TAB & "[" & Asc($sANSI_Escape) & "]" & @TAB & "<-----------------------------" & @CRLF) ; control character interpreter ; --------------------------------------------------------------------------------------- $aParameters[0] = $sANSI_Escape Select Case $aParameters[0] = Chr(7) ; Bell, rings the bell Beep(900, 150) Case $aParameters[0] = Chr(8) ; Backspace <-- $iHtab -= 1 $iCursorPosX = $iHtab Case $aParameters[0] = Chr(9) ; Horizontal tab ; (Historically tab stops were every 8th character) If $iHtab >= 0 Then $iHtab = $iHtab + (Mod($iHtab, $iTabStop) * -1) + $iTabStop Else $iHtab = $iHtab + (Mod(Abs($iHtab) - 1, $iTabStop) + 1) EndIf $iCursorPosX = $iHtab Case $aParameters[0] = Chr(10) ; Line Feed @LF (move cursor down by 1 line) $iVtab += 1 $iCursorPosY = $iVtab Case $aParameters[0] = Chr(11) ; Vertical tab (move cusros up by 1 line) $iVtab -= 1 $iCursorPosY = $iVtab Case $aParameters[0] = Chr(12) ; Form Feed ; Case $aParameters[0] = Chr(13) ; Carriage Return @CR (move cursor to the beginning of this line) $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] = Chr(24) ; backspace with deletion (Cancel) $iHtab -= 1 __Sub_Print(" ", $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) $iCursorPosX = $iHtab Case $aParameters[0] = Chr(30) ; LF + a partial CR (Carriage Return stops below previous HTab) ; (custom private) $iVtab += 1 $iHtab = $iStartingHtab $iCursorPosX = $iHtab $iCursorPosY = $iVtab Case $aParameters[0] = Chr(31) ; move cursor to the right by 1 char --> ; ConsoleWrite(".") $iHtab += 1 $iCursorPosX = $iHtab EndSelect Else ; print the text ; ConsoleWrite("Debug: FG=" & $iActiveFGColor & @TAB & "BG=" & $iActiveBGColor & @CRLF) ; $aStringChunks[$iChunk] = StringReplace(StringStripCR(_StringToCodepage($aStringChunks[$iChunk], 437)), @LF, "") __Sub_Print(StringReplace($aStringChunks[$iChunk], ChrW(0), ""), $iHtab, $iVtab, $iForegroundColor, $iBackgroundColor) $iHtab = $iCursorPosX $iVtab = $iCursorPosY EndIf Next EndFunc ;==>_TextMode_Print ; keep only the string portion that will fall into the the screen (parts outside the screen will be discarded) Func __Sub_Print($sString = "", $iHtab = $iCursorPosX, $iVtab = $iCursorPosY, $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) Local $iStringFullLen = StringLen($sString) Local $iStringLen = $iStringFullLen If Not $iStringLen Then Return ; no string to print Local $iStringEnd = $iHtab + $iStringLen - 1 $iCursorPosX = $iHtab + $iStringLen $iCursorPosY = $iVtab If _ ; check if all the string falls outside the printable area $iHtab > $iHwidth Or _ ; over the right edge $iVtab > $iVheight Or _ ; below the bottom $iVtab < 1 Or _ ; over the top edges $iStringEnd < 1 _ ; over the left edge Then Return ; adjust string if only a part has to be Printed If $iHtab < 1 Then ; remove the part outside on the left $sString = StringRight($sString, $iStringEnd) $iStringLen = StringLen($sString) $iHtab = 1 EndIf If $iStringEnd > $iHwidth Then ; removes the exceeding part on the right $sString = StringTrimRight($sString, $iStringEnd - $iHwidth) $iStringLen = StringLen($sString) EndIf Local $iAnchor = __GetAbsPos($iHtab, $iVtab) - 1 Local $iActive = $iAnchor + $iStringLen Switch _TextMode_Mode() Case $Normal ; print normal text on both layers __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case $Inverse ; switch foreground and background colors and print on both layers __PokeText(0, $sString, $iAnchor, $iActive, $iBackgroundColor, $iForegroundColor) Case $Blink ; to be continued .... __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case $Flash ; to be continued .... __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case Else EndSwitch EndFunc ;==>__Sub_Print ; Place string on the "screen" buffer Func __PokeText($iLayer, $sString, $iAnchor, $iActive, $iForeColor, $iBackColor) ; select the part of the screen buffer to be replaced with the incoming $sString _GUICtrlRichEdit_SetSel($hScreen[$iLayer], $iAnchor, $iActive, True) ; set styles for the incoming text _GUICtrlRichEdit_SetFont($hScreen[$iLayer], $iFontSize, $sFontName, $iCharSet) _GUICtrlRichEdit_SetCharColor($hScreen[$iLayer], __PeekColor($iForeColor)) _GUICtrlRichEdit_SetCharBkColor($hScreen[$iLayer], __PeekColor($iBackColor)) ; set or unset bold, italic, underline according if the rispective variable is set to true or false _GUICtrlRichEdit_SetCharAttributes($hScreen[$iLayer], $aAttribute[$Bold] & 'bo' & $aAttribute[$Italic] & 'it' & $aAttribute[$Underline] & 'un') ; place the text on the screen _GUICtrlRichEdit_ReplaceText($hScreen[$iLayer], $sString, False) _GUICtrlRichEdit_Deselect($hScreen[$iLayer]) EndFunc ;==>__PokeText Func _PushCursor($sAction = "Push") Local Static $iCursorPushX = $iCursorPosX Local Static $iCursorPushY = $iCursorPosY If $sAction = "Push" Then $iCursorPushX = $iCursorPosX $iCursorPushY = $iCursorPosY EndIf Local $aXY[2] = [$iCursorPushX, $iCursorPushY] Return $aXY EndFunc ;==>_PushCursor Func _PullCursor() Local $aXY = _PushCursor("Pull") $iCursorPosX = $aXY[0] $iCursorPosY = $aXY[1] EndFunc ;==>_PullCursor ; if you pass a number 0-15 it returns a predefined color from the $aColor[] array. ; if the number is > 15 and <= 0xFFFFFF it returns the same number, while if the passed ; number is out of range it return 0 ($Black)and sets @error Func __PeekColor($iColor) $iColor = Number($iColor) If $iColor >= 0 And $iColor < UBound($aColor) Then Return $aColor[$iColor] ; predefined colors ElseIf $iColor >= UBound($aColor) And $iColor <= 0xFFFFFF Then Return $iColor ; value is <= 0xFFFFFF Else Return SetError(1, 0, 0) ; if out of range return Black and set error EndIf EndFunc ;==>__PeekColor ; clear the screen (fill screen buffer with spaces) ; (for 'crazy' effects you could also select another char instead of the space and custom colors) Func _TextMode_CLS($sFillChr = " ", $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) ; clear the screen ; fill screen with white spaces (screen buffer) _GUICtrlRichEdit_SetText($hScreen[0], _StringReplay(_StringReplay($sFillChr, $iHwidth) & @CRLF, $iVheight - 1) & _StringReplay($sFillChr, $iHwidth)) _GUICtrlRichEdit_SetSel($hScreen[0], 0, -1, True) ; select whole screen ; set parameters _GUICtrlRichEdit_SetFont($hScreen[0], $iFontSize, $sFontName, $iCharSet) ; Set Font _GUICtrlRichEdit_SetCharColor($hScreen[0], __PeekColor($iForegroundColor)) ; Set Foreground default color _GUICtrlRichEdit_SetCharBkColor($hScreen[0], __PeekColor($iBackgroundColor)) ; Set Background default color _GUICtrlRichEdit_SetSel($hScreen[0], 0, 0, False) ; set cursor to home $iCursorPosX = 1 $iCursorPosY = 1 EndFunc ;==>_TextMode_CLS Func _TextMode_SetDefaultColors($iForeColor = $iDefaultForeground, $iBackColor = $iDefaultBackground) If $iForeColor = Default Then $iForeColor = $iDefaultForeground If $iForeColor < $Black Or $iForeColor > $BrightWhite Or $iForeColor = "" Then $iForeColor = $iActiveFGColor If $iBackColor = Default Then $iBackColor = $iDefaultBackground If $iBackColor < $Black Or $iBackColor > $BrightWhite Or $iBackColor = "" Then $iBackColor = $iActiveBGColor $iActiveFGColor = $iForeColor $iActiveBGColor = $iBackColor Local $aDefaultColors = [$iActiveFGColor, $iActiveBGColor] Return $aDefaultColors EndFunc ;==>_TextMode_SetDefaultColors Func _TextMode_SetActiveForeColor($iForeColor = $iActiveFGColor) If $iForeColor = Default Then $iForeColor = $iDefaultForeground If $iForeColor < $Black Or $iForeColor > $BrightWhite Then $iForeColor = $iActiveFGColor $iActiveFGColor = $iForeColor Return $iActiveFGColor EndFunc ;==>_TextMode_SetActiveForeColor Func _TextMode_SetActiveBackColor($iBackColor = $iActiveBGColor) If $iBackColor = Default Then $iBackColor = $iDefaultBackground If $iBackColor < $Black Or $iBackColor > $BrightWhite Then $iBackColor = $iActiveBGColor $iActiveBGColor = $iBackColor Return $iActiveBGColor EndFunc ;==>_TextMode_SetActiveBackColor ; Get / Set active TextMode effect Func _TextMode_Mode($iMode = -1) Local Static $iTextMode If $iMode >= $Normal And $iMode <= $Flash Then $iTextMode = $iMode Return $iTextMode EndFunc ;==>_TextMode_Mode ; set Normal or Inverse or Blink or Flash Func _TextMode_SetMode($iMode = $Normal) If $iMode >= $Normal And $iMode <= $Flash Then Return _TextMode_Mode($iMode) Else Return _TextMode_Mode() EndIf EndFunc ;==>_TextMode_SetMode ; check if is within color ranges Func _IsRGB($iColor) Return $iColor >= 0x000000 And $iColor <= 0xFFFFFF EndFunc ;==>_IsRGB ; move the TextMode GUI to Func _TextMode_GUIMoveTo($iX = 5, $iY = 5, $_hGUI = $_hVintageGui) If IsHWnd($_hGUI) Then WinMove($_hGUI, "", $iX, $iY) EndFunc ;==>_TextMode_GUIMoveTo Func _EndANSI() _GUICtrlRichEdit_Destroy($hScreen[0]) Exit EndFunc ;==>_EndANSI ; returns one or more chars replicated n times ; Example: ConsoleWrite(_StringReplay('*', 5) & @CRLF) Func _StringReplay($sChars = "", $iRepeats = 0) $sChars = String($sChars) $iRepeats = Int(Abs(Number($iRepeats))) Return StringReplace(StringFormat('%' & $iRepeats & 's', ""), " ", $sChars) EndFunc ;==>_StringReplay
  3. regex and iso escape sequences Hi, I would like to extract all ISO escape squences embedded in a string and separate them from the rest of the string, still keeping the information about their position, so that, for exemple, a string like this one (or even more complex): (the string could start with normal text or iso sequences) '\u001B[4mUnicorn\u001B[0m' should be 'transformed' in an array like this $a[0] = '\u001B[4m' ; first iso escape sequence $a[1] = 'Unicorn' ; normal text $a[2] = '\u001B[4m' ; second iso escape sequence ... and so on (note: the above escape sequence has 'control codes' marked as "\u001B' for the asc "esc" char for exemple and a similar notation is also used for other control chars, but in the real string to be parsed those control chars are embedded as a single byte with a value from 01 to 31). at this link (http://artscene.textfiles.com/ansi/) there are many example of real ANSI text files . searching on the web I've found some possible solutions that make use of regexp to achieve similar purpose, and above some others, the regexp pattern posted in the following link by kfir (https://stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python) seems to be able to catch a wider range of ISO escape sequences (not only color sequences), but my lack of skills on regexp, prevents me from evaluating and testing such patterns I would be very grateful if some regexp guru could come to my rescue... thanks everybody for reading...
  4. Hello, i need to save files with ANSI-Encoding. Since 3.3.14.2 Auto-It it doesn't work in any direction. I tried the following: #include <FileConstants.au3> FileDelete(@ScriptDir&"\Test.txt") $o = FileOpen(@ScriptDir&"\Test.txt", BitOR($FO_BINARY,$FO_ANSI,$FO_OVERWRITE)) FileWrite($o, "Test") FileClose($o) Or #include <FileConstants.au3> FileDelete(@ScriptDir&"\Test.txt") $o = FileOpen(@ScriptDir&"\Test.txt", 514) FileWrite($o, "Test") FileClose($o) Both create UTF-8 encoded files. What am i doing wrong? Thank you!
  5. sqlite database written in ANSI code reading?The current version is based on UTF 8 encoding to read and write。 UNICODE or ANSI transfer method
  6. Hello, can anybody tell me what is wrong with the uincode version of my C Run() function? Ansi Version works fine, but I have no clue why CreateProcess does not work in Unicode. #include <windows.h> int RunA(LPSTR szRun) { PROCESS_INFORMATION pi; STARTUPINFOA si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); char szDir[1024]; GetCurrentDirectoryA(sizeof(szDir), szDir); if (!CreateProcessA(NULL, szRun, NULL, NULL, FALSE, 0, NULL, szDir, &si, &pi)) { return 1; } CloseHandle(pi.hThread); return 0; } int RunW(LPWSTR szRun) { PROCESS_INFORMATION pi; STARTUPINFOW si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); wchar_t szDir[1024]; GetCurrentDirectoryW(sizeof(szDir), szDir); if (!CreateProcessW(NULL, szRun, NULL, NULL, FALSE, 0, NULL, szDir, &si, &pi)) { return 1; } CloseHandle(pi.hThread); return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (RunA("calc.exe")) { MessageBox(NULL, TEXT("Failure ANSI version"), TEXT("CreateProcess"), MB_ICONERROR); return 1; } /* // Why does the unicode function crash ?? if (RunW(L"notepad.exe")) { MessageBox(NULL, TEXT("Failure UNICODE version"), TEXT("CreateProcess"), MB_ICONERROR); return 1; } */ return 0; }
  7. _WinGetTextFixed & _StringFixANSIInWide Update: Text problems no longer exist as of v3.3.9.11 Sick of getting rows of '?' from WinGetText, ControlGetText, and other AutoIt functions? The problem lies in the way the text is encoded - AutoIt 'sees' a Windows wide string (UTF-16), but in reality it grabs a string of 8-bit ANSI characters and shoves them into a 16-bit wide string. Here's a small example: Original string "x4" with null-term as an ANSI string sequence: 0x78 0x34 0x00 Same string interpreted as Unicode (reversal is due to little-endian encoding): 0x3478 0x00 The latter string produces the Unicode character "㑸" (hopefully that shows up properly as an asian character) So, as you can see, from the software side, "x4" compacted into a UTF-16 string still produces an acceptable string, even though it wasn't intended to be an asian character. Now, where the '?'s show up is during conversion of the same string back to ANSI. You can see the result of this by doing a ConsoleWrite(), which itself causes an implicit Wide-ANSI conversion to occur. Also, pasting text into another text editor that's using an ANSI code page will give the same results. (A workaround for the conversion is to set the encoding to Unicode) Of course, even if you can display the wide characters correctly, it's not the intended result - you want what the window in question produces. Plus, there are many invalid UTF-16 code points that can be produced, and certain values will be interpreted as a pair of UTF-16 code points.. which just gets messy. So how do we fix this? The easiest workaround, when the format of the string is known to be ANSI beforehand is: $sStr = BinaryToString(StringToBinary($sStr, 2), 1) However, determining whether a window or control will give you ANSI or Wide characters is another issue.. I had written the _StringFixANSIInWide function below to try and detect ANSI-in-Wide situations, and return the corrected string.. Unfortunately its a bit naive in its implementation (see update next paragraph), but it works okay for most situations. I can see it failing only when a Wide string contains nothing but >8-bit characters (usually there is a lot of 7-bit ASCII characters encoded in the lower part of true Wide strings). In theory that is an extremely unlikely situation (unless there are no ASCII characters in a string). Update - _WinGetTextFixed() alternative: Now I've identified the core issue is with the call to SendMessage (using WM_GETTEXT): The function will return either ANSI or Unicode (wide) characters, and its up to our code to determine, based on the length, whether it is an ANSI or wide string. We can then return the correct string. See _WinGetTextFixed() below. Note that AutoIt's WinGetText() function returns text for more than just the window - it returns text for various controls also. While this can be beneficial, it also introduces issues when different controls return Wide or ANSI characters. The result is basically a contaminated string, meaning it packs ANSI characters into UTF-16 sequences and includes legitimate Wide characters in the same string. This is unacceptable and really hard to work with. That's a reason there's now a 'force conversion' parameter in _StringFixANSIInWide. I would really really emphasize that it's best to not use WinGetText() and instead opt for _WinGetTextFixed instead. I may suggest this behavior be fixed in the AutoIt source code, but it looks like all the Devs are gone Anyway, enjoy! Example: Notepad 2 $hWnd = WinGetHandle("[CLASS:Notepad2]") $hControl = ControlGetHandle($hWnd,"","[CLASS:Scintilla]") ; Previous fix: ;~ $sText = _StringFixANSIInWide(ControlGetText($hWnd,"",$hControl)) $sText = _WinGetTextFixed($hControl) ConsoleWrite("Text:"&$sText&@CRLF) Example: SciTE $hWnd = WinGetHandle("[CLASS:SciTEWindow]") $hControl=ControlGetHandle($hWnd,"","[CLASS:Scintilla; INSTANCE:1]") ; Previous fix: ;~ $sText = _StringFixANSIInWide(ControlGetText($hWnd,"",$hControl)) $sText = _WinGetTextFixed($hControl) ConsoleWrite("Text:"&$sText&@CRLF) Example: Programmer's Notepad 2 $hWnd = WinGetHandle("[REGEXPTITLE:Programmer's Notepad]") $hControl = ControlGetHandle($hWnd, "", "[CLASS:ScintillaWindowImpl; INSTANCE:1]") ; Previous fix: ;~ $sText = _StringFixANSIInWide(ControlGetText($hWnd,"",$hControl)) $sText = _WinGetTextFixed($hControl) ConsoleWrite("Text:"&$sText&@CRLF) ; =================================================================================================== ; Func Func _WinGetTextFixed($hWnd) ; ; Function to get Text of a window or control ; This is an alternative to AutoIt's 'WinGetTitle', 'WinGetText', and 'ControlGetText', ; which have issues with reading ANSI text from some windows ; ; Author: Ascend4nt ; =================================================================================================== Func _WinGetTextFixed($hWnd) If Not IsHWnd($hWnd) Then Return SetError(1,0,'') Local $aRet, $stWideText, $stANSIText, $sText Local $nGetTextLen, $nHalfLen ; WM_GETTEXTLENGTH 0x0E $aRet = DllCall("user32.dll", "long", "SendMessageW", "hwnd", $hWnd, "uint", 0x0E, "wparam", 0, "lparam", 0) If @error Then Return SetError(2, @error, '') If Not $aRet[0] Then Return SetError(3, 0, '') $nGetTextLen = $aRet[0] ;~ ConsoleWrite("WM_GETTEXTLENGTH return:"&$nGetTextLen&@CRLF) ; Create a union structure, add 2 characters - 1 for null-term, 1 to handle odd-count cases $stWideText = DllStructCreate("wchar["&$nGetTextLen + 2&"]") If @error Then Return SetError(4, 0, '') $stANSIText = DllStructCreate("char["&($nGetTextLen+2)*2&"]", DllStructGetPtr($stWideText)) ; WM_GETTEXT $aRet = DllCall("user32.dll", "long", "SendMessageW", "hwnd", $hWnd, "uint", 0x0D, "wparam", $nGetTextLen + 1, "ptr", DllStructGetPtr($stWideText)) If @error Then Return SetError(2, @error, '') If Not $aRet[0] Then Return SetError(3, 0, '') $nGetTextLen = $aRet[0] ; Get text as WIDE characters 1st $sText = DllStructGetData($stWideText, 1) ;~ ConsoleWrite("$nGetTextLen = "&$nGetTextLen&", $nHalfLen = "&$nHalfLen&", StringLen() = "&StringLen($sText)&@CRLF) ; Determine if the wide string length is half the supposed returned text length ; - If so, it's an ANSI string $nHalfLen = ($nGetTextLen + BitAND($nGetTextLen, 1) ) / 2 If (StringLen($sText) - $nHalfLen < 2) Then ; Retrieve text correctly as ANSI $sText = DllStructGetData($stANSIText, 1) EndIf Return $sText EndFunc ; ====================================================================================================== ; Func _StringFixANSIInWide($sStr, $bForceCnvt = False) ; ; Function to fix a common issue where ANSI text is embedded in UTF-16 strings ; Problem occurs in 'WinGetText', 'ControlGetText', 'WinGetTitle' ; and some COM functions using 'bstr' types ; ; Easiest method, when you *know* the text is ANSI: ; BinaryToString(StringToBinary($sStr, 2), 1) ; ; *However*, if it is unknown what the string holds, we need to look ; for null characters (0's) in the string ; ; Alternatives:'WideCharToMultiByte' API call, which does the same replacements as below ; However, on Vista+, WC_ERR_INVALID_CHARS can be used to error-out on illegal characters ; ; Author: Ascend4nt ; ====================================================================================================== Func _StringFixANSIInWide($sStr, $bForceCnvt = False) If $sStr = '' Then Return '' Local $nLen, $stStrVer, $stBinVer, $sTmp, $nReplacements ; This fails to work in many mixed-ANSI/UTF-16 scenarios (as seen in WinGetText): ;~ If $bForceCnvt Then ;~ Return BinaryToString(StringToBinary($sStr, 2), 1) ;~ EndIf $nLen = StringLen($sStr) ; Struct for string (+1 for null-term) $stStrVer = DllStructCreate("wchar [" & $nLen + 1 & "]") ; Create a union, granting us binary 1-byte access to the wide chars $stBinVer = DllStructCreate("byte [" & $nLen * 2 & "]", DllStructGetPtr($stStrVer)) ; Set String in structure DllStructSetData($stStrVer, 1, $sStr) ; Load string as binary data, convert to ANSI string ; AND Replace 0's with 0xFFFD (the Unicode 'REPLACEMENT CHARACTER') $sTmp = StringReplace(BinaryToString(DllStructGetData($stBinVer, 1)), ChrW(0), ChrW(0xFFFD), 0, 2) $nReplacements = @extended ; Trim off null-terminator and any other trailing 0's at the end (all converted to 0xFFFD's) While (StringRight($sTmp, 1) = ChrW(0xFFFD)) $sTmp = StringTrimRight($sTmp, 1) $nReplacements -= 1 WEnd ; If no replacements remaining, then every byte contains data, so its a safe bet the string is ANSI ; Also, in mixed-ANSI/UTF-16 situations (sometimes seen in WinGetText), allow a force If ($nReplacements = 0 Or $bForceCnvt) Then Return $sTmp ; Same result as: ;Return BinaryToString(StringToBinary($sStr, 2), 1) Else Return $sStr EndIf EndFunc ;==>_StringFixANSIInWide *updates: - Added a 'force' parameter for scenarios where WinGetText() will return a mix of ANSI and Unicode text in the same string. The result will contain some '?'s in these scenarios, but there's really nothing you can do without modifying the AutoIt source code. update: problem no longer exists as of v3.3.9.11 (see BugTracker ticket # 2362)
×
×
  • Create New...