views:

193

answers:

3

I've registered a message filter using

Application.AddMessageFilter(m_messageFilter);

using this I can log all of the mouse clicks a user makes in the application's user interface.

However, one dialog is run on a separate thread, with code something like:

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        dialog.ShowDialog();
    }
}

Thread thread = new Thread(Run);

The message filter I set up doesn't get to see messages that go to this window. How can I get them (ideally without being too intrusive)?

I tried to override MyDialog.PreProcessMessage, but I'm confused that this never seems to get called.

Thanks.

+1  A: 

Just a stab, but you may be able to leverage the volatile keyword, here's an example of using a volatile bool to check state between processes on different threads.

You could probably adapt that methodology to meet your needs. Flip it depending on whether or not the msg came across on the second dialog

{EDIT} In relation to the PreProcessMessage, I believe that is only for Keyboard input, not mouse. You'd probably have to override WndProc to get those events, that's most likely why the overridden PreProcessMessage isn't firing.

Good Luck!

curtisk
How is volatile going to be helpful here or even relevant? Clearly the problem is that there are two separate message pumps (main UI thread and the second UI thread) and the filter is only added to the main UI thread and the messages in the second thread goes to that thread's message pump which does not have any filters.
Mehmet Aras
+1  A: 

I suppose you should rewrite your code in the following way

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.Run();
        dialog.ShowDialog();
    }
}

Or may be

Application.Run(dialog);

inside using { ... } will also work

Application.Run() begins running a standard application message loop on the current thread. Usually message loop is working only in the main thread. Without Application.Run() standard message loop will not start in the second thread.

Here is an article Creating a Splash Screen Form on a Separate Thread where similar technique was used - second form (SlpashScreen) is started in another thread and they call Application.Run(splash); in this second thread.

As one can get from this article, running forms in different threads requires from a developer to be very careful regarding how you will close/dispose forms.

Bogdan_Ch
+2  A: 

Pretty much all Application methods, including AddMessageFilter, are thread specific. So, if you want to filter the messages on the other thread you have to call AddMessageFilter on that thread.

Just change your Run method to:

void Run()
{
    using( MyDialog dialog = new MyDialog() )
    {
        Application.AddMessageFilter(new MyMessageFilter());
        Application.Run(dialog); 
    }
}
Stephen Martin