详细步骤
例行说明
V1.3.1
BUG 记录 中写到,使用 Hook 钩子函数拦截系统按键信息,并屏蔽系统按键,导致一个问题,只要程序运行着,即使程序最小化,系统也无法正常按键,所以这个版本将修正该 BUG
具体步骤
- 当程序窗口获得焦点时,启用钩子函数监听系统按键
- 反之,当程序窗口失去焦点时,取消监听屏蔽,恢复系统按键
代码分析
-
KeyboardPiano
-
implements
WindowFocusListener
overridewindowGainedFocus()
&windowLostFocus()
-
setHookOn()
当窗口获得焦点时,启动钩子函数
setHookOff()
当窗口失去焦点时,取消钩子函数
-
KeyboardHook keyboardHook = new KeyboardHook(this);
JFrame.addWindowFocusListener(new WindowFocusAdapter);
private class WindowFocusAdapter implements WindowFocusListener {
@Override
public void windowGainedFocus(WindowEvent e) {
// TODO Auto-generated method stub
if(keyboardHook != null && !keyboardHook.isFocused &&
window.frmKeyboardpiano.isFocused()) {
keyboardHook.setHookOn();
}
}
@Override
public void windowLostFocus(WindowEvent e) {
// TODO Auto-generated method stub
if(keyboardHook != null && keyboardHook.isFocused &&
!window.frmKeyboardpiano.isFocused()) {
keyboardHook.setHookOff();
}
}
}
-
KeyboardHook
setHookOn()
=> 启动 Hook 线程HookThread
=>setHookOnInner()
启动钩子函数并获取系统信息setHookOff()
=>User32.INSTANCE.UnhookWindowsHookEx(hhk);
关闭钩子
public boolean isFocused = false;
private void setHookOnInner() {
if(hhk == null) {
HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
hhk = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardProc, hMod, 0);
} else {
return;
}
isFocused = true;
WinUser.MSG msg = new WinUser.MSG();
/*
* GetMessage is a blocking thread, it calls callback?
*/
User32.INSTANCE.GetMessage(msg, null, 0, 0);
}
public void setHookOn(){
hookThread = new HookThread();
hookThread.start();
}
public void setHookOff(){
synchronized(this) {
User32.INSTANCE.UnhookWindowsHookEx(hhk);
hhk = null;
isFocused = false;
}
}
private class HookThread extends Thread {
@Override
public void run() {
setHookOnInner();
}
}
相关链接
-
回调函数和钩子函数(CSDN 转) 又是一篇排版糟糕的干货