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

C# 检测富文本框内是否发生粘贴事件,c#,.net,winforms,richtextbox,C#,.net,Winforms,Richtextbox,是否有一种方法可以确定富文本框中是否发生了剪贴板粘贴事件?此事件将用于执行某些操作,包括粘贴的文本块 谢谢 这是我的密码 protected override void WndProc(ref System.Windows.Forms.Message m) { if (m.Msg == WM_PASTE) { OnPasteOccurred(); MessageBox.Show("Pas");

是否有一种方法可以确定富文本框中是否发生了剪贴板粘贴事件?此事件将用于执行某些操作,包括粘贴的文本块

谢谢

这是我的密码

 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);
        }
    }
编辑


我希望在粘贴事件的基础上进行一些语法高亮显示或缩进,这似乎是非常有效的。我不知道它是怎么做到的。在这方面需要帮助。我很确定一定有一些本机Win32代码或类似的东西可以被拦截。我试过追踪按键、鼠标事件,但效果并不好

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

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

天真的检测 要检测键盘事件是否有效(您必须覆盖
OnKeyDown
功能),然后检查组合键(CTRL+V和SHIFT+INS)是否有效。大概是这样的:

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();
}
它工作得很好,但是您无法捕获使用鼠标(右键单击以打开上下文菜单)进行的粘贴操作和通过拖放进行的粘贴操作。如果您不需要它们,您可以使用此解决方案(至少它简单明了)

更好的检测 假设:当用户在
RichTextBox
中键入内容时,他每次插入一个字符。你怎么能用这个?嗯,当您检测到较大的更改时,您会检测到一个粘贴操作,因为用户每次只能键入一个字符(好的,您可以争辩说,由于Unicode代理,这并不总是正确的)。另请参阅和其他内容

请注意,您不能(因为IME的工作方式不同)使用
OnKeyDown
(或类似)。这仅适用于西方语言,但在Unicode方面存在问题(例如,当用户键入单个字符时,
String.Length
属性可能会增加两个
Char
。有关这方面的更多详细信息,请参阅(好吧,这是一个强烈建议的阅读,即使——在本例中——你不关心它)。在那篇文章中,你还将找到一个更好的算法来确定字符串长度的代码。简而言之,你必须替换:

   int currentLength = richTextBox.Text.Length;
为此:

   int currentLength = StringInfo.GetTextElementEnumerator(richTextBox.Text)
       .Cast<string>()
       .Count();
int currentLength=StringInfo.GetTextElementEnumerator(richTextBox.Text)
.Cast()
.Count();
经过所有这些努力,你可能会意识到…用户甚至可以粘贴一个字符,但它可能不会被检测到。你是对的,这就是为什么这是一个更好的检测,而不是一个完美的解决方案

完美解
完美的解决方案(如果您在Windows 8上运行)当然存在,本机富编辑控件会发送一条
EN_CLIPFORMAT
通知消息。其目的是通知富编辑控件的父窗口使用特定剪贴板格式进行粘贴。然后,您可以覆盖其父控件的
WndProc
,以检测此通知的
WM_notify
消息在上。无论如何,这不是几行代码,请查看此以了解详细信息。

从.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();
}

快速的web搜索显示RichTextBox不会通过向自身发送WM_paste来处理粘贴事件。因此我没有主意。您可以将控件包装在自己的自定义类中并重写该方法。当然,这是假设在粘贴时调用该方法。嗯,在.NET 2.0中,您无法重写paste()方法,原因可能是上面的@David给出的。难道你不能只检查你的富文本控件是否有焦点,如果有,然后粘贴在其中吗?msdn不是只适用于windows 8吗?@redDragonzz很遗憾……是的,这是一条只适用于windows 8的通知消息。我会更新我的答案以澄清它!@redDragonzz update:我猜是“真的”syntax highligh算法不会因为性能差而受到影响,因为他不会处理全文,而且在你打字时,它会在另一个线程的后台处理。你看过(旧)的代码了吗SharpDevelop IDE?他们确实提供了颜色和智能感知。但是,上下文菜单在富文本框中不是标准的,也不是拖放。通过它,您可以完全控制任何粘贴操作。据我所知,只有快捷方式真正需要检查。@Nyerguds是的,它是!实际上我喜欢这个主题(自我广告:)但是,是的,它是数千个问题和头痛的根源!这个WPF不是winforms吗?
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();
}