我已经设置了一个查看器,这是当前进程,并希望收到消息qazxsw poi。
WM_DRAWCLIPBOARD
它说[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
var result = WinapiClipboard.SetClipboardViewer(Process.GetCurrentProcess().Handle);
我应该使用应用程序定义的函数来解析该消息。但它永远不会碰到功能/方法。
right here
我该怎么收到这条消息?我甚至订阅正确吗?
更新:
我没有使用WinForms / WPF或任何.NET经典框架功能。我只有.net标准2.0或.net核心。
从winforms应用程序来看,这一切都非常简单
注意:您无法通过控制台应用程序执行此操作(轻松)
声明这个
private static IntPtr WndProc(IntPtr hWnd, uint message, IntPtr wParam, IntPtr lParam)
{
var hdc = Process.GetCurrentProcess().Handle;
var clipboard = new WinClipboard();
switch (message)
{
case WinapiClipboard.WM_DRAWCLIPBOARD:
var result = clipboard.GetUnicodeTextAsync().Result;
return IntPtr.Zero;
default:
break;
}
return WinapiClipboard.DefWindowProc(hWnd, message, wParam, lParam);
}
在您的表单构造函数中
[DllImport("User32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);
然后,您将通过覆盖WndProc接收表单中的// this.handle is your forms handle
_ClipboardViewerNext = SetClipboardViewer(this.Handle);
消息
在你的形式
WM_DRAWCLIPBOARD
另一种方法是做到这一点,也许是一种更现代的方法
声明这个
protected override void WndProc(ref Message m)
{
switch ((Win32.Msgs)m.Msg)
{
case Win32.Msgs.WM_DRAWCLIPBOARD:
// Handle clipboard changed
break;
// ...
}
// we call this so we to pass the message along
base.WndProc(ref m);
}
在您的表单构造函数中
public const int WM_CLIPBOARDUPDATE = 0x031D;
public static IntPtr HWND_MESSAGE = new IntPtr(-3);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AddClipboardFormatListener(IntPtr hwnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
在你的形式
SetParent(Handle, HWND_MESSAGE);
AddClipboardFormatListener(Handle);
如果您使用的是类库,则必须创建一个隐藏的并传回一个动作或事件
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_CLIPBOARDUPDATE)
{
// handle message
}
base.WndProc(ref m);
}
注意:这些都没有经过测试,但应该让您入门
更新1
private class HiddenForm : Form { public HiddenForm() { SetParent(Handle, HWND_MESSAGE); AddClipboardFormatListener(Handle); } protected override void WndProc(ref Message m) { if (m.Msg == WM_CLIPBOARDUPDATE) { // do stuff here like call event } base.WndProc(ref m); } }
需要一个窗口句柄,而不是一个进程句柄。如果您没有窗口句柄,请创建仅用于接收剪贴板消息的仅消息窗口 - 感谢IInspectable
更新2
这只适用于那种始终具有完整框架的机器。 - 感谢Hans Passant
由于您正在执行winforms项目,因此覆盖现有的Control.WndProc而不是提供静态。
SetClipboardViewer