L
Ok, dann kommt mal ein wenig Code. Ich habe ein Java programm, welches über eine in C geschriebene DLL erweitert wurde. Und in einer DLL mach ich diese Hooks. Es wird einmal ein MouseHook und einmal ein Keyboard Hook gesetzt.
Ich poste mal die DLL mit den wichtigsten Funktionen.
HINSTANCE hInst = NULL;
JavaVM * jvm = NULL;
jobject hookObj = NULL;
jmethodID processKeyID = NULL;
jmethodID onHotKeyID = NULL;
DWORD hookThreadId = 0;
HHOOK hookHandle;
HHOOK hookHandleMouse;
extern "C" BOOL APIENTRY DllMain(HINSTANCE _hInst, DWORD reason, LPVOID reserved) {
switch (reason) {
case DLL_PROCESS_ATTACH:
hInst = _hInst;
break;
default:
break;
}
return TRUE;
}
//Wird aus Java aufgerufen, um die Hooks zu registrieren
JNIEXPORT void JNICALL Java_LowLevelHook_Hook_registerHook(JNIEnv * env, jobject obj) {
setHook(env, obj); //ist die Funktion drunter
MsgLoop();
if (!UnhookWindowsHookEx(hookHandleMouse)) {
printf("C++: Java_Hook_registerHook - Unhook failed\n");
} else {
printf("C++: Java_Hook_registerHook - Unhook successful\n");
}
if (!UnhookWindowsHookEx(hookHandle)) {
printf("C++: Java_Hook_registerHook - Unhook Keyboard failed\n");
} else {
printf("C++: Java_Hook_registerHook - Unhook Keyboard successful\n");
}
}
void setHook(JNIEnv *env, jobject obj) {
hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInst, 0);
hookHandleMouse = SetWindowsHookEx(WH_MOUSE_LL, MouseProc, hInst, 0);
if (hookHandle == NULL || hookHandleMouse == NULL) {
printf("C++: Java_Hook_registerHook - Hook failed!\n");
printf("C++: Java_Mouse_Hook_registerHook - Hook failed!\n");
return;
} else {
printf("C++: Java_Hook_registerHook - Hook successful\n");
printf("C++: Java_Mouse_Hook_registerHook - Hook successful\n");
}
hookObj = env->NewGlobalRef(obj);
jclass cls = env->GetObjectClass(hookObj);
processKeyID = env->GetMethodID(cls, "processKey", "(IZ)I");
onHotKeyID = env->GetMethodID(cls, "onHotKey", "(I)V");
env->GetJavaVM(&jvm);
hookThreadId = GetCurrentThreadId();
}
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) {
JNIEnv * env;
MSLLHOOKSTRUCT * m = (MSLLHOOKSTRUCT*) lParam;
int a;
if (nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam);
if (jvm->AttachCurrentThread((void **) & env, NULL) >= 0) {
if (nCode == HC_ACTION) {
switch (wParam) {
case WM_MOUSEWHEEL:
env->CallIntMethod(hookObj, processKeyID, (int) m->mouseData, false);
break;
case WM_LBUTTONUP:
env->CallVoidMethod(hookObj, onHotKeyID, -10, false);
break;
case WM_RBUTTONUP:
/* Hier handelt es sich um die beschriebene Sache, dass ich selbst ein MouseEvent alle 5 sec auslöse und es dann wieder "auffange" um zu schauen, ob der Hook noch läuft.
*/
int extra = (int) m->dwExtraInfo;
if (extra == -99) {
env->CallVoidMethod(hookObj, onHotKeyID, -99, false);
return 1;
}
env->CallVoidMethod(hookObj, onHotKeyID, -30, false);
break;
case WM_MBUTTONUP:
env->CallVoidMethod(hookObj, onHotKeyID, -20, false);
break;
case WM_XBUTTONDOWN:
a = HIWORD(m->mouseData);
int ret;
if (a == 1) {
ret = -40;
}
if (a == 2) {
ret = -50;
}
env->CallVoidMethod(hookObj, onHotKeyID, ret, false);
break;
default:
break;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
So, hoffentlich jetzt keine Glaskugel mehr. Wie gesagt, meine komplette Programmlogik ist in Java, ich brauch die Winapi wirklich nur um auf einige Dinge zu reagieren. Und ich versteh nicht, wieso manchmal (und nur bei einigen Usern) plötzlich die Notifikations aufhören. So als wäre der Hook auf einmal weg.