So I've got some text. It's in Rich Text format - some lines are bold, etc. It's multi-line text too. I want to load the file, scroll to the bottom of the file then determine which is the top line displaying in the text box. Well technically I don't need to do the scrolling part. But let's assume I have already done that. Sort of a "what's displaying in my text box" property. Is there any way to find out what's displaying on the top of my text box?
Many other than me are pretty proficient with the RTB. But to head them off, let me ask a question for clarity.
Are you asking to get the displayed top line of the RTB after the scrollbar is all the way to the bottom? If so, what are you looking for? The text? The character index? Something else? What if it happens to be blank line?
If word wrapping is in play, may want to mention that too.
Insomnia is just a byproduct of, "It can't be done"
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const EM_GETFIRSTVISIBLELINE = &HCE
And to get the position of the first visible character:
Code:
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const EM_GETFIRSTVISIBLELINE = &HCE
Private Const EM_LINEINDEX = &HBB
That's some next level genius stuff there Eduardo! I'm actually using an old control called Roboprint. It will try to print the entire contents of the RTB regardless of what's showing. It starts at the top of the text and prints until it runs out of room.
My customer is adding to the bottom of a text file and only wants to print the most recent entry. I'm going to load the entire contend of the document to the box, somehow scroll to the to the bottom (if I can figure out how) then delete the top portion of the box just leaving the bottom portion in the box. Finally I'm going to print the box.
The box is 7 rows tall and 80 characters wide so it could theoretically display 560 characters. But the entire project is difficult because as you know, the RTB might be comprised of 20 CRLF characters or it might be densely packed text. There's no way to know what the customer has typed so I can't just take the bottom 560 characters.
Anyway you have given me a really solid lead. Now I just need to play around with it and see what works. Thanks!
Option Explicit
'
'Swoop to or export the last "page" of data.
'
'Requires a reference to "tom" (RichEdit Text Object Model type library).
'
Private Const WM_USER = &H400&
Private Const EM_GETOLEINTERFACE = WM_USER + 60
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private TextDocument1 As tom.ITextDocument
Private TextDocument2 As tom.ITextDocument
Private ExportFormat As RichTextLib.LoadSaveConstants
Private Sub Form_Load()
Dim IUnknown As IUnknown
SendMessage RichTextBox1.hWnd, EM_GETOLEINTERFACE, 0, VarPtr(IUnknown)
Set TextDocument1 = IUnknown
SendMessage RichTextBox2.hWnd, EM_GETOLEINTERFACE, 0, VarPtr(IUnknown)
Set TextDocument2 = IUnknown
'Clear out RichTextBox2:
With TextDocument2.Selection
.Expand tomStory
.Delete tomCharacter, 0
End With
End Sub
Private Sub Form_Resize()
If WindowState <> vbMinimized Then
RichTextBox1.Move 0, 0, ScaleWidth, ScaleHeight
End If
End Sub
Private Sub mnuActionExportlastpage_Click()
Dim Selection2 As tom.ITextSelection
Set Selection2 = TextDocument2.Selection
With TextDocument1
'To be reliably repeatable, move up a bit first in case we're already at the end:
.Selection.Move tomParagraph, -1
'Ok, now we can move to end:
.Selection.Move tomStory, 1
With .RangeFromPoint(0, 0) 'Get an ITextRange at top of RichTextBox view.
.Expand tomWindow 'Expand this to the entire displayed contents.
'These next two calls are dealing with the undeletable final CR that every
'RTB document has:
.MoveStart tomLine, -1 'Match the Selection to what shows after
'mnuActionMovelastpage_Click.
.ScrollIntoView tomEnd 'Make it look the same on-screen as
'mnuActionMovelastpage_Click does.
If ExportFormat = rtfRTF Then
On Error Resume Next
Kill "Exported.rtf"
On Error GoTo 0
Selection2.FormattedText = .FormattedText
RichTextBox2.SaveFile "Exported.rtf", ExportFormat
Else
On Error Resume Next
Kill "Exported.txt"
On Error GoTo 0
Selection2.Text = .Text
RichTextBox2.SaveFile "Exported.txt", ExportFormat
End If
End With
End With
'Clean up by clearing the entire document:
Selection2.Expand tomStory
Selection2.Delete tomCharacter, 0
End Sub
Private Sub mnuActionGohome_Click()
With TextDocument1.Selection
.Move tomStory, -1
.ScrollIntoView tomStart
End With
End Sub
Private Sub mnuActionMovelastpage_Click()
With TextDocument1.Selection
.Move tomParagraph, -1
.Move tomStory, 1
.ScrollIntoView tomEnd
End With
End Sub
Private Sub mnuLoadSample_Click(Index As Integer)
Select Case Index
Case 0
RichTextBox1.LoadFile "Sample1.rtf", rtfRTF
ExportFormat = rtfRTF
Case 1
RichTextBox1.LoadFile "Sample2.txt", rtfText
ExportFormat = rtfText
End Select
mnuAction.Enabled = True
End Sub