热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

键盘事件:订单是否有保证?-Keyboardevents:Istheorderguaranteed?

Forpressingasinglekey,therearemultipleeventsthatcanbehandled.对于按下单个键,可以处理多个事件。Therei

For pressing a single key, there are multiple events that can be handled.

对于按下单个键,可以处理多个事件。

There is: KeyDown, KeyPressed, KeyUp.

有:KeyDown,KeyPressed,KeyUp。

Is it guaranteed that an application will receive those events in that order?

是否保证应用程序将按该顺序接收这些事件?

What I mean is: is the order of a single key pressing event, not a series of different keys pressed.

我的意思是:是按下单个按键事件的顺序,而不是按下一系列不同的按键。

Context:

After I had some problems with keypress-events in a legacy C++ application I inspected the events with spy++. There I saw that the order seems sometimes not to be right and the keypressed is not fired for every keydownor keyup.

在我在遗留C ++应用程序中遇到keypress-events的一些问题之后,我用spy ++检查了事件。在那里,我看到订单似乎有时不正确,并且每次keydownor keyup都没有触发keypressed。

But, I was sure that the events should be fired in exactly that order, but could not find anything on the internet. So I came up with this question here.

但是,我确信事件应该按照那个顺序被触发,但是在互联网上找不到任何东西。所以我在这里提出了这个问题。

Please note that this is not a multiple languages problem, but I am interested whether this is true for C++, Java and C#.

请注意,这不是一个多语言问题,但我感兴趣的是CID,Java和C#是否正确。

2 个解决方案

#1


4  

They should happen in that order when they happen, in most apps. But your window might not receive every event for every character entered.

在大多数应用中,它们应该按顺序发生。但是,您输入的每个字符的窗口可能都不会收到任何事件。

For example, in Windows, if you hold down a key you'll see a KeyDown and/or KeyPressed repeatedly as the key repeats, and a single KeyUp once the key is released.

例如,在Windows中,如果按住某个键,您将在键重复时重复看到KeyDown和/或KeyPressed,并在键释放后重复显示单个KeyUp。

Edit:

Now that i think about it, though...Windows starts out only posting WM_KEYDOWN and WM_KEYUP messages to your window (and only if you have focus). WM_CHAR messages (the Win32 analogue to KeyPressed) are posted based on those when the message loop calls TranslateMessage. This means two things:

现在我考虑一下,但是...... Windows开始只向你的窗口发布WM_KEYDOWN和WM_KEYUP消息(只有你有焦点)。 WM_CHAR消息(Win32模拟到KeyPressed)基于消息循环调用TranslateMessage时发布的消息。这意味着两件事:

  • If the window has a backlog of messages, the API might just add the message to the end of the queue (IDK); this makes more sense to me (the message queue being a queue, after all, and not a stack), but it does mean that if there is already a WM_KEYUP for that key in the queue (for example, if the user hit and released a key while another message was being processed), the corresponding WM_CHAR might appear after it.
  • 如果窗口有积压的消息,API可能只是将消息添加到队列的末尾(IDK);这对我来说更有意义(消息队列毕竟是一个队列,而不是堆栈),但它确实意味着如果队列中已存在该键的WM_KEYUP(例如,如果用户命中并释放当正在处理另一条消息时,一个密钥),相应的WM_CHAR可能会出现在它之后。

  • Languages like C and C++ have more flexibility (read: less built-in automation) in how they handle messages; in order for them to get WM_CHAR messages, they have to either call TranslateMessage explicitly or do the translation themselves (barring another app posting such messages to it). With the latter, there's no telling what order the messages will be posted in.
  • C和C ++等语言在处理消息方面具有更大的灵活性(读取:内置自动化程度更低);为了让他们获得WM_CHAR消息,他们必须明确地调用TranslateMessage或自己进行翻译(除非另一个应用程序向其发布此类消息)。对于后者,无法确定消息的发布顺序。

Also, as mentioned in the comments, if the focus switches while a key is down, you might only see a KeyUp or KeyDown. (The key state was already that way before the focus switch, and Windows probably won't tell you about it.) And dead keys (ones that don't generate a character on their own) won't trigger a KeyPressed at all (though they do typically trigger KeyUp and KeyDown). They typically just wait for the next real character and modify it.

此外,如评论中所述,如果焦点在按键关闭时切换,您可能只会看到KeyUp或KeyDown。 (关键状态在焦点切换之前已经是这样了,Windows可能不会告诉你它。)死键(不能自己生成一个字符的键)根本不会触发KeyPressed(虽然他们通常会触发KeyUp和KeyDown)。他们通常只是等待下一个真正的角色并进行修改。

Short version of all that: You can rely on the order in which KeyDown events appear in relation to each other. Same with KeyPressed, and even KeyUp. But, at least in Windows, the three message types are not really coordinated with each other. So don't assume that every KeyUp will match a KeyDown (or vice versa), or that KeyPressed appears before KeyUp.

所有这些的简短版本:您可以依赖KeyDown事件相对于彼此出现的顺序。与KeyPressed相同,甚至与KeyUp相同。但是,至少在Windows中,这三种消息类型并不真正相互协调。因此,不要假设每个KeyUp都与KeyDown匹配(反之亦然),或KeyPress出现在KeyUp之前。

You should probably also decide whether you want to process characters or keys. That's part of the confusion here, i think; the two are actually different concepts, and most of the time you only really care about one or the other. While Win32 would allegedly tell you the key code when you're handling a KeyPressed event, the real intent of that event is to tell you what character was entered. (There's a reason it's called WM_CHAR and not WM_KEYPRESS. :) And why .net's KeyPressEventArgs type only has a KeyChar and not a KeyCode.) The other two treat the keyboard as basically a bunch of buttons.

您可能还应该决定是否要处理字符或键。我认为这是混乱的一部分;这两者实际上是不同的概念,大多数时候你只关心其中一个。据称Win32会在您处理KeyPressed事件时告诉您关键代码,而该事件的真正意图是告诉您输入的字符。 (有一个原因,它被称为WM_CHAR而不是WM_KEYPRESS。:)为什么.net的KeyPressEventArgs类型只有KeyChar而不是KeyCode。)其他两个将键盘视为基本上是一堆按钮。

#2


0  

If you are Windows user, the rule of thumb here is: check the order of events by logging or in debugger and then assume that this will be always so.

如果您是Windows用户,那么这里的经验法则是:通过记录或在调试器中检查事件的顺序,然后假设这将始终如此。

This is not perfect, but this works in 95% of cases. I many times heard stories that Windows team always pushes back to change anything because 100% sure this will break something.

这并不完美,但这在95%的情况下有效。我多次听过Windows团队总是推迟改变任何事情的故事,因为100%肯定会破坏某些东西。

This is direct result of poor documentation of the Windows 2.0 era.

这是Windows 2.0时代文档记录不佳的直接结果。


推荐阅读
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 本文探讨了如何利用HTML5和JavaScript在浏览器中进行本地文件的读取和写入操作,并介绍了获取本地文件路径的方法。HTML5提供了一系列API,使得这些操作变得更加简便和安全。 ... [详细]
  • 本文深入探讨了UNIX/Linux系统中的进程间通信(IPC)机制,包括消息传递、同步和共享内存等。详细介绍了管道(Pipe)、有名管道(FIFO)、Posix和System V消息队列、互斥锁与条件变量、读写锁、信号量以及共享内存的使用方法和应用场景。 ... [详细]
  • java文本编辑器,java文本编辑器设计思路
    java文本编辑器,java文本编辑器设计思路 ... [详细]
  • 探讨ChatGPT在法律和版权方面的潜在风险及影响,分析其作为内容创造工具的合法性和合规性。 ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
  • LeetCode: 实现队列与栈的高级应用
    本文介绍如何使用队列和栈实现特定功能,包括动态维护队列元素并计算其平均值,以及栈操作中的优化技巧。 ... [详细]
  • Java中的基本数据类型与包装类解析
    本文探讨了Java编程语言中的8种基本数据类型及其对应的包装类。通过分析这些数据类型的特性和使用场景,以及自动拆装箱机制的实现原理,帮助开发者更好地理解和应用这些概念。 ... [详细]
  • 软件工程课堂测试2
    要做一个简单的保存网页界面,首先用jsp写出保存界面,本次界面比较简单,首先是三个提示语,后面是三个输入框,然 ... [详细]
  • 本文详细探讨了Java中的ClassLoader类加载器的工作原理,包括其如何将class文件加载至JVM中,以及JVM启动时的动态加载策略。文章还介绍了JVM内置的三种类加载器及其工作方式,并解释了类加载器的继承关系和双亲委托机制。 ... [详细]
  • KMP算法是处理字符串匹配的一种高效算法它首先用O(m)的时间对模板进行预处理,然后用O(n)的时间完成匹配。从渐进的意义上说,这样时间复 ... [详细]
  • 本文深入探讨了 PHP 实现计划任务的方法,包括其原理、具体实现方式以及在不同操作系统中的应用。通过详细示例和代码片段,帮助开发者理解和掌握如何高效地设置和管理定时任务。 ... [详细]
  • iOS 开发技巧:TabBarController 自定义与本地通知设置
    本文介绍了如何在 iOS 中自定义 TabBarController 的背景颜色和选中项的颜色,以及如何使用本地通知设置应用程序图标上的提醒个数。通过这些技巧,可以提升应用的用户体验。 ... [详细]
  • 本文介绍了如何使用JFreeChart库创建一个美观且功能丰富的环形图。通过设置主题、字体和颜色等属性,可以生成符合特定需求的图表。 ... [详细]
  • 使用OpenCV和Python 4.2提升模糊图像清晰度
    本文介绍如何利用OpenCV库在Python中处理图像,特别是通过不同类型的滤波器来改善模糊图像的质量。我们将探讨均值、中值和自定义滤波器的应用,并展示代码示例。 ... [详细]
author-avatar
高俊伦丽成
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有