我正在创建一个剪贴板监视器作为项目,在剪贴板更改时,应用程序通过调用 GetClipboardOwner 检测哪个程序使用了剪贴板。
这是代码的摘录:
protected override void WndProc(ref Message m)
{
const int WM_DRAWCLIPBOARD = 0x308;
const int WM_CHANGECBCHAIN = 0x030D;
switch (m.Msg)
{
case WM_DRAWCLIPBOARD:
Debug.Indent();
//Process the clipboard here
uint processId;
IntPtr ownerHwnd = GetClipboardOwner();
GetWindowThreadProcessId(ownerHwnd, out processId);
Process proc = Process.GetProcessById((int)processId);
Debug.WriteLine(String.Format("Window Title: {0} Filename: {1}", proc.MainWindowTitle, process.MainModule.FileName));
SendMessage(_NextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
case WM_CHANGECBCHAIN:
if (m.WParam == _NextClipboardViewer)
_NextClipboardViewer = m.LParam;
else
SendMessage(_NextClipboardViewer, m.Msg, m.WParam, m.LParam);
break;
default:
base.WndProc(ref m);
break;
}
}
和 DLLImports:
[DllImport("User32.dll")]
public static extern IntPtr SetClipboardViewer(IntPtr _newviewerhandle);
[DllImport("User32.dll")]
public static extern bool ChangeClipboardChain(IntPtr removehandle, IntPtr nexthandle);
[DllImport("User32.dll")]
public static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);
[DllImport("User32.dll")]
public static extern IntPtr GetClipboardOwner();
[DllImport("kernel32.dll")]
public static extern int GetWindowThreadProcessId(IntPtr handle, out uint threadid);
输出窗口中的异常是 -Something.exe 中出现“System.EntryPointNotFoundException”类型的第一次机会异常
更新 2将“Kernel32”更改为“User32”后,它可以工作,但对于 Word、Excel 等某些应用程序,我得到了这个异常;System.dll 中出现“System.ComponentModel.Win32Exception”类型的第一次机会异常
有任何想法吗 ?
更新 3上述异常是由于 32 位进程(我的应用程序)访问 64 位进程(Word、Excel 等)的模块而导致的。将配置更改为 x64 有效。