C# – 捕获来自特定应用程序的Windows消息

我正在编写一个C#应用程序,它需要拦截另一个应用程序发出的Window Messages 。 编写我正在监控的应用程序的公司给我发了一些示例代码,但它是用C ++编写的,我真的不知道。

在C ++示例代码中,我得到了他们使用以下代码:

UINT uMsg = RegisterWindowMessage(SHOCK_MESSAGE_BROADCAST); ON_REGISTERED_MESSAGE(WM_SHOCK_BROADCAST_MESSAGE, OnShockStatusMessage) LRESULT OnShockStatusMessage(WPARAM wParam, LPARAM lParam); 

据我了解,这将从Windows中检索我们想要侦听的特定消息的Id。 然后我们要求C ++在拦截与Id匹配的消息时调用OnShockStatusMessage

经过一番研究后,我在C#中整理了以下内容

 [DllImport("user32.dll", SetLastError = true)] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] static extern uint RegisterWindowMessage(string lpString); private IntPtr _hWnd; // APS-50 class reference private List _windowsMessages = new List(); // APS-50 messages private const string _className = "www.AuPix.com/SHOCK/MessageWindowClass"; // Windows Messages events private const string _messageBroadcast = "www.AuPix.com/SHOCK/BROADCAST"; private const string _messageCallEvents = "www.AuPix.com/SHOCK/CallEvents"; private const string _messageRegistrationEvents = "www.AuPix.com/SHOCK/RegistrationEvents"; private const string _messageActions = "www.AuPix.com/SHOCK/Actions"; private void DemoProblem() { // Find hidden window handle _hWnd = FindWindow(_className, null); // Register for events _windowsMessages.Add( new IntPtr( RegisterWindowMessage( _messageActions ) ) ); _windowsMessages.Add( new IntPtr( RegisterWindowMessage( _messageBroadcast ) ) ); _windowsMessages.Add( new IntPtr( RegisterWindowMessage( _messageCallEvents ) ) ); _windowsMessages.Add( new IntPtr( RegisterWindowMessage( _messageRegistrationEvents ) ) ); } protected override void WndProc(ref Message m) { base.WndProc(ref m); // Are they registered Windows Messages for the APS-50 application? foreach (IntPtr message in _windowsMessages) { if ((IntPtr)m.Msg == message) { Debug.WriteLine("Message from specified application found!"); } } // Are they coming from the APS-50 application? if ( m.HWnd == shock.WindowsHandle) { Debug.WriteLine("Message from specified application found!"); } } 

据我所知,这应该做同样的基本事情,因为它:

  1. 找到我想要监控的应用程序
  2. 注册我希望拦截的窗口消息
  3. 观看所有窗口消息 – 然后删除我需要的窗口消息

但是,在我覆盖WndProc()方法时,我的检查都没有拦截任何特定消息或来自我正在监视的应用程序的任何消息。

如果我通过它调试所有消息的Debug.WriteLine ,我可以看到它正在监视它们。 但是它永远不会过滤掉我想要的消息。

通过运行用C ++编写的示例监视应用程序,我可以看到正在发送和拾取窗口消息 – 这只是我的C#实现不会做同样的事情。

事实certificate我还需要向其他应用程序发送一个PostMessage,要求它向我的应用程序发送Window Messages。

 PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_ACTIVE_CALLINFO, (int)_thisHandle); PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_ALL_REGISTRATIONINFO, (int)_thisHandle); PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_CALL_EVENTS, (int)_thisHandle); PostMessage((int)_hWnd, _windowsMessages[0], SHOCK_REQUEST_REGISTRATION_EVENTS, (int)_thisHandle); 

不是漂亮的代码,但足以certificate它的工作原理我现在需要的全部:)

我认为问题在于RegisterWindowMessage() P / Invoke定义。 pinvoke.net建议使用以下内容:

 [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)] static extern uint RegisterWindowMessage(string lpString); 

使用uint作为返回值而不是IntPtr应该有所不同。 通常,当返回值是句柄(例如HWNDHANDLE )时,您希望使用IntPtr ,但是当返回值可以直接转换为C#类型时,最好使用该类型。