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

2024-06-20 10:04

本文主要是介绍《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 键盘基础的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

安装centos8设置基础软件仓库时出错的解决方案

《安装centos8设置基础软件仓库时出错的解决方案》:本文主要介绍安装centos8设置基础软件仓库时出错的解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录安装Centos8设置基础软件仓库时出错版本 8版本 8.2.200android4版本 javas

Windows 系统下 Nginx 的配置步骤详解

《Windows系统下Nginx的配置步骤详解》Nginx是一款功能强大的软件,在互联网领域有广泛应用,简单来说,它就像一个聪明的交通指挥员,能让网站运行得更高效、更稳定,:本文主要介绍W... 目录一、为什么要用 Nginx二、Windows 系统下 Nginx 的配置步骤1. 下载 Nginx2. 解压

Linux基础命令@grep、wc、管道符的使用详解

《Linux基础命令@grep、wc、管道符的使用详解》:本文主要介绍Linux基础命令@grep、wc、管道符的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录grep概念语法作用演示一演示二演示三,带选项 -nwc概念语法作用wc,不带选项-c,统计字节数-

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

Python使用pynput模拟实现键盘自动输入工具

《Python使用pynput模拟实现键盘自动输入工具》在日常办公和软件开发中,我们经常需要处理大量重复的文本输入工作,所以本文就来和大家介绍一款使用Python的PyQt5库结合pynput键盘控制... 目录概述:当自动化遇上可视化功能全景图核心功能矩阵技术栈深度效果展示使用教程四步操作指南核心代码解析

python操作redis基础

《python操作redis基础》Redis(RemoteDictionaryServer)是一个开源的、基于内存的键值对(Key-Value)存储系统,它通常用作数据库、缓存和消息代理,这篇文章... 目录1. Redis 简介2. 前提条件3. 安装 python Redis 客户端库4. 连接到 Re

Windows Server 2025 搭建NPS-Radius服务器的步骤

《WindowsServer2025搭建NPS-Radius服务器的步骤》本文主要介绍了通过微软的NPS角色实现一个Radius服务器,身份验证和证书使用微软ADCS、ADDS,具有一定的参考价... 目录简介示意图什么是 802.1X?核心作用802.1X的组成角色工作流程简述802.1X常见应用802.

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现

windows和Linux安装Jmeter与简单使用方式

《windows和Linux安装Jmeter与简单使用方式》:本文主要介绍windows和Linux安装Jmeter与简单使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows和linux安装Jmeter与简单使用一、下载安装包二、JDK安装1.windows设