GUI应用编程初体验
不同平台的GUI实现原理是一样的。 本实验基于 windos平台。
先捋一捋概念
什么是消息队列(Message Queue)
假 设一个场景:系统正在处理WM_PAINT消息,就在这时用户在键盘上敲击了一些按键,这时会发生什么呢?系统应该中断绘图操作然后处理按键消息还是应该 丢弃按键的消息?很明显这些都是不合理的,因此我们引入了消息队列,当消息发送过来,将消息加入消息队列,当一个消息被处理时,将其从消息队列移除。这样 确保消息不会丢失,当你正在处理一个消息时,其它到来的消息可以加入到消息队列直到被处理。
什么是消息循环(Message Loop)
{
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) != 0)
while(GetMessage(&Msg, NULL, 0, 0) == TRUE)
上面的代码都是错误的!有些程序中你会看到会使用第一中方式,使用这种方式你必须保证GetMessage()总是执行成功,否则应该使用下面这段代码:
希望你对Windows消息循环能有很好的理解,如果还没有,慢慢来,在使用过程中会逐渐理解的。
GUI应用编程初体验的更多相关文章
- ASP.NET Core 6框架揭秘实例演示[01]: 编程初体验
作为<ASP.NET Core 3框架揭秘>的升级版,<ASP.NET Core 6框架揭秘>提供了很多新的章节,同时对现有的内容进行大量的修改.虽然本书旨在对ASP.NET ...
- Linux下使用gcc编程初体验
近期刚刚放弃了Windows,投入了Ubuntu 的怀抱.今天就拿一个小小的案例来做一下C语言的编译和运行流程.额,顺便说一句.本文适合那些Linux新手,不适合老鸟哈. 看完本文可以学到什么? 程序 ...
- Erlang OTP编程初体验——gen_server和行为模式
http://blog.sina.com.cn/s/blog_3fe961ae0101k4p6.html 行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的.OTP行为模式将一些反复出现 ...
- IOS - socket 编程初体验
#import "ViewController.h" @interface ViewController () <NSStreamDelegate, UITextFieldD ...
- Shell脚本编程初体验
原文:http://linoxide.com/linux-shell-script/guide-start-learning-shell-scripting-scratch/ 作者: Petras L ...
- 实验1 C语言开发环境使用和编程初体验
#include <stdio.h> #include <stdlib.h> int main() { printf ("202083290273\n2020 ,wh ...
- Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)
数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
随机推荐
- vue组件获取和vue-cli的基本了解
Vue获取组件的一些方法 this.$refs.xxx 给标签绑定ref属性,获取的是当前DOM对象 给组件绑定ref属性,获取的是组件实例对象 this.$parent 获取当前组件的父组件,为一个 ...
- 【原创】Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- Update LateUpdae FixedUpdate
这个问题本来是在研究动画系统时遇到的:OnAnimatorMove在Animator.Update()调用,那这个Animator.Update是什么时候调用的呢. Animator Componen ...
- Photon PUN 三 RPCs & RaiseEvent
官方文档地址 https://doc.photonengine.com/en-us/pun/current/manuals-and-demos/rpcsandraiseevent 一, RPC P ...
- 【转】对初学LoadRunner朋友的建议
对初学LoadRunner朋友的建议 作者:wind摘要:随着Internet的普及与迅速发展,企业业务量的迅速加大,数据大集中成为一种趋势,IT系统承载的负荷越来越重,系统性能的好坏严重的影响了企业 ...
- 关于前端Ajaxc传FormData后台如何接收转base64
前端是Jquery的ajax,后台是C#MVC,代码如下: <------前端-----> var formData = new FormData(); formData.append(& ...
- JavaWeb三大器(过滤器、拦截器、监听器)概念梳理
最近工作碰到了一个问题:项目A需要收集项目B中的用户活跃数信息,最后通过HttpSessionAttributeListener实现.在开发过程中,网上查找了过滤器.拦截器.监听器的帖子,这里对自己收 ...
- 深入理解 IoC、DI
本文转载自博客:https://www.cnblogs.com/xinhuaxuan/p/6132372.html 1.控制反转:谁控制谁?控制什么?为何叫反转(对应于正向)?哪些方面反转了?为何需要 ...
- 转载:使用java获取某A股当天/上一交易日的交易基本信息
整个程序是借用了新浪的对外股票接口http://hq.sinajs.cn/list=sh603696,如果把这个地址放到浏览器地址栏里,你将看到: var hq_str_sh603696=" ...
- 用Nginx将web请求引导到本机两个tomcat
如何在本机启动两个tomcat请参考:https://www.cnblogs.com/xiandedanteng/p/12100461.html 而Nginx这边,将\conf\nginx.conf ...