检测富文本框内是否发生粘贴事件

时间:2011-04-11 07:32:14

标签: c# .net winforms richtextbox

有没有办法可以找出富文本框中是否发生剪贴板粘贴事件?这个事件将用于粘贴文本块的某些内容。

感谢

这是我的代码

 protected override void WndProc(ref System.Windows.Forms.Message m)
    {
        if (m.Msg == WM_PASTE)
        {
            OnPasteOccurred();
            MessageBox.Show("Pas");
        }
        if (m.Msg == 0x000F)
        {
            if (PaintControl)
            {
                base.WndProc(ref m);
            }
            else
            {
                m.Result = IntPtr.Zero;
            }
        }
        else
        {
            base.WndProc(ref m);
        }
    }

修改

我希望根据粘贴事件做一些语法突出显示或缩进,这个特定的code editor似乎非常有效。我不知道它是怎么做的。在这个特定方向需要帮助。我很确定必须有一些原生的Win32代码或类似的东西可以截取。我试过追踪键,鼠标事件并不是很漂亮。

2 个答案:

答案 0 :(得分:17)

RichTextBox中检测粘贴操作有点棘手。

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

Naïve检测

要检测键盘事件可能有效(您必须覆盖WndProc功能)然后检查是否有组合键( CTRL + V SHIFT + INS )。像这样:

OnKeyDown

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

更好的检测

假设:当用户在protected override OnKeyDown(KeyEventArgs e) { bool ctrlV = e.Modifiers == Keys.Control && e.KeyCode == Keys.V; bool shiftIns = e.Modifiers == Keys.Shift && e.KeyCode == Keys.Insert; if (ctrlV || shiftIns) DoSomething(); } 内输入时,每次插入一个字符。你怎么用这个?好吧,当你检测到一个更大的变化时,你检测到一个粘贴操作,因为用户每次不能输入多个字符(好吧,你可以说因为Unicode替代品并不总是这样)。另请参阅VB.NET versionmore details about Unicode内容。

RichTextBox

请注意,您不能(因为IME的工作方式不同)使用private int _previousLength = 0; private void richTextBox_TextChanged(object sender, EventArgs e) { int currentLength = richTextBox.Text.Length; if (Math.Abs(currentLength - _previousLength) > 1) ProcessAllLines(); _previousLength = currentLength; } (或类似)。这种方法仅适用于西方语言,但它存在Unicode内容问题(例如,当用户键入单个字符时,OnKeyDown属性可能会增加两个String.Length。另请参阅this post有关这方面的更多详细信息(即使是 - 在这种情况下 - 你也不关心它,这是一个强烈建议的阅读)。在那篇文章中你还会找到一个更好的算法来确定字符串长度的代码。简而言之,你必须更换:

Char

有了这个:

   int currentLength = richTextBox.Text.Length;

经过所有这些努力,您可能会意识到......用户甚至可以粘贴单个字符,但可能无法检测到。你是对的,这就是为什么这是一个更好的检测而不是完美的解决方案

完美的解决方案

当然,完美的解决方案(如果您在Windows 8上运行)存在,本机富编辑控件会发送 int currentLength = StringInfo.GetTextElementEnumerator(richTextBox.Text) .Cast<string>() .Count(); 通知消息。它旨在通知富编辑控件的父窗口,使用特定的剪贴板格式粘贴。然后,您可以覆盖其父级的EN_CLIPFORMAT以检测此通知的WndProc消息。无论如何,这不是几行代码,请查看MSDN article以获取详细信息。

答案 1 :(得分:-1)

从.Net 3.0开始,有一种检测粘贴事件的内置方法:

DataObject.AddPastingHandler(this, OnPaste);

只需在构造函数中调用此方法即可。例如,如果您想要自己处理粘贴事件,就像用户手动输入文本一样,您可以使用

private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
    if (e.DataObject.GetDataPresent(typeof(string)))
    {
        var text = (string)e.DataObject.GetData(typeof(string));
        var composition = new TextComposition(InputManager.Current, this, text);
        TextCompositionManager.StartComposition(composition);
    }

    e.CancelCommand();
}