The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: jj2007 on February 13, 2008, 03:42:16 PM

Title: RichEdit limits, EM_SETSCROLLPOS
Post by: jj2007 on February 13, 2008, 03:42:16 PM
I am fumbling with a richedit box and stumbled over an odd behaviour:
EM_SETSCROLLPOS works fine up to, say, 104k plain text characters.
With larger files, the scroll position is set gradually a bit lower than expected.
The problems get serious around 115 k characters, corresponding to a scrollpos .y of, surprise surprise, 65k... oh my dear tired nerds at Microsoft, what where you doing? Playing with Vista?
Similar is true for the EM_FINDTEXT message: It works fine until roughly that limit, afterwards it simply doesn't find the text any more.
This is RichEd 2.0 on WinXP SP2; EM_LIMITTEXT is -1
Needless to say that M$ is silent about this bug, but maybe one of you has found a workaround?
Title: Re: RichEdit limits, EM_SETSCROLLPOS
Post by: ToutEnMasm on February 13, 2008, 05:48:43 PM
Not a bug,You must center the line in the middle of the screen.
Title: Re: RichEdit limits, EM_SETSCROLLPOS
Post by: MichaelW on February 13, 2008, 07:10:03 PM
Per the PSDK:

"Use the message EM_EXLIMITTEXT for text length values greater than 64,000."

Also EM_SETSCROLLPOS is for Rich Edit version 3 and later, but under Windows XP you should have version 3, and not version 2. For the details:

http://msdn2.microsoft.com/en-us/library/bb787873.aspx

Using this app:

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
include \masm32\include\masm32rt.inc
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

  ; --------------------------------------------------------------------
  ; 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   dd 0
      hWndRE  dd 0
    .code

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
DlgProc proc hDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM

    LOCAL rc:RECT

    Switch uMsg

      Case WM_INITDIALOG

        ; -------------------------------------------
        ; Size the RE control to fit the client area.
        ; -------------------------------------------
     
        invoke GetClientRect, hDlg, ADDR rc
        invoke GetDlgItem, hDlg, 100
        mov hWndRE, eax
        invoke MoveWindow, hWndRE, 0, 0, rc.right, rc.bottom, TRUE

        ; -------------------
        ; Set the text limit.
        ; -------------------

        ;invoke SendMessage, hWndRE, EM_LIMITTEXT, -1, 0
        invoke SendMessage, hWndRE, EM_EXLIMITTEXT, 1000000, 0

      Case WM_COMMAND

        Switch wParam

          Case IDCANCEL

            invoke EndDialog, hDlg, NULL

        EndSw

      Case WM_CLOSE

        invoke EndDialog, hDlg, NULL

    EndSw

    return 0

DlgProc endp
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    ; ---------------------------------------------------
    ; Load the DLL for Rich Edit control versions 2 or 3.
    ; ---------------------------------------------------

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

    invoke GetModuleHandle, NULL
    mov hInst, eax
    Dialog  0, \
            "Courier New",8, \
            WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
            1, \
            0,0,200,150, \
            1024

    ; -------------------------------------------------------------
    ; Specify the class name for Rich Edit control versions 2 or 3.
    ; -------------------------------------------------------------

    DlgControl 0, \
               "RichEdit20A", \
               WS_VSCROLL or \
               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,100

    CallModalDialog hInst, 0, DlgProc, NULL
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


I performed a crude test under Windows 2000 with RichEdit version 3.0. Loading windows.inc Version 1.4c BETA 20 July 2007 into the control (847,948 bytes, 22,219 lines), with the key rollover rate set to the maximum (30 repeats/second ??), and setting the text limit with EM_LIMITTEXT, -1, scrolling from the top to the bottom using Page Down took ~48 seconds. Setting the text limit with EM_EXLIMITTEXT, scrolling from the top to the bottom using Page Down took ~4 seconds.

Title: Re: RichEdit limits, EM_SETSCROLLPOS
Post by: jj2007 on February 13, 2008, 11:46:10 PM
Quote from: ToutEnMasm on February 13, 2008, 05:48:43 PM
Not a bug,You must center the line in the middle of the screen.
Sorry, I don't quite see the relevance of your message.

Quote from: MichaelW on February 13, 2008, 07:10:03 PM
"Use the message EM_EXLIMITTEXT for text length values greater than 64,000."
Thanks, Michael, I had overlooked the "EX"...

QuoteAlso EM_SETSCROLLPOS is for Rich Edit version 3 and later, but under Windows XP you should have version 3, and not version 2
I use 3.0, but it doesn't help... the EM_SETSCROLLPOS works perfectly for file sizes below ca. 108 kBytes. Above this size, it behaves erratically as described above.

Attached samples. The largest files I could find come from EditMasm, so I took them. Drag the files over RichEd.exe, maximize the window, and click into one of the generated bookmarks in the lower right corner.
For buttons.asm, 64k, everything fine: selected text close to the top (I left 2-3 lines on purpose)
except.asm, 118k, is almost fine.
Editmasm.asm, 127k, shows already 6-7 lines for the lower bookmarks
Editmasm_larger.asm, 155k, shows the selected text at the bottom - imho a bug.

For setting the scroll pos, I use the proc below.

SetSelFromB proc selStart:DWORD, selEnd:DWORD, selLines:DWORD
LOCAL chrg:CHARRANGE
LOCAL pt:POINT

; sm = invoke SendMessage,

mov pt.x, 0
mov pt.y, 65536*64 ; this is already kind of a workaround, with best possible results
sm hRE, EM_SETSCROLLPOS, 0, addr pt
mrm chrg.cpMin,selStart
mrm chrg.cpMax,selEnd
sm hRE, EM_EXSETSEL, 0, addr chrg
sm hRE, EM_GETSCROLLPOS, 0, addr pt
mov eax, selLines
sub pt.y, eax ; 10 lines back
.if pt.y<300
mov pt.y, 0 ; except if close to the top
.endif
sm hRE, EM_SETSCROLLPOS, 0, addr pt
  ret
SetSelFromB endp

[attachment deleted by admin]