Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF application message loop and PostThreadMessage

For a WPF application, is there internally a classic message loop (in Windows's GetMessage/DispatchMessage sense), inside Application.Run? Is it possible to catch a message posted from another Win32 application with PostThreadMessage to a WPF UI thread (a message without HWND handle). Thank you.

like image 295
avo Avatar asked Aug 12 '13 08:08

avo


1 Answers

I used .NET Reflector to track the Applicaton.Run implementation down to Dispatcher.PushFrameImpl. It's also possible to obtain the same information from .NET Framework reference sources. There is indeed a classic message loop:

private void PushFrameImpl(DispatcherFrame frame)
{
    SynchronizationContext syncContext = null;
    SynchronizationContext current = null;
    MSG msg = new MSG();
    this._frameDepth++;
    try
    {
        current = SynchronizationContext.Current;
        syncContext = new DispatcherSynchronizationContext(this);
        SynchronizationContext.SetSynchronizationContext(syncContext);
        try
        {
            while (frame.Continue)
            {
                if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
                {
                    break;
                }
                this.TranslateAndDispatchMessage(ref msg);
            }
            if ((this._frameDepth == 1) && this._hasShutdownStarted)
            {
                this.ShutdownImpl();
            }
        }
        finally
        {
            SynchronizationContext.SetSynchronizationContext(current);
        }
    }
    finally
    {
        this._frameDepth--;
        if (this._frameDepth == 0)
        {
            this._exitAllFrames = false;
        }
    }
}

Further, here's the implementation of TranslateAndDispatchMessage, which indeed fires ComponentDispatcher.ThreadFilterMessage event along its course of execution inside RaiseThreadMessage:

private void TranslateAndDispatchMessage(ref MSG msg)
{
    if (!ComponentDispatcher.RaiseThreadMessage(ref msg))
    {
        UnsafeNativeMethods.TranslateMessage(ref msg);
        UnsafeNativeMethods.DispatchMessage(ref msg);
    }
}

Apparently, it works for any posted message, not just keyboard ones. You should be able to subscribe to ComponentDispatcher.ThreadFilterMessage and watch for your message of interest.

like image 53
noseratio Avatar answered Oct 10 '22 04:10

noseratio