用 Java JNA 编写的关键监听器。防止多次回调

2024-04-16

我使用以下代码来监听全局按键事件: Win32HookManager.java

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HMODULE;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinDef.LPARAM;
import com.sun.jna.platform.win32.WinUser;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.KBDLLHOOKSTRUCT;
import com.sun.jna.platform.win32.WinUser.LowLevelKeyboardProc;
import com.sun.jna.platform.win32.WinUser.MSG;

/** Sample implementation of a low-level keyboard hook on W32. */
public class KeyHook {
    private static volatile boolean quit;
    private static HHOOK hhk;
    private static LowLevelKeyboardProc keyboardHook;

    public static void main(String[] args) {
        final User32 lib = User32.INSTANCE;
        HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
        keyboardHook = new LowLevelKeyboardProc() {
            @Override
            public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT info) {
                if (nCode >= 0) {
                    switch(wParam.intValue()) {
                    case WinUser.WM_KEYUP:
                    case WinUser.WM_KEYDOWN:
                    case WinUser.WM_SYSKEYUP:
                    case WinUser.WM_SYSKEYDOWN:
                        System.err.println("in callback, key=" + info.vkCode);
                        if (info.vkCode == 81) {
                            quit = true;
                        }
                    }
                }

                Pointer ptr = info.getPointer();
                long peer = Pointer.nativeValue(ptr);
                return lib.CallNextHookEx(hhk, nCode, wParam, new LPARAM(peer));
            }
        };
        hhk = lib.SetWindowsHookEx(WinUser.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
        System.out.println("Keyboard hook installed, type anywhere, 'q' to quit");
        new Thread() {
            @Override
            public void run() {
                while (!quit) {
                    try { Thread.sleep(10); } catch(Exception e) { }
                }
                System.err.println("unhook and exit");
                lib.UnhookWindowsHookEx(hhk);
                System.exit(0);
            }
        }.start();

        // This bit never returns from GetMessage
        int result;
        MSG msg = new MSG();
        while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
            if (result == -1) {
                System.err.println("error in get message");
                break;
            }
            else {
                System.err.println("got message");
                lib.TranslateMessage(msg);
                lib.DispatchMessage(msg);
            }
        }
        lib.UnhookWindowsHookEx(hhk);
    }
}

我想知道如果我们按一次回调键,为什么会调用两次,以及如何防止它?是否可能。这是单个按键的示例。

in callback, key= 70
in callback, key= 70

我不确定我是否有权在本主题中提出另一个问题,但问题是以第一个问题结束,我不想创建另一个主题。那么为什么我们得到 keycode=70 而不是 VC_F = 0x0021。有什么方法可以只获取 VC_F 代码

VC_F = 0x0021;

该程序正在监听几个消息:WM_KEYUP 和 WM_KEYDOWN

您应该只监听 WM_KEYDOWN。

相关问题:键盘输入和 Win32 消息循环 https://stackoverflow.com/questions/2441457/keyboard-input-the-win32-message-loop

MSDN 信息:https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx https://msdn.microsoft.com/en-us/library/windows/desktop/ms646280(v=vs.85).aspx

如果您需要更复杂的行为,那么您应该存储一些信息并查看是否收到连续的消息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用 Java JNA 编写的关键监听器。防止多次回调 的相关文章

  • Java GuardedString - 用于加密的随机密钥是否存储在 Java 堆内存中?如果不是,那么密钥保存在哪里?

    Oracle 的 org identityconnectors common security GuardedString 要转换为 GuardedString 的原始数据需要由 EncryptorImpl class 随机生成的加密密钥
  • Jackson Json 将对象反序列化为列表

    我正在使用 Spring 的 Web 服务RestTemplate并反序列化Jackson 在来自服务器的 JSON 响应中 其中一个字段可以是对象或列表 这意味着它可以是 result or result 有没有办法通过对我要反序列化的类
  • 无法从 TemporalAccessor 获取 OffsetDateTime

    当我这样做时 String datum 20130419233512 DateTimeFormatter formatter DateTimeFormatter ofPattern yyyyMMddHHmmss withZone ZoneI
  • 按对象值分组,统计后按最大对象属性设置组键

    我设法使用 Java 8 Streams API 编写了一个解决方案 该解决方案首先按对象 Route 的值对列表进行分组 然后计算每组中的对象数量 它返回一个映射 Route gt Long 这是代码 Map
  • 黄瓜与 Micronaut

    我正在尝试将 Cucumber 与 Micronaut 一起使用 但当我尝试将其与 Cucumber 一起使用时 MicronautTest 注释根本不起作用 未注入 theApple 请参阅下面的代码 如果我在没有黄瓜的情况下运行它就可以
  • Java 中的本机方法

    我花了一些时间学习什么是 Java Native 方法以及它们是在平台相关代码 主要是 C 中实现的 但是我在哪里可以找到这些 Java 的本机实现呢 例如 Thread 类的 sleep long millis 方法是本机的 但它的实现代
  • 将二进制数据的 byte[] 转换为 String

    我有二进制格式的数据 hex 80 3b c8 87 0a 89 我需要将其转换为字符串 以便通过 Jackcess 将二进制数据保存在 MS Access 数据库中 我知道 我不打算在 Java 中使用 String 来存储二进制数据 但
  • 文件保存在文件系统中 VS 保存在数据库中

    我正在设计一个 servlet 或 Struts2 中的操作 用于文件 图像 文档等 下载 但我想知道哪种更好的方法可以将文件保留在文件系统和数据库中 只需保留文件的路径或将文件保留在数据库中 如 BLOB 我知道当我查询数据库时 哪里的
  • 从 org.w3c.dom.Node 获取 Xpath

    我可以从 org w3c dom Node 获取完整的 xpath 吗 假设当前节点指向 xml 文档中间的某个位置 我想提取该元素的 xpath 我正在寻找的输出 xpath 是 parent child1 chiild2 child3
  • org.hibernate.MappingException:没有 JDBC 类型的方言映射:1111

    我使用的是 postgres v8 3 它的列类型为 XML DDL 看起来像这样 CREATE TABLE contact ID INTEGER NOT NULL NAME VARCHAR NOT NULL Details XML 在映射
  • 如何将 wsdl 内部架构设置为 Jaxb2Marshaller 以验证我所做的每篇文章?

    我正在使用 SOAP Web 服务 在调用它之前我必须验证每个 xml 帖子 所以我正在使用 The CXF codegen 插件生成POJO树结构 第三部分 wsdl xxxx soap service wsdl 一个类实现Web服务网关
  • 将传入字符串的 unicode 表示形式转换为 UTF-8?

    我正在读取一些已经转换为 html 样式 代码的数据 我现在需要将其转换回 UTF 8 字符以供查看 不幸的是我无法使用浏览器查看该字符串 我读过有关 java 中的转换的内容 似乎如果你有一个 uxxxx 字符串 那么编译器会为你转换 然
  • 如何减少 JSF 中的 javax.faces.ViewState

    减少 JSF 中视图状态隐藏字段大小的最佳方法是什么 我注意到我的视图状态约为 40k 这会在每次请求和响应时下降到客户端并返回到服务器 特别是到达服务器时 这对用户来说会显着减慢 我的环境 JSF 1 2 MyFaces Tomcat T
  • 日志记录在 Android 设备上实际上有什么作用?

    我一直在 Android 示例中看到这样的代码 try catch Exception e Log e Error e getMessage 什么是Log e实际上在物理设备上做什么 它进入系统日志 开发人员可以通过 SDK 工具访问该日志
  • 为什么jdk中没有ConcurrentLinkedHashMap类?

    这个问题直接接着问从我之前的问题来看 https stackoverflow com q 12299731 1527084 我想我的第二个问题的答案是否定的 所以我想了解为什么 java util concurrent 包中没有 Concu
  • Android - 保持用户登录状态

    我正在尝试使用 PHP 和 MySQLi for Android 进行登录 我不明白的是如何保持用户登录状态 我看到一个简单的教程 其中有人使用 SQLite 来保护信息 但我不知道这是否真的安全 如何保存用户信息以保持用户登录状态 谢谢
  • 相当于 C# 中 Java 的“ByteBuffer.putType()”

    我正在尝试通过从 Java 移植代码来格式化 C 中的字节数组 在 Java 中 使用方法 buf putInt value buf putShort buf putDouble 等等 但我不知道如何将其移植到 C 我尝试过 MemoryS
  • 为什么 HttpServletRequest 输入流为空?

    我有这段代码 我从请求输入流读取输入并使用 JacksonMapper 转换为 POJO 它在具有 guice 支持的 jetty 7 容器中运行 Override protected void doPost HttpServletRequ
  • Maven `help: effective-pom` 只为单个项目生成,而不是所有项目

    我想为多模块构建中的所有子项目生成有效的 pom The help effective pom文档here http maven apache org plugins maven help plugin usage html The hel
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我

随机推荐

  • nginx auth_basic 时间限制

    我正在使用 nginx 和auth basic模块 但我似乎找不到一种方法来指定 身份验证 过期的时间间隔 我希望能够强制 nginx 每 6 小时询问一次密码 有没有办法做到这一点 如果不是 可接受的解决方法是什么 这可能是不可能的 似乎
  • 什么是 iOS 的渐进式 Web 应用程序解决方案 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道 iOS 设备的渐进式 Web 应用程序的解决方案是什么 因为他们的默认浏览器 SAFARI 尚不支持渐进式 Web 应用程序
  • 如何按嵌套属性对数组进行排序

    let array id 248439 name Cross Creek Ranch Creek Cove surveyStatus territoryName Fulshear subdivisionName Cross Creek Ra
  • 如何使用 Java 中的 Jersey 安全注释绕过 servlet 过滤器中的路径

    我已经使用 Jersey 实现了 REST 服务 为了提供更多安全性 我在 REST 方法中添加了球衣安全注释 PermitAll DenyAll 以下是我的 REST 服务示例 GET Path getall Produces Media
  • python/pandas 中的整数在 sqlite 中变成 BLOB(二进制)

    在 sqlite 中存储整数会导致 BLOB 二进制值 而不是 sqlite 中的 INTEGER 问题出在 Baujahr 列中的 INT 该表已创建 CREATE TABLE Objekt No INTEGER NOT NULL UNI
  • Ruby:通过正则表达式过滤数组?

    这对我来说是一个常见的 重复的习惯用法 使用正则表达式过滤数组 然后返回子数组 我的方法看起来不太像 Ruby 我来自 Java 我最终得到了很多看起来很像这样的方法 改进此代码的惯用 Ruby 方法是什么 def get all gifs
  • 使用 jQuery 选择 CSS 中具有 color:lightGreen 的元素

    如何选择具有属性的元素color lightGreen使用 jQuery 在 CSS 中 然后将其更改为 666 示例 HTML a class CorporateHyperlink href EstimateSite Estimate D
  • Eclipse 导出的 Runnable JAR 不显示图像

    运行从 Eclipse 导出的 JAR 文件时 我的图像不会加载 我的图像位于资源类包中 我也尝试过图像源文件夹 但没有成功 从 Eclipse 加载时工作完美 图像位于导出的 JAR 文件中 因此导出正常 我试过了 label setIc
  • 与经过验证的位置交互? - 谷歌地图

    好的 有很多Google 地图上标记的商家这些日子 但我无法以任何方式与这些互动 这是我掌握的信息 场地名称 声音部 地址 伦敦冈特街 103 号 SE1 6DP 谷歌的地理位置only给我 坐标 纬度 经度 格式化地址 我想要一个应用程序
  • 将 mysql 转换为 mysqli [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我对 My
  • 如何使用 NavigationLink 在 SwiftUI 中创建文本(仅文本中的一些单词)

    我正在开发适用于 iOS 的 SwiftUI 应用程序 我想以这种方式格式化文本 其中蓝色单词应该是导航链接 文本应该如何显示 我知道可以将 UIKit 实现到 SwiftUI 代码中 但是 我不明白如何以这种方式使用 UIKit 和正常工
  • 休眠并删除所有

    最好的方法是什么删除 Hibernate 中表中的所有行 如果我迭代一个集合并调用session delete 据我所知 它的表现并不好 如果我使用其他选项session createQuery delete 它不会影响持久化上下文 如果没
  • 日志文件未使用 java 中的 log4j 更新/创建

    我正在尝试使用 Java 中的 log4j 捕获日志 该可执行文件位于Linux环境中 它显示日志消息 但是 它没有写入日志文件 我正在使用 log4j xml 这就是我到目前为止所拥有的
  • 使用 iScroll 会阻止键盘在我的设备上显示

    我正在使用 iScroll 来提供 iPhone 风格的滚动 但是 当单击文本框时 键盘不会显示 在尝试查找可能的原因时 我发现删除iScroll脚本 使其正常工作 但在这种情况下我错过了滚动功能 这是 iScroll 中的错误吗 如果是
  • 无法使用 Visual C++ 编译 allegro

    我刚刚下载了 allegro 库 我创建一个新的空项目 然后添加一个源文件 我添加这行代码 include
  • 安装多个 npm 版本

    是否可以安装多个版本npm对于我正在从事或正在从事的不同项目npm安装总是全局的 Windows 10 还尝试安装不同版本https github com marcelklehr nodist https github com marcel
  • Maven 提供的作用域可以传递吗?

    我有一个祖先依赖项 它具有所提供的依赖范围 我需要将该范围传播到依赖于我的项目的任何内容 例如 假设我有SomeProjectA这取决于SomeLibraryB 我需要确定范围SomeLibraryB已提供 目前编译任何依赖于SomePro
  • 设计用于库存控制的“EAV”或“类/具体表继承”数据库

    我正在为一个建设项目开发库存控制系统 店员负责添加新库存并将其分发给员工 从员工处返还 这些物品 以及它们的属性 将会非常多样化 例如钢制品 服装 设备 机械 工具等 我的问题是是否要去类 具体表继承 https stackoverflow
  • 核心数据对多关系在将对象添加到父实体时创建重复项

    我是 Core Data 和 Objective c 的新手 我正在开发一个项目 从 Web 服务获取 JSON 数据并将其与核心数据同步 我成功地遵循了这个tutorial http www raywenderlich com 15916
  • 用 Java JNA 编写的关键监听器。防止多次回调

    我使用以下代码来监听全局按键事件 Win32HookManager java import com sun jna Pointer import com sun jna platform win32 Kernel32 import com