WPF的消息机制(一)- 让应用程序动起来

简介: 前言 谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际上消息是被Post到特定窗口所在线程的消息队列,应用程序的消息循环再不断的从消息队列当中获取消息,然后再派发给特定窗口类的窗口过程来处理,在窗口过程中完成一次用户交互。

前言

谈起“消息机制”这个词,我们都会想到Windows的消息机制,系统将键盘鼠标的行为包装成一个Windows Message,然后系统主动将这些Windows Message派发给特定的窗口,实际上消息是被Post到特定窗口所在线程的消息队列,应用程序的消息循环再不断的从消息队列当中获取消息,然后再派发给特定窗口类的窗口过程来处理,在窗口过程中完成一次用户交互。

其实,WPF的底层也是基于Win32的消息系统,那么对于WPF应用程序来说,它是如何跟Win32的消息交互,这里到底存在一个什么样的机制?接下来我会通过下面几篇博文介绍这个消息机制:

WPF的消息机制(一)-让应用程序动起来

WPF的消息机制(二)-WPF内部的5个窗口

(1)隐藏消息窗口

(2)处理激活和关闭的消息的窗口和系统资源通知窗口

(3)用于UI窗口绘制的可见窗口

(4)用于用户交互的可见窗口

WPF的消息机制(三)-WPF输入事件的来源

WPF的消息机制(四)-WPF中UI的更新

 

让应用程序动起来

谈到WPF的消息,首先应该知道DispactherObject以及Dispatcher在WPF系统中的作用。

WPF大部分的对象都是从DispatcherObject派生的,从这里派生的对象具有一个明显的特征,那就是:修改对象时所在的线程,和创建对象时所在线程必须为同一个线程,这就是微软所谓的线程亲缘性(Thread affinity)的最简单理解。那么谁能保证线程亲缘性呢?那就是Dispacher了。从DispatcherObject派生的类型继承三个重要的成员:Dispatcher属性,CheckAccess(), VerifyAccess()方法。其中后面两个方法就是检验线程亲缘性的。按照WPF的实现,如果你自己定义了个WPF的类型,并且是DispatcherObject的子类,你就必须在public的成员定义的逻辑开始处,调用base.Dispatcher.VerifyAccess(),检验线程亲缘性。那么Dispatcher到底还做了什么事情呢?

首先,我们看一下一个WPF的Application在启动之后都走了哪些逻辑:

clip_image002

通过调用堆栈可以看出,蓝色的部分是启动了一个线程,VisualStudio在Host的进程当中运行当前应用程序;红色的部分是从Application.Main函数开始执行,经过几个函数到达Dispatcher.Run(),最后到达Dispather.PushFrameInpl()方法。那么一个Application在Run之后,为什么要调用Dispatcher.Run()呢,他做了些什么事情你?如果通过Reflector仔细查看Application.Run(),你会发现里面实际起作用的代码并不多,最后都是Dispatcher.Run在做事情。那么一个Application启动之后,按照以前对Win32的消息机制的理解,当应用程序启动后,必须进入消息循环,对于WPF,也是一样的。那么WPF应用程序是在什么地方进入消息循环呢?其实这就是Dispatcher.Run()做的事情。查看上图最后一步Dispacther.PushFrameImpl()的代码,你会看到有下面的一段代码:

clip_image004

很明显,橙色的部分是一个循环,看起来是不是很眼熟,跟Win32编程碰到的消息循环是否很像?对了,这就是WPF应用程序进入了消息循环。循环调用GetMessage方法从当前线程的消息队列当中不停的获取消息,取出一个msg之后,交给TranslateAndDispatchMessage方法Dispatch到不同的窗口过程去处理。这样以来,任何需要应用程序处理的消息通过这个过程,被不同的窗口处理了,应用程序就动起来了。

开发工具

ComponentOne Studio WPF 是专为桌面应用程序开发所准备的一整套控件包,崇尚优雅和创新,以“触控优先”为设计理念,内含轻量级高性能表格控件,和大量类型丰富的2D和3D图表控件,能使开发的应用程序更富创意。

 

下面的一篇我会介绍WPF当中的Win32窗口,正是这些窗口,处理着来自系统,或者来自应用程序内部的消息。

敬请期待~

相关文章
|
8月前
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
230 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
8月前
|
机器学习/深度学习 存储 传感器
DeepMind发布Matryoshka(套娃)量化:利用嵌套表示实现多精度LLM的低比特深度学习
本文介绍 Google DeepMind 提出的 Matryoshka 量化技术(MatQuant),该技术通过训练单个大型语言模型(LLM)实现多精度部署,革新了深度学习
189 4
|
12月前
|
SQL 网络安全 数据库
机房电脑下载并安装SQL Server的详细步骤
在机房电脑上下载并安装SQL Server是一个常见的任务,特别是对于学习数据库管理或进行相关项目开发的学生和开发者来说
|
存储 数据可视化 数据挖掘
大数据环境下的房地产数据分析与预测研究的设计与实现
本文介绍了一个基于Python大数据环境下的昆明房地产市场分析与预测系统,通过数据采集、清洗、分析、机器学习建模和数据可视化技术,为房地产行业提供决策支持和市场洞察,探讨了模型的可行性、功能需求、数据库设计及实现过程,并展望了未来研究方向。
628 4
大数据环境下的房地产数据分析与预测研究的设计与实现
|
负载均衡 安全 Linux
openstack 网络Neutron知识点《openstack》
本人cdsn账号 https://liuyunshengsir.blog.csdn.net/article/details/124927149
1156 1
openstack 网络Neutron知识点《openstack》
|
存储 移动开发 前端开发
APP 开发技术该如何选型 ?
APP 开发技术该如何选型 ?
866 0
APP 开发技术该如何选型 ?
|
机器学习/深度学习 人工智能 算法
【深度学习之美】LSTM长短记,长序依赖可追忆(入门系列之十四)
如果你是一名单身狗,不要伤心,或许是因为你的记忆太好了。有时,遗忘是件好事,它让你对琐碎之事不再斤斤计较。然而每当自己记不住单词而“问候亲人”时,也确实气死个人。于是你懂得了如何控制好什么信息该保留,什么信息该遗忘。而长短期记忆网络(LSTM)就是这么干的。来看看是怎么回事吧?
29172 0
|
数据挖掘 索引 编解码
R-loop数据分析之R-ChIP(环境准备)
提高自己分析能力的一个好的方法就是重复别人文章里的分析策略,所以这里会尝试对第一篇介绍R-ChIP技术文章"R-ChIP Using Inactive RNase H Reveals Dynamic Coupling of R-loops with T...
1656 0
R-loop数据分析之R-ChIP(环境准备)
|
iOS开发 移动开发
iOS模拟器安装debug包
由于项目是Hybrid的平台,有第三方人员需要在上面开发H5应用,但是release包不能调试H5,只有debug报可以调试,但是项目源码不能交给第三方,在google搜索了下,发现一篇霜神的文章,讲的是debug包可以拷贝到其它机器运行,于是实践了一波。
1863 0
iOS模拟器安装debug包