如何从Windows窗体创建仅消息窗口? [英] How do I create a message-only window from windows forms?
问题描述
我试图在Winforms应用程序中创建一个仅消息窗口,以从MFC库类接收窗口消息。
I'm trying to create a message-only window to receive window messages from an MFC library class, within a winforms application.
我尝试了子类化 NativeWindow
,并在构造函数中请求这样的窗口句柄:
I've tried subclassing NativeWindow
, and in the constructor requesting a window handle like this:
CreateParams cp = new CreateParams();
cp.Parent = (IntPtr)HWND_MESSAGE;
this.CreateHandle(cp);
但是我收到一条Win32Exception消息错误创建窗口句柄。如何从Windows窗体创建仅消息窗口?是使用 NativeWindow
正确的方法吗?
but I get a Win32Exception thrown with the message "Error creating window handle". How do I create a message-only window from windows forms? Is using NativeWindow
the right approach?
推荐答案
我知道这是7.5岁,但万一有人发现这个,我想我会回应。我使用了Microsoft的 TimerNativeWindow代码,并删除了计时器功能。我最终使用了这种方法:
I know this is 7.5 years old, but just in case anyone finds this, I thought I would respond. I used Microsoft's TimerNativeWindow code and removed the timer functionality. I ended up using this approach:
public class MyNativeWindow : NativeWindow
{
private readonly string _caption;
private const int WmClose = 0x0010;
[SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
private static readonly HandleRef HwndMessage = new HandleRef(null, new IntPtr(-3));
[DllImport("user32.dll", CharSet = CharSet.Auto)]
[ResourceExposure(ResourceScope.None)]
private static extern IntPtr PostMessage(HandleRef hwnd, int msg, int wparam, int lparam);
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[ResourceExposure(ResourceScope.Process)]
private static extern int GetWindowThreadProcessId(HandleRef hWnd, out int lpdwProcessId);
[DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
[ResourceExposure(ResourceScope.Process)]
private static extern int GetCurrentThreadId();
public MyNativeWindow(string caption)
{
_caption = caption;
}
public bool CreateWindow()
{
if (Handle == IntPtr.Zero)
{
CreateHandle(new CreateParams
{
Style = 0,
ExStyle = 0,
ClassStyle = 0,
Caption = _caption,
Parent = (IntPtr)HwndMessage
});
}
return Handle != IntPtr.Zero;
}
public void DestroyWindow()
{
DestroyWindow(true, IntPtr.Zero);
}
private bool GetInvokeRequired(IntPtr hWnd)
{
if (hWnd == IntPtr.Zero) return false;
int pid;
var hwndThread = GetWindowThreadProcessId(new HandleRef(this, hWnd), out pid);
var currentThread = GetCurrentThreadId();
return (hwndThread != currentThread);
}
private void DestroyWindow(bool destroyHwnd, IntPtr hWnd)
{
if (hWnd == IntPtr.Zero)
{
hWnd = Handle;
}
if (GetInvokeRequired(hWnd))
{
PostMessage(new HandleRef(this, hWnd), WmClose, 0, 0);
return;
}
lock (this)
{
if (destroyHwnd)
{
base.DestroyHandle();
}
}
}
public override void DestroyHandle()
{
DestroyWindow(false, IntPtr.Zero);
base.DestroyHandle();
}
}
这篇关于如何从Windows窗体创建仅消息窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!