下面的代码和junwhj(junwhj.myrice.com)的有同样的问题
Option Explicit
Private Const EM_GETFIRSTVISIBLELINE = &HCE
Private Const EM_GETRECT = &HB2
Private Const EM_CHARFROMPOS = &HD7
Private Const WM_GETFONT = &H31
Private Const EM_GETLINE = &HC4
Private Const EM_GETLINECOUNT = &HBA
Private Const EM_FMTLINES = &HC8
Private Const EM_LINEINDEX = &HBB
Private Const EM_LINELENGTH = &HC1
Private Const EM_LINEFROMCHAR = &HC9
Private Declare Sub RtlMoveMemory Lib "KERNEL32" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA" (ByVal hDc As Long, lpMetrics As TEXTMETRIC) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDc As Long, ByVal hObject As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDc As Long) As Long
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type TEXTMETRIC
tmHeight As Long
tmAscent As Long
tmDescent As Long
tmInternalLeading As Long
tmExternalLeading As Long
tmAveCharWidth As Long
tmMaxCharWidth As Long
tmWeight As Long
tmOverhang As Long
tmDigitizedAspectX As Long
tmDigitizedAspectY As Long
tmFirstChar As Byte
tmLastChar As Byte
tmDefaultChar As Byte
tmBreakChar As Byte
tmItalic As Byte
tmUnderlined As Byte
tmStruckOut As Byte
tmPitchAndFamily As Byte
tmCharSet As Byte
End Type
Private Type TextOffset
FirstLine As Long
FirstCharOffset As Long
LastLine As Long
LastCharOffset As Long
End Type
Private Function getvisiblelines(mTextbox As TextBox) As Long
Dim Rc As RECT
#If Win32 Then
Dim hDc As Long
Dim lFont As Long
Dim oldFont As Long
Dim dl As Long
#Else
Dim hDc As Integer
Dim lFont As Integer
Dim oldFont As Integer
Dim dl As Integer
#End If
Dim Tm As TEXTMETRIC
Dim lc As Long
lc = SendMessage(mTextbox.hWnd, EM_GETRECT, 0, Rc)
lFont = SendMessage(mTextbox.hWnd, WM_GETFONT, 0, ByVal 0&)
hDc = GetDC(mTextbox.hWnd)
If lFont <> 0 Then
oldFont = SelectObject(hDc, lFont)
End If
dl = GetTextMetrics(hDc, Tm)
If lFont <> 0 Then
oldFont = SelectObject(hDc, lFont)
End If
getvisiblelines = (Rc.Bottom - Rc.Top) / Tm.tmHeight
dl = ReleaseDC(mTextbox.hWnd, hDc)
End Function
Private Sub Command4_Click()
Dim MYTEXTOFF As TextOffset
MYTEXTOFF = getTextOffset(Text1)
Debug.Print "可见的第一行的行号:"; MYTEXTOFF.FirstLine
Debug.Print "可见的第一个字的位置:"; MYTEXTOFF.FirstCharOffset
Debug.Print "可见的最后一行的行号:"; MYTEXTOFF.LastLine
Debug.Print "可见的最后一个字的位置:"; MYTEXTOFF.LastCharOffset
End Sub
Private Sub Form_Load()
Dim Str As String
Dim I As Integer
Str = "Line0"
For I = 1 To 99
Str = Str & vbCrLf & "Line" & I
Next I
Text1.Text = Str
End Sub
Private Function getTextOffset(mTextbox As TextBox) As TextOffset
Dim mFirstLine As Long
Dim mFirstCharOffset As Long
Dim mLastLine As Long
Dim mLastCharOffset As Long
mFirstLine = SendMessage(mTextbox.hWnd, EM_GETFIRSTVISIBLELINE, 0, ByVal 0&)
getTextOffset.FirstLine = mFirstLine
mFirstCharOffset = SendMessage(mTextbox.hWnd, EM_LINEINDEX, mFirstLine, ByVal 0&)
getTextOffset.FirstCharOffset = mFirstCharOffset
Dim LineCount As Long
LineCount = SendMessage(mTextbox.hWnd, EM_GETLINECOUNT, 0, ByVal 0&)
Dim VisLine As Long
VisLine = getvisiblelines(mTextbox)
If mFirstLine + VisLine - 1 >= LineCount Then
mLastLine = LineCount
Else
mLastLine = mFirstLine + VisLine - 1
End If
getTextOffset.LastLine = mLastLine
mLastCharOffset = SendMessage(mTextbox.hWnd, EM_LINEINDEX, mLastLine, ByVal 0&)
Dim LLength As Long
LLength = SendMessage(mTextbox.hWnd, EM_LINELENGTH, mLastLine, ByVal 0&)
mLastCharOffset = mLastCharOffset + LLength
getTextOffset.LastCharOffset = mLastCharOffset
End Function
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function GetScrollInfo Lib "user32" _
(ByVal hWnd As Long, _
ByVal n As Long, _
lpScrollInfo As SCROLLINFO) As Long
Private Declare Sub CopyMemory Lib "kernel32" _
Alias "RtlMoveMemory" _
(Destination As Any, _
Source As Any, _
ByVal Length As Long)
Private Type SCROLLINFO
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type
Private Sub Form_Load()
Dim Str As String
Dim i As Integer
Str = "第0行"
For i = 1 To 99
Str = Str & vbCrLf & "第" & i & "行"
Next i
Text1.Text = Str
End Sub
Private Sub Command1_Click()
Dim LineNo1 As Long, LineNo2 As Long
Dim CharIndex1 As Long, CharIndex2 As Long
Dim Length As Long
Dim SI As SCROLLINFO
Dim arr() As Byte, src() As Byte
Private Declare Function SendMessage Lib "user32" _
Alias "SendMessageA" _
(ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Declare Function GetScrollInfo Lib "user32" _
(ByVal hWnd As Long, _
ByVal n As Long, _
lpScrollInfo As SCROLLINFO) As Long
Private Type SCROLLINFO
cbSize As Long
fMask As Long
nMin As Long
nMax As Long
nPage As Long
nPos As Long
nTrackPos As Long
End Type
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Const EM_GETFIRSTVISIBLELINE = &HCE
Public Property Get GetFirstLineVisible() As Long
GetFirstLineVisible = SendMessage(rtfMain.hwnd, EM_GETFIRSTVISIBLELINE, 0&, 0&)
End Property