Home All Groups Group Topic Archive Search About
Author
20 Mar 2009 11:26 PM
Bee
I am trying to get limited rich text into a RichTextbox.
i.e. I want to load only a few lines rather than the whole text.
Let's say the richtext file is 100,000 lines but I only want to see the
first twenty and only load the first twenty so as not to take up too much
memory.  Multiple things eating memory then.

I have tried opening the file and reading in raw lines to a string sLines
then "loading" the string into the richtextbox, but the result is rich text
jibberish.

rtbSample.TExt = sLines
rtbSample.TextRTF = sLine
rtbSample.SelRTF = sLine

none accept the rich text as rich text.
Maybe some tag I need to add after the last line to tell it that is richtext
end of text?
What am I missing?
If I load the whole file I have no problem looking at the first few lines so
the richtext file itself is not corrupt.

Author
21 Mar 2009 6:02 AM
Jeremiah D. Seitz
On Fri, 20 Mar 2009 16:26:01 -0700, Bee
<B**@discussions.microsoft.com> wrote:

Show quoteHide quote
>I am trying to get limited rich text into a RichTextbox.
>i.e. I want to load only a few lines rather than the whole text.
>Let's say the richtext file is 100,000 lines but I only want to see the
>first twenty and only load the first twenty so as not to take up too much
>memory.  Multiple things eating memory then.
>
>I have tried opening the file and reading in raw lines to a string sLines
>then "loading" the string into the richtextbox, but the result is rich text
>jibberish.
>
>rtbSample.TExt = sLines
>rtbSample.TextRTF = sLine
>rtbSample.SelRTF = sLine
>
>none accept the rich text as rich text.
>Maybe some tag I need to add after the last line to tell it that is richtext
>end of text?
>What am I missing?
>If I load the whole file I have no problem looking at the first few lines so
>the richtext file itself is not corrupt.

What's the source of the data? OLE drag-n-drop(tm) and clipboard
transfer would be complicated to intercept, almost definitely
involving subclassing. Directly setting the RTFText(?) property would
work, but all three methods would require (afaik) a working knowledge
of the RTF format.

Tell us the source of the data, and we can likely help a bit more.

    J.
    Jeremiah D. Seitz
    Omega Techware
    http://www.omegatechware.net
Author
21 Mar 2009 12:01 PM
Hiker123
This is a tough task especially if you are not an expert in parsing
RTF yourself.

You can't just pass X characters or Lines from an RTF file.

     Problem 1 - The RichTextBox control will choke if you give
it a string with opening RTF tags that are not properly closed.
Things
like closing brakets.   Or if you try to load a string with just parts
of an RTF entity like part of a table, or an embedded image.

     Problem 2 - some lines of the RTF are not going to contain any
real text - just things like the font table and color table
definition .

     Problem 3, 4, ....


So - if this kind of thing is critical to you, you are going to need
to have code to parse the RTF, recognize RTF elements, and
load full elements into the control.

This way you can also do things like giving the user an option for
dropping things like images.    The text itself is likely to require
very little memory so if you drop all images you may be able to load
the entire document.

If your RTF string is very simple ( for example, just text with
colors,
bold, italics and no other formatting or objects ), you may want to
try
to parse this yourself.    The RTF Specification is available on-line.
If you would outsource this portion of the project, for expertise
in RTF handling, drop me a note by e-mail.  We created the ALLText
control - used for RTF presentations by Bill Gates personally.

      Jeff
       Jeff   AT   Bennet-Tec   DOT  Com

==============================================
Author
21 Mar 2009 3:27 PM
Bee
OK so this is difficult.
So then I tried using the .MaxLength property to limit the text.
But this does not seem to work for LoadFile, only for typing.
THere are a number of API SendMessage calls to access the RichTextBox, is
there something there that would help?

Another problem has come up.
As used, The RichTextBox is hidden.
Once loaded by LoadFile and getting all the text from the file, I want to
pull lines one at a time from the top for the first few lines of text.

Even when I turn on both scroll bars, the line length returned equates to
the .width parameter of the RichTextbox rather that the what I would expect
with scrollbars on.

     lLen = SendMessageAsString(rtb.hwnd, EM_GETLINE, lLineNumber, sBuffer)
Does not return a line but returns a string length that fits the .width
regardless of anything else it seems.
How can I get on full line simply?
Is there another EM_something that will do this?

Simply I say since I could put all text into a string using .Text then split
on vbCrlf and work with that array, but now I am using much more memory and
using too much time.
Time is the parameter that I have to minimize more than anything else.

The whole point is to rapidy get the first few lines of a rich text file and
display to the user.
The user is going to scan may files rapidly looking for info contained in
the first few lines.


Show quoteHide quote
"Bee" wrote:

> I am trying to get limited rich text into a RichTextbox.
> i.e. I want to load only a few lines rather than the whole text.
> Let's say the richtext file is 100,000 lines but I only want to see the
> first twenty and only load the first twenty so as not to take up too much
> memory.  Multiple things eating memory then.
>
> I have tried opening the file and reading in raw lines to a string sLines
> then "loading" the string into the richtextbox, but the result is rich text
> jibberish.
>
> rtbSample.TExt = sLines
> rtbSample.TextRTF = sLine
> rtbSample.SelRTF = sLine
>
> none accept the rich text as rich text.
> Maybe some tag I need to add after the last line to tell it that is richtext
> end of text?
> What am I missing?
> If I load the whole file I have no problem looking at the first few lines so
> the richtext file itself is not corrupt.
>
Author
21 Mar 2009 6:32 PM
Hiker123
> Simply I say since I could put all text into a string using .Text then split
> on vbCrlf and work with that array, but now I am using much more memory and
> using too much time.

vbCrLF is not relevant inside an RTF file.
These may be inserted at what would appear like
random locations and do not correspond to actual line breaks.
Sort of like with HTML file


> Time is the parameter that I have to minimize more than anything else.
> The whole point is to rapidy get the first few lines of a rich text file and
> display to the user.
> The user is going to scan may files rapidly looking for info contained in
> the first few lines.

Possibly our ALLText control may help.
ALLText works on many RTF files much better than MS RichTextbox
and was designed for fast display of the start of the text - we
display
the start while background processing the rest.

However we have not updated ALLText in a LONG while and it
may have troubles with RTF from some recent versions of Word.
Also ALLText is not well suited to certain types of RTF where
you have a huge number of very short paragraps ( \par tags - not
vbcrlf ).

I could suggest that you might give this a try.    Or you could post
a couple of sample RTF files somewhere and I could test this out for
you.

  Jeff
       Jeff   AT   Bennet-Tec   DOT  Com


==============================================
Author
21 Mar 2009 11:38 PM
mayayana
I'm not clear on whether you actually want the RTF
formatting. If not then you might just load the file
into a second RTB and then get the Text property
of that content to strip off the formatting. Alternatively,
you could paste in the new text and reformat the whole
RTB yourself.

  I don't think htere's a way to limit LodFile. I've tried to
do it when using the API EM_STREAMIN and didn't find
a way that didn't crash. So instead I just read in the
file and use Left$ to get the number of characters that
I want.

To get an RTB line:

Private Const GETLINE_MASK_1 As Long = &HFF
Private Const GETLINE_MASK_2 As Long = &H100

Public Function GetLine(ByVal LineNumber As Long) As String
  Dim LineLen As Long, LIndex as long
  Dim sBuf As String
  On Error GoTo woops
   GetLine = ""

     LIndex = SendMessageLong(hRTB, EM_LINEINDEX, LineNumber, 0&)
     LineLen = SendMessageLong(hRTB, EM_LINELENGTH, LIndex, 0&) + 1
     sBuf = String$((LineLen + 2), 0)
       Mid$(sBuf, 1, 1) = Chr$(LineLen And GETLINE_MASK_1)
       Mid$(sBuf, 2, 1) = Chr$(LineLen \ GETLINE_MASK_2)
     LineLen = SendMessageString(hRTB, EM_GETLINE, LineNumber, sBuf)
     If (LineLen > 0) Then
       GetLine = Left$(sBuf, LineLen)
     End If
End Function

You can also use EM_LINEINDEX and EM_LINELENGTH to
get startpoint/endpoint and then access it that way.


Show quoteHide quote
> OK so this is difficult.
> So then I tried using the .MaxLength property to limit the text.
> But this does not seem to work for LoadFile, only for typing.
> THere are a number of API SendMessage calls to access the RichTextBox, is
> there something there that would help?
>
> Another problem has come up.
> As used, The RichTextBox is hidden.
> Once loaded by LoadFile and getting all the text from the file, I want to
> pull lines one at a time from the top for the first few lines of text.
>
> Even when I turn on both scroll bars, the line length returned equates to
> the .width parameter of the RichTextbox rather that the what I would
expect
> with scrollbars on.
>
>      lLen = SendMessageAsString(rtb.hwnd, EM_GETLINE, lLineNumber,
sBuffer)
> Does not return a line but returns a string length that fits the .width
> regardless of anything else it seems.
> How can I get on full line simply?
> Is there another EM_something that will do this?
>
> Simply I say since I could put all text into a string using .Text then
split
> on vbCrlf and work with that array, but now I am using much more memory
and
> using too much time.
> Time is the parameter that I have to minimize more than anything else.
>
> The whole point is to rapidy get the first few lines of a rich text file
and
> display to the user.
> The user is going to scan may files rapidly looking for info contained in
> the first few lines.
>
>
> "Bee" wrote:
>
> > I am trying to get limited rich text into a RichTextbox.
> > i.e. I want to load only a few lines rather than the whole text.
> > Let's say the richtext file is 100,000 lines but I only want to see the
> > first twenty and only load the first twenty so as not to take up too
much
> > memory.  Multiple things eating memory then.
> >
> > I have tried opening the file and reading in raw lines to a string
sLines
> > then "loading" the string into the richtextbox, but the result is rich
text
> > jibberish.
> >
> > rtbSample.TExt = sLines
> > rtbSample.TextRTF = sLine
> > rtbSample.SelRTF = sLine
> >
> > none accept the rich text as rich text.
> > Maybe some tag I need to add after the last line to tell it that is
richtext
> > end of text?
> > What am I missing?
> > If I load the whole file I have no problem looking at the first few
lines so
> > the richtext file itself is not corrupt.
> >
Author
22 Mar 2009 2:25 PM
mayayana
A couple of additional notes to that last post:

If you're getting a line length equal to the visible window...
is wordwrap on? I think RightMargin control wordwrap. You
need to set it to some big number in order to stop wordwrap.
Or use this method:

Public Sub WordWrap(hRTB as long, BooWrap As Boolean)
    On Error Resume Next
  If (BooWrap = False) Then
      SendMessageLong hRTB, EM_SETTARGETDEVICE, 0, 1
  Else
      SendMessageLong hRTB, EM_SETTARGETDEVICE, 0, 0
  End If
End Property

  Also, on your point about MaxLength: That's the RTB
wrapper around EM_SETLIMITTEXT. If you look that up
you'll see it doesn't affect EM_STREAMIN (LoadFile). It
only affects typing and pasting. As mentioned in my last
post, if you want to limit the loaded file to a given number
of characters then you need to read it out with basic file
I/O and then pick out the string you want to load into
the RTB.

--
JSWare
www.jsware.net
jsw***@jsware.net
__________________

Please note:
  JSWare does not accept email from free,
commercial "webmail" sources such yahoo,
gmail, or hotmail. For further explanation please see:
www.jsware.net/jsware/contact.php3#webmail
mayayana <mayayaX***@rcXXn.com> wrote in message
Show quoteHide quote
news:uVEynXnqJHA.1240@TK2MSFTNGP02.phx.gbl...
>   I'm not clear on whether you actually want the RTF
> formatting. If not then you might just load the file
> into a second RTB and then get the Text property
> of that content to strip off the formatting. Alternatively,
> you could paste in the new text and reformat the whole
> RTB yourself.
>
>   I don't think htere's a way to limit LodFile. I've tried to
> do it when using the API EM_STREAMIN and didn't find
> a way that didn't crash. So instead I just read in the
> file and use Left$ to get the number of characters that
> I want.
>
> To get an RTB line:
>
> Private Const GETLINE_MASK_1 As Long = &HFF
> Private Const GETLINE_MASK_2 As Long = &H100
>
> Public Function GetLine(ByVal LineNumber As Long) As String
>   Dim LineLen As Long, LIndex as long
>   Dim sBuf As String
>   On Error GoTo woops
>    GetLine = ""
>
>      LIndex = SendMessageLong(hRTB, EM_LINEINDEX, LineNumber, 0&)
>      LineLen = SendMessageLong(hRTB, EM_LINELENGTH, LIndex, 0&) + 1
>      sBuf = String$((LineLen + 2), 0)
>        Mid$(sBuf, 1, 1) = Chr$(LineLen And GETLINE_MASK_1)
>        Mid$(sBuf, 2, 1) = Chr$(LineLen \ GETLINE_MASK_2)
>      LineLen = SendMessageString(hRTB, EM_GETLINE, LineNumber, sBuf)
>      If (LineLen > 0) Then
>        GetLine = Left$(sBuf, LineLen)
>      End If
> End Function
>
>  You can also use EM_LINEINDEX and EM_LINELENGTH to
> get startpoint/endpoint and then access it that way.
>
>
> > OK so this is difficult.
> > So then I tried using the .MaxLength property to limit the text.
> > But this does not seem to work for LoadFile, only for typing.
> > THere are a number of API SendMessage calls to access the RichTextBox,
is
> > there something there that would help?
> >
> > Another problem has come up.
> > As used, The RichTextBox is hidden.
> > Once loaded by LoadFile and getting all the text from the file, I want
to
> > pull lines one at a time from the top for the first few lines of text.
> >
> > Even when I turn on both scroll bars, the line length returned equates
to
> > the .width parameter of the RichTextbox rather that the what I would
> expect
> > with scrollbars on.
> >
> >      lLen = SendMessageAsString(rtb.hwnd, EM_GETLINE, lLineNumber,
> sBuffer)
> > Does not return a line but returns a string length that fits the .width
> > regardless of anything else it seems.
> > How can I get on full line simply?
> > Is there another EM_something that will do this?
> >
> > Simply I say since I could put all text into a string using .Text then
> split
> > on vbCrlf and work with that array, but now I am using much more memory
> and
> > using too much time.
> > Time is the parameter that I have to minimize more than anything else.
> >
> > The whole point is to rapidy get the first few lines of a rich text file
> and
> > display to the user.
> > The user is going to scan may files rapidly looking for info contained
in
> > the first few lines.
> >
> >
> > "Bee" wrote:
> >
> > > I am trying to get limited rich text into a RichTextbox.
> > > i.e. I want to load only a few lines rather than the whole text.
> > > Let's say the richtext file is 100,000 lines but I only want to see
the
> > > first twenty and only load the first twenty so as not to take up too
> much
> > > memory.  Multiple things eating memory then.
> > >
> > > I have tried opening the file and reading in raw lines to a string
> sLines
> > > then "loading" the string into the richtextbox, but the result is rich
> text
> > > jibberish.
> > >
> > > rtbSample.TExt = sLines
> > > rtbSample.TextRTF = sLine
> > > rtbSample.SelRTF = sLine
> > >
> > > none accept the rich text as rich text.
> > > Maybe some tag I need to add after the last line to tell it that is
> richtext
> > > end of text?
> > > What am I missing?
> > > If I load the whole file I have no problem looking at the first few
> lines so
> > > the richtext file itself is not corrupt.
> > >
>
>
Author
22 Mar 2009 7:55 AM
Rick Rothstein
Give this a try. Put the following code in a Module (Project/AddModule from
the menu bar)...

'*************** START OF CODE ***************
Private Const KEYEVENTF_KEYUP = &H2
Private Const INPUT_KEYBOARD = 1

Private Type KEYBDINPUT
  wVk As Integer
  wScan As Integer
  dwFlags As Long
  time As Long
  dwExtraInfo As Long
End Type

Private Type GENERALINPUT
  dwType As Long
  xi(0 To 23) As Byte
End Type

Private Declare Function SendInput _
                Lib "user32.dll" _
               (ByVal nInputs As Long, _
                pInputs As GENERALINPUT, _
                ByVal cbSize As Long) As Long

Private Declare Sub CopyMemory _
                Lib "kernel32" _
                Alias "RtlMoveMemory" _
               (pDst As Any, _
                pSrc As Any, _
                ByVal ByteLen As Long)

Private Function SendKeysA(ByVal vKey As Integer)
  Dim GInput(0) As GENERALINPUT
  Dim KInput As KEYBDINPUT
  KInput.wVk = vKey
  GInput(0).dwType = INPUT_KEYBOARD
  CopyMemory GInput(0).xi(0), KInput, Len(KInput)
  Call SendInput(1, GInput(0), Len(GInput(0)))
End Function

Public Sub StripRTB(RTB As RichTextBox, NumOfLines As Long)
  Dim X As Long
  Dim TextAsShown As String
  With RTB
    .SetFocus
    .SelStart = 0
    For X = 1 To NumOfLines - 1
      SendKeysA vbKeyDown
      DoEvents
    Next
    SendKeysA vbKeyEnd
    DoEvents
    .SelLength = Len(.TextRTF)
    .SelText = ""
    .SelStart = 0
  End With
End Sub
'*************** END OF CODE ***************

To use this code, simply load your RichTextFile into the RichTextBox and
then call the StripRTB subroutine passing in the name of the RichTextBox and
how many lines you want to display in it. For example, kicked off from a
CommandButton (displaying the first 5 lines of the file loaded into
RichTextBox1)...

Private Sub Command1_Click()
  RichTextBox1.LoadFile "c:\Your\Path\And\FileName.rtf"
  StripRTB RichTextBox1, 5
End Sub

--
Rick (MVP - Excel)
Author
22 Mar 2009 4:41 PM
Rick Rothstein
Sorry, I misread your posting to say you wanted the lines you could see in
the RichTextBox. To get the first so many **full** lines, and to show them
without wordwrapping, use this subroutine...

Public Sub StripRTB(RTB As RichTextBox, NumOfLines As Long)
  Dim X As Long
  Dim LastCrLf As Long
  With RTB
    .RightMargin = 100000
    For X = 1 To NumOfLines
      LastCrLf = InStr(LastCrLf + 1, .Text, vbCrLf)
    Next
    .SelStart = LastCrLf
    .SelLength = Len(.Text)
    .SelText = ""
    .SelStart = 0
  End With
End Sub

and call it like this...

Private Sub Command1_Click()
  RichTextBox1.LoadFile "c:\Your\Path\And\FileName.rtf"
  StripRTB RichTextBox1, 7
End Sub

--
Rick (MVP - Excel)


Show quoteHide quote
"Rick Rothstein" <rick.newsNO.SPAM@NO.SPAMverizon.net> wrote in message
news:OD$zVOsqJHA.5356@TK2MSFTNGP03.phx.gbl...
> Give this a try. Put the following code in a Module (Project/AddModule
> from the menu bar)...
>
> '*************** START OF CODE ***************
> Private Const KEYEVENTF_KEYUP = &H2
> Private Const INPUT_KEYBOARD = 1
>
> Private Type KEYBDINPUT
>  wVk As Integer
>  wScan As Integer
>  dwFlags As Long
>  time As Long
>  dwExtraInfo As Long
> End Type
>
> Private Type GENERALINPUT
>  dwType As Long
>  xi(0 To 23) As Byte
> End Type
>
> Private Declare Function SendInput _
>                Lib "user32.dll" _
>               (ByVal nInputs As Long, _
>                pInputs As GENERALINPUT, _
>                ByVal cbSize As Long) As Long
>
> Private Declare Sub CopyMemory _
>                Lib "kernel32" _
>                Alias "RtlMoveMemory" _
>               (pDst As Any, _
>                pSrc As Any, _
>                ByVal ByteLen As Long)
>
> Private Function SendKeysA(ByVal vKey As Integer)
>  Dim GInput(0) As GENERALINPUT
>  Dim KInput As KEYBDINPUT
>  KInput.wVk = vKey
>  GInput(0).dwType = INPUT_KEYBOARD
>  CopyMemory GInput(0).xi(0), KInput, Len(KInput)
>  Call SendInput(1, GInput(0), Len(GInput(0)))
> End Function
>
> Public Sub StripRTB(RTB As RichTextBox, NumOfLines As Long)
>  Dim X As Long
>  Dim TextAsShown As String
>  With RTB
>    .SetFocus
>    .SelStart = 0
>    For X = 1 To NumOfLines - 1
>      SendKeysA vbKeyDown
>      DoEvents
>    Next
>    SendKeysA vbKeyEnd
>    DoEvents
>    .SelLength = Len(.TextRTF)
>    .SelText = ""
>    .SelStart = 0
>  End With
> End Sub
> '*************** END OF CODE ***************
>
> To use this code, simply load your RichTextFile into the RichTextBox and
> then call the StripRTB subroutine passing in the name of the RichTextBox
> and how many lines you want to display in it. For example, kicked off from
> a CommandButton (displaying the first 5 lines of the file loaded into
> RichTextBox1)...
>
> Private Sub Command1_Click()
>  RichTextBox1.LoadFile "c:\Your\Path\And\FileName.rtf"
>  StripRTB RichTextBox1, 5
> End Sub
>
> --
> Rick (MVP - Excel)