Jump to content

Get Access to RichEdit (Log) in PSPad with Autoit

Recommended Posts

Hey there!

I'm gonna try to get access to an RichEdit Control in PSPad with Autoit which is scripted with Delphi. I wrote the commands out ouf the RichEdit.au3 UDF to can change them, because it always fails or crashs, when i call it. I Just want to set the Textcolor for the RichEdit.

It seems to be a Problem with $EM_SETCHARFORMAT... (maybe protected?) I can use e.g. $EM_SETBKGNDCOLOR or other messages with no error. Sadly it doesn't exist a message constant to just set the textcolor... This is what i already tried:

  • use $EM_GETCHARFORMAT but it crashs/doesn't work too.
  • I saw the riched20.dll is linked to GDI+ but i couldn't make something work with it... (GetDc and so on but maybe there is another way?)
  • Tried to set some other style on it (setWindowLong)

I read the MSDN about $EM_SETCHARFORMAT up and down, but i can't find any other solution.

The RichEdit should be version 2 ( error message point to riched20.dll )


Here is the PSPad that will be required for testing:


You need to start PSPad.exe first!

; = Info ===========================================================================================
; Title           : RichEdit_Test
; --------------------------------------------------------------------------------------------------
; Version (vnots) : 0.0.1
; Date            : 2020-05-13
; Author(s)       : Aelc
; ==================================================================================================
#include <File.au3>
#include <Misc.au3>
#include <Date.au3>
#include <String.au3>
#include <GuiListBox.au3>
#include <WinAPI.au3>
#include <MsgBoxConstants.au3>
#include <Color.au3>

#include <GuiRichEdit.au3>
#include <EditConstants.au3>

AutoItSetOption("MustDeclareVars", 1)


Func RichEdit_Test_Main()

    Local $hPSPad = Null
    Local $tLogCtrls
    Local $hLB_hwnd
    Local $hLB_ID

    $hPSPad = _WinAPI_GetForegroundWindow()
    If Not WinExists("[CLASS:TfPSPad]") Then
        MsgBox ( 48,"","PSPad not found." )

    $hPSPad = WinGetHandle("[CLASS:TfPSPad]")

;~  If $hPSPad = Null Then
;~      MsgBox($MB_SYSTEMMODAL + $MB_ICONWARNING, 'AutoIt3_CompilerRunner: - Error -', 'No handle found for PSPad!')
;~      Exit (2) ; 2 = PSPad-hwnd not found
;~  EndIf

    If _WinAPI_IsClassName($hPSPad, "TfPSPad") Then

        ; --------------------------------------------------------------------------
        If _Singleton("PSPad->RichEdit_Test " & String($hPSPad), 1) = 0 Then
            MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, "RichEdit_Test: - Error -", _
                    '"RichEdit_Test" is already running')
        ; --------------------------------------------------------------------------

        $tLogCtrls = PSPad_GetLogControls($hPSPad, 'Log')
        $hLB_hwnd = $tLogCtrls.hWnd_ListBox
        $hLB_ID = $tLogCtrls.ID_ListBox
        If $hLB_hwnd > 0 Then
        _SendMessage($hLB_hwnd, 0xCF,False) ;Set $READONLY to False
        Local $tagCHARFORMAT_changeable = "struct;uint cbSize;long dwMask;long dwEffects;long yHeight;long yOffset;INT crTextColor;" & _
                "byte bCharSet;byte bPitchAndFamily;wchar szFaceName[32];endstruct"
        Local $aColor[3] = [0xFF, 0x00, 0xFF]
        Local $nColor = _ColorSetCOLORREF($aColor)
        Local $tCharFormat = DllStructCreate($tagCHARFORMAT_changeable)
        DllStructSetData($tCharFormat, 1, DllStructGetSize($tCharFormat))
        DllStructSetData($tCharFormat, 2, $CFM_COLOR)
        DllStructSetData($tCharFormat, 6, $nColor)
        MsgBox ( 64,"",_SendMessage($hLB_hwnd, $EM_SETCHARFORMAT, $SCF_SELECTION, $tCharFormat, 0, "wparam", "struct*"))
        Else ; Log-Fenster konnte nicht gefunden werden.
            MsgBox($MB_SYSTEMMODAL + $MB_ICONERROR, "AutoIt3_CompilerRunner: - Error -", _
                    "The log window of PSPad could not be found.")

EndFunc   ;==>RichEdit_Test_Main

;~ Func _RichEditGetTextLength($hWnd)
;~  If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, 0)
;~  Local $bChars = True
;~  Local $bExact = True
;~  Local $tGetTextLen = DllStructCreate($tagGETTEXTLENGTHEX)
;~  Local $iFlags = BitOR($GTL_USECRLF, ($bExact ? $GTL_PRECISE : $GTL_CLOSE))
;~  $iFlags = BitOR($iFlags, ($bChars ? $GTL_DEFAULT : $GTL_NUMBYTES))
;~  DllStructSetData($tGetTextLen, 1, $iFlags)
;~  DllStructSetData($tGetTextLen, 2, ($bChars ? $CP_ACP : $CP_UNICODE))
;~  Local $iRet = _SendMessage($hWnd, $EM_GETTEXTLENGTHEX, $tGetTextLen, 0, 0, "struct*")
;~  Return $iRet
;~ EndFunc   ;==>_RichEditGetTextLength

;~ Func _RichEditGetBKColor($hWnd)
;~  If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, 0)
;~  Local $iBkColor = _SendMessage($hWnd, $EM_SETBKGNDCOLOR, False, 0)
;~  _SendMessage($hWnd, $EM_SETBKGNDCOLOR, False, $iBkColor)
;~  Return $iBkColor
;~ EndFunc   ;==>_RichEditGetBKColor

;~ Func _RichEditSetBKColor($hWnd, $iBkColor)
;~  If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, 0)
;~  _SendMessage($hWnd, $EM_SETBKGNDCOLOR, False, $iBkColor)
;~  Return $iBkColor
;~ EndFunc   ;==>_RichEditSetBKColor

Func PSPad_GetLogControls($_hPSPad, $_sSheetText = 'Log')

    Local $sStruct_LogCtrls = _
            'hwnd hWnd_PageControl;' & _ ; TPageControl
            'int ID_PageControl;' & _
            'hwnd hWnd_TabSheet;' & _ ; TTabSheet
            'int ID_TabSheet;' & _
            'hwnd hWnd_ListBox;' & _ ; TListBox
            'int ID_ListBox;'
    Local $tResult = DllStructCreate($sStruct_LogCtrls)
    Local $aEnum
    Local $sSheet
    Local $i, $x
    $aEnum = _WinAPI_EnumChildWindows($_hPSPad, False)
    If IsArray($aEnum) Then
        For $i = 1 To $aEnum[0][0]
            If $aEnum[$i][1] = "TTabSheet" Then
                $sSheet = ControlGetText($_hPSPad, '', _WinAPI_GetDlgCtrlID($aEnum[$i][0]))
                If $sSheet = $_sSheetText Then ; TabSheet gefunden.
                    $tResult.hWnd_TabSheet = $aEnum[$i][0]
                    $tResult.ID_TabSheet = _WinAPI_GetDlgCtrlID($tResult.hWnd_TabSheet)
                    $tResult.hWnd_PageControl = _WinAPI_GetParent($tResult.hWnd_TabSheet)
                    $tResult.ID_PageControl = _WinAPI_GetDlgCtrlID($tResult.hWnd_PageControl)
                    For $x = $i + 1 To $aEnum[0][0]
                        If $aEnum[$x][1] = "TRichEdit" Then
                            $tResult.hWnd_ListBox = $aEnum[$x][0]
                            $tResult.ID_ListBox = _WinAPI_GetDlgCtrlID($tResult.hWnd_ListBox)
                            Return $tResult ; Wenn gefunden, dann raus aus der Funktion.
    Return $tResult
EndFunc   ;==>PSPad_GetLogControls

I don't have any ideas anymore :( But maybe someone else has?

I would be happy for every idea :P 


Thanks in advance

why do i get garbage when i buy garbage bags? <_<

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Professor_Bernd
      PSPad4AutoIt3 v2.0.0 beta (2021-04-16)
      All parts are freeware.

      PSPad4AutoIt3 consists of the Editor PSPad and the Improvement Kit, and can be used as an portable editor IDE for AutoIt3.

      The author of the PSPad Editor is Jan Fiala.
      I (Professor Bernd) am only the author of the Improvement Kit.

      Contact us:
      This is the first fully portable version of PSPad4AutoIt3.

      There are a lot of changes and new features, e.g.

      - a separate AutoIt3 menu in the PSPad main menu,
      - the shortcuts are SciTE-like,
      - Tidy for Au3,
      - in CallTipViewer a recognition for writing "(",
      - a dialog for registering file extensions with Pau3,
      - a nice about dialog in "90s style",
      - the CodeExplorer can now be displayed together with the FavTools on the right side,
      ( so the panel on the left side can be completely hidden )
      - and much more ...
      See here for details
      All in all a lot has been done and it is worth to have a look   Praise, criticism, ideas, tips and hints on bugs are welcome. Have fun with the new features!
      Thank you very much,
      Professor Bernd.
      Special thanks for the friendly support goes to:
      Jan Fiala (Author of PSPad)
      Jos van der Zande (Author of AutoIt3Wrapper, Tidy, ...)
      alpines (suggestions, ideas, testing, design for syntax colors, develop routines)
      argumentum (feedback, suggestions, ideas)
      AspirinJunkie (RegExp pattern, ideas and code snippets)
      Bitnugger (suggestions, ideas and code snippets)
      BugFix (suggestions, ideas and code snippets)
      Gun-Food (for making it possible to publish the project here)
      LarsJ (VBScript<->AutoIt communication, …)
      Musashi (suggestions and ideas)
      Credits for many other contributors can be found in the Pau3 About dialog.
      PSPad4AutoIt3 v2.1.0 beta - Update (2021-05-02) 
      See here for details v2.1.0 beta - Update
      Download in the german forum PSPad4AutoIt3 (Editor IDE), end of post #1   
    • By Page2PagePro
      Excel VBA's IDE registers a Control-y as "cut this line of code".
      For those prone to Undo/Redo (Ctrl+Z/Ctrl+Y) you may find frustration when your code in the editor does not redo, but in fact clears your active line of code while killing redo history.
      Though not perfect, I keep this tool running in background on startup.
      The purpose is to allow Cltr+Y to act normally throughout Windows and Office and only interact *differently* with the "Microsoft Visual Basic for Applications" window that is active.
      If the Standard Menu bar exists, it'll try to click the ReDo (Blue Arrow to the right), else "Alt+e, r" keystrokes (less desired).
      Here's the code:
      Opt('MustDeclareVars', 1) Opt("WinTitleMatchMode", 1) HotKeySet("^y", "TriggerRedo") While 1 Sleep(10) WEnd Func TriggerRedo() ConsoleWrite("TriggerRedo()" & @CRLF) Local $title = "Microsoft Visual Basic for Applications - " Local $hWnd If WinExists($title) And WinActive($title) Then ;~ Parent Window Handle $hWnd = WinGetHandle($title) Local $aWindowPos = WinGetPos($hWnd) ;~ Control Bar Handle, Position and If Visible Local $sControlID = "[CLASS:MsoCommandBar; TEXT:Standard;]" Local $hStandardBar = ControlGetHandle($hWnd, "", $sControlID) Local $bIsVisible = ControlCommand($hWnd, "", $sControlID, "IsVisible") If $hStandardBar And $bIsVisible Then ConsoleWrite("Using Mouse Click." & @CRLF) ;~ Determine Redo button location on visible Control Bar Local $aBarPos = ControlGetPos($hWnd, "", $sControlID) Local $mX = $aWindowPos[0] + $aBarPos[0] + 217 + Int(23/2) Local $mY = $aWindowPos[1] + $aBarPos[1] + 27 + Int(22/2) MouseClick("Left", $mX, $mY, 1, 0) Else ConsoleWrite("Using VBA Send Keys." & @CRLF) $sControlID = "[CLASS:MsoCommandBar; TEXT:Menu Bar;]" Local $hMenuBar = ControlGetHandle($hWnd, "", $sControlID) ControlSend($hWnd, "", $hMenuBar, "!e") ;~ Send("r") $sControlID = "[CLASS:MsoCommandBarPopup; TEXT:Edit;]" Local $hPopupBar = ControlGetHandle($hWnd, "", $sControlID) ControlSend($hWnd, "", $hPopupBar, "r") EndIf Else ConsoleWrite("Using NATIVE Send Keys." & @CRLF) HotKeySet("^y") Send("^y") ;~ may cause "yyy..." when held HotKeySet("^y", "TriggerRedo") EndIf EndFunc ;==>TriggerRedo Hope this inspires someone.
    • By MrCreatoR
      This UDF allows to create formatted label using pseudo element RichLabel (RichEdit actually). Formating is set by using special modificator similar to <font> tag in Html.
      Notes: This UDF is a transformation-continuation of related UDF

      Small syntax related fix: GUIRichLabel_1.1.zip
      History version:
    • By loganizzi
      If you look at the help file for the above command, you'll see that it states that it only works for certain zoom values (100 and 200 to 6400).   I assume that this is due to an issue in an MSDN library that the command relies on.
      After doing some investigating, I noticed that the GUIRichEdit.au3 library file contains the following code:
      ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: ; =============================================================================================================================== Func _GUICtrlRichEdit_SetZoom($hWnd, $iPercent) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) If Not __GCR_IsNumeric($iPercent, ">0") Then Return SetError(1021, 0, False) Local $iNumerator, $iDenominator Select Case Not ($iPercent = 100 Or ($iPercent >= 200 And $iPercent < 6400)) Return SetError(1022, 0, False) Case $iPercent >= 100 $iNumerator = 10000 $iDenominator = 10000 / ($iPercent / 100) Case Else $iNumerator = 10000 * ($iPercent / 100) $iDenominator = 10000 EndSelect Return _SendMessage($hWnd, $EM_SETZOOM, $iNumerator, $iDenominator) <> 0 EndFunc ;==>_GUICtrlRichEdit_SetZoom Which ensures that values are only within the bounds specified in the help file.    I found that if I comment out the portion of the code that limits the values, the function works fine for most (if not all) values.   I changed the code in the library file to this by simply commenting out the restricting lines of code:
      ; #FUNCTION# ==================================================================================================================== ; Authors........: Chris Haslam (c.haslam) ; Modified ......: ; =============================================================================================================================== Func _GUICtrlRichEdit_SetZoom($hWnd, $iPercent) If Not _WinAPI_IsClassName($hWnd, $__g_sRTFClassName) Then Return SetError(101, 0, False) If Not __GCR_IsNumeric($iPercent, ">0") Then Return SetError(1021, 0, False) Local $iNumerator, $iDenominator Select ; Case Not ($iPercent = 100 Or ($iPercent >= 200 And $iPercent < 6400)) ; Return SetError(1022, 0, False) Case $iPercent >= 100 $iNumerator = 10000 $iDenominator = 10000 / ($iPercent / 100) Case Else $iNumerator = 10000 * ($iPercent / 100) $iDenominator = 10000 EndSelect Return _SendMessage($hWnd, $EM_SETZOOM, $iNumerator, $iDenominator) <> 0 EndFunc ;==>_GUICtrlRichEdit_SetZoom  
      I assume whatever windows bug existed at the time this was created, no longer exists so there is no need to restrict the values.   
      Just wanted to point this out if anyone else is using this part of the library and required this functionality like I did.
    • By AndreyS
      Tell me, please, how to set / change the cursor over RichEdit (created with _GUICtrlRichEdit_Create)?
  • Create New...