《Windows API每日一练》5.1 键盘基础

news2025/4/11 18:25:34

本节我们讲述关于键盘的一些基础知识。当我们按下一个键盘按键时,会产生一个键盘按键消息。这一点你能确定吗?假如是一个菜单快捷键消息,或者是一个子窗口控件消息呢?这就超出了本节讨论的范围,我们将在菜单和子窗口控件详细讲述。假设的确是一个按键消息,它将被送入窗口消息队列,做同步处理。在消息循环中,GetMessage函数获取到按键消息后,如果是一个字符按键消息,TranslateMessage函数会将其转化为字符消息WM_CHAR并将其送入消息队列,然后再由DispatchMessage函数继续将按键消息分发给Windows系统。如果是一个非字符按键消息,则直接由DispatchMessage函数将其分发给Windows系统。

本节必须掌握的知识点:

        忽略键盘

        键盘焦点

        队列和同步

        击键和字符

5.1.1 忽略键盘

       当我们按下键盘按键的时候会产生键盘按键消息,或者我们调用PostMessage或SendMessage函数发送键盘消息,也可能是Windows系统产生的按键消息。所有这些按键消息并不是都需要我们主动去处理的。我们只需要处理真正需要关注的一些按键消息,把一些不需要我们处理的按键消息统统交给Windows系统默认的窗口过程去处理。这些常常忽略的按键消息有以下几类:

       ■系统按键消息

通常可以忽略一些属于系统功能的按键操作。这些按键一般都包含Alt键。程序不必去监控这些按键消息,因为Windows会将按键的效果通报给程序,在默认情况下,它们会被交付给DefWindowProc函数处理。有时候我们处于某种目的也可能会拦截系统按键消息,在后面的章节中遇到了我们再详细讲述。

键盘快捷键消息

许多Windows程序用键盘快捷键来调用常用菜单项。快捷键经常是Ctrl键同功能键或 者字母键的组合(例如,Ctrl+S键用于保存一个文件)。这些键盘快捷键和程序菜单一起在程 序的资源脚本中定义,这些我们将在第九章中看到。Windows会把这些键盘快捷键转换为菜单命令消息。你不必自己去做转换,窗口过程只需要处理菜单消息就可以了。

控件消息

对话框也有键盘接口,但是程序不必在对话框活跃的时候去监视键盘。Windows会处理 键盘接口,接着Windows把击键效果的消息传送给程序。对话框包含了用于文本输入的编 辑控件。它们一般是一些小方框,用户可以输入字符串。Windows处理所有的编辑控件逻辑,并在用户输入完成后,将最终的内容传送给程序。关于对话框,将在第十章详细介绍。

编辑控件不必局限于只有单独的一行,它的位置也不必局限在对话框中。程序主窗口中的多行编辑控件可以用作一个简单的文本编辑器。(参见第八章的POPPAD程序。)另外,Windows也有专业的富文本编辑控件,可以允许你编辑和显示格式化的文本(第十一章我们会详细讲解富文本控件) 。

当你设计Windows程序时,将会发现可以使用子窗口控件来处理键盘和鼠标的输入以 便把更高层的消息传回父窗口。只要积累了足够多的这样的控件,你就不会再为处理键盘消息而烦恼了。

5.1.2 键盘焦点

       假如我们现在按下了一个键盘按键,但是桌面当前有多个窗口同时存在,那么就产生了一个问题,这个按键消息会送入到哪个窗口的消息队列呢?

       我们在第二章2.3节消息机制中讲述过,当用户按下一个按键时,产生的按键消息会被送入到Windows系统总的消息队列,然后根据按键消息所属的窗口将其送入到对应的窗口消息队列。是否还记得MSG消息结构的第一个字段就是消息所属的窗口句柄。意思是当我们按下按键的那一刻就已经确定了消息所属的窗口,而不是等到送入总消息队列后再确定所属窗口的。那么,确定消息所属窗口的依据是什么呢?就是当前具有键盘输入焦点的窗口。

       接收到这个键盘事件的窗口称为有输入焦点的窗口。输入焦点的概念和活动窗口的概 念是紧密相连的。具有输入焦点的窗口要么是活动窗口,要么是活动窗口的子孙窗口——也就是说,活动窗口的子窗口,或者是活动窗口的子窗口的子窗口,等等。

活动窗口通常是很好鉴别的。它总是最上层的窗口——也就是说,它的父窗口句柄是 NULL。如果一个活动窗口有标题栏,Windows会加亮显示其标题栏。如果活动窗口有会话边框(常见的对话框的外形)而不是标题栏,Windows会加亮显示其边框。如果活动窗口目前处于最小化状态,Windows将突出显示它在任务栏中的条目,就像一个按下的按钮似的。

如果活动窗口有子窗口,具有输入焦点的窗口可以是活动窗口,也可以是它的子孙窗口中的一个。最常见的子窗口是出现在对话框中的如下控件:按钮、单选按钮、复选框、滚动条、编辑框或列表框。子窗口自己不能成为活跃窗口。仅当它是活跃窗口的子孙窗口时,该子窗口才具有输入焦点。子窗口控件通常通过显示一个闪烁的插入符号或虚线指出输入焦点。

有时没有窗口具有输入焦点。这种情况会发生在所有程序都最小化时。但Windows仍 将发送键盘消息给活动窗口,只不过此时的消息形式不同于活动窗口没有最小化时发送的 键盘消息。

窗口过程通过捕获WM_SETFOCUS和WM_CILLFOCUS消息来确定自己的窗口是否具有输入焦点。WM_SETFOCUS表明窗口正在接受输入焦点,而WM_KILLFOCUS表明窗口正在失去输入焦点。这些消息将在本章的稍后部分详细介绍。

 

总结

1.活动窗口:桌面最上层窗口,其父窗口句柄为NULL,加亮标题栏或突出显示在任务栏。

2.焦点窗口:活动窗口的子孙窗口,通常是一个闪烁的插入符或虚线框指示输入焦点。

3.捕获WM_SETFOCUS来确定其具有输入焦点,WM_KILLFOCUS说明正失去焦点。

4.当所有程序都最小化时,没有窗口具有输入焦点,Windows仍将发送键盘消息给活动窗口。这时所有击键都产生WM_SYSKEYDOWN和WM_SYSKEYUP消息。

5.1.3 队列和同步

当用户按下和释放键盘上的一个键时,Windows和键盘设备驱动程序将硬件扫描码转 换为格式化后的消息。但是,这些消息并不立即被放入应用程序消息队列,而是由Windows 把这些消息存储在系统总消息队列中。系统消息队列是一个单独的消息队列,它被Windows 用来初步存储用户从键盘和鼠标输入的消息。仅当Windows应用程序完成了对前一个用户输入消息的处理后,Windows才从系统消息队列中取出下一条消息,并把它放入应用程序消息队列。

这是一种两步处理法,即先把消息存储在系统消息队列里,再把它们发送到应用程序消息队列。采用两步处理法的原因是需要同步。像我们刚了解的那样,被期望接收键盘输入的窗口是具有活动焦点的窗口。用户输入的速度可能快于应用程序能处理的击键动作,而一个特殊的击键可能会使焦点从一个窗口转换到另一个窗口。后续的击键也应该跟着到了另一个窗口。但如果后续的击键己经被转到了目的窗口,且被放置在了应用程序消息队列中,则它们不能被输入到另一个窗口。

图5-1 消息队列

 

总结

●两步法处理键消息:先把消息存储在系统消息队列里,再发送到应用程序消息队列里。

1.击键事件:将击键转为消息,放入系统消息队列(注意不立即放入应用程序消息队列);

2.应用程序处理完前一个输入消息,Windows从系统队列取下一条消息放入应用程序消息队列。

●两步处理法的原因——同步

因为当应用程序1接收到一个特殊的、转换窗口焦点的击键动作时,后续的击键消息也应被转移到另一个程序(如应用程序2)的队列中去。如果键盘消息不经系统队列的缓冲,当用户输入太快,而应用程序1来不及没处理完这个特殊消息时,可能后续的击键消息又被发送到应用程序1的队列中来了,从而导致错误。因此,键盘消息要先放到系统队列中,起到同步的作用。

5.1.4 击键和字符

应用程序从Windows接收的关于键盘事件的消息可分为击键和字符两种。

首先,你可以认为键盘是键的集合。键盘上仅有一个键标示为“A”。按下此键是一次击键,释放此键也认为是一次击键。同时键盘也是能产生可显示字符或者控制字符的输入设备。“A”键能产生一些不同的字符,这取决于同Ctrl、Shift、Caps Lock键的组合,通常此字符为小写字母“a”。如果Shift键被按下或者Caps Lock键被锁定,此字符就为大写字母“A”。如果Ctrl键被按下,则此字符就是Ctrl+A(它在ASCII码中有意义,但是在Windows里,就可能是一个键盘快捷键)。在一些键盘上,可能会有死字符键或者 Shift、Ctrl、Alt键与“A”键的组合。这种组合能产生带重音符号的小写字母或大写字母,例如,à、á、â、Ä、或 Å等。

对产生可显示字符的击键组合,Windows在发送击键消息的同时还发送字符消息。有些键不产生字符,如Shift键、功能键、光标移动键和特殊字符键(如Insert键和Delete键)。 对于这些键,Windows只产生击键消息。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零编程数据可视化展示:十个简易案例!

数据可视化是呈现数据内在价值的最终手段。数据可视化实例利用各种图表和图形设计手段,合乎逻辑地展示复杂而不直观的数据。为了让用户直观清楚地了解他们想要的数据及其比较关系,数据可视化实例的呈现至关重要。即时设计整理了10个数据可视化实例&#…

OceanBase 列存中多列过滤性能解析

今天有同事问我,列存大宽表场景下,如果在多个列上有等值过滤条件,OceanBase 的性能是不是无法满足要求? Hi 晓楚,帮评估个OTS替换场景 大概1亿大宽表,查询姿势就是任意字段的组合,进行等值查询g…

使用Docker在Mac上部署OnlyOffice,预览编辑word、excel、ppt非常好

前端编辑word、ppt文档,开源免费方案并没有找到合适的,像wps、石墨文档都是自研的方案。实现过程中wps采用的svg方案,而石墨文档采用的是canvas,它们均是自己来实现编辑器,不依赖浏览器提供的编辑器(conten…

【调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法】

调试笔记-系列文章目录 调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法 文章目录 调试笔记-系列文章目录调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法 前言一、调试环境操作系统:Windows 10 专业版调试环境调试目标 二、调试步骤搜…

【数据结构】选择题

在数据结构中,从逻辑上可以把数据结构分为(线性结构和非线性结构) 当输入规模为n时,下列算法渐进复杂性中最低的是() 时间复杂度 某线性表采用顺序存储结构,每个元素占4个存储单元&#xf…

【笔记】打卡01 | 初学入门

1 基本介绍 MindSpore Data(数据处理层) ModelZoo(模型库) MindSpore Science(科学计算),包含了业界领先的数据集、基础模型、预置高精度模型和前后处理工具 MindSpore Insight(可视…

【stm32-新建工程-HAL库版本】

stm32-新建工程-HAL库版本 ■ HAL库版本目录■ Drivers■ Middlewares 文件夹, 同寄存器版本一样。■ Output 文件夹, 同寄存器版本一样。■ Projects 文件夹, 同寄存器版本一样。■ User 文件夹 ■ HAL库版本目录 ■ Drivers ① &#xff0c…

Vitis Accelerated Libraries 学习笔记--OpenCV 安装指南

目录 1. 简介 2. 安装过程 2.1 安装准备 2.2 常见错误 2.2.1 核心共享库报错 3. 通过实例测试 4. 总结 1. 简介 使用Vitis Vision Library Vitis 视觉库,为什么要安装opencv库? 在使用Vitis Vision Library时,安装OpenCV库是因为许…

前端 CSS 经典:边框转圈动画效果

前言:首先我们要知道 css 动画只对数值类的 CSS 属性起作用。要实现边框转圈动画效果,实际就是渐变背景的旋转。但是在以前,渐变背景是不支持动画的。现在我们可以利用浏览器新出的 Houdini API 来实现这个动画效果。Houdini API 特别强大&am…

leetcode119 杨辉三角②

给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: rowIndex 3 输出: [1,3,3,1]示例 2: 输入: rowIndex 0 输出: [1]示例 3: 输入: rowIndex 1 输出: [1,1] pub…

centos 7.8 安装sql server 2019

1.系统环境 centos 7.8 2.数据库安装文件准备 下载 SQL Server 2019 (15.x) Red Hat 存储库配置文件 sudo curl -o /etc/yum.repos.d/mssql-server.repo https://packages.microsoft.com/config/rhel/7/mssql-server-2019.repo 采用yum源进行不安装下载,这时yum 会自动检测…

知觉感知:AI深层理解的关键

在人工智能(AI)的广阔领域中,一个核心议题始终萦绕在科学家和哲学家的心头:人工智能是否需要感知能力,以实现对意义的深层理解?这一议题不仅关乎技术的边界,更触及了人类心智的本质。从Stevan H…

[笔记] CCD相机测距相关的一些基础知识

1.35mm胶片相机等效焦距 https://zhuanlan.zhihu.com/p/419616729 拿到摄像头拍摄的数码照片后,我们会看到这样的信息: 这里显示出了两个焦距:一个是实际焦距:5mm,一个是等效焦距:25mm。 实际焦距很容易…

数据结构:4.1.1二叉搜素树及查找

静态查找:要找的集合的元素是不动的,主要是find操作,没有delete操作 动态查找:要查找的集合会经常发生插入删除的操作 静态查找的一个很好的方法就是二分查找 把数据直接放在树上 结点右子树的值>结点的值>结点左子树的…

Flutter-无限循环滚动标签

1. 序章 在现代移动应用开发中,滑动视图是常见的交互模式之一。特别是当你需要展示大量内容时,使用自动滚动的滑动视图可以显著提升用户体验。在这篇文章中,我们将讨论如何使用 Flutter 实现一个自动滚动的列表视图。 2. 效果 3. 实现思路 …

Java安全

Java安全 Java2Sec靶场搭建 靶场地址 https://github.com/bewhale/JavaSec 查看数据库配置文件,mysql,用户名密码根据自己数据库密码更改 使用小皮面板的mysql,新建一个数据名为javasec的数据库 运行javasec.sql文件 下载运行jar包即可 …

STM32单片机I2C通信详解

文章目录 1. I2C通信概述 2. 硬件电路 3. I2C时序基本单元 4. I2C时序 4.1 指定地址写 4.2 当前地址读 4.3 指定地址读 5. I2C外设 6. I2C框图 7. I2C基本结构 8. 主机发送 9. 主机接收 10. 软件和硬件波形对比 11. 代码示例 1. I2C通信概述 I2C(Inter-Integrat…

定制汽车霍尔传感器

磁电效应霍尔传感器、饱和霍尔传感器、非线性霍尔传感器 霍尔传感器原理 霍尔传感器的工作原理基于霍尔效应,即当一块通有电流的金属或半导体薄片垂直地放在磁场中时,薄片的两端会产生电位差。这种现象称为霍尔效应,两端具有的电位差值称为…

YoloV8改进策略:Block篇|即插即用|StarNet,重写星操作,使用Block改进YoloV8(全网首发)

摘要 本文主要集中在介绍和分析一种新兴的学习范式——星操作(Star Operation),这是一种通过元素级乘法融合不同子空间特征的方法,通过元素级乘法(类似于“星”形符号的乘法操作)将不同子空间的特征进行融…

(0撸)Nillion空投教程,现在开启激励测试网

Nillion 是一个去中心化的公共网络,通过启用去中心化信用评分、去中心化可信执行环境、私有 NFT、去中心化安全存储服务等用例来解锁 Web3 中重要的新实用程序 Nillion已经完成2000万美元融资、由Distributed Global领投、同时还有HashKey Capital、GSR等多家机构参…