如何计算一个文本框中文本得行数?我现在想固定一个Richtextbox得大小,然后往其中载入文本,当文本内容一次显示不下得时候,换屏显示。可以做吗?

解决方案 »

  1.   

    你的文本多大啊?
    应该不至于载不下。Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hwnd As Long, _
       ByVal wMsg As Long, _
       ByVal wParam As Long, _
       lParam As Any) As LongPublic Const EM_GETFIRSTVISIBLELINE = &HCEPublic Function TopLineIndex(txtBox As TextBox) As Long
       TopLineIndex = SendMessage(txtBox.hWnd, EM_GETFIRSTVISIBLELINE, 0&, 0&)
    End Function
       富文本框有一个方法GetLineFromChar能够更具给定的字符序号来判断它所在的行序号。而标准的文本框却没有这个功能。我们已可以通过上面的方法来解决这个问题。不过这一次,你需要用到的是EM_LINEFROMCHAR消息:Public Const EM_LINEFROMCHAR = &HC9
       EM_LINEFROMCHAR消息把要传递的字符序号放在参数wParam中:
    Public Function GetLineFromChar(txtBox As TextBox, CharPos As Long) As Long
       GetLineFromChar = SendMessage( _txtBox.hWnd, EM_LINEFROMCHAR, CharPos, 0&)
    End Function
       因而,如果你想知道光标所在行的具体的行序号,用上面的这个函数就可以轻松的实现了.   Dim lngLineIndex As Long
       lngLineIndex = GetLineFromChar(Text1, Text1.SelStart)
       MsgBox "You are on line number " & lngLineIndex + 1   反过来,你也可以查到每一行的第一个字符在全文中的字符序号,EM_LINEINDEX消息能帮助你做到这一点:
    Public Const EM_LINEINDEX = &HBB
    Public Function GetCharFromLine(txtBox As TextBox, LineIndex As Long) As Long
        GetCharFromLine = SendMessage(txtBox.hWnd, EM_LINEINDEX, LineIndex, 0&)
    End Function   想知道文本框里到底有多少行?简单:用EM_GETLINECOUNT消息就可以轻松搞定。同样的,因为这个消息不带任何的参数,我们还是把参数wParam和lParam都置为0:
    Public Const EM_GETLINECOUNT = &HBA
    Public Function LineCount(txtBox As TextBox) As Long
       LineCount = SendMessage(TxtBox.hWnd, EM_GETLINECOUNT, 0&, 0&)
    End Function OK,确实很简单吧,我们再来看看另外一个消息:EM_LINELENGTH。通过制定在参数wParam的一个字符序数,返回该字符所在行的长度:
    Public Const EM_LINELENGTH = &HC1
    Public Function LineLen(txtBox As TextBox, CharPos As Long) As Long
       LineLen = SendMessage(TxtBox.hWnd, EM_LINELENGTH, CharPos, 0&)
    End Function   很简单是吗?或者你会说,这也太简单了。OK,我们来看看一些稍微复杂一点的东西。下面介绍的一个函数可以帮你从一个文本框中把一指定行的内容提取出来。这里需要用的消息是EM_GETLINE,行序号放在参数wParam中,在参数lParam中指定一个字符缓冲区用来接受行的内容。
       虽然听起来有点简单,实际上问题的麻烦在于在消息中需要为字符缓冲区指定一个最大字符数,把它放在指定缓冲区的前16位中。并且在字符缓冲区中,字符串的形式是不能够直接被VB所能识别的。因为VB所识别的字符串事Unicode编码的,而一般的API函数所返回的都是C语言中的字符数组。这也是在VB中调用API函数会经常碰到的问题。解决的方法是:我们需要使用中间的一个字节数组,然后把这个字节数组转换成一个VB所能识别的字符串。
    Public Const EM_GETLINE = &HC4
    Public Function GetLine(txtBox As TextBox, LineIndex As Long) As String
       Dim bBuffer( ) As Byte '字符数组
       Dim lngLength As Long '行最大长度
       Dim sRetVal As String '要返回的字符串
       '检查行号是否合法
       If LineIndex >= LineCount(txtBox) 
       '调用上面提到的LineCount函数
       Exit Function '错误退出
       End If
       '得到行的长度
       lngLength = LineLen(txtBox, GetCharFromLine(txtBox, LineIndex))
       '检查此行是否有任何的字符
       If lngLength < 1 Then
       Exit Function
       End If
       '重新申明字符数组
       ReDim bBuffer(lngLength)
       '把字符串长度保存在缓冲区的前两个字节中
       bBuffer(0) = lngLength And 255
       bBuffer(1) = lngLength And 256
       '发送消息
       SendMessage txtBox.hWnd, EM_GETLINE, LineIndex, bBuffer(0)
       '最后进行编码转换,并输出字符串
       sRetVal = Left$(StrConv(bBuffer, vbUnicode), lngLength)
       GetLine = sRetVal
    End Function   我们还可以做很多类似的事情来扩展VB中标准控件的功能,这儿就不一一列举了。重要的是,你应该知道,VB表面上确实是很简单,很多东西要靠自己不停的发掘才能更好的利用它。下面给出一些其它的消息以供参考:   EM_CANUNDO:判断是否能够对最近一次的修改进行UNDO操作。
         EM_UNDO:恢复最近一次的修改。
       EM_GETMODIFY:判断文本框中的内容是否被更改过了。
       EM_SETMODIFY:手工设置修改标志,当文本框的内容被修改过了之后,这个标志被自动的置为ture。