需要实现实现系统托盘,以及热键恢复窗口。默认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编程不同呢?还是哪里弄错了, 弄过的兄弟帮忙下了,谢了。
#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编程不同呢?还是哪里弄错了, 弄过的兄弟帮忙下了,谢了。
解决方案 »
- swing JTree的树节点拖拽问题(急啊!求助!)
- 请教:关于Jtable的问题
- 使用Mina2时,能否将IoSession存放到Memcached中
- 请看下面简短程序, 为什么一运行就抛错? 请指点
- 我想用有个数组,给一个对象的属性赋值,改如何实现呢?
- webstart程序,都通过什么方式和别的程序通信的?
- Java3D的鼠标捕捉事件(高手请进)
- 当在输入框中未输入任何东西,
- 在java中如何实现对话框?
- 有谁知道在《java2核心技术》卷I中的光盘中的corejava包的Day类的两个关于日期算法???
- 求助!!
- 什么是算法?举例说下。虽做过几个简单小程序但一直是自已摸索的,不知道何为算法。
JDK1.6实现了系统托盘,JDK版本比较低的话用JDIC这个其实就是JDK1.6吸取了这个开源,热键恢复用捕捉热键来实现,写了这么多 实在没心思看光 提点意见 希望有帮助
现在剩下的问题就是在其他window窗口也能按热键恢复窗口这个, 似乎只能用win的hook了
这样的帖,我已经发了三遍了,都没有得到解决。
似乎唯一的解决方案就是不同平台不同JNI了。
回头再来。