Jump to content
Sign in to follow this  
Ascend4nt

Fix for unreadable '?' text from WinGetText, ControlGetText

Recommended Posts

Ascend4nt

_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 :o

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)

Edited by Ascend4nt
  • Like 1

Share this post


Link to post
Share on other sites
KaFu

One of those things I've always noticed and wondered about, but never enough to really ask why :)! Great function, definitely a keeper for the snippet box, much appreciated m8 :)... Despite everything else, this imho might still be worth a bug ticket.

Edited by KaFu

Share this post


Link to post
Share on other sites
Ascend4nt

Actually, as it turns out, I was a bit wrong in assuming the '?'s were invalid characters. I was able to see what the output really looked like by changing the encoding in Notepad2 and doing a paste..

So basically, a lot of the 2-byte ANSI characters are perfectly valid UTF-16 combinations, and they generally show up as Eastern language characters in a Unicode viewer. The '?'s are what results when converting from those eastern language codes to an ANSI version, which is what you see in most text editors in their default locale settings (and in SciTE's output).

Soo now I'm thinking MultiByteToWideChar may be a better option.. and just 'fool' AutoIt into thinking it is accepting a "wstr" as the 3rd parameter in the DLLCall. The issue I'm a bit uncertain about is deciding what to put as the Locale info.. I'd need to find out the encoding the given window uses - which in most cases would be the system (or user?) code page. Hmm.. I'll have to see if there's a Windows API function for detecting the encoding of a window. If anyone knows it, let me know (otherwise I'll be poking around the API for a bit)

Also, another problem is that MultiByteToWideChar will either drop illegal code points or fail completely (depending on the MB_ERR_INVALID_CHARS flag.. Oh, and of course any mixed ANSI/Wide strings would give some funky results for the Wide string portion.. which is why I'm leaning towards telling people just to avoid WinGetText on problem windows, since you're basically getting a contaminated string by doing that.

Hmm.. for now I suppose I'll leave the function intact, as it works relatively well for Controls, but there's still a minimal chance that embedded ANSI can produce a completely valid UTF-16 string..

Share this post


Link to post
Share on other sites
KaFu

Maybe it's related to the code page and language defined in the resources?

FileGetVersion($sFile, "DefaultLangCodepage")

From Help-File for FileGetVersion():

"Another special stringname is "DefaultLangCodepage" can be used to retrieve the default language and codepage.

The language and codepage can be used if needed to differentiate the "stringname" i.e. "080904b0Comments" (see MSDN StringFileInfo in VerQueryValue function)."

Share this post


Link to post
Share on other sites
Ascend4nt

Thanks for the idea KaFu, but I don't know that that would work well with multilanguage apps or text editors that let you change the encoding..

However, I've identified the problem - its the call to SendMessage (with WM_GETTEXT). It returns either an ANSI or Wide string, and the length of the returned string. I've found its pretty easy once we know the string length - we can just compare the wide string length to this and determine if it should be read as ANSI if its approximately half that returned length.

I've updated the first post with the new _WinGetTextFixed() function.

Share this post


Link to post
Share on other sites
Jon

Hopefully this is all fixed in 3.3.9.11.

I've fixed my window handling class so that all calls for WM_GETTEXT use it (there were a few places I'd missed).  I've checked WinGetText() and ControlGetText() with it and Scite.

Same fixes for Au3Info too.

  • Like 2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Similar Content

    • FrancescoDiMuro
      By FrancescoDiMuro
      Good morning everyone

      I was playing a little bit with "Screen Capture" UDF, and I was trying to make a "Window" capture, but, since I made a GUI which through I fire the event "Capture", my GUI is captured as well, and I don't want to
      This is the line of code that makes the capture:
       
      _ScreenCapture_CaptureWnd($strScreenCaptureFileName, $objActiveWindow, 0, 0, -1, -1, False) And these are the lines of code which select the "active" window:
       
      Local $objCurrentWindow = 9999 If _IsPressed("01") Then $objCurrentWindow = WinGetHandle("[ACTIVE]") If $objCurrentWindow <> $objMyGUI Then $objActiveWindow = $objCurrentWindow EndIf EndIf Sorry If I made stupid mistakes
      Thanks in advance.

      Francesco
    • WoodGrain
      By WoodGrain
      Hi All,
      I'd like to replace 'COMMA' with ',' for example:
      $myString = "COMMA" StringRegExpReplace($myString, 'COMMA', ',') Now I've tried escaping the ',' in various ways unsuccessfully, such as:
      '[,]'
      "[,]"
      '\,'
      [,] seems to work in the pattern, I just can't figure out how to use it in the replace, and it seems everyone online is only interested in removing/replacing commas lol.
      I also tried creating and using a variable as the replacement but also didn't work:
      $myComma = "," $myString = "COMMA" StringRegExpReplace($myString, 'COMMA', $myComma) I'm sure it's super simple if someone could point me in the right direction - thanks.
    • vin1
      By vin1
      i need a script that can replace words in text with other words from a words list
      it has to have 2 edit boxes input/output and a button "run"
      from word_list.txt it choses which word to replace with. words are separated with commas for multiple choice
       

       
       

       
       
      ; AutoIt GUI Example ; Created: 17/01/2005 - CyberSlug ; Modifed: 05/12/2011 - guinness ; Modifed: 09/06/2014 - mLipok #Region INCLUDE #include <AVIConstants.au3> #include <GuiConstantsEx.au3> #include <TreeViewConstants.au3> #EndRegion INCLUDE #Region GUI GUICreate("Sample GUI", 400, 420) GUISetIcon(@SystemDir & "\mspaint.exe", 0) #EndRegion GUI #Region EDIT GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 10, 380, 175) GUICtrlSetTip(-1, '#Region EDIT') #EndRegion EDIT #Region EDIT2 GUICtrlCreateEdit(@CRLF & " Sample Edit Control", 10, 185, 380, 175) GUICtrlSetTip(-1, '#Region EDIT') #EndRegion EDIT2 #Region BUTTON GUICtrlCreateButton("Sample Button", 10, 360, 100, 30) GUICtrlSetTip(-1, '#Region BUTTON') #EndRegion BUTTON #Region GUI MESSAGE LOOP GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() #EndRegion GUI MESSAGE LOOP  
    • Chimp
      By Chimp
      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  
    • Ambient
      By Ambient
      I have tried several way sto get this to work to no avail. Any help would be appreciated. #include <ListViewConstants.au3> #include <GuiListView.au3> #include "GuiListViewEx.au3" $idItem = GUICtrlCreateListViewItem($r & " | " & $c & $adoRs.Fields("TransactionAmount").value & " | " & $Timestamp & " | " & _StringProper($adoRs.Fields("Tillid").value) & @CRLF & @CRLF & "Card Number : " & $cardnum & " " , $idListView) ConsoleWrite( "IDITEM" & $idItem) If STRINGLEFT($adoRs.Fields("TransactionAmount").value,1)= "-" Then Consolewrite(" String is Negative" & @CRLF) ;Drops in Here as expected ;GUICtrlSetColor(-1, $COLOR_RED) ; Colour line if item is negative this didn' work $TxC= _GUICtrlListView_SetTextColor($hListView, $CLR_RED) ; I also tried $TxC= _GUICtrlListView_SetTextColor(-1, 0xFF0000) CONSOLEWRITE("TEXTCOLOUR RETURNED " & $TxC & @crlf) ; This is returning True ELSE Consolewrite(" String is NOT Negative" & @CRLF) EndIf  
×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.