- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口.docx
HYPERLINK /powertoolsteam/archive/2010/12/31/1922794.html WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口
目录
HYPERLINK /powertoolsteam/archive/2010/12/30/1921426.html WPF的消息机制(一)-让应用程序动起来
HYPERLINK /powertoolsteam/archive/2010/12/31/1922794.html WPF的消息机制(二)-WPF内部的5个窗口
(1) HYPERLINK /powertoolsteam/archive/2010/12/31/1922794.html 隐藏消息窗口
(2)处理激活和关闭的消息的窗口和系统资源通知窗口
(3)用于用户交互的可见窗口
(4)用于UI窗口绘制的可见窗口
WPF的消息机制(三)-WPF输入事件的来源
WPF的消息机制(四)-WPF中UI的更新
?
WPF内部的5个窗口
对于Windows系统来说,它是一个消息系统,消息系统的核心就是窗口。对于WPF来说也是如此。那么WPF内部为什么需要窗口,又存在哪些窗口呢?
在上一篇,我们频繁的提及“线程”,“Dispatcher”其实,运行WPF应用程序所在的线程就是WPF所谓的UI线程,在Application.Run之后,调用Dispatcher.Run时会检查当前线程是否已经存在了一个Dispatcher对象,如果没有就构造一个,在这里,一个线程对应一个Dispatcher。因此,WPF的对象在获取this.Dispatcher属性时,不同对象取的都是同一个Dispatcher实例。另外,前面提到的“消息循环”,“消息队列”等都是Win32应用程序的概念,我们知道,提起这些概念,必然会跟Win32的“窗口”,“Handle”,“WndProc”之类的概念离不开,那么WPF里面究竟有没有“窗体”,“Handle”,“WndProc”呢?
我想说的是:有,还不止一个,只不过没有暴露出来,外面不需要关心这些。
通常情况下,一个WPF应用程序在运行起来的时候,后台会创建5个Win32的窗口,帮助WPF系统来处理操作系统以及应用程序内部的消息。在这5个窗口中,只有一个是可见的,可以处理输入事件与用户交互,其他4个窗口都是不可见的,帮助WPF处理来自其他方面的消息。接下来我会来介绍究竟这5个Win32的窗口如何帮助WPF处理消息,我会根据每个窗口创建的顺序来介绍。
?
隐藏消息窗口
创建时机:在Application的构造函数调用基类DispatcherObject的构造函数的时候,会创建一个Dispatcher对象,在Dispatcher的私有构造函数当中。
用途:实现WPF线程模型的异步调用。
谈到异步调用,相信许多人都不陌生。WinForm下,我们通常为了使一些花费较多时间的方法调用不影响UI的响应,会将这个操作分为很多步,然后使用BeginInvoke调用每一步,这样UI响应就不会被阻塞。BeginInvoke的本质是往消息队列当中PostMessage,而不是直接调用,与此同时,UI行为(MouseMove)导致系统也往消息队列当中PostMessage更新UI,但由于彼此花费的时间很短,就感觉两个消息是被同时处理似的,界面就不会觉得被阻塞了。WPF同样面临这样的问题,他是如何解决的呢?在这里Window 1#起着至关重要的作用。通过下面一副图我们来看看Window 1#在做什么事情?
WPF也是通过BeginInvoke来解决的,而Wpf的BeginInvoke是在Dispatcher上面暴露了,因为整个消息系统都是Dispatcher在协调。从上面图可以看出Dispatcher在调用BeginInvoke之后所经历的流程,最终是什么时候Foo()被真正执行的。
第一步,就是将调用的Delegate和优先级包装成一个DispatcherOperation放入Dispatcher维护的优先级队列当中,这个Queue是按DispatcherPriority排序的,总是高优先级的DispatcherOperation先被处理。关于优先级相关知识可以参考MSDN对WPF线程模型的解释。
第二步,往当前线程的消息队列当中Post一个名为MsgProcessQueue的Message。这个消息是WPF自己定义的,见Dispatcher的静态构造函数当中的
HYPERLINK /roeder/dotnet/Default.aspx?Target=code://WindowsBase::31bf3856ad364e35/System.Windows.Threading.Di
文档评论(0)