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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With