2010-07-20 31 views
7

我正在編寫一個C#應用程序,它需要攔截另一個應用程序發出的窗口消息。編寫我正在監控的應用程序的公司向我發送了一些示例代碼,但是它是使用C++編寫的,我不太清楚。C# - 從特定應用程序捕獲Windows消息

在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<IntPtr> _windowsMessages = new List<IntPtr>(); // 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. 查找應用程序I希望監控
  2. 註冊我希望截取的窗口消息
  3. 所有窗口消息的手錶 - 然後去掉我需要的手錶

然而,在我的既不的我的支票截距任何特定的消息或從我監視應用程序的任何消息的的WndProc()方法的重寫。

如果我對Debug.WriteLine對於通過它發出的所有消息,我可以看到它正在監視它們。但它絕不會過濾出我想要的信息。

通過運行用C++編寫的示例監視應用程序,我可以看到窗口消息正在發送和拾取 - 這只是我的C#實現不會這樣做。

回答

1

原來我還需要發送另一個應用程序PostMessage要求它向我的應用程序發送窗口消息。

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); 

不漂亮的代碼,但不夠好,以證明它的工作原理是所有我需要現在:)

0

我認爲問題在於您的P/Invoke定義爲RegisterWindowMessage()pinvoke.net建議使用以下物質:

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

使用uint作爲返回值,而不是IntPtr應該賺取差價。通常,當返回值是一個句柄(如HWNDHANDLE)時,您希望使用IntPtr,但當返回值可以直接轉換爲C#類型時,最好使用該類型。

+0

你這裏給出的示例代碼實際上是我使用的那一刻是什麼:) – 2010-07-20 12:13:09

+0

@Peter啊,錯過了。你爲什麼把列表列爲IntPtr列表?爲什麼不把它列入清單? – Andy 2010-07-20 14:29:12

+0

我預計它只是複製來自不同網站的[DllImport]語句,看看它是否有任何區別,但每個語句都有細微差異。 – 2010-07-20 14:56:32

相關問題