News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Rich Edit Text

Started by cman, February 13, 2014, 09:53:17 AM

Previous topic - Next topic

cman

Is there a way to read a line of text from a rich edit control without reading all the formatting characters ? I want to use a Rich Edit in an application basically so I can change the background color of the edits , but I don't need the extra information a Rich Edit provides ( I just want to work in plain text ).  Am I better off just writing a function to strip the special characters from any string read? Thanks for any information.

jj2007

EM_GETTEXTRANGE is your friend ;-)

MichaelW

I could not find any clear statement regarding the format of the characters copied in the EM_GETTEXTRANGE documentation, so I modified an old source to test this. For sample.rtf I used my source file, loaded into Microsoft Word and saved as RTF.

;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
IDC_RE equ 100
;==============================================================================

  ;----------------------------------------------------------------------
  ; This is a general-purpose control definition macro that adds support
  ; for controls of any type to the MASM32 In-Memory Dialogs. For this
  ; macro the control class is specified as a quoted string, instead of
  ; being hard coded.
  ;----------------------------------------------------------------------

    DlgControl MACRO quoted_caption,quoted_class,dstyle,tx,ty,wd,ht,ctlID
      align_4 edi
      mov DWORD PTR [edi+0],  WS_VISIBLE or WS_CHILD or dstyle
      mov WORD  PTR [edi+8],  tx
      mov WORD  PTR [edi+10], ty
      mov WORD  PTR [edi+12], wd
      mov WORD  PTR [edi+14], ht
      mov WORD  PTR [edi+16], ctlID
      add edi, 18
      ustring quoted_class
      ustring quoted_caption
      ;-------------------------------------------
      ; Advance edi past the creation data array.
      ;-------------------------------------------
      add edi, 2
    ENDM

;==============================================================================
    .data
        hInst         HMODULE 0
        hwndRE        HWND    0
        hFileIn       HANDLE  0
        hFileOut1     HANDLE  0
        hFileOut2     HANDLE  0
        flag          dd      0
        bytesWritten  dd      0
        editStreamIn  EDITSTREAM <0,,EditStreamCallbackIn>
        editStreamOut EDITSTREAM <0,,EditStreamCallbackOut>
        tr            TEXTRANGE <{0,-1}, OFFSET buffer>
        buffer        db 10000 dup(0)
    .code
;==============================================================================

EditStreamCallbackIn proc dwCookie:DWORD, pbBuff:DWORD, cb:DWORD, pcb:DWORD

    invoke ReadFile, hFileIn, pbBuff, cb, pcb, NULL
    return 0

EditStreamCallbackIn endp

EditStreamCallbackOut proc dwCookie:DWORD, pbBuff:DWORD, cb:DWORD, pcb:DWORD

    invoke WriteFile, hFileOut1, pbBuff, cb, pcb, NULL
    return 0

EditStreamCallbackOut endp

;==============================================================================

DlgProc proc hwndDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    LOCAL rc:RECT

    SWITCH uMsg

        CASE WM_INITDIALOG

            invoke CreateFile, chr$("sample.rtf"), GENERIC_READ, FILE_SHARE_READ,
                               NULL, OPEN_EXISTING, NULL, NULL
            mov hFileIn, eax

            invoke CreateFile, chr$("streamout.txt"), GENERIC_WRITE, FILE_SHARE_WRITE,
                               NULL, CREATE_ALWAYS, NULL, NULL
            mov hFileOut1, eax

            invoke CreateFile, chr$("gettextrange.txt"), GENERIC_WRITE, FILE_SHARE_WRITE,
                               NULL, CREATE_ALWAYS, NULL, NULL
            mov hFileOut2, eax

            invoke GetDlgItem, hwndDlg, IDC_RE
            mov hwndRE, eax

            invoke SendMessage, hwndRE, EM_EXLIMITTEXT, 1000000, 0

            invoke SendMessage, hwndRE, EM_STREAMIN, SF_RTF, ADDR editStreamIn

            ;-----------------------------------------------------------------
            ; I could not find any way to deselect the streamed in text from
            ; here, so I set up a timer to deselect it after a short delay.
            ;-----------------------------------------------------------------

            invoke SetTimer, hwndDlg, 1, 10, NULL

        CASE WM_TIMER

            invoke SendMessage, hwndRE, EM_SETSEL, 0, 0
            invoke KillTimer, hwndDlg, 1

        CASE WM_SYSCOMMAND

            .IF flag == 0

                inc flag

                invoke FlashWindow, hwndDlg, TRUE
                invoke Sleep, 300
                invoke FlashWindow, hwndDlg, TRUE

                invoke SendMessage, hwndRE, EM_STREAMOUT, SF_TEXT, ADDR editStreamOut
                invoke SetFilePointer, hFileOut1, 0, NULL, FILE_BEGIN

                invoke SendMessage, hwndRE, EM_GETTEXTRANGE, 0, ADDR tr
                invoke WriteFile, hFileOut2, ADDR buffer, eax, ADDR bytesWritten, NULL

                invoke CloseHandle,hFileOut1
                invoke CloseHandle,hFileOut2

            .ENDIF

        CASE WM_SIZE

            invoke GetClientRect, hwndDlg, ADDR rc
            invoke MoveWindow, hwndRE, 0, 0, rc.right, rc.bottom, TRUE

        CASE WM_COMMAND

            SWITCH wParam

                CASE IDCANCEL

                    invoke CloseHandle,hFileIn
                    invoke CloseHandle,hFileOut1
                    invoke CloseHandle,hFileOut2
                    invoke EndDialog, hwndDlg, NULL
            ENDSW

        CASE WM_CLOSE

            invoke CloseHandle,hFileIn
            invoke CloseHandle,hFileOut1
            invoke CloseHandle,hFileOut2
            invoke EndDialog, hwndDlg, NULL

    ENDSW

    return 0

DlgProc endp

;==============================================================================
start:
;==============================================================================

    invoke LoadLibrary, chr$("RICHED20.DLL")

    invoke GetModuleHandle, NULL
    mov hInst, eax

    Dialog  "Click title bar to write files...", \
            "Courier New",8, \
            WS_OVERLAPPEDWINDOW or DS_CENTER, \
            1, \
            0,0,400,300, \
            1024

    DlgControl 0, \
               "RichEdit20A", \
               WS_VSCROLL or \
               WS_HSCROLL or \
               ES_SUNKEN or \
               ES_MULTILINE or \
               ES_AUTOVSCROLL or \
               ES_AUTOHSCROLL or \
               ES_NOHIDESEL or \
               ES_WANTRETURN, \
               0,0,0,0,IDC_RE

    CallModalDialog hInst, 0, DlgProc, NULL

    exit

;==============================================================================
end start


The result was that EM_GETTEXTRANGE copied only the text, but converted the CRLFs to CRs. I think there is a way to control this but I did not have time to investigate.
Well Microsoft, here's another nice mess you've gotten us into.

jj2007

Quote from: MichaelW on February 14, 2014, 11:49:51 AM
The result was that EM_GETTEXTRANGE copied only the text, but converted the CRLFs to CRs. I think there is a way to control this but I did not have time to investigate.

You can control this with the EM_GETTEXTEX message, but for the OP's case EM_GETTEXTRANGE is probably sufficient.

Beware of option 3, EM_STREAMOUT - it's broken.