• 语法高亮组件(BETA)


    感觉上用C#来写这种扩充组件确实比较麻烦。一个调用系统级的API需要用DllImport来封装,比较麻烦。特别是用SendMessage时,一大堆的message id等常量需要查资料。二个就是.net组件封装得太厉害。封装厉害倒不是件什么坏事,但是总得考虑用户重写某些接口的可能,应该将接口多用virtual修饰允许重写吧?
      好,牢骚到此结束,现在言归正传。从Richtextbox继承的语法高亮控件已经很多。原理基本一样。有些控件实现了显示行号的功能(本控件也是),可以算是一个亮点吧。下面从几个方面来讲述。

    1. 语法高亮
      当用户插入一个字符的时候,有些控件的实现会将整个Text扫描一遍,对各个关键字进行处理。这个包含了很多重复的工作,效率有点低。既然内容是控件自身管理,那么就可以断定:除了插入点临近的地方高亮模式被破坏以外,其它的地方都是不需要改变的。因此,只需要对插入点向左、向右(向前和向后太容易混淆弄糊涂)检查相邻的第一个Word是不是关键字就可以了。
    Code: ProcessHighlight

    将关键字高亮也挺简单,就是先选中一段文字,然后设置SelectionColor=Color.Blue。
    Code:DoHighlightWord

      但是这也带来了新的问题,就是必须处理粘贴的文本。本控件在这个版本就没有加入对它的实现。打算在以后的版本再做吧。

    2. 显示行号
      这个问题要完美地解决还真不简单。我在写代码的时候,想了很多的办法,结果还是没有很好地解决这个问题。
      我的做法是,在主TextBox中嵌入一个独立的靠左的TextBox显示行号。为了使TextBox不遮住内容,在插入字符时,设置TextBox的SelectionIndent为一个固定值。当然普通的Textbox是不能用的,需要重写。重写的主要目的是:(1)去掉textBox的光标,让它不像一个可输入的控件。(2)在右边画一条竖的虚线。(3)加入显示行号的逻辑。
      去掉textBox的光标的做法是,textBox获得Focus的时候,立即让它失去Focus。代码如下:
    void RowNumTextBox_GotFocus(object sender, EventArgs e)
    {
        Native.SendMessage(
    this.Handle, WinMsgs.WM_KILLFOCUS, IntPtr.Zero, IntPtr.Zero);
    }
      
      现在的情况是,TextBox显示内容,另一个TextBox显示行号。但在滚动内容时,又想让行号跟着滚动。这就有了同步的问题。要说.net封装得太厉害,想要实现某些功能却又不能。比如监听TextBox的滚动条的滚动位置。这个事件没有办法监听,只能从引起滚动条变化的因素入手。在之前,先说明,让TextBox内容自动滚动,可以对某个TextBox发送EM_LINESCROLL事件。看代码:
    Code:ScrollRowNumberTextBox

    然后重写WndProc方法,当以下事件发生时,调用ScrollRowNumberTextBox滚动行号方法。
    WM_VSCROLL
    EM_SCROLL
    EM_LINESCROLL
    WM_MOUSEWHEEL
    消息的相关意思可以查阅MSDN。此外,当内容有改变时,也需要调用ScrollRowNumberTextBox并更新行号。
    Code: WndProc


    3. 代码中有许多直接用SendM种essage来操作控件。这原生的Windows API真是异常地生猛。如果要开发出一个可用的代码编辑器来,还不如用WIN32编程来得直接。最后看看截图。


    下载示例:/Files/qkhh/Editor.zip
    下载源码:/Files/qkhh/Editor-Soruce.zip
    源码请用VS2008(SP1)打开。
  • 相关阅读:
    记录我发现的第一个关于 Google 的 Bug
    iOS 中的 Delayed Transition
    Appstore|IPA
    地图|定位
    开发者账号
    App跳转
    国际化
    短信|彩信
    闪光灯
    Cornerstone|SVN
  • 原文地址:https://www.cnblogs.com/qkhh/p/1560768.html
Copyright © 2020-2023  润新知