Estoy escribiendo una aplicación C# que necesita interceptar Mensajes de ventana que están enviando otras aplicaciones. La compañía que escribió la aplicación que estoy monitoreando me envió un código de ejemplo, sin embargo, está en C++, que realmente no sé.C# - Capturar mensajes de Windows desde una aplicación específica
En el ejemplo de código C++ Tengo que utilizan el siguiente código:
UINT uMsg = RegisterWindowMessage(SHOCK_MESSAGE_BROADCAST);
ON_REGISTERED_MESSAGE(WM_SHOCK_BROADCAST_MESSAGE, OnShockStatusMessage)
LRESULT OnShockStatusMessage(WPARAM wParam, LPARAM lParam);
Tengo entendido que este recupera un ID de Windows para el mensaje específico que queremos escuchar. Luego le pedimos a C++ que llame al OnShockStatusMessage siempre que se intercepte un mensaje que coincida con el Id.
Después de un poco de investigación he elaborado la siguiente en 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!");
}
}
Según entiendo esto debería hacer la misma cosa básica, en la que:
- Finds la aplicación I desea monitorear
- Registra los mensajes de la ventana Deseo interceptar
- Relojes para todos los mensajes de la ventana - luego quita los que necesito
Sin embargo en mi anulación de la WndProc() método de ninguno de mis cheques de interceptación de los mensajes específicos o cualquier mensaje de la aplicación que estoy monitoreo.
If I Debug.WriteLine para todos los mensajes que vienen a través de él, puedo ver que los está monitoreando. Sin embargo, nunca filtra los mensajes que quiero.
Ejecutando la aplicación de supervisión de ejemplo escrita en C++, puedo ver que los mensajes de la ventana se envían y recogen, es solo que mi implementación de C# no hace lo mismo.
El código de ejemplo que ha dado aquí es en realidad lo que estoy usando en este momento :) –
@Peter Ah, se perdió eso. ¿Por qué hiciste que la lista fuera una lista de IntPtr? ¿Por qué no simplemente hacer que sea List? –
Andy
Supongo que fue solo para copiar las declaraciones [DllImport] de diferentes sitios web, ver si hacía alguna diferencia, pero cada una tenía pequeñas diferencias. –