C# 通过WinApi32监视剪贴板中的更改
我想监视剪贴板更改(仅文本)。我试图找到一些解决方案,在StackOverflow上发现了以下问题:C# 通过WinApi32监视剪贴板中的更改,c#,winapi,clipboard,C#,Winapi,Clipboard,我想监视剪贴板更改(仅文本)。我试图找到一些解决方案,在StackOverflow上发现了以下问题: 但我的问题/要求是,我不想向Windows.Forms或WPF(我的应用程序是一个控制台应用程序)添加依赖项。我尝试查看user32.dll中的可用方法。我写了一个代码,创建一个窗口和窗口样式。将WNDPC方法重写为自定义方法,然后将侦听器添加到剪贴板更改。WndProcFunction已为以下消息调用4次: WM_GETMINMAXINFO 创建 WM_NCCALCSIZE 创建
- WM_GETMINMAXINFO
- 创建
- WM_NCCALCSIZE
- 创建
SetDashboardViewer
),但它没有任何改变。代码如下所示:
使用PInvoke;
...
内部静态类User32Ext
{
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
内部静态外部bool AddClipboardFormatListener(IntPtr hwnd);
[DllImport(“user32.dll”,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
内部静态外部布尔RemoveClipboardFormatListener(IntPtr hwnd);
[DllImport(“kernel32.dll”)]
内部静态外部uint GetLastError();
}
班级计划
{
私有静态IntPtr _nextInChain=IntPtr.Zero;
内部静态不安全IntPtr WndProcFunction(IntPtr hwnd,User32.WindowMessage WindowMessage,void*wParam1,void*lParam1)
{
if(windowMessage==User32.windowMessage.WM\u创建)
{
var listener=User32Ext.AddClipboardFormatListener(hwnd);
var result=User32.OpenClipboard(窗口);
//_nextInChain=User32Ext.SetClipboardViewer(hwnd);
}
if(windowMessage==User32.windowMessage.WM_剪贴簿更新)
{
var pointerToText=User32.GetClipboardData_IntPtr(1);
var text=Marshal.PtrToStringAnsi(pointerToText);
控制台写入线(文本);
}
if(windowMessage==User32.windowMessage.WM\u剪贴板)
{
如果(_nextInChain!=IntPtr.Zero)
{
User32.SendMessage(_nextInChain,windowMessage,wParam1,lParam1);
}
}
if(windowMessage==User32.windowMessage.WM_CHANGECBCHAIN)
{
_nextInChain=hwnd;
//发送消息。。。
}
if(windowMessage==User32.WM\u)
{
//链味精
User32Ext.RemoveClipboardFormatListener(hwnd);
}
return hwnd;//成功
}
静态void Main(字符串[]参数)
{
不安全的
{
var hInstance=Marshal.GetHINSTANCE(typeof(Program).Module);
string name=“Test”;
User32.WNDCLASSEX WNDCLASSEX=新User32.WNDCLASSEX
{
cbSize=Marshal.SizeOf(typeof(User32.WNDCLASSEX)),
style=User32.ClassStyles.CS\u GLOBALCLASS,
cbClsExtra=0,
cbWndExtra=0,
hbrBackground=IntPtr.Zero,
hCursor=IntPtr.Zero,
hIcon=IntPtr.Zero,
hIconSm=IntPtr.Zero,
lpszMenuName=null,
hInstance=hInstance,
lpfnWndProc=newuser32.WndProc(WndProc函数)
};
var stringPtr=Marshal.StringToHGlobalAuto(名称);
wndClassEx.lpszClassName_IntPtr=stringPtr;
var register=User32.RegisterClassEx(参考wndClassEx);
var window=User32.CreateWindowEx(
User32.WindowStylesEx.WS_EX_透明,
名称
“测试窗口”,
0,
0, 0, 0, 0,
IntPtr.Zero,
IntPtr.Zero,
wndClassEx.hInstance,
IntPtr.Zero
);
User32.SetClipboardData(13,stringPtr);
...
}
}
}
代码中是否还有我遗漏的东西,一些额外的侦听器?每次从user32.dll调用方法后,我都会查看错误代码。但是,所有这些都成功了,没有任何失败。A是接收消息所必需的。如果您不需要窗口,可以创建一个允许您发送和接收消息的窗口
它不可见、没有z顺序、无法枚举且不存在
接收广播信息。窗口只是发送消息
在C#中,在main
函数的末尾,它将如下所示:
MSG msg;
while (User32.GetMessage(out msg, IntPtr.Zero, 0, 0) != 0)
{
User32.TranslateMessage(ref msg);
User32.DispatchMessage(ref msg);
}
请参阅,.是否已检查是否调用了
AddClipboardFormatListener
?如果是,请检查是否成功执行?如果没有,请通过检查返回值和窗口句柄来确保您的窗口创建成功。@RitaHan MSFT“每次从user32.dll调用方法后,我都会查看错误代码。但所有操作都成功,没有任何失败。”。此外,所有侦听器函数都返回true
。一切似乎都很好。谢谢!我发现我未能在MSDN上“谷歌”搜索该信息:(