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

red*_*nzz 12 .net c# richtextbox winforms

有没有办法可以找出富文本框中是否发生剪贴板粘贴事件?此事件将用于使用粘贴的文本块执行某些操作.

谢谢

这是我的代码

 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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑

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

Adr*_*tti 18

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

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

天真的检测

要检测键盘事件可能有效(您必须覆盖该OnKeyDown功能),然后检查键组合(CTRL+ VSHIFT+ 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();
}
Run Code Online (Sandbox Code Playgroud)

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

更好的检测

假设:当用户输入内部时,RichTextBox他每次插入一个字符.你怎么用这个?好吧,当你检测到一个更大的变化时,你检测到一个粘贴操作,因为用户每次不能输入多个字符(好吧,你可以说因为Unicode替代品并不总是这样).另请参阅VB.NET版本以及有关Unicode内容的更多详细信息.

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;
}
Run Code Online (Sandbox Code Playgroud)

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

   int currentLength = richTextBox.Text.Length;
Run Code Online (Sandbox Code Playgroud)

有了这个:

   int currentLength = StringInfo.GetTextElementEnumerator(richTextBox.Text)
       .Cast<string>()
       .Count();
Run Code Online (Sandbox Code Playgroud)

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

完美解决方案

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