【发布时间】:2014-10-23 01:53:57
【问题描述】:
我正在尝试制作一个全局多值剪贴板。我使用堆栈来存储值。我正在使用WinProc() 来捕获全局复制操作,在该操作中我将值压入堆栈。同样,我正在使用 Windows 键盘挂钩来捕获 Ctrl-V(粘贴)操作。这两个函数的代码如下。我已经从this复制并修改了代码。
private int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
var hookStruct = (KbLLHookStruct)Marshal.PtrToStructure(lParam, typeof(KbLLHookStruct));
// Quick and dirty check. You may need to check if this is correct. See GetKeyState for more info.
bool ctrlDown = GetKeyState(VK_LCONTROL) != 0 || GetKeyState(VK_RCONTROL) != 0;
if (ctrlDown && hookStruct.vkCode == 0x56) // Ctrl+V
{
if (clipBoardStack.Count > 0)
{
lock (this)
{
localChange = true;
RemoveClipboardFormatListener(this.Handle); // Remove our window from the clipboard's format listener list.
System.Threading.Thread.Sleep(200);
Clipboard.SetText(clipBoardStack.Pop());
AddClipboardFormatListener(this.Handle);
System.Threading.Thread.Sleep(200);
}
}
}
}
// Pass to other keyboard handlers. Makes the Ctrl+V pass through.
return CallNextHookEx(_hookHandle, nCode, wParam, lParam);
}
我的 WinProc 覆盖如下。我也从 SO 复制了它,但不记得链接了。
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_CLIPBOARDUPDATE)
{
if (!localChange)//Only store the data in stack when it comes from outside. Just to prevent the side effect of Paste Operation
{
IDataObject iData = Clipboard.GetDataObject(); // Clipboard's data.
if (iData.GetDataPresent(DataFormats.Text))
{
lock (this)
{
string text = (string)iData.GetData(DataFormats.Text);
clipBoardStack.Push(text);
}
}
}
else
{
localChange = false;
}
}
复制操作运行良好。它填充堆栈,但是当我使用粘贴操作时,它会触发 WM_CLIPBOARDUPDATE 事件。这使得堆栈再次填充最新的值。
我认为当我更改粘贴拦截中的剪贴板值时,它会触发 WM_CLIPBOARDUPDATE 事件。我尝试取消注册列表器,我尝试使用标志变量“localChange”,我尝试使用 block() ,但没有任何工作。
可以做些什么来解决它。
【问题讨论】:
标签: c# clipboard copy-paste keyboard-hook setwindowshookex