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支持库)负责在屏幕上画出来,除非我们想搞定制,比如画一个不规则多边形的按钮。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

跳格子3 - 华为OD统一考试

OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 200分 题解&#xff1a; Java / Python / C 题目描述 小明和朋友们一起玩跳格子游戏&#xff0c; 每个格子上有特定的分数 score [1, -1, -6, 7, -17, 7]&#xff0c; 从起点score[0]开始&#xff0c;每次最大的步…

YOLO部署实战(2):使用OpenCV优化视频转图片流程并设置帧数

在计算机视觉和图像处理领域&#xff0c;OpenCV是一个强大的开源库&#xff0c;它为处理图像和视频提供了丰富的工具和功能。本文将介绍如何使用OpenCV将视频文件转换为一系列图片&#xff0c;并演示如何通过设置转换的帧数来优化这一过程。 1 Win10配置OpenCV 在Windows操作…

【Linux】基于管道进行进程间通信

进程间通信 一、初识进程间通信1. 进程间通信概念2. 进程间通信分类 二、管道1. 管道概念2. 管道原理3. 匿名管道4. 匿名管道系统接口5. 管道的特性和情况6. 匿名管道的应用&#xff08;1&#xff09;命令行&#xff08;2&#xff09;进程池 7. 命名管道&#xff08;1&#xff…

c++阶梯之类与对象(中)< 续集 >

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 前言&#xff1a; 在上文中&#xff0c;我们学习了类的六个默认成员函数之构造&#xff0c;析构与拷贝构造函数&#xff0c;接下来我们来看看剩下…

操作系统-信号量机制(整型信号量 记录型信号量)与用信号量实现进程互斥,同步,前驱关系

文章目录 信号量机制总览信号量机制整型信号量记录型信号量例子记录型信号量小结 小结 用信号量实现进程互斥&#xff0c;同步&#xff0c;前驱关系总览信号量机制实现进程互斥信号量机制实现进程同步进程同步信号量实现进程同步 信号量机制实现前驱关系小结 信号量机制 总览 …

索引失效问题

1、 like 以%开头&#xff0c;索引无效&#xff1b;当like前缀没有%&#xff0c;后缀有%时&#xff0c;索引有效。 &#xff08;1&#xff09;创建索引 create index text1 on emp(name); &#xff08;2&#xff09;不走索引 EXPLAIN select id,name,age,workno from emp wh…

什么是MVVM模型

MVVM&#xff08;Model-View-ViewModel&#xff09;是一种用于构建 Web 前端应用程序的架构模式。它是从传统的 MVC&#xff08;Model-View-Controller&#xff09;模型演变而来&#xff0c;旨在解决界面逻辑与业务逻辑之间的耦合问题。 在传统的 MVC 架构中&#xff0c;View …

【Linux笔记】文件系统与软硬链接

一、文件系统概述 1.1、先来聊一聊“磁盘” 在讲解文件系统之前&#xff0c;我觉得有必要先聊一下“磁盘”&#xff0c;因为我觉得如果弄懂了磁盘的存储原理&#xff0c;大家可能更容易理解文件系统是怎么管理数据的&#xff0c;并且理解计算机是怎么将磁盘抽象到文件系统的。…

前端常用代码整理(不断更新中)— js,jquery篇

1.随机函数代码 function getRandom(min, max) {return Math.floor(Math.random() * (max - min 1)) min}2.倒计时代码 let now new Date()// 2. 得到指定时间的时间戳let last new Date(这里写想要达到的时间)// 3. &#xff08;计算剩余的毫秒数&#xff09; / 1000 剩余…

如何在 Linux 中安装 s3cmd 并管理 Amazon s3 存储桶

概述 S3&#xff0c; – 简单存储服务- 是亚马逊的存储服务&#xff0c;为 IT 团队提供一种安全、可扩展且可靠的方式来存储和检索云上的文件和文件夹。 S3 可确保数据在需要时可用并随着需求的增长而扩展&#xff0c;从而帮助您充分利用数据。 通常&#xff0c;在登录到您的…

RabbitMQ-5.消费者的可靠性

消费者的可靠性 5.消费者的可靠性5.1.消费者确认机制5.2.失败重试机制5.3.失败处理策略5.4.业务幂等性5.4.1.唯一消息ID5.4.2.业务判断 5.5.兜底方案 5.消费者的可靠性 当RabbitMQ向消费者投递消息以后&#xff0c;需要知道消费者的处理状态如何。因为消息投递给消费者并不代表…

【数据结构与算法】堆 / 堆排序 / TopK问题(Heap)

文章目录 1.堆2.C语言实现堆2.1 堆结构与基本操作2.2 其它辅助操作2.3 堆的基本操作2.3.1 插入2.3.2 删除 3. 堆排序4. TopK5. 所有代码 1.堆 堆总是一棵完全二叉树&#xff0c;而完全二叉树更适合使用**顺序结构&#xff08;数组&#xff09;**存储&#xff0c;完全二叉树前h…

阿里云企业用户2核4G5M固定带宽199元一年,续费不涨价

2024年2月阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核…

Echarts统计用户近七日走量趋势:前后端实现

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f492; 公众号&#xff1a;知识浅谈 &#x1f525;网站…

嵌入式学习Day14 C语言 --- 位运算

位运算 注意&#xff1a;符号位也遵循这个规则 一、按位与(&) 运算规则&#xff1a;一假则假 int a 0x33;a & 0x55;0011 00110101 0101 &----------0001 0001 //0x11 二、按位或(|) 运算规则&#xff1a;一真则真 int a 0x33;a |0x55;0011 00110101 0101 |…

STM32Cubmax stm32f103zet6 SPI通讯

一、基本概念 SPI 是英语 Serial Peripheral interface 的缩写&#xff0c;顾名思义就是串行外围设备接口。是 Motorola 首先在其 MC68HCXX 系列处理器上定义的。 SPI 接口主要应用在 EEPROM&#xff0c; FLASH&#xff0c;实时时 钟&#xff0c; AD 转换器&#xff0c;还有数…

GLSL ES 1.0

GLSL ES 概述 写在前面 程序是大小写敏感的每一个语句都应该以英文分号结束一个shader必须包含一个main函数&#xff0c;该函数不接受任何参数&#xff0c;并且返回voidvoid main() { }数据值类型 GLSL支持三种数据类型&#xff1a; 整型浮点型&#xff1a;必须包含小数点&…

eclipse使用google的Java代码格式

插件下载地址 1.下载eclipse的插件 2.下载的jar包放到eclipse安装目录的dropins文件夹 D:\install_package\STS\sts-4.10.0.RELEASE\dropins&#xff13;.重启后设置 eclipse - windows - preference - java - code style - formatter -

Excel——合并计算

1.表格的合并计算&#xff08;单张表格/多个表格&#xff09; Q&#xff1a;请统计两个表格中各商品的总销量和总销售额&#xff0c;将结果放置在下方任意位置。 A&#xff1a;选择一个需要将合并计算数据放置区域的空白单元格 选择【数据】——【合并计算】&#xff0c;【函…

Linux安装Java

yum安装 下面命令直接复制粘贴一件安装java17 yum list installed | grep java #查看已经安装的javayum remove java* -y #移除现在系统已经安装的javayum list | grep java-17 #查看安装java17yum install -y java-17-openjdk #安装java17此处可…