2009-06-04 62 views
0

我在寫一個需要通知客戶端應用程序的C++ DLL。在C++(MFC)中,我可以在DLL中註冊一個客戶端窗口句柄,然後在需要通知客戶端某事時調用PostMessage。當客戶端是C#應用程序時,我能做些什麼?將通知從C++ DLL發送到.NET應用程序

回答

1

您可以覆蓋在C#窗口WndProc方法來處理這個特定的消息

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg = YOUR_MESSAGE) 
    { 
     // handle the notification 
    } 
    else 
    { 
     base.WndProc(ref m); 
    } 
} 
1

PostMessage只是告訴Windows向另一個應用程序的主應用程序循環發出消息。如果客戶端是C#應用程序,幾乎肯定會做同樣的事情,所以更合適的問題是,如何讀取發送到C#中主應用程序循環的消息。

+0

對。答案是......? – Curtis 2009-06-04 22:36:25

0

如果你想實現一個窮人版的發佈 - 訂閱模式,回調是要走的路。在this thread有一些很好的信息。

1

通過發送消息到窗口句柄可以做到這一點。在你的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."); 
     } 
    } 
} 
1

取決於如何密切兩人攜手,我可能會使用一個回調/事件的方法。

對我來說,整個「PostMessage的」做法,似乎有點像一個黑客(取決於你想做的事,如果是要發佈的標準的消息是什麼,這顯然是罰款)

可以使託管包裝器可以處理回調併發出C#類可以監聽的託管(C#兼容)事件。

一般來說,我是通過託管C++層將本機C++鏈接到C#的一個忠實粉絲 - 這樣,您的C#應用​​程序不需要知道本機C++代碼的所有「醜陋」低級細節。

相關問題