我正在做一个项目,该项目跟踪用户必须复制和过去数据的频率,因此如果用户不断从一个表单粘贴到另一个表单,我们可以自动化零件,以便表单自动填充。这正在企业呼叫中心用于质量保证人员。表格做了一堆其他的事情,但对于这个问题来说并不重要。
就目前而言,表单应用程序使用键盘挂钩来捕获用户何时执行 control+v。当它捕获 control+v 组合时,它会抓取剪贴板的内容并将其发送到程序的处理部分。这一切都运行良好,但是当用户右键单击复制/粘贴时,它无法拾取,我必须为此走不同的路线。
为了尝试捕获用户何时使用右键单击复制/粘贴消息,我认为收听剪贴板进行更改同样容易。我用AddClipboardFormatListener(this.Handle);
和 WndProc 方法的覆盖完成了此操作,如下所示:
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_CLIPBOARDUPDATE)
{
IDataObject iData = Clipboard.GetDataObject(); // Clipboard's data.
uint processID = 0;
IntPtr ForeGroundWindowHandle = GetForegroundWindow();
GetWindowThreadProcessId(ForeGroundWindowHandle, out processID);
if (iData.GetDataPresent(DataFormats.Text))
{
string text = (string)iData.GetData(DataFormats.Text);
ClipboardEventQueue.Enqueue(new ClipboardDataStorage(text, Convert.ToInt32(processID)));
LogWrite(text);
}
else if (iData.GetDataPresent(DataFormats.Bitmap))
{
Bitmap image = (Bitmap)iData.GetData(DataFormats.Bitmap);
ClipboardEventQueue.Enqueue(new ClipboardDataStorage("Clipboard copied an image", Convert.ToInt32(processID)));
LogWrite("Clipboard copied an image");
}
}
}
问题是仅当用户复制到剪贴板时,才会发送WM_CLIPBOARDUPDATE消息。我只关心他们实际粘贴的内容。有没有办法在用户粘贴某些内容时获得消息,或者我是否必须使用鼠标钩子通过跟踪右键单击来完成此操作?
我想在任何粘贴完成时抓住。因此,如果他们打开一个 Chrome 中的网页并复制街道地址,然后将其粘贴到 其他一些程序,我也想捕捉那个糊状物。
不幸的是,剪贴板并不完全允许这种功能。剪贴板基于两个主要事件 - 广告和请求。假设我们有应用程序"X"和"Y"正在运行。所有其他正在运行的应用程序都可以看到 X 何时播发剪贴板上可用的新数据。WM_CLIPBOARDUPDATE消息将发送到每个应用程序。但是当Y请求这些数据时,只有X知道。WM_RENDERFORMAT消息直接从 X 转到 Y。
作为一种非常笨拙的解决方法,您可以收听广告。每当有人宣传新数据时,您都会向他们请求所有数据。然后,控制剪贴板,并再次播发数据。这样,您就可以窃取数据的所有权,因此您可以确定何时有人从剪贴板请求。按照此处的教程将窗口设置为剪贴板查看器。在他们的 WndProc 循环中,试试这个:
protected override void WndProc(ref Message m)
{
...
if (m.Msg == WM_DRAWCLIPBOARD)
{
IDataObject iData = Clipboard.GetDataObject();
ClipBoard.SetDataObject(iData);
}
if (m.Msg == WM_RENDERFORMAT)
Console.WriteLine("Clipboard data requested");
}