如何在RichTextBox中检测多行粘贴

时间:2012-04-12 11:07:36

标签: .net vb.net richtextbox syntax-highlighting paste

目前我正在制作一个简单的语法荧光笔,我有几个问题。你能救我一下吗?

我有一个包含组件类的类库。一切都在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)。你能帮帮我吗?感谢。

Rafal Chmiel,@ RafalChmiel

1 个答案:

答案 0 :(得分:2)

Naïve检测

您可能考虑的第一个解决方案是检测覆盖WM_PASTE的{​​{1}}消息,但遗憾的是,控件在执行粘贴操作时不会将该消息发送给自身。

检测键盘事件(您必须覆盖WndProc功能)并检查键组合(CTRL + V和SHIFT + INS)是否是要粘贴文本的键组合。

OnKeyDown

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

更好的检测

假设:当用户在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 内输入时,每次插入一个字符。你怎么用这个?好吧,当您检测到更大的更改时,您检测到粘贴操作,因为用户每次不能输入多于一次的字符(由于Unicode代理,这并不总是正确的,但在这种情况下这不是问题)。

它不能很好地与每个IME(我没有尝试远东语言,例如)和Unicode代理,但对于西方语言,它是可以的(无论如何,即使它不起作用,你只需重新处理所有线路)。另请阅读this postthis post,了解有关Unicode的更多详细信息以及针对C#版本的this(双胞胎)答案。

RichTextBox

完美的解决方案

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