1

目前我正在研究一个简单的语法荧光笔,我有几个问题。你能帮帮我吗?

我有一个包含组件类的类库。一切都在 VB.NET 中。它只有一个文件,因此您可以在此处查看https://gist.github.com/2366507。在第 92 行,有 OnTextChanged Sub。我正在考虑将 ProcessAllLines() (如第 128 行)添加到该 Sub 的末尾,并且它起作用了。但是,当我在每次文本更改后向 RichTextBox(我使用的源代码在这里https://gist.github.com/2366526)输入代码时,它正在检查和处理所有行。所以我删除了 OnTextChanged Sub 中的 ProcessAllLines()。

当用户将某些内容粘贴到 SyntaksRichTextBox 时,我正在考虑运行 ProcessAllLines()。但是我不知道该怎么做。我知道它应该是这样的:

If [CTRL Pressed] And [V Pressed] Then
ProcessAllLines()
End If

我还希望它在类库中,而不是在应用程序中(Syntaks Demo)。你能帮帮我吗?谢谢。

拉法尔奇米尔,@RafalChmiel

4

1 回答 1

2

幼稚检测

您可能想到的第一个解决方案是检测WM_PASTE覆盖的消息,WndProc但不幸的是,控件在执行粘贴操作时不会将该消息发送给自身。

检测键盘事件(您必须覆盖该OnKeyDown功能)并检查组合键(CTRL+V 和 SHIFT+INS)是否是粘贴文本的方式,您可以解决此问题。

Protected Sub OnKeyDown(ByVal e As KeyEventArgs)
    Dim ctrlV As Boolean = e.Modifiers = Keys.Control && e.KeyCode = Keys.V
    Dim shiftIns As Boolean = e.Modifiers = Keys.Shift && e.KeyCode = Keys.Insert

    If ctrlV Or shiftIns Then
        ProcessAllLines
    End If
End Sub

它运行良好,但您无法捕捉使用鼠标进行的粘贴操作(右键单击以打开上下文菜单)和通过拖放进行的粘贴操作。如果您不需要它们,您可以使用此解决方案(至少它简单明了)。

更好的检测

假设:当用户在里面输入时,RichTextBox他每次插入一个字符。你怎么能用这个?好吧,当您检测到更大的更改时,您检测到了粘贴操作,因为用户每次不能输入超过一次的字符(由于 Unicode 代理项,这并不总是正确的,但在这种情况下这不是问题)。

它不适用于每个 IME(例如,我没有尝试使用远东语言)和 Unicode 代理,但对于西方语言来说没关系(无论如何,即使它不起作用,您也只需重新处理所有行) . 另请阅读这篇文章这篇文章,了解有关 Unicode 和C# 版本的这个(双)答案的更多详细信息。

Dim _previousLength As Int32 = 0

Protected Sub richTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
   Dim currentLength As Int32 = richTextBox.Text.Length
   If Math.Abs(currentLength - _previousLength) > 1 Then
      ProcessAllLines
   End If

   _previousLength = currentLength
End Sub

完美解决方案

完美的解决方案当然存在(在 Windows 8 或更高版本上),原生富编辑控件发送EN_CLIPFORMAT通知消息。它旨在通知 Rich Edit 控件的父窗口发生了特定剪贴板格式的粘贴。然后,您可以覆盖WndProc其父级以检测WM_NOTIFY此通知的消息。无论如何,这不是几行代码,有关详细信息,请查看 MSDN 上的此链接:http: //msdn.microsoft.com/en-us/library/windows/desktop/hh768385 (v=vs.85).aspx 。

于 2012-04-12T11:34:22.027 回答