《Windows API每日一练》5.1 键盘基础
本节我们讲述关于键盘的一些基础知识。当我们按下一个键盘按键时,会产生一个键盘按键消息。这一点你能确定吗?假如是一个菜单快捷键消息,或者是一个子窗口控件消息呢?这就超出了本节讨论的范围,我们将在菜单和子窗口控件详细讲述。假设的确是一个按键消息,它将被送入窗口消息队列,做同步处理。在消息循环中,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只产生击键消息。
相关文章:
《Windows API每日一练》5.1 键盘基础
本节我们讲述关于键盘的一些基础知识。当我们按下一个键盘按键时,会产生一个键盘按键消息。这一点你能确定吗?假如是一个菜单快捷键消息,或者是一个子窗口控件消息呢?这就超出了本节讨论的范围,我们将在菜单和子窗口控…...
Class.forName()方法总结
Class.forName()方法总结 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!Class.forName()方法是Java反射机制中的一个重要方法,它用于动态加载类并返…...
Python | Leetcode Python题解之第168题Excel表列名称
题目: 题解: class Solution:def convertToTitle(self, columnNumber: int) -> str:ans list()while columnNumber > 0:columnNumber - 1ans.append(chr(columnNumber % 26 ord("A")))columnNumber // 26return "".join(an…...
【ARMv8/ARMv9 硬件加速系列 3.5.2 -- SVE 向量寄存器 有多少位数?】
文章目录 SVE 向量寄存器SVE 向量寄存器大小SVE 可伸缩性的好处SVE 寄存器长度示例SVE 向量寄存器 在 ARMv9 架构中,包括其 Scalable Vector Extension (SVE) 和 Scalable Vector Extension 2 (SVE2) 的增强,向量寄存器(通常称为 Z 寄存器)的大小设计为可伸缩的,以便在不…...
Vulkan入门系列2- 绘制三角形(未完待续)
概述: Vulkan的学习曲线是比较陡峭的,学习Vulkan刚开始像是在爬一个陡坡,等上了这个陡坡之后,后面学习曲线就相对比较平缓了。那么在Vulkan中绘制一个三角形,就相当于是在爬这样一个陡坡,因为绘制三角形需…...
企业UDP文件传输工具测速的方式(下)
在前一篇文章中,我们深入讨论了UDP传输的基本概念和镭速UDP文件传输工具如何使用命令行快速进行速度测试。现在,让我们进一步探索更为高级和灵活的方法,即通过整合镭速UDP的动态或静态库来实现网络速度的测量,以及如何利用这一过程…...
Artalk-CORS,跨域拦截问题
今天重新部署Artalk之后,遇到了CORS——跨域拦截的问题,卡了好一会记录一下。 起因 重新部署之后,浏览器一直提示CORS,之前在其他项目也遇到过类似的问题,原因就在于跨域问题。...
SSL证书怎样配置部署更安全?
在互联网上,SSL证书是用于加密网站与用户之间传输的数据的一种数字证书。它通过建立安全的连接,确保网站的身份和保护用户的隐私,是网站安全的重要组成部分。然而,要想让SSL证书发挥最大的作用,除了检查证书是否过期外…...
M1失效后,哪个是观察A股的关键新指标?
M1失效后,哪个是观察A股的关键新指标? 央地支出增速差(地方-中央支出增速的差值)或许是解释沪深300定价更有效的前瞻指标。该数值扩张,则有利于大盘指数,反之亦然,该指标从2017年至今对大盘指数…...
springboot集成积木报表,怎么将平台用户信息传递到积木报表
springboot集成积木报表后怎么将平台用户信息传递到积木报表 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选新的模块 起因是因为需要研究在积木报表做数据筛选的时候需要拿到系统当前登录用户信息做筛选 官网有详细介绍怎么集成进去的&…...
Spring Bean详解
Spring Bean作用域 默认情况下,所有的 Spring Bean 都是单例的,也就是说在整个 Spring 应用中, Bean 的实例只有一个 如果我们需要创建多个实例的对象,那么应该将 Bean 的 scope 属性定义为 prototype,如果 Spring 需…...
前端根据环境变量配置网页的title和favicon
前端根据环境变量配置网页的title和favicon 前言流程步骤一、设置environment文件二、在入口文件中配置三、删除index.html中的title和 icon link四、使用对应的打包命令进行部署 注意事项一、angular中,需要在angular.json添加favicon.ico额外的构建 前言 有些项目…...
服务器负载均衡
什么是服务器负载 1. 常见理解的平均负载 每次发现系统变慢时,我们通常做的第一件事,就是执行 top 或者 uptime 命令,来了解系统的负载情况。比如下列情况 [rootkube-node1 ~]# uptime09:44:37 up 74 days, 11:53, 1 user, load average:…...
如何设置Excel单元格下拉列表
如何设置Excel单元格下拉列表 在Excel中设置单元格下拉列表可以提高数据输入的准确性和效率。以下是创建下拉列表的步骤: 使用数据验证设置下拉列表: 1. 选择单元格: 选择你想要设置下拉列表的单元格或单元格区域。 2. 打开数据验证&…...
红队内网攻防渗透:内网渗透之Linux内网权限提升技术:LXDDockerRbash限制型bash
红队内网攻防渗透 1. 内网权限提升技术1.1 Linux系统提权-普通用户-LXD容器1.2 Linux系统提权-普通用户-Docker容器1.3 权限在docker里面1.4 Linux系统提权-普通用户-Rbash限制型bash1. 内网权限提升技术 利用参考 https://gtfobins.github.io/LXD、LXC 和 Docker 是三种不同…...
【笔记】复制Edge的网址粘贴后自动变成中文标题超链接
问题 1、从edge复制的网址粘贴直接显示网页内容名称而不是网址url。 2、复制任何网址粘贴到CSDN里面粘贴时直接转换成标题超链接(很讨厌的功能习惯)。 而如上两种问题不是互相影响的,就算设置了Edge的粘贴方式,复制到CSDN的文章…...
HTML5和CSS3总结
HTML5 HTML5是最新的HTML标准,它的主要目标是提供所有内容而不需要任何像flash,silverlight等的额外插件,这些内容来自动画、视频、富GUI等。HTML5是万维网联盟(W3C)和网络超文本应用技术工作组(WHATWG&am…...
探索数据分析无限潜能:vividime Desktop助力企业智能决策
在数字化浪潮席卷全球的今天,数据已经成为企业最宝贵的资产之一。通过对海量数据的深度挖掘和分析,企业能够洞察市场趋势、优化运营流程、提升用户体验,从而在激烈的市场竞争中脱颖而出。永洪科技的vividime Desktop作为一款功能强大、操作简…...
gitee添加别人的仓库后,在该仓库里添加文件夹/文件
一、在指定分支里添加文件夹(如果库主没有创建分支,自己还要先创建分支) eg:以在一个项目里添加视图文件为例,用Echarts分支在usr/views目录下添加Echarts文件夹,usr/views/Echarts目录下添加index.vue 1.切换为本地仓…...
[笔记] CCD相机测距相关的一些基础知识
1.35mm胶片相机等效焦距 https://zhuanlan.zhihu.com/p/419616729 拿到摄像头拍摄的数码照片后,我们会看到这样的信息: 这里显示出了两个焦距:一个是实际焦距:5mm,一个是等效焦距:25mm。 实际焦距很容易…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)
第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10pip3.10) 一:前言二:安装编译依赖二:安装Python3.10三:安装PIP3.10四:安装Paddlepaddle基础框架4.1…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
第22节 Node.js JXcore 打包
Node.js是一个开放源代码、跨平台的、用于服务器端和网络应用的运行环境。 JXcore是一个支持多线程的 Node.js 发行版本,基本不需要对你现有的代码做任何改动就可以直接线程安全地以多线程运行。 本文主要介绍JXcore的打包功能。 JXcore 安装 下载JXcore安装包&a…...
