前言

  谈起“消息机制”这个词,我们都会想到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在启动之后都走了哪些逻辑:

  通过调用堆栈可以看出,蓝色的部分是启动了一个线程,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()的代码,你会看到有下面的一段代码:

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

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

一起谈.NET技术,WPF的消息机制(一)- 让应用程序动起来相关推荐

  1. WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口

    原文:WPF的消息机制(二)- WPF内部的5个窗口之隐藏消息窗口 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/powertoolsteam/ar ...

  2. WPF的消息机制(三)- WPF内部的5个窗口之处理激活和关闭的消息窗口以及系统资源通知窗口...

    目录 WPF的消息机制(一)-让应用程序动起来 WPF的消息机制(二)-WPF内部的5个窗口 (1)隐藏消息窗口 (2)处理激活和关闭的消息窗口和系统资源通知窗口 (3)用于用户交互的可见窗口 (4) ...

  3. 一起谈.NET技术,.NET缓存机制探讨与比对

    相信大多数开发人员都比较了解缓存了,很多开发人员都在软件开发中使用了预定义或自定义的缓存,并从中获得了预期的应用程序的性能提升.这篇和后续文章将详细的介绍与探讨.net体系下的缓存实现的机制,并讨论它 ...

  4. Window捕获消息机制-C#

    C#捕获鼠标消息 在C#中怎样禁用鼠标按键,我们可以通过ImessageFilter接口下的PreFilterMessage方法.Application类的AddMessageFilter方法,Rem ...

  5. windows消息机制和Linux,Windows消息机制初谈 (转)

    Windows消息机制初谈 (转)[@more@]是一个消息的OS,什么是消息呢?我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解. 1.消息的组 ...

  6. Windows消息机制详解

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  7. Windows消息机制详解-6

    消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用程序某个事情发生了.例如, ...

  8. Windows消息机制详解-2

    消息是指什么?      消息系统对于一个win32程序来说十分重要,它是一个程序运行的动力源泉.一个消息,是系统定义的一个32位的值,他唯一的定义了一个事件,向 Windows发出一个通知,告诉应用 ...

  9. 浅谈Hybrid技术的设计与实现【转】

    https://www.cnblogs.com/yexiaochai/p/4921635.html 前言 浅谈Hybrid技术的设计与实现 浅谈Hybrid技术的设计与实现第二弹 浅谈Hybrid技术 ...

最新文章

  1. KubeSphere安装Mysql5.7
  2. 零基础入门学习Python(26)-文件1
  3. 【基于libRTMP的流媒体直播之 AAC、H264 推送】
  4. NSOperation下载网络图片(四)
  5. hive中如何读取数组_hive解析json嵌套数组
  6. HTML DOM教程 21-HTML DOM Event 对象
  7. Java Web整合开发(81)
  8. qthread run结束了算销毁吗_Java线程的run()方法和start()方法有什么区别?
  9. 算法面试题:均分纸牌
  10. matlab-自控原理 已知x~=Ax+Bu中的AB矩阵和X0,求单位输入下的时间响应
  11. python做后端速度慢吗_【后端开发】python如何提高运行速度
  12. centos 卸载docker_Docker (一) 安装
  13. 台式计算机最常用的IO总线,三总线结构的计算机总线系统由 (1) 组成。
  14. Node.js学习笔记(五)——WebSocket
  15. ucfirst php_PHP ucfirst()函数与示例
  16. matlab对频谱傅里叶逆变换,基于功率谱的傅里叶逆变换问题
  17. Ubuntu 18.04 ibus安装配置中文拼音输入法
  18. iOS iPhone各机型尺寸及导航栏高度
  19. 菜鸟日记(yzy):集成Ucrop裁剪图片架构,并创建管理类使用
  20. 在网上请不要惹一个程序员

热门文章

  1. Hudson安装配置文档
  2. 阿里巴巴MySQL DBA面试题答案(欢迎进来讨论)
  3. 数学建模——遗传算法(GA)
  4. 工业大数据有哪些特征
  5. android 任意剪切view,Android 任意View切圆角
  6. [最后几天]蓝桥杯如何优雅控分
  7. AcWing 1132. 农场派对(最短路反向建边)
  8. java 执行oracle命令_利用oracle存储过程执行操作系统命令
  9. android 自定义 build.gradle,Gradle for Android 第二篇( Build.gradle入门 )
  10. R语言︱决策树族——随机森林算法