K
Knitter
I'm trying to develop a simple program that intercepts braille key
strokes and translates them into normal letters. The goal is to create
a "braille keyboard emulator", is one can call it that.
I'm using java and a c++ dll making them comunicate with JNI.
The java program loads the dll in a static block in the Main class with
the 'System.loadLibrary' method the dll is loaded and the 'DllMain'
funtion is called.
What I don't know is if the 'SetWindowsHookEx' is called or not. I can
make the java program send messages to the C++ dll library and I can
make the dll send back messages to the java program but I'm never
notified about keys being pressed. I have no idea about what is going
wrong and have had no success searching for similar problems on the
web.
Here is the code for the C++ dll:
/**
Library that allows the hooking of the keyboard so that
the Java componet of the system is able to process the key codes
and send the right information to the user desktop aplication.
It's responsible for the 'grabing' of the keyboard and is the bridge
between
the java part and the aplication waiting for the key.
*/
#include "winlib.h"
#include "bkey_keyParser.h"
#include "resource.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//DllClass:llClass(){}
//DllClass::~DllClass (){}
LRESULT CALLBACK LowLevelKeyboardProc(int, WPARAM, LPARAM);
jobject parser;
JNIEnv *java;
HHOOK hhkLowLevelKybd = NULL;
/*'Params'
HINSTANCE hInst - Library instance handle.
DWORD reason - Reason this function is being called.
LPVOID reserved - Not used.
*/
extern "C" BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID
reserved)
{
printf("Metodo dllmain invocado\n");
switch (reason)
{
case DLL_PROCESS_ATTACH:
//start hook!
hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc, hInst, 0);
if(hhkLowLevelKybd == NULL)
printf("hook at process attach failed!");
else
printf("hook feito no process attach\n");
break;
case DLL_PROCESS_DETACH:
//break hook!
UnhookWindowsHookEx(hhkLowLevelKybd);
printf("unhook feito no process detach\n");
break;
/*Are process and thread called allways or is only one of them
called?*/
case DLL_THREAD_ATTACH:
//ignore
printf("DLL_THREAD_ATTACH invocado\n");
break;
case DLL_THREAD_DETACH:
//ignore
printf("DLL_THREAD_DETACH invocado\n");
break;
}
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
printf("callback de teclado invocada!\n");
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *) lParam;
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
printf("Pressionada a tecla\n");
jclass cls = (java)->GetObjectClass(parser);
jmethodID mid = (java)->GetMethodID(cls, "processKey", "(I)V");
(java)->CallVoidMethod(parser, mid, p->vkCode);
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
printf("Tecla libertada\n");
break;
}
//return the control to the sytem!
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
/*
Function called by the Java part in order to return the processed key.
*/
JNIEXPORT void JNICALL Java_bkey_KeyParser_parsedKey (JNIEnv *env,
jobject object, jint key)
{
if(key == VK_L)
printf("Java enviou a tecla L\n");
else
printf("Codigo da tecla enviada por Java diferente da tecla L\n");
}
/*
Function called by the Java part to register itself as the owner and
caller of this library.
This is used to make the library able to call java methods and send the
intercepted keys to be processed.
*/
JNIEXPORT void JNICALL Java_bkey_KeyParser_registerOwner (JNIEnv *env,
jobject object)
{
printf("C a registar o dono\n");
parser = object;
java = env;
}
Thanks.
strokes and translates them into normal letters. The goal is to create
a "braille keyboard emulator", is one can call it that.
I'm using java and a c++ dll making them comunicate with JNI.
The java program loads the dll in a static block in the Main class with
the 'System.loadLibrary' method the dll is loaded and the 'DllMain'
funtion is called.
What I don't know is if the 'SetWindowsHookEx' is called or not. I can
make the java program send messages to the C++ dll library and I can
make the dll send back messages to the java program but I'm never
notified about keys being pressed. I have no idea about what is going
wrong and have had no success searching for similar problems on the
web.
Here is the code for the C++ dll:
/**
Library that allows the hooking of the keyboard so that
the Java componet of the system is able to process the key codes
and send the right information to the user desktop aplication.
It's responsible for the 'grabing' of the keyboard and is the bridge
between
the java part and the aplication waiting for the key.
*/
#include "winlib.h"
#include "bkey_keyParser.h"
#include "resource.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//DllClass:llClass(){}
//DllClass::~DllClass (){}
LRESULT CALLBACK LowLevelKeyboardProc(int, WPARAM, LPARAM);
jobject parser;
JNIEnv *java;
HHOOK hhkLowLevelKybd = NULL;
/*'Params'
HINSTANCE hInst - Library instance handle.
DWORD reason - Reason this function is being called.
LPVOID reserved - Not used.
*/
extern "C" BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID
reserved)
{
printf("Metodo dllmain invocado\n");
switch (reason)
{
case DLL_PROCESS_ATTACH:
//start hook!
hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL,
LowLevelKeyboardProc, hInst, 0);
if(hhkLowLevelKybd == NULL)
printf("hook at process attach failed!");
else
printf("hook feito no process attach\n");
break;
case DLL_PROCESS_DETACH:
//break hook!
UnhookWindowsHookEx(hhkLowLevelKybd);
printf("unhook feito no process detach\n");
break;
/*Are process and thread called allways or is only one of them
called?*/
case DLL_THREAD_ATTACH:
//ignore
printf("DLL_THREAD_ATTACH invocado\n");
break;
case DLL_THREAD_DETACH:
//ignore
printf("DLL_THREAD_DETACH invocado\n");
break;
}
/* Returns TRUE on success, FALSE on failure */
return TRUE;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM
lParam)
{
printf("callback de teclado invocada!\n");
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *) lParam;
switch (wParam)
{
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
printf("Pressionada a tecla\n");
jclass cls = (java)->GetObjectClass(parser);
jmethodID mid = (java)->GetMethodID(cls, "processKey", "(I)V");
(java)->CallVoidMethod(parser, mid, p->vkCode);
}
break;
case WM_KEYUP:
case WM_SYSKEYUP:
printf("Tecla libertada\n");
break;
}
//return the control to the sytem!
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
/*
Function called by the Java part in order to return the processed key.
*/
JNIEXPORT void JNICALL Java_bkey_KeyParser_parsedKey (JNIEnv *env,
jobject object, jint key)
{
if(key == VK_L)
printf("Java enviou a tecla L\n");
else
printf("Codigo da tecla enviada por Java diferente da tecla L\n");
}
/*
Function called by the Java part to register itself as the owner and
caller of this library.
This is used to make the library able to call java methods and send the
intercepted keys to be processed.
*/
JNIEXPORT void JNICALL Java_bkey_KeyParser_registerOwner (JNIEnv *env,
jobject object)
{
printf("C a registar o dono\n");
parser = object;
java = env;
}
Thanks.