WPF应用程序消息循环和PostThreadMessage [英] WPF application message loop and PostThreadMessage

查看:400
本文介绍了WPF应用程序消息循环和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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆