For an application I’m making I want to intercept window messages from an external process (much like the way spy++ does it). I figured out that I can use SetWinEventHook to do this.
This is the code I have.
class Program
{
internal delegate void WinEventProc(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime);
[DllImport("user32.dll", SetLastError = true)]
internal static extern IntPtr SetWinEventHook(int eventMin, int eventMax, IntPtr hmodWinEventProc, WinEventProc lpfnWinEventProc, int idProcess, int idThread, SetWinEventHookFlags dwflags);
//[DllImport("user32.dll", SetLastError = true)]
internal static extern int UnhookWinEvent(IntPtr hWinEventHook);
internal enum SetWinEventHookFlags
{
WINEVENT_INCONTEXT = 4,
WINEVENT_OUTOFCONTEXT = 0,
WINEVENT_SKIPOWNPROCESS = 2,
WINEVENT_SKIPOWNTHREAD = 1
}
static void Main(string[] args)
{
int threadId = 0x000306D4;
int processId = 0x000306BC;
WinEventProc listener = new WinEventProc(EventCallback);
//setting the window hook and writing the result to the console
Console.WriteLine(SetWinEventHook(1, 0x7fffffff, IntPtr.Zero, listener, processId, threadId, SetWinEventHookFlags.WINEVENT_INCONTEXT).ToString());
Console.WriteLine("done");
Console.ReadKey();
}
private static void EventCallback(IntPtr hWinEventHook, int iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
{
//callback function, called when message is intercepted
Console.WriteLine(hWnd.ToString());
}
}
}
As far as I know I am using the correct P/Invoke declaration, but when I run this code the output is:
0 done
If successful, it should return an HWINEVENTHOOK value that identifies this event hook instance. If unsuccesful it returns 0. (according to microsoft’s website at least)
The thread and process both seem to be valid and running.
Could anyone help me to get any closer to where my problem is? I think it must be either something small or I am just using completely the wrong method to do what I want to do. Thanks in advance.
According to msdn
I tried your example in a console app and as you mentioned no events were received. But on a winform the example works and the events are received. So, I think, this is because of single thread of execution in a console application.
Put the SetWinEventHook call in a button click event and you should start receiving events in the callback.