【问题标题】:Java Keylistener without window being open?没有打开窗口的Java Keylistener?
【发布时间】:2010-10-16 07:41:15
【问题描述】:

我正在尝试在 Java 中创建一个自动点击器(只有我知道的语言并且我刚刚学习了线程)。我想让小程序在它自己的窗口中打开(而不是在网页上),并且我希望能够在不选择窗口的情况下使用空格键启动和停止程序,以便我可以在另一个程序上使用自动点击器并且能够在不使用 alt-f4 的情况下阻止它。

您有什么可以推荐给我的可以帮助我的吗?或者您有什么建议?

【问题讨论】:

    标签: java keylistener


    【解决方案1】:

    迟到的答案,但希望对您有所帮助:)

    您可以使用 JNA,这简直是小菜一碟!!

    1. 获取 JNA (jna.jar)
    2. 在表单中为 User32 (User32.dll) 创建自己的映射

      公共接口 User32 扩展 StdCallLibrary { User32 INSTANCE = (User32) Native.loadLibrary("User32", User32.class, Options.UNICODE_OPTIONS); // dwWakeMask 常量 公共静态最终int QS_ALLEVENTS = 0x04BF; 公共静态最终 int QS_ALLINPUT = 0x04FF; 公共静态最终 int QS_ALLPOSTMESSAGE = 0x0100; 公共静态最终 int QS_HOTKEY = 0x0080; 公共静态最终 int QS_INPUT = 0x407; 公共静态最终int QS_KEY = 0x0001; 公共静态最终 int QS_MOUSE = 0x0006; 公共静态最终 int QS_MOUSEBUTTON = 0x0004; 公共静态最终int QS_MOUSEMOVE = 0x0002; 公共静态最终int QS_PAINT = 0x0020; 公共静态最终 int QS_POSTMESSAGE = 0x0008; 公共静态最终int QS_RAWINPUT = 0x0400; 公共静态最终 int QS_SENDMESSAGE = 0x0040; 公共静态最终int QS_TIMER = 0x0010; 公共静态最终 int INFINITE = 0xFFFFFFFF; /* DWORD WINAPI MsgWaitForMultipleObjects( __in DWORD nCount, __in const HANDLE *pHandles, __in BOOL bWaitAll, __in DWORD dwMilliseconds, __in DWORD dwWakeMask );*/ int MsgWaitForMultipleObjects(int nCount, Pointer pHandles, boolean bWaitAll, int dwMilliSeconds, int dwWakeMask); /* fsModifiers 值 */ 公共静态最终 int MOD_ALT = 0x0001; 公共静态最终 int MOD_CONTROL = 0x0002; 公共静态最终 int MOD_NOREPEAT = 0x4000; 公共静态最终 int MOD_SHIFT = 0x0004; 公共静态最终 int MOD_WIN = 0x0008; /* BOOL WINAPI 注册热键( __in_opt HWND hWnd, __in int id, __in UINT fsModifiers, __in UINT vk ); */ boolean RegisterHotKey(指针 hWnd, int id, int fsModifiers, int vk); }
    3. 只需查看以下页面,即可清楚了解幕后工作的原理:

    h**p://msdn.microsoft.com/en-us/library/ms646309%28VS.85%29.aspx

    h**p://msdn.microsoft.com/en-us/library/ms684242%28VS.85%29.aspx

    1. 查看此页面,了解可以为其注册回调的关键常量是什么

    h**p://msdn.microsoft.com/en-us/library/dd375731%28v=VS.85%29.aspx

    1. 像这样创建一个测试程序:
    用户 32 用户 32 = 用户 32.实例; boolean res = user32.RegisterHotKey(Pointer.NULL, 9999, User32.MOD_ALT | User32.MOD_CONTROL, WINUSER.VK_LEFT); 如果(!res) System.out.println("无法注册热键"); System.out.println("启动和等待"); user32.MsgWaitForMultipleObjects(0, Pointer.NULL, true, User32.INFINITE, User32.QS_HOTKEY); System.out.println("结尾");

    User32.INFINITE 是一个未记录的常量,值为 0xFFFFFFFF

    抱歉,http 链接重命名为 h**p :) Stackoverflow 规则 斯特凡诺

    【讨论】:

      【解决方案2】:

      这可能超出了 Java 小程序的范围。事实上,全局键盘挂钩绝对超出了简单使用 Java 的范围,但我可以帮助您朝着正确的方向前进。

      但是,你有一些希望。我将向您指出JNI (Java Native Interface) 的方向,这将允许您使用本机库。现在,既然您想留在 Java 世界中,我建议您不要直接使用 JNI,因为您将不得不编写一些令人困惑的本机代码(通常是 C、C++)。有几个 JNI 包装器允许您使用这些函数,但原生实现被抽象掉了,但其中很多都需要花钱。


      所以我认为最适合您的解决方案是JNA (Java Native Access)。这允许您从 Java 中直接调用本机库。 (注意:实现不会是跨平台的。您必须为 Windows、Linux 等单独实现。)项目网站上的示例中有一个很好的 Windows 键盘挂钩示例。

      至于打开它自己的窗口而不是在网页中,您是否希望小程序不在浏览器中运行而是在它自己的单独进程中运行,或者只是在一个单独的窗口中并且仍然依赖浏览器窗口打开?

      • 如果您只想启动一个新窗口并且仍然需要打开浏览器,那么这里有一个很好的例子:

        final Frame window = new Frame("This is the Frame's Title Bar!");
        window.add(new Label("This is the Frame."));
        window.setSize(300,200);
        window.setVisible(true);
        
        window.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent we){
                window.dispose();
            }
        });
        
      • 如果您希望小程序生成一个新进程并在不需要浏览器的情况下运行,请查看JavaFX

      【讨论】:

      • 在它自己的单独窗口中可能是最好的。
      【解决方案3】:

      我认为你可以使用setVisible(false) 方法来做到这一点。 窗口会在那里,但用户将看不到它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-12
        • 2018-01-21
        • 1970-01-01
        • 2020-10-20
        • 1970-01-01
        • 2021-06-30
        相关资源
        最近更新 更多