- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
这里举个例子来说明问题。假设我正在跟踪并向用户显示鼠标全局当前位置和最后单击按钮和位置。这是一张图片:
为了存档捕获 windows 框上的点击事件,这将被发送到其他程序事件消息队列,我使用 winapi 创建了一个钩子(Hook),即 user32.dll
库。这是在 JDK 沙箱之外,所以我使用 JNA 来调用 native 库。
这一切都很完美,但它并没有像我预期的那样关闭。
我的问题是 - 如何正确关闭以下示例程序?
下面的代码不是我写的,而是来自this Oracle 论坛中的问题并部分修复。
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import com.sun.jna.Native;
import com.sun.jna.NativeLong;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.LRESULT;
import com.sun.jna.platform.win32.WinDef.WPARAM;
import com.sun.jna.platform.win32.WinUser.HHOOK;
import com.sun.jna.platform.win32.WinUser.HOOKPROC;
import com.sun.jna.platform.win32.WinUser.MSG;
import com.sun.jna.platform.win32.WinUser.POINT;
public class MouseExample {
final JFrame jf;
final JLabel jl1, jl2;
final CWMouseHook mh;
final Ticker jt;
public class Ticker extends Thread {
public boolean update = true;
public void done() {
update = false;
}
public void run() {
try {
Point p, l = MouseInfo.getPointerInfo().getLocation();
int i = 0;
while (update == true) {
try {
p = MouseInfo.getPointerInfo().getLocation();
if (!p.equals(l)) {
l = p;
jl1.setText(new GlobalMouseClick(p.x, p.y)
.toString());
}
Thread.sleep(35);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
} catch (Exception e) {
update = false;
}
}
}
public MouseExample() throws AWTException, UnsupportedOperationException {
this.jl1 = new JLabel("{}");
this.jl2 = new JLabel("{}");
this.jf = new JFrame();
this.jt = new Ticker();
this.jt.start();
this.mh = new CWMouseHook() {
@Override
public void globalClickEvent(GlobalMouseClick m) {
jl2.setText(m.toString());
}
};
mh.setMouseHook();
jf.setLayout(new GridLayout(2, 2));
jf.add(new JLabel("Position"));
jf.add(jl1);
jf.add(new JLabel("Last click"));
jf.add(jl2);
jf.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
mh.dispose();
jt.done();
jf.dispose();
}
});
jf.setLocation(new Point(0, 0));
jf.setPreferredSize(new Dimension(200, 90));
jf.pack();
jf.setVisible(true);
}
public static class GlobalMouseClick {
private char c;
private int x, y;
public GlobalMouseClick(char c, int x, int y) {
super();
this.c = c;
this.x = x;
this.y = y;
}
public GlobalMouseClick(int x, int y) {
super();
this.x = x;
this.y = y;
}
public char getC() {
return c;
}
public void setC(char c) {
this.c = c;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public String toString() {
return (c != 0 ? c : "") + " [" + x + "," + y + "]";
}
}
public static class CWMouseHook {
public User32 USER32INST;
public CWMouseHook() throws UnsupportedOperationException {
if (!Platform.isWindows()) {
throw new UnsupportedOperationException(
"Not supported on this platform.");
}
USER32INST = User32.INSTANCE;
mouseHook = hookTheMouse();
Native.setProtected(true);
}
private static LowLevelMouseProc mouseHook;
private HHOOK hhk;
private boolean isHooked = false;
public static final int WM_LBUTTONDOWN = 513;
public static final int WM_LBUTTONUP = 514;
public static final int WM_RBUTTONDOWN = 516;
public static final int WM_RBUTTONUP = 517;
public static final int WM_MBUTTONDOWN = 519;
public static final int WM_MBUTTONUP = 520;
public void dispose() {
unsetMouseHook();
mousehook_thread = null;
mouseHook = null;
hhk = null;
USER32INST = null;
}
public void unsetMouseHook() {
isHooked = false;
USER32INST.UnhookWindowsHookEx(hhk);
System.out.println("Mouse hook is unset.");
}
public boolean isIsHooked() {
return isHooked;
}
public void globalClickEvent(GlobalMouseClick m) {
System.out.println(m);
}
private Thread mousehook_thread;
public void setMouseHook() {
mousehook_thread = new Thread(new Runnable() {
@Override
public void run() {
try {
if (!isHooked) {
hhk = USER32INST.SetWindowsHookEx(14, mouseHook,
Kernel32.INSTANCE.GetModuleHandle(null), 0);
isHooked = true;
System.out
.println("Mouse hook is set. Click anywhere.");
// message dispatch loop (message pump)
MSG msg = new MSG();
while ((USER32INST.GetMessage(msg, null, 0, 0)) != 0) {
USER32INST.TranslateMessage(msg);
USER32INST.DispatchMessage(msg);
if (!isHooked)
break;
}
} else
System.out
.println("The Hook is already installed.");
} catch (Exception e) {
System.err.println("Caught exception in MouseHook!");
}
}
});
mousehook_thread.start();
}
private interface LowLevelMouseProc extends HOOKPROC {
LRESULT callback(int nCode, WPARAM wParam, MOUSEHOOKSTRUCT lParam);
}
private LowLevelMouseProc hookTheMouse() {
return new LowLevelMouseProc() {
@Override
public LRESULT callback(int nCode, WPARAM wParam,
MOUSEHOOKSTRUCT info) {
if (nCode >= 0) {
switch (wParam.intValue()) {
case CWMouseHook.WM_LBUTTONDOWN:
globalClickEvent(new GlobalMouseClick('L',
info.pt.x, info.pt.y));
break;
case CWMouseHook.WM_RBUTTONDOWN:
globalClickEvent(new GlobalMouseClick('R',
info.pt.x, info.pt.y));
break;
case CWMouseHook.WM_MBUTTONDOWN:
globalClickEvent(new GlobalMouseClick('M',
info.pt.x, info.pt.y));
break;
default:
break;
}
}
return USER32INST.CallNextHookEx(hhk, nCode, wParam,
info.getPointer());
}
};
}
public class Point extends Structure {
public class ByReference extends Point implements
Structure.ByReference {
};
public NativeLong x;
public NativeLong y;
}
public static class MOUSEHOOKSTRUCT extends Structure {
public static class ByReference extends MOUSEHOOKSTRUCT implements
Structure.ByReference {
};
public POINT pt;
public HWND hwnd;
public int wHitTestCode;
public ULONG_PTR dwExtraInfo;
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
new MouseExample();
} catch (AWTException e) {
e.printStackTrace();
}
}
});
}
}
最佳答案
在你的线程中你应该调用
User32.PostQuitMessage(0)
通知 native 线程( Hook )您不再需要它。当你这样做时,在你的代码中检查
while ((USER32INST.GetMessage(msg, null, 0, 0)) != 0)
发现您不再需要钩子(Hook)并在 native 端终止它。我建议您首先尝试使用内部事件关闭钩子(Hook),例如
CWMouseHook.WM_MBUTTONDOWN
只是为了看看它是否正常工作。
在这篇文章中:Working example of JNA mouse hook你可以看到一些应该对你有帮助的代码。干杯。
关于java - 关闭捕获全局输入事件的 Hook ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4527931/
我创建了一个简单的钩子(Hook),我安装了它 SetWindowsHookEx(WH_CBT, addr, dll, 0); 完成后,我卸载 UnhookWindowsHookEx(0); 然后我可
我正在使用 React Hooks,当我用 mobx 的观察者包装我的组件时,我收到了这个错误。可能是什么问题?是否可以将 mobx 与 React Hooks 一起使用? import classn
我知道这个问题已经被回答过很多次了。我只是找不到解决我的问题的答案,让我相信,我要么是愚蠢的,要么是我的问题没有被解决,因为它比我更愚蠢。除此之外,这是我的问题: 我正在尝试创建一个功能组件,它从 r
我正在使用 React Navigation 的 useNavigation 钩子(Hook): 在 MyComponent.js 中: import { useNavigation } from "
我想在 gitlab 中使用预提交钩子(Hook)。我做的一切都像文档中一样:https://docs.gitlab.com/ce/administration/custom_hooks.html 在
我最近在和一些人谈论我正在编写的程序时听到了“hook”这个词。尽管我从对话中推断出钩子(Hook)是一种函数,但我不确定这个术语到底意味着什么。我搜索了定义,但找不到好的答案。有人可以让我了解这个术
我正在寻找一个在页面创建或页面更改后调用的钩子(Hook),例如“在导航中隐藏页面”、“停用页面”或“移动/删除页面“ 有人知道吗? 谢谢! 最佳答案 这些 Hook 位于 t3lib/class.t
我正在使用钩子(Hook)将新方法添加到 CalEventLocalServiceImpl 中... 我的代码是.. public class MyCalendarLocalServiceImpl e
编译器将所有 SCSS 文件编译为 STANDALONE(无 Rails)项目中的 CSS 后,我需要一个 Compass Hook 。 除了编辑“compiler.rb”(这不是好的解决方案,因为
我“.get”一个请求并像这样处理响应: resp = requests.get('url') resp = resp.text .. # do stuff with resp 阅读包的文档后,我看到
我们想在外部数据库中存储一些关于提交的元信息。在克隆或 checkout 期间,应引用此数据库,我们将元信息复制到克隆的存储库中的文件中。需要数据库而不是仅仅使用文件是为了索引和搜索等...... 我
我有一个 react 钩子(Hook)useDbReadTable,用于从接受tablename和query初始数据的数据库读取数据。它返回一个对象,除了数据库中的数据之外,还包含 isLoading
在下面的代码中,当我调用 _toggleSearch 时,我同时更新 2 个钩子(Hook)。 toggleSearchIsVisible 是一个简单的 bool 值,但是,setActiveFilt
问题 我想在可由用户添加的表单中实现输入字段的键/值对。 参见 animated gif on dynamic fields . 此外,我想在用户提交表单并再次显示页面时显示保存的数据。 参见 ani
当状态处于 Hook 状态时,它可能会变得陈旧并泄漏内存: function App() { const [greeting, setGreeting] = useState("hello");
const shouldHide = useHideOnScroll(); return shouldHide ? null : something useHideOnScroll 行为应该返回更新后
我正在使用 React-native,在其中,我有一个名为 useUser 的自定义 Hook,它使用 Auth.getUserInfro 方法从 AWS Amplify 获取用户信息,并且然后获取返
我正在添加一个 gitolite 更新 Hook 作为 VREF,并且想知道是否有办法将它应用于除 gitolite-admin 之外的所有存储库。 有一个更简单的方法而不是列出我想要应用 Hook
如何使用带有 react-apollo-hooks 的 2 个 graphql 查询,其中第二个查询取决于从第一个查询中检索到的参数? 我尝试使用如下所示的 2 个查询: const [o, setO
我是 hooks 的新手,到目前为止印象还不错,但是,如果我尝试在函数内部使用 hooks,它似乎会提示(无效的 hook 调用。Hooks can only be called inside o
我是一名优秀的程序员,十分优秀!