将通知从C++ DLL发送到.NET应用程序
问题描述:
我在写一个需要通知客户端应用程序的C++ DLL。在C++(MFC)中,我可以在DLL中注册一个客户端窗口句柄,然后在需要通知客户端某事时调用PostMessage。当客户端是C#应用程序时,我能做些什么?将通知从C++ DLL发送到.NET应用程序
答
您可以覆盖在C#窗口WndProc方法来处理这个特定的消息
protected override void WndProc(ref Message m)
{
if (m.Msg = YOUR_MESSAGE)
{
// handle the notification
}
else
{
base.WndProc(ref m);
}
}
答
PostMessage只是告诉Windows向另一个应用程序的主应用程序循环发出消息。如果客户端是C#应用程序,几乎肯定会做同样的事情,所以更合适的问题是,如何读取发送到C#中主应用程序循环的消息。
答
通过发送消息到窗口句柄可以做到这一点。在你的dotnet类中创建一个可以拦截消息的虚拟窗口,然后发出消息。
这里有一些代码,你只需填写我使用WM_MYMESSAGE的地方,引用一个正确的Windows消息,现在在你的C++ DLL中,你可以发布消息给它。请注意,我确信有更好的/其他的方式来做你想做的事,但这也可能会起作用。
//Dummy window classes. Because we don't have access to the wndproc method of a form, we create
//dummy forms and expose the method to the SystemHotKeyHook class as an event.
/// <summary>
/// Inherits from System.Windows.Form.NativeWindow. Provides an Event for Message handling
/// </summary>
private class NativeWindowWithEvent : System.Windows.Forms.NativeWindow
{
public event MessageEventHandler ProcessMessage;
protected override void WndProc(ref Message m)
{
//Intercept the message you are looking for...
if (m.Msg == (int)WM_MYMESSAGE)
{
//Fire event which is consumed by your class
if (ProcessMessage != null)
{
bool Handled = false;
ProcessMessage(this, ref m, ref Handled);
if (!Handled)
{
base.WndProc(ref m);
}
}
else
{
base.WndProc(ref m);
}
}
else
{
base.WndProc(ref m);
}
}
}
/// <summary>
/// Inherits from NativeWindowWithEvent and automatic creates/destroys of a dummy window
/// </summary>
private class DummyWindowWithEvent : NativeWindowWithEvent, IDisposable
{
public DummyWindowWithEvent()
{
CreateParams parms = new CreateParams();
this.CreateHandle(parms);
}
public void Dispose()
{
if (this.Handle != (IntPtr)0)
{
this.DestroyHandle();
}
}
}
类截取消息:
// <summary>
/// System hotkey interceptor
/// </summary>
public class MessageIntercept: IDisposable
{
private delegate void MessageEventHandler(object Sender, ref System.Windows.Forms.Message msg, ref bool Handled);
//Window for WM_MYMESSAGE Interceptor
private DummyWindowWithEvent frmDummyReceiver_m;
/// <summary>
/// Default constructor
/// </summary>
public MessageIntercept()
{
this.frmDummyReceiver_m = new DummyWindowWithEvent();
this.frmDummyReceiver_m.ProcessMessage += new MessageEventHandler(this.InterceptMessage);
}
private void InterceptMessage(object Sender, ref System.Windows.Forms.Message msg, ref bool Handled)
{
//Do something based on criteria of the message
if ((msg.Msg == (int)WM_MYMESSAGE) &&
(msg.WParam == (IntPtr)xyz))
{
Handled = true;
System.Diagnostics.Debug.WriteLine("Message intercepted.");
}
}
}
答
取决于如何密切两人携手,我可能会使用一个回调/事件的方法。
对我来说,整个“PostMessage的”做法,似乎有点像一个黑客(取决于你想做的事,如果是要发布的标准的消息是什么,这显然是罚款)
可以使托管包装器可以处理回调并发出C#类可以监听的托管(C#兼容)事件。
一般来说,我是通过托管C++层将本机C++链接到C#的一个忠实粉丝 - 这样,您的C#应用程序不需要知道本机C++代码的所有“丑陋”低级细节。
对。答案是......? – Curtis 2009-06-04 22:36:25