不同平台的GUI实现原理是一样的。 本实验基于 windos平台。

先捋一捋概念

什么是消息队列(Message Queue)

假 设一个场景:系统正在处理WM_PAINT消息,就在这时用户在键盘上敲击了一些按键,这时会发生什么呢?系统应该中断绘图操作然后处理按键消息还是应该 丢弃按键的消息?很明显这些都是不合理的,因此我们引入了消息队列,当消息发送过来,将消息加入消息队列,当一个消息被处理时,将其从消息队列移除。这样 确保消息不会丢失,当你正在处理一个消息时,其它到来的消息可以加入到消息队列直到被处理。

什么是消息循环(Message Loop)

while(GetMessage(&Msg, NULL, 0, 0) > 0) 

    TranslateMessage(&Msg); 
    DispatchMessage(&Msg); 

上面代码的执行过程为:
1. 消息循环调用GetMessage()从消息队列中查找消息进行处理,如果消息队列为空,程序将停止执行并等待(程序阻塞)。
2. 事件发生时导致一个消息加入到消息队列(例如系统注册了一个鼠标点击事件),GetMessage()将返回一个正值,这表明有消息需要被处理,并且消息已经填充到传入的MSG参数中;当传入WM_QUIT消息时返回0;如果返回值为负表明发生了错误。
3. 取出消息(在Msg变量中)并将其传递给TranslateMessage()函数,这个函数做一些额外的处理:将虚拟键值信息转换为字符信息。这一步实际上是可选的,但有些地方需要用到这一步。
4. 上面的步骤执行完后,将消息传递给DispatchMessage()函数。DispatchMessage()函数将消息分发到消息的目标窗口,并且查找目标窗口过程函数,给窗口过程函数传递窗口句柄、消息、wParam、lParam等参数然后调用该函数。
5. 在窗口过程函数中,检查消息和其他参数,你可以用它来实现你想要的操作。如果不想处理某些特殊的消息,你应该总是调用DefWindowProc()函数,系统将按按默认的方式处理这些消息(通常认为是不做任何操作)。
6. 一旦一个消息处理完成,窗口过程函数返回,DispatchMessage()函数返回,继续循环处理下一个消息。

消 息循环对Windows编程来说是一个非常重要的概念。窗口过程函数并不是系统自动调用的,而是由开发人员自己通过调用 DispatchMessage()间接的调用的。

代码可以看出,程序的大部分时间都在处理消息循环。窗 口会不断的处理发过来的消息,但如果要退出程序该怎么做呢?因为我们用的是while()循环,如果GetMessage()返回的是FALSE(即0) 会退出循环,程序能够执行到WinMain()结束处,即程序退出:这正是PostQuitMessage()函数完成的工作,该函数会将WM_QUIT 消息添加到消息队列的队尾,GetMessage()从消息队列取出WM_QUIT消息,填充Msg结构,返回的不是正数,而是0。与此同时,结构Msg 的成员wParam的值会被置为你传给PostQuitMessage()函数参数的值,你可以选择忽略它或做为WinMain()函数的返回值即进程的 退出代码(Exit Code)。

注意:如果发生错误,GetMessage()函数将返回-1。你应该记住这点,说不定你的程序会因此 出错。尽管GetMessage()返回值位BOOL型,但它可以返回TRUE或FALSE之外的值,因为BOOL被定义成UINT(unsigned int)。下面的程序貌似能正常工作,但有些时候不能正常工作。

while(GetMessage(&Msg, NULL, 0, 0)) 

while(GetMessage(&Msg, NULL, 0, 0) != 0) 

while(GetMessage(&Msg, NULL, 0, 0) == TRUE)

上面的代码都是错误的!有些程序中你会看到会使用第一中方式,使用这种方式你必须保证GetMessage()总是执行成功,否则应该使用下面这段代码:

while(GetMessage(&Msg, NULL, 0, 0) > 0)

希望你对Windows消息循环能有很好的理解,如果还没有,慢慢来,在使用过程中会逐渐理解的。

GUI应用编程初体验的更多相关文章

  1. ASP.NET Core 6框架揭秘实例演示[01]: 编程初体验

    作为<ASP.NET Core 3框架揭秘>的升级版,<ASP.NET Core 6框架揭秘>提供了很多新的章节,同时对现有的内容进行大量的修改.虽然本书旨在对ASP.NET ...

  2. Linux下使用gcc编程初体验

    近期刚刚放弃了Windows,投入了Ubuntu 的怀抱.今天就拿一个小小的案例来做一下C语言的编译和运行流程.额,顺便说一句.本文适合那些Linux新手,不适合老鸟哈. 看完本文可以学到什么? 程序 ...

  3. Erlang OTP编程初体验——gen_server和行为模式

    http://blog.sina.com.cn/s/blog_3fe961ae0101k4p6.html 行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的.OTP行为模式将一些反复出现 ...

  4. IOS - socket 编程初体验

    #import "ViewController.h" @interface ViewController () <NSStreamDelegate, UITextFieldD ...

  5. Shell脚本编程初体验

    原文:http://linoxide.com/linux-shell-script/guide-start-learning-shell-scripting-scratch/ 作者: Petras L ...

  6. 实验1 C语言开发环境使用和编程初体验

    #include <stdio.h> #include <stdlib.h> int main() { printf ("202083290273\n2020 ,wh ...

  7. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  8. 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)

    数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...

  9. Spring之初体验

                                     Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...

随机推荐

  1. 通过DatabaseMetaData数据库元信息类,获取特定数据库的元信息

    数据库版本:mysql8.0.18 ide:idea 2019.3 可以看到代码中连接的数据库为course_select,是一个学生的选课系统的数据库 然后通过DatabaseMetaData的ge ...

  2. SwiftUI - Grid View 的实现方法,逐步剖析助你实现

    简介 在当前正式 SwiftUI 版本而言,很多控件都是缺少的.比如在 UIKit 框架里有 UICollectionView 组件,可以很方便地做 Gird 格子类型的视图.但是在 SwiftUI ...

  3. 性能提升40%: 腾讯 TKE 用 eBPF 绕过 conntrack 优化 K8s Service

    Kubernetes Service 用于实现集群中业务之间的互相调用和负载均衡,目前社区的实现主要有userspace,iptables和IPVS三种模式.IPVS模式的性能最好,但依然有优化的空间 ...

  4. Python 快速验证代理IP是否有效

    有时候,我们需要用到代理IP,比如在爬虫的时候,但是得到了IP之后,可能不知道怎么验证这些IP是不是有效的,这时候我们可以使用Python携带该IP来模拟访问某一个网站,如果多次未成功访问,则说明这个 ...

  5. python执行gradle脚本

    import os import shutil import subprocess #拷贝文件 def copyFile(srcFile, dstFile): #检查源文件是否存在 if not os ...

  6. POJ-3255-Roadblocks(次短路的另一种求法)

    Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. Sh ...

  7. Java是否还能再辉煌十年?

    目录 Java是否还能再辉煌十年? 一.前言 二.如今的Java语言 2.1 位居TIOBE榜首 2.2 革命性的语言 三.Java受到的挑战 3.1 后台服务器软件的语言竞争 3.1.1 Pytho ...

  8. jenkins安装和邮件配置

    一.jenkins下载 Jenkins的下载地址是https://jenkins.io/download/,下载的时候可以选择各个版本的以及对应操作系统的版本,一般你下载的时候下载通用的.war文件即 ...

  9. 【NOIP2015模拟】终章-剑之魂

    背景介绍 古堡,暗鸦,斜阳,和深渊-- 等了三年,我独自一人,终于来到了这里-- "终焉的试炼吗?就在这里吗?"我自言自语道. "终焉的试炼啊!就在这里啊!"我 ...

  10. 没使用Spring Cloud的版本管理导致Eureka服务无法注册到Eureka服务注册中心

    创建了一个Eureka Server的服务注册集群(两个Eureka服务),都能相互注册,写了一个Eureka客户端服务无法注册到服务发现注册中心 注册中心1: 注册中心2: 服务正常: pom依赖文 ...