近日使用RichTextBox控件的几个问题总结

作者在 2010-09-02 10:25:32 发布以下内容
测试平台:WindowsXP+VB2008Express
1、光标定位问题:
     Richtextbox控件内,一般情况下,SelectionStart属性可以表示出光标的位置。但是如果移动了光标,即使用了[LEFT]和[RIGHT]方向键,这个位置就位不准确。左移后,光标在同样的位置,SelectionStart属性值会比原来的值少1.右移后,光标在同样的位置,SelectionStart属性值同样比实际位置要少1.如果在光标移动后依然使用SelectionStart属性定位,就会出现混乱。
     解决方法:网上有帖子使用API函数定位光标。但感觉比较麻烦。尚无更好建议,希望看的这个问题的高手来指点。
 
2、Tab键宽度问题:
     在记事本等文字编辑软件中,默认Tab键占8个字符宽度。测试了一下,在记事本中,字体大小是固定的,字体大小为12px.在这和情况下,Tab键宽等于8个字符的宽度(数字或者英文字符),等于4个汉字的宽度。
     在程序中,如果更改了RichTextBox字体的大小,如设定字体为42px.这时候,Tab键的宽度没有变化,一个Tab键的宽度不能刚好等于字体宽的整倍数,更重要的问题是一个Tab键宽仅能容下3、4个西方字符,这个的情况下,很难对每组字符(大于3~4个)进行对齐。比较好的解决办法就是重新设置Tab的键宽。
     如果想确定新设定的Tab键宽能容纳下几个字符,就要按字符宽度计算Tab键宽。因为我不太明白字体大小和字体宽度之间有关系,同时也有不等宽的字,如R和i,所以可以自己测试下,看多少像素的宽度能够满足需要。举例来说,在窗口运行时,设定了RichTextBox控件的宽度为1000px,同时这个宽度下在当前的字体大小设定下能够容纳下5组自己可以输入的字符,当然还要确定有空余。比如说我们希望在这个宽度下能够Tab键5次,那么可以设定每个Tab键宽200个px.设定方法如下:
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        '设置制表符新的长度,以像素为单位
        RichTextBox1.SelectionTabs = New Int32() {200, 400, 600, 800, 1000}
      
End Sub

网上有人说用空格代替Tab,我认为这种方法也不太合适,使用空格的话,绝对定位变成了相对定位,如果相邻两行对应的每组字符不一样宽,用空格也无法对齐,除非动态改变空格的数量。

3、文件拖放问题

    很多控件都有AllowDrog属性,RichTextBox控件在VB6里面可以通过OLEDrogMode来设定,VB.NET里面,这个可以设定的属性只能在代码里用,但是用了也不行。必须通过API函数了来实现文件拖放了。代码如下:
Implements IMessageFilter

    ' API申明               ’用于实现文件拖放

    Const WM_DROPFILES = &H233  '拖放文件消息

    <DllImport("shell32.dll")> Public Shared Sub DragFinish(ByVal hDrop As Integer)

    End Sub

    <DllImport("shell32.dll")> Public Shared Sub DragAcceptFiles(ByVal hwnd As Integer, ByVal fAccept As Boolean)

    End Sub

    <DllImport("shell32.dll")> Public Shared Function DragQueryFile(ByVal HDROP As Integer, ByVal UINT As Integer, ByVal lpStr As System.Text.StringBuilder, ByVal ch As Integer) As Integer

    End Function

    '文件拖放过程
    Overridable Function PreFilterMessage(ByRef m As System.Windows.Forms.Message) As Boolean Implements IMessageFilter.PreFilterMessage
        Dim h1, h2 As Label
        On Error GoTo h1
        Dim i As Int16
        Dim sb As New System.Text.StringBuilder(256)
        DragQueryFile(m.WParam.ToInt32, i, sb, 256)
        If sb.ToString <> "" Then      '如果存在文件拖放操作
            If IsChanged Then
                Select Case MsgBox("文件尚未保存,是否保存?", MsgBoxStyle.YesNoCancel, "退出系统")
                    Case MsgBoxResult.Yes       '选择是,保存后加载
                        RichTextBox1.SaveFile(FilePath, RichTextBoxStreamType.PlainText)
                        GoTo h2
                    Case MsgBoxResult.No        '选择否,直接加载
                        GoTo h2
                    Case MsgBoxResult.Cancel    '选择取消,不保存也不退出程序
                        DragFinish(m.WParam.ToInt32) '终止当前文件拖放过程
                        Exit Function
                End Select
            Else            '文件未被修改的状态,直接退出
                GoTo h2
            End If
        Else
            Exit Function
        End If

h2:
        FilePath = sb.ToString  '将文件路径赋给变量 FilePath
        RichTextBox1.Text = ""
        RichTextBox1.LoadFile(FilePath, RichTextBoxStreamType.PlainText)        '加载文件
        Me.Text = "清风制作" & "  " & FilePath
        DragFinish(m.WParam.ToInt32) '终止当前文件拖放过程
        IsChanged = False
        rtbColor(RichTextBox1)      '整体加色

        Exit Function
h1:     MsgBox(Err.Description)
    End Function
另外要在From_Load事件里设定拖放。
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        '允许文件拖放
        Application.AddMessageFilter(Me)
        DragAcceptFiles(Me.RichTextBox1.Handle.ToInt32, True)
End Sub
VB.NET技术学习 | 阅读 6020 次
文章评论,共0条
游客请输入验证码
浏览95098次
最新评论