C # - Capturing Windows messages from a specific application

I am writing a C # application that should intercept Windows Messages sent by other applications. The company that wrote the application I'm tracking sent me some kind of code example, however it is in C ++, which I really don't know.

In C ++ code code, I have the following code:

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

As I understand it, this retrieves the Id from Windows for the specific message that we want to listen to. Then we ask C ++ to call OnShockStatusMessage when the message matching the identifier is intercepted.

After a little research, I put together the following in 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!"); } } 

As I understand it, this should do the same basic thing in which it:

  • Finds the application I want to track
  • Logs window messages I want to intercept
  • Clock for all window messages - then deletes the ones I need.

However, in my redefinition of the WndProc () method, none of my checks intercept any specific messages or any message from the application that I control.

If I Debug.WriteLine for all messages that go through it, I see that it tracks them. However, it never filters out the messages I want.

By running an example monitoring application written in C ++, I see that Window messages are being sent and collected - it's just that my C # implementation does not do the same.

+7
c ++ c # mfc windows-messages
source share
2 answers

Turns out I also needed to send another PostMessage application a request to send my application to 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); 

Not very good code, but good enough to prove that it works, and thatโ€™s all I need now :)

+1
source share

I think the problem is with your P / Invoke definition for RegisterWindowMessage() . pinvoke.net suggests using the following:

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

Using uint , since the return value instead of IntPtr should have a value. Usually you want to use IntPtr when the return value is a descriptor (for example, HWND or HANDLE ), but when the return value can be directly converted to a C # type, it is better to use this type.

0
source share

All Articles