【问题标题】:Are they really the virtual codes?它们真的是虚拟代码吗?
【发布时间】:2012-06-01 10:51:03
【问题描述】:

shift、[、]、Del 等键的虚拟键代码在 java 中显示为与 C++/C 不同的值。例如:

Key     Java       C / C++
Shift   16         160
[       91         219
]       93         221
\       92         220
Del     127        46
Window  524        91

这是什么原因?这些代码是虚拟代码还是它们是不同的类型?对于包括字母、数字、功能键(F1-F12)、退格、`等的按键都是一样的。

我可能误解了一个概念,在这种情况下请澄清。

已在 C/C++ 中检查

KBDLLHOOKSTRUCT * kbhook = (KBDLLHOOKSTRUCT *) lParam;
printf("%u\n",kbhook->vkCode);

在 Java 中检查

private void jTextField1KeyPressed(java.awt.event.KeyEvent evt) {                                       
    int code = evt.getKeyCode();
    // code isEqualTo KeyEvent.VK_DELETE : NOTE

}

参考:KeyEvent class

【问题讨论】:

  • 对于[]、`\` 和 Del,这些 Java 代码是这些键的 ASCII 值。为什么它们应该是虚拟的?你从 Windows 钩子函数得到的结果似乎是扫描码。
  • 那些不是 C/C++ 代码,那些是 WinAPI 代码。它们不用于其他平台上的 C 或 C++,其他基于 WinAPI 的应用程序(例如使用 Delphi 构建)使用相同的代码。
  • 它们是否相同有关系吗?它们用于识别某些键(通过将它们与常量进行比较 - 例如 java 中的KeyEvent.VK_X)。我唯一能想到的问题是Java应用程序是否通过转发关键事件以某种方式与C++应用程序通信。然后,您要么必须将代码解析为统一代码,要么在转发它们之前将它们翻译到其他系统。
  • @brimborium 是的,我想要一个 b/w c++->java 的通信
  • 从钩子回调函数中,调用ToAsciiToUnicode 将虚拟键代码转换为Java 可以理解的代码。

标签: java c++ c keycode


【解决方案1】:

我应该说,虚拟键码是非常虚拟的。

如果没有 JavaKeyToWin32Key、Win32KeyToJava 等代码,您将无法逃脱您尝试与之互操作的每个平台。

我相信所有这些键码大部分都是历史性的。有些来自硬件设计决策(看看 Apple 的“现代”关键代码,其中 0 代码是“A”,1 是“S”,2 是“D”等等 - 我应该继续还是你得到“模式" 是从键盘布局得出的?)。

“为什么没有标准?”

这是生意,不是私人的。 340 年前每个人都从零开始开发自己的硬件,25 年前每个人都在努力制造最好的 CPU,15 年前一切都始于“平台”,一切都重新定义,但也应该保持与现有解决方案的兼容性(当然是同一家公司)。

Java 是一个标准,但并不适合所有人。它已经是所有操作系统之上的抽象,具有自己的一组键码。所以“VK_”是微软的遗留物,Java键码可能会受到Sun Solaris OS的影响,但我不确定。

【讨论】:

  • @SuhailGupta 有人必须协调标准,一切都会突然变得复杂。不同的系统有不同的键盘,因此代码(看看旧 Sun 机器的键盘)并创建一个单一的标准来处理它们会变得不必要地复杂。另外,它只在少数罕见的情况下很重要,通常如果您为 PC 编写应用程序,您不必也不想关心处理来自 1970 年代一些稀有企业机器的关键代码。
【解决方案2】:

Virtual Key Codes 是典型键盘上某些键的特定于 MS 的表示。因此 virtual 修饰符。请注意,您为 Java 指定的值表示使用 ASCII 编码时这些键的值。它们构成lower ASCII 编码的一部分。如果 OTOH,您使用了标准 C 函数,例如 getchar,您将获得与 Java 中相同的值,前提是您使用的是 ASCII 编码。但是,您可以有一个特殊的(想想非 ASCII/非 Unicode)编码,其中这些字符将被分配不同的整数。

ASCII 集特别经过精心设计,考虑到某些经常使用的操作(例如小写到大写)等可以优化。

【讨论】:

  • 我想要一个 c++ sn-p 与 java 应用程序通信。当代码不同时,我怎么知道按下了哪个键?
  • @SuhailGupta 要么选择其中一个作为新规范,并根据需要转换为/从,要么发明自己的映射并转换为/从该规范。当然,这假设您同时拥有 C++ 和 Java 代码。
【解决方案3】:

MSDN 库提到Using Virtual-Key Codes“键盘上的每个键在按下和释放键时都会生成一个扫描码。扫描码是一个与硬件相关的数字,用于识别该键。键盘驱动程序会翻译或将每个扫描代码映射到一个虚拟键代码。虚拟键代码是一个独立于硬件的数字,用于标识键。由于键盘布局因语言而异,Windows CE 仅提供核心虚拟键代码集可在所有键盘上找到。此核心集包括英文字符、数字和一些关键键,例如功能键和箭头键"

这是Virtual-Key Codes 的集合 - 这些是您从KBDLLHOOKSTRUCT 的成员vkCode 检索到的值。

【讨论】:

  • 我想要一个 c++ sn-p 与 java 应用程序通信。当代码不同时,我怎么知道按下了哪个键?
【解决方案4】:

是的,在这两种情况下,它们都是虚拟代码。

【讨论】:

  • 你能解释一下原因吗,为什么它们不一样?
  • “虚拟键码”通常是指仅在 Windows API 中使用的 Microsoft 术语。 Java 语言对此一无所知,因此我不会将 Java 值称为虚拟键代码。
  • @Lundin 那么KeyEventVK_DELETE 中的静态术语是什么意思?我认为这肯定意味着Delete 键的虚拟键代码。
  • @SuhailGupta 它看起来确实像 Windows 虚拟键代码。但它有不同的价值吗?如果是这样,你最好问问设计那个 Java 类的人他们在抽什么......
  • @Lundin 不同。例如,java 中的 Windows 虚拟键代码 是 524,winapi 是 91
猜你喜欢
  • 2010-10-06
  • 1970-01-01
  • 2013-01-12
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
  • 2017-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多