WPF应用程序消息循环和PostThreadMessage

时间:2013-08-12 08:46:32

标签: wpf windows multithreading winapi

对于WPF应用程序,内部是GetMessage/DispatchMessage内部的经典消息循环(在Windows' Application.Run意义上)?是否可以捕获从另一个带有PostThreadMessage的Win32应用程序发布到WPF UI线程(没有HWND句柄的消息)的消息。谢谢。

1 个答案:

答案 0 :(得分:3)

我使用.NET Reflector跟踪Applicaton.Run实现到Dispatcher.PushFrameImpl。也可以从.NET Framework reference sources获得相同的信息。确实有一个经典的消息循环:

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的实现,它确实会在RaiseThreadMessage内执行ComponentDispatcher.ThreadFilterMessage事件。

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

显然,它适用于任何已发布的消息,而不仅仅是键盘消息。您应该可以订阅ComponentDispatcher.ThreadFilterMessage并留意您感兴趣的消息。