I am trying to make a global multi value Clipboard. I have used a stack to store the values. I am using WinProc()
to capture the global Copy operation where I push the value on stack. Similarly I am using a windows keyboard hook to capture the Ctrl-V (Paste) operation. The code for both the functions is as below. I have copied and modified the code from 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);
}
My WinProc override is as follows. I have copied it from SO as well but dont remember the link.
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;
}
}
The copy operation is working well. It populates the stack, but when I use a paste operation, it triggers the WM_CLIPBOARDUPDATE event. Which makes the stack populated again with the most recent value.
I think when I change the Clipboard value in the Paste intercept, it triggers the WM_CLIPBOARDUPDATE event.I have tried to Unregister the listner, I have tried to use a flag variable 'localChange', I have tried to use block(), but nothing is working.
What can be done to solve it.