需要实现实现系统托盘,以及热键恢复窗口。默认Ctrl+Alt+任意键。
#include <jni.h>
typedef struct HotKeyEntry
{
JNIEnv* env;
jobject callBackObject;
int* hotKeyCodes;
int hotKeyCount;
} *PHotKeyEntry;
#pragma data_seg( ".JOE ")
PHotKeyEntry pHotKeyEntry = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.JOE,rws ")
void showKeyInfo(int nCode, WPARAM wParam, LPARAM lParam) {
if (pHotKeyEntry == NULL || pHotKeyEntry-> hotKeyCodes == NULL) {
MessageBox(NULL, TEXT( "Strange!!!pHotKeyEntry!!NULL "), TEXT( "Strange!!!pHotKeyEntry!!NULL "), MB_OK);
return;
}
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
showKeyInfo(nCode, wParam, lParam);
return CallNextHookEx(0, nCode, wParam, lParam);
}
JNIEXPORT jboolean JNICALL Java_com_gy_image_HotKeyHookManager_startHotKeyHook(JNIEnv * env,
jobject hotKeyManagerObj, jobject hotKeyCallBackObj) {
//Get the KeyCodes.
jintArray hotKeyCodeArray = getInstanceIntArrayField(env, hotKeyManagerObj);
int hotKeyCount = env-> GetArrayLength(hotKeyCodeArray);
int* hotKeyCodes = new int[hotKeyCount];
jint* rawIntArray = env-> GetIntArrayElements(hotKeyCodeArray, 0);
for (int i = 0; i < hotKeyCount; ++i) {
hotKeyCodes[i] = rawIntArray[i];
}
env-> ReleaseIntArrayElements(hotKeyCodeArray, rawIntArray, 0);
if (pHotKeyEntry == NULL) {
pHotKeyEntry = new HotKeyEntry;
pHotKeyEntry-> env = env;
pHotKeyEntry-> callBackObject = hotKeyCallBackObj;
pHotKeyEntry-> hotKeyCodes = hotKeyCodes;
pHotKeyEntry-> hotKeyCount = hotKeyCount;
}
hhook = SetWindowsHookEx(WH_KEYBOARD, LowLevelKeyboardProc, dllModule, NULL);
if (hhook == NULL) {
releaseHotKeyHook();
MessageBox(NULL, TEXT( "SetWindoesHook fail "), TEXT( "SetWindowsHook fail "), MB_OK);
return FALSE;
}
return TRUE;
}
一堆问题:
1。在任意窗口按键,回调是能捕获输入的,HotKeyEntry包含了我设置的热键keyCode以及Java里面的回调对象callBackObject(JFrame), 原本想保存这些东西,等到特定的键触发的时候恢复JFrame; 但是很可惜HotKeyEntry总是空的,网上说#pragma comment(linker, "/SECTION:.JOE,rws ")说可以共享数据,但是为什么总是不生效呢?用的是VS2005,把/SECTION设置在Project的Linker的Commandline也不行, 请问如果保存这些数据?
2.MSDN说HOOK是要调DLL好,创建HOOK和回调要分开,我就又把CALLBACK写成DLL来调, HotKeyEntry也传过去了,问题还是一样, 回调里面有字符扑获,但是不同窗口出发按键打印的HotKeyEntry都是空的,除非在Java的Frame里面就没问题。
3.后来都懵了,以为是要用底层的KeyBoardHook,我就又设置SetWindowsHookEx为WH_KEYBOARD_LL,继续尝试1,2步骤,结果更死,回调根本没东西打出来,点一下键盘还卡死一下,应该是没响应PENDING了,准备直接用VC写写看了。
是不是JNI里面这些线程还是什么影响了DLL跟普通window编程不同呢?还是哪里弄错了, 弄过的兄弟帮忙下了,谢了。