Page246~250 11.1GUI下的I/O基础

11.1.1  从“控制台”说起

“命令行交互界面”(简称CUI,也有人称为CLI)。

CUI需要我们记忆并在控制台输入命令文本内容,而GUI则以图形的方式呈现、组织各类命令,比如Windows的“开始”菜单,用户只需通过简单的键盘或鼠标操作,就可以发起命令。

GUI操作系统重,用户可以同时处理多个任务,然而,一个总喜欢等待你“按下任意键”的CUI屏幕,就是史前操作系统展现各用户的全部,难以实现多任务

CUI和GUI的形同之处

我们写过的许多与用户交互的代码,其过程基本类似于图11-1

                                        图11 -1 典型的CUI主循环

11.1.2    GUI下的输入处理

基于控制台的程序,输入用cin, 输出用cout,非常简单。

GUI的输入,并非通过一个函数直接读取用户的一个按键操作或鼠标动作(也包括触摸屏的输入)的结果,而是操作系统,帮我们捕获这些输入操作,然后再有它转发到程序。

在GUI的世界里,往往有多个程序同时运行,哪怕就只有一个程序在运行,屏幕也可能有多个“图形元素”等待用户输入,所以必须有一套机制,以方便操作系统将用户的输入准确地转发到特定的那个图形元素。

这套机制最基础的要求是:每个图元元素都有一个“编号”(可以理解为“地址”)。综上所述,输入过程如图11-2所示

                                                        图11-2  消息传递与分发

统一术语:

以Windows操作系统为例,操作系统发送给各个应用程序的信息(包括用户输入),称为“消息(Message/Msg)”;各个拥有标号的“图形元素”,称为“窗口(Windows/Wnd)”;而编号也不是普通编号,它叫“句柄(Handle)

句柄的含义:句柄就是每个窗口在操作系统中唯一的编号。

控制台程序中,当程序运行到“cin >> i”之类的语句时,程序就卡在那里等待用户输入了。

但在GUI环境下,一个带窗口的程序运行起来之后,用户抓过鼠标就在窗口上挪动,并乱点一气……,这些操作都被认为是合理的,于是就将这些消息一次发送给程序了;如果程序不处理这些消息(哪怕是收到后就直接丢弃),操作系统就会会怀疑这个程序挂掉了。

所以编写一个GUI应用,最重要的事情,就是抓紧搞一个“死循环”来接收这些消息。以Windows操作系统为例,这个“死循环”的C代码类似:

//Windows API编程示例的伪代码
MSG msg; //消息
while(::GetMessage(&msg)
{::TranslateMessage(&msg);::DispatchMessage(&msg);
}

三个全局函数,都是Windows操作系统提供的编程接口(API)函数。

GetMessage源源不断地获取属于当前进程的消息

然后通过TranslateMessage做必要的转换

再调用DispatchMessage将它们正确地分派给本进程内的窗口。

但,代码里没有看到窗口句柄,怎么知道各个消息属于哪个窗口呢?猜一下就知道了,MSG结构里有一个成员,就是这个消息所属窗口的句柄

再往后的工作,就是每个窗口都会有一个术语为"WndProc(窗口过程)"的函数,它会收到操作系统发来的消息,然后搞一个“switch / case”结构来区分消息是什么,再做处理。

                                                图  11-3    GUI下的消息循环

这个过程被称为消息循环。简单地理解,就是应用程序将源源不断地接收到消息,然后判断这消息是什么,根据这个消息触发并执行一段事件(回调函数),然后再收到新消息……

一个从零开始的GUI应用代码,需要从“GetMessage(...)”开始写起,但多数C++  GUI库,都将这个过程封装起来,所以编程重心变成是为每一类窗口(如图11-3中的窗口1和窗口2)写它处理消息的过程;但一大块的"switch / case"是令人厌烦的结构,所以GUI库提供了一些手段,帮助我们绕过"switch / case"。

11.1.3    GUI下的输出处理

既然叫“图形用户界面”,自然要在屏幕上画各种信息。屏幕再大,面积总是有限的,外加“多任务”,每个进程都抢这在屏幕上涂鸦,结果很容易想到:后面画的内容,会将前面的内容覆盖掉。

电脑上打开QQ登录框,把它摆在屏幕中央;然后打开浏览器,拖过去盖住QQ登录框,此时,我们看到的那个QQ登录框还在吗?

那个QQ登录框真的不在了。QQ程序肯定还在内存里,QQ登录框的窗口句柄也还在操作系统的“账本”里,但此时操作系统无需尝试网屏幕上“画”那个对话框;

假设我们将浏览器一点一点地挪开,此时QQ程序会收到一个消息:“你快重画窗口,不过就这一小块有效。

如此,是否可以推出GUI程序和CUI程序在界面显示上最大的不同?

CUI程序是主动的,在你想要的时间,地点,想说一句话是,直接cout一下,比如:

char C;//此时,此处,需要一句提示
cout << "请输入一个字母:";
cin >> C;//此时,此处,又需要一句话
cout << "您输入的字母是:" << C << "。" << endl;
//想想,觉得需要再补一句
cout << "我是不是很聪明?" << endl;

GUI程序在这方面却是被动的,它必须等操作系统发消息通知它:“嘿,你可以在屏幕上输出点什么了。”  操作系统通知一次,就得响应一次。

假设GUI程序使用DrawText(int x, int y, char const* text)函数可以在屏幕上指定位置上输出一句话,但程序只是主动调用一次,比如:

DrawText(100, 100, "Hello World");

屏幕上确实有可能出现那句话,但此时再把浏览器拖过啦,“盖住”那行话,然后移开……那行话消失不见了,浏览器就像一个橡皮擦,把那行话擦掉了

其间原因在于:我们写的程序也接收到了操作系统“快重画吧”的消息,却不理会这个消息,没有再次调用DrawText()操作。

那么,是不是屏幕上显示的所有内容,都需要我们写代码自行绘画呢?当然不是,像常规窗口,对话框,按钮,列表框和菜单等标准袁术,它们在不同的应用中长得样子都相似,可见其画法都一样。因为它们统一由操作系统(或其GUI支持库)负责在屏幕上画出来,除非我们想搞定制,比如画一个不规则多边形的按钮。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/458802.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

登录+JS逆向进阶【过咪咕登录】(附带源码)

JS渗透之咪咕登录 每篇前言&#xff1a;咪咕登录参数对比 captcha参数enpassword参数搜索enpassword参数搜索J_RsaPsd参数setPublic函数encrypt加密函数运行时可能会遇到的问题此部分改写的最终形态JS代码&#xff1a;运行结果python编写脚本运行此JS代码&#xff1a;运行结果&…

hummingbird,一个非常好用的 Python 库!

前言 随着人工智能和机器学习的快速发展&#xff0c;将训练好的模型部署到生产环境中成为了一个重要的任务。而边缘计算设备&#xff0c;如智能手机、嵌入式系统和物联网设备&#xff0c;也需要能够运行机器学习模型以进行实时推理。Python Hummingbird 是一个强大的工具&…

【图形学】投影和消隐简介

投影 正交投影 对于物体上任意一点的三维坐标P(x,y,z),投影后的三维坐标为 P ′ ( x ′ , y ′ , z ′ ) P^\prime(x^\prime,y^\prime,z^\prime) P′(x′,y′,z′),那么正交投影的方程为 { x ′ x y ′ y z ′ 0 \begin{cases} x^\primex\\y^\primey\\z^\prime0 \end{case…

做跨境电商需要使用住宅代理IP吗?

住宅代理IP是近年来跨境电商领域日益受到重视的技术工具&#xff0c;不仅可以保护隐私、优化网络速度&#xff0c;还能助推跨境电商的精细化管理。接下来&#xff0c;我们将深入探讨利用住宅代理IP如何为跨境电商业务带来竞争优势。 一、住宅代理IP与跨境电商 住宅代理IP&…

flex:1最后一行或者只有一行时不想占满整行

flex:1最后一行或者只有一行时不想占满整行 问题解决方法注意 问题 在设置flex1的时候&#xff0c;如果内容只有一行或者多行的最后一行的时候&#xff0c;往往最后一行会占满整行&#xff0c;导致项目比其他行宽&#xff0c;比如&#xff1a; 解决方法 这时候我们可以使用…

2.3_9 吸烟者问题

2.3_9 吸烟者问题 问题描述 问题分析 假设一个系统有三个抽烟者进程和一个供应者进程。每个抽烟者不停地卷烟并抽掉它&#xff0c;但是要卷起并抽掉一支烟&#xff0c;抽烟者需要有三种材料&#xff1a;烟草、纸和胶水。三个抽烟者中&#xff0c;第一个拥有烟草、第二个拥有纸…

BlueLotus 下载安装使用

说明 蓝莲花平台BlueLotus&#xff0c;是清华大学曾经的蓝莲花战队搭建的平台&#xff0c;该平台用于接收xss返回数据。 正常执行反射型xss和存储型xss&#xff1a; 反射型在执行poc时&#xff0c;会直接在页面弹出执行注入的poc代码&#xff1b;存储型则是在将poc代码注入用…

【Docker】Docker Image(镜像)

文章目录 一、Docker镜像是什么&#xff1f;二、镜像生活案例三、为什么需要镜像四、镜像命令详解docker rmidocker savedocker loaddocker historydocker image prune 五、镜像操作案例六、镜像综合实战实战一、离线迁移镜像实战二、镜像存储的压缩与共享 一、Docker镜像是什么…

孙思邈中文医疗大模型

孙思邈, 唐代医药学家、道士, 被后人尊称为"药王". 其十分重视民间的医疗经验, 不断积累走访, 及时记录下来, 写下著作《千金要方》. 唐朝建立后, 孙思邈接受朝廷的邀请, 与政府合作开展医学活动, 完成了世界上第一部国家药典《唐新本草》. 孙思邈中医药大模型(简称:…

【C语言】位与移位操作符详解

目录 1.⼆进制和进制转换 ①十进制&#xff1a;生活中最常用 ②二进制&#xff1a;计算机中使用的&#xff0c;每个数字称为一个比特 ③八进制、十六进制也如上 ④二进制转十进制 ⑤十进制转二进制 ⑥二进制转八进制 ⑦二进制转十六进制 2.原码、反码、补码 3.移位操…

【C++航海王:追寻罗杰的编程之路】类与对象你学会了吗?(下)

目录 1 -> 再谈构造函数1.1 -> 构造函数体赋值1.2 -> 初始化列表1.3 -> explicit关键字 2 -> static成员2.1 -> 概念2.2 -> 特性 3 -> 友元3.1 -> 友元函数3.2 -> 友元类 4 -> 内部类5 -> 匿名对象6 -> 拷贝对象时的一些编译器优化 1 -…

[N-141]基于springboot,vue网上拍卖平台

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 系统分前后台&#xff0c;项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plusredi…