6

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.

1
  • 2
    It might be possible to watch for a specific message with ComponentDispatcher.ThreadFilterMessage event, although the docs say it's intended for keyboard messages. Here's a related question answered. Commented Aug 12, 2013 at 9:00

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.