【问题标题】:How to detect multiline paste in RichTextBox如何检测 RichTextBox 中的多行粘贴
【发布时间】:2015-02-18 18:28:06
【问题描述】:

目前我正在开发一个简单的语法荧光笔,但遇到了几个问题。你能帮帮我吗?

我有一个类库,里面有一个组件类。一切都在 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

【问题讨论】:

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


    【解决方案1】:

    幼稚检测

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

    检测键盘事件(您必须覆盖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 代理,但对于西方语言来说没关系(无论如何,即使它不起作用,您也只需重新处理所有行)。另请阅读 this postthis post 了解有关 Unicode 的更多详细信息,以及 C# 版本的 this(双)答案。

    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

    【讨论】:

    • 您好,非常感谢您的回答。我正在寻找类似你给我的第一个代码 sn-p 的东西。我将它转换为 VB:gist.github.com/2367050 并将其粘贴在 OnTextChanged Sub 下,但它似乎不起作用。我做错了吗?附言我也尝试了第二种解决方案(似乎也没有工作)。谢谢你的时间。但是有用的答案!
    • @RafalChmiel 欢迎您,但这不是一个很好的解决方案,它不会检测用户是否会使用上下文菜单或通过拖放粘贴一些文本!第二种解决方案要好一些。
    • 我(还)不太关心上下文菜单或拖放。无论如何它都没有启用(上下文菜单) - 不确定你是否可以拖放。
    • @RafalChmiel 我猜这个代码可能会让很多人感到恐惧,但我们会保守秘密! ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多