JNI and SetWindowsHookEx Callback not being called?
I seem to have an issue that I cant resolve. I have a jni dll that
calls SetWindowsHookEx with a callback to HookKeyboardProc (basically
a real simple global keyboard hook). Now the dll almost works all the
jni hooks are fine and the program appears to run but the callback
(HookKeyboardProc) does not seem to get executed or possibly never
returns from execution. The code is as follows. None of the
variables being set in the code actually get set so im not sure what i
botched. The hook does complete successfully as it returns non-null
value for hkb. I would appreciate any help or suggestions on where to
get help.
Thanks
// syshook.cpp
/*
* SysHook - 7/17/05
* Jacob Gohlke
*
* JNI Interface for setting a Keyboard Hook and monitoring
* it Java-side
*
* (c) Copyright 2005 Jacob Gohlke
*
* Feel free to use and learn from this code, royalty-free!
* I only ask you acknkowlege what library you are using
* and who made it. Thanks, and happy hooking!
*/
#include <windows.h>
#include <winuser.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include "org_dotnative_globalkeylistener_PollThread.h"
//#pragma data_seg(".HOOKDATA") //Shared data among all instances.
//#pragma data_seg("Shared")
static HHOOK hkb = NULL;
static HANDLE g_hModule = NULL;
static WPARAM g_wParam = 0;
static LPARAM g_lParam = 0;
static bool test = FALSE;
//extern "C" {
JNIEXPORT void NotifyJava(JNIEnv *env, jobject obj) {
jclass cls = env->GetObjectClass(obj);
jmethodID mid;
mid = env->GetMethodID(cls, "Callback", "(ZIZZ)V");
if (mid == NULL) {
return;
}
if( (HIWORD( g_lParam ) & KF_UP) ) {
env->CallVoidMethod(obj, mid, (jboolean)FALSE, (jint)(g_wParam),
(jboolean)(HIWORD( g_lParam ) & KF_ALTDOWN), (jboolean)
(HIWORD( g_lParam ) & KF_EXTENDED));
}
else {
env->CallVoidMethod(obj, mid, (jboolean)TRUE, (jint)(g_wParam),
(jboolean)(HIWORD( g_lParam ) & KF_ALTDOWN), (jboolean)
(HIWORD( g_lParam ) & KF_EXTENDED));
}
}
//#pragma data_seg()
//#pragma comment(linker, "/SECTION:.HOOKDATA,RWS")
LRESULT CALLBACK HookKeyboardProc(INT nCode, WPARAM wParam, LPARAM
lParam) {
//printf("Callback\n");
test = TRUE;
if (nCode < 0) {
// do not process message
return CallNextHookEx(hkb, nCode, wParam, lParam);
}
g_wParam = wParam;
g_lParam = lParam;
return CallNextHookEx(hkb, nCode, wParam, lParam);
}
JNIEXPORT void JNICALL
Java_org_dotnative_globalkeylistener_PollThread_checkKeyboardChanges(JNIEnv
*env, jobject obj) {
if (test) {
printf("%i %i\n", g_wParam, g_lParam);
}
if(g_wParam != 0 && g_lParam != 0) {
NotifyJava(env, obj);
g_wParam = 0;
g_lParam = 0;
}
}
static void Init() {
hkb = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)HookKeyboardProc,
(HINSTANCE)g_hModule, 0);
printf("Call Init\n");
}
static void Cleanup() {
if (hkb != NULL) {
printf("Call Unhook\n");
UnhookWindowsHookEx( hkb );
}
hkb = NULL;
printf("Call Clean\n");
}
//BOOL APIENTRY
//extern "C" BOOL WINAPI DllMain(HANDLE hModule, DWORD
ul_reason_for_call, LPVOID lpReserved) {
extern "C" BOOL WINAPI DllMain(HANDLE hModule, DWORD
ul_reason_for_call, LPVOID lpReserved) {
switch(ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
printf("Start\n");
g_hModule = hModule;
Init();
return TRUE;
case DLL_PROCESS_DETACH:
printf("Stop\n");
Cleanup();
return TRUE;
}
return TRUE;
}