WPF应用程序消息循环和PostThreadMessage [英] WPF application message loop and PostThreadMessage
问题描述
对于WPF应用程序,在Application.Run
内部是否存在内部经典的消息循环(就Windows的GetMessage/DispatchMessage
而言)?是否可以使用 PostThreadMessage 到WPF UI线程(无HWND句柄的消息).谢谢.
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.
推荐答案
我使用.NET Reflector跟踪Applicaton.Run
实现,直到Dispatcher.PushFrameImpl
.也可以从 .NET Framework参考源获取相同的信息.确实有一个经典的消息循环:
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;
}
}
}
此外,这是TranslateAndDispatchMessage
的实现,它的确触发了 ComponentDispatcher.ThreadFilterMessage 事件在RaiseThreadMessage
内执行的过程:
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);
}
}
显然,它适用于任何已发布的消息,而不仅仅是键盘消息.您应该可以订阅ComponentDispatcher.ThreadFilterMessage
并注意您感兴趣的消息.
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.
这篇关于WPF应用程序消息循环和PostThreadMessage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!