I am wondering if any one can help me with this. I am working an advance text editor and i want it to to line number like this when it is word wraped
1
-
-
2
-
3
4
5
-
-
what the '-' is for is when the line wraps i dont want it to number it with the following number i want it ot be a '-' and i dont want it to show the number until the line is actually anew line. my code that i have words when your on line one but once you start scrolling it get off set beacause i am using an api call to get the first visible line. below is my sub that i use to write the line numbers with.
Code:
Private Sub WriteLineNumbers()
Dim y As Long
Dim x As Long
Dim lStart As Long
Dim FontHeight As Long
Dim lFinish As Long
Dim lCurrent As Long
lStart = SendMessage(RichTxtBox.hwnd, EM_GETFIRSTVISIBLELINE, 0, 0) + 1
lCurrent = CurrentLine <-- calls an api function
y = 1
With picLines
.Cls
.Font = RichTxtBox.Font
FontHeight = .textHeight("12345")
.CurrentY = Screen.TwipsPerPixelY * 1
'.CurrentY = .CurrentY + 15
lFinish = (RichTxtBox.Height / FontHeight) + lStart
If lFinish > LineCount Then lFinish = LineCount ' LineCount is the api call in a function
y = lStart
' loop from the first visible line in the rtb to the end of the page
For x = lStart To lFinish
If x = lCurrent Then
.FontBold = True
Else
.FontBold = False
End If
' check for wordwrap
If WordWrap Then
If GetLine(x) Or x = 1 Then
picLines.Print Right$(" " & y, 5)
y = y + 1
Else
picLines.Print Right$(" -", 5)
End If
Else
picLines.Print Right$(" " & x, 5)
End If
Next x
End With
End Sub
RichTxtBox is a richtext box and picLines is a Picture Box.
If you think the problem is with the api call, why don't you post that function?
Easiest thing might be to post your project (or a mini project with this functionality), so we can see better what the idea is and what goes wrong.
If you mean the line gets cropped when you scroll due to the RTB smooth scrolling the line you need to subclass the RTB and capture the WM_VScroll message. Check if the entire line is visible by calling the GetScrollPos API and divide the result by i think the textheight and check the result a round number, if not round it using Int() to the next whole number and pass it back to the RTB for processing..
If you think the problem is with the api call, why don't you post that function?
Easiest thing might be to post your project (or a mini project with this functionality), so we can see better what the idea is and what goes wrong.
Here is the Project. Just run the group. Type in some lines of code and then all you have to do is scroll down and you'll see the problem..
attached is a screen shot.
As you said, the problem is how you're counting the lines. In CurrentLine (and probably also LineCount), you should do that differently when WordWrap is on. One way:
- Get the current line like you do now
- get the first character of that line with SendMessage and EM_LINEINDEX
- count the number of vbCr from the start to that point
That doesn't make much sense, MikeJ. The problem was printing the right line numbers on the picturebox, not what happens in the textbox when you press Enter.
As you said, the problem is how you're counting the lines. In CurrentLine (and probably also LineCount), you should do that differently when WordWrap is on. One way:
- Get the current line like you do now
- get the first character of that line with SendMessage and EM_LINEINDEX
- count the number of vbCr from the start to that point
Hope that helps.
Edit: corrected mistake
ok that makes sense. I'll try that tonight and i'll get back to you about how it works.
Quote:Originally Posted by Deadalus As you said, the problem is how you're counting the lines. In CurrentLine (and probably also LineCount), you should do that differently when WordWrap is on. One way:
- Get the current line like you do now
- get the first character of that line with SendMessage and EM_LINEINDEX
- count the number of vbCr from the start to that point
Hope that helps.
Edit: corrected mistake
Deadalus
I am having problems getting this to work. Can you please give me some more pointers. I'm not sure how i'm going to get this going. here is what i though of right now.
1. Get the FirstVisibleLine
2. Find some way to get the number of line returns from line 1 to the first visible line.
3. check the line right above the first visible line for a return. if no return exists place a '-' and then just keep on going down the line from there.
I am just not sure how to do step 2. If you could please provide some pointers it would be great. Thanks!
Edit
here is what i have done so far. it seems to work good but it gets off count when i start scrolling. if you have any ideas. they will be appricated.
Code:
Private Sub WriteLineNumbers()
Dim y As Long
Dim x As Long
Dim lStart As Long
Dim FontHeight As Long
Dim lFinish As Long
Dim lCurrent As Long, _
twiX As Long, _
twiY As Long
twiX = Screen.TwipsPerPixelX
twiY = Screen.TwipsPerPixelY
lStart = FirstVisibleLine
lCurrent = CurrentLine
With picLineNumbers
.Move 2 * twiX, 2 * twiY, picLineNumbers.TextWidth("12345") + twiX, ZeroIfNegative(ScaleHeight - VScrollBarHeight)
.Cls
.Font = rtbText.Font
.FontSize = rtbText.Font.Size
FontHeight = .TextHeight("12345")
.CurrentY = Screen.TwipsPerPixelY * 2
'.CurrentY = .CurrentY + 15
lFinish = (rtbText.Height / FontHeight) + lStart
If lFinish > LineCount Then lFinish = LineCount
y = CountLineReturns ' changed this line
' loop from the first visible line in the rtb to the end of the page
For x = lStart To lFinish
If x = lCurrent Then
.FontBold = True
Else
.FontBold = False
End If
' check for wordwrap
If WordWrap Then
If GetLine(x) Or x = 1 Then
picLineNumbers.Print Right$(" " & y, 5)
y = y + 1
Else
picLineNumbers.Print Right$(" -", 5)
End If
Else
picLineNumbers.Print Right$(" " & x, 5)
End If
picLineNumbers.Refresh
Next x
End With
End Sub
' added these two functions
Private Function CountLineReturns() As Integer
Dim FVL As Long
Dim x, y As Integer
y = 0
FVL = FirstVisibleLine
For x = 0 To FVL
If GetLineNoMinus(x) Then
y = y + 1
End If
Next x
CountLineReturns = y
End Function
Private Function GetLineNoMinus(ByVal lineNum As Integer) As Boolean
Dim sBuffer As String
Dim retVal
Dim retVal1
sBuffer = String(255, Chr(32))
retVal = SendMessageStr(rtbText.hWnd, EM_GETLINE, lineNum, ByVal sBuffer)
retVal1 = Left(sBuffer, retVal)
If Right(retVal1, 1) = vbLf Or Right(retVal1, 1) = vbCrLf Or Right(retVal1, 1) = vbCr Then
GetLineNoMinus = True
Else
GetLineNoMinus = False
End If
End Function
SiD
Last edited by sidhighwind; 03-27-2003 at 05:33 PM.
I'm too tired to really look at your code now, but this should give you the "return line" if you pass it the line number, meaning in this context that it gives the line number that you want to be in the left margin.
Code:
Private Function GetReturnLine(rtb As RichTextBox, Line As Long) As Long
Dim lpos As Long
Dim s As String
Dim i As Long
Dim count As Long
lpos = SendMessage(rtb.hwnd, EM_LINEINDEX, Line, 0)
s = rtb.Text
For i = 1 To lpos
If Mid$(s, i, 1) = vbCr Then
count = count + 1
End If
Next i
GetReturnLine = count + 1
End Function
Edit: The declaration for the constant is
Const EM_LINEINDEX = &HBB
Word, PowerPoint, Outlook, and Other Office Products
2
04-22-2002 08:07 PM
Advertisement:
Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET. subscribe