Global Hotkeys in Java?

Also ich weiß selber nicht genau wo das Problem liegt..
Die Registrierung des Hooks klappt halt ohne Fehler, allerdings wird die Callback Methode nicht aufgerufen...

Ich vermute nun, dass es an der Art liegt, wie ich den Hook registriere
C++:
#include "dll.h"
#include "keyhook_HotKeyManager.h"

//HINSTANCE hDll = NULL;
HHOOK g_hKeyHook SHARED = NULL;    // Handle unseres Hooks (als "shared" Deklariert)
HINSTANCE g_hInst SHARED = NULL;     // Handle der DLL selbst
JavaVM *javavm = NULL;
JNIEnv *jniEnv = NULL;
int hotkeyCount = 0;
jobject globClass;
jmethodID action;

BOOL APIENTRY DllMain( HINSTANCE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved)
{
    switch (ul_reason_for_call)
            {
                case DLL_PROCESS_ATTACH:
                    g_hInst = hModule;
                     break;
                case DLL_THREAD_ATTACH:
                    break;
                case DLL_THREAD_DETACH:
                    break;
                case DLL_PROCESS_DETACH:
                    break;
            }
    return TRUE;
}

BOOL InstallHook( int nrOfHotkeys, JavaVM *vm, jobject clazz )
{
    //Werte sichern
    hotkeyCount = nrOfHotkeys;

    //MessageBox(NULL, "Install!", "Out", MB_OK);
    if(g_hKeyHook != NULL)
        return TRUE;

    g_hKeyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(NULL), 0);
    
    if(g_hKeyHook == NULL)
        return FALSE;
        
    return TRUE;
}

BOOL UninstallHook()
{
    if(g_hKeyHook != NULL)
    {
        UnhookWindowsHookEx(g_hKeyHook);
        g_hKeyHook = NULL;
    }
    return TRUE;
}

BOOL IsModifier ( WPARAM wParam )
{
     switch ( (WORD) wParam )
     {
            case VK_RETURN: return TRUE;
            case VK_CONTROL: return TRUE;
            case VK_SHIFT: return TRUE;
            case VK_MENU: return TRUE;
            case VK_LCONTROL: return TRUE;
            case VK_RCONTROL: return TRUE;
            case VK_LSHIFT: return TRUE;
            case VK_RSHIFT: return TRUE;
            case VK_TAB: return TRUE;
            case VK_LWIN: return TRUE;
            case VK_RWIN: return TRUE;
     }
     return FALSE;
}

JNIEXPORT jboolean JNICALL Java_keyhook_HotKeyManager_installHook
  (JNIEnv *env, jobject clazz, jint nrOfHooks)
  {
          globClass = env->NewGlobalRef( clazz );
          action = env->GetMethodID( env->GetObjectClass( clazz ), "jniActionPerformed", "(III)V" );
          return (jboolean) InstallHook( (int)nrOfHooks, javavm, globClass );
  }


JNIEXPORT jboolean JNICALL Java_keyhook_HotKeyManager_uninstallHook
  (JNIEnv *env, jobject clazz)
  {      
         bool ret = UninstallHook();
         return (jboolean) ret;
  }

jint JNI_OnLoad
  (JavaVM *vm, void *reserved)
  {
         javavm = vm;
         return JNI_VERSION_1_4;
  }

Ich glaube halt das
C++:
    g_hKeyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandle(NULL), 0);
nicht richtig funktioniert, ich würde auch als 3.ten Parameter den Habdle nehmen der der DLLMain übergeben wird, die wird aber gar nicht erst aufgerufen..
Was hast du denn als 3.ten Parameter?

Wäre echt gut wenn du mir mal deine Klassen zeigen könntest..
Wenn du das nicht posten möchtest: tobias.viehweger@gmx.de

Gruß
Tobias
 
Zuletzt bearbeitet:
Hallo!

Also ich würde das so machen:
Java:
/**
 * 
 */
package de.tutorials;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author Tom
 * 
 */
public class GlobalHotKeyExample {

    static {
        System.loadLibrary("globalHotKeySupport");
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        registerGlobalHotKeyListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                EventQueue.invokeLater(new Runnable() {
                    public void run() {
                        System.out.println("Global hotkey was pressed: " + e);
                        // hier die Swing UI Manipulieren...
                    }
                });
            }
        });
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
            public void run() {
                while (true) {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    private static native void registerGlobalHotKeyListener(
            ActionListener listener);
}

und meine globalHotKeySupport.dll schaut so aus:
C++:
// globalHotKeySupport.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
//

#include "stdafx.h"
#include <iostream>
#include "de_tutorials_GlobalHotKeyExample.h"

using namespace std;


jobject hotKeyListener;
JNIEnv *jniEnv;

/*
 * Class:     de_tutorials_GlobalHotKeyExample
 * Method:    registerGlobalHotKeyListener
 * Signature: (Ljava/awt/event/ActionListener;)V
 */
JNIEXPORT void JNICALL Java_de_tutorials_GlobalHotKeyExample_registerGlobalHotKeyListener
(JNIEnv *env, jclass clazz, jobject listener){
	cout << "test" << endl;
	hotKeyListener = listener;
	jniEnv = env;
	//Das hier in losfeuern, wenn der Hotkey betätigt wurde... -> in andere Funktion verschieben.
	/*
	jclass actionListenerClass = jniEnv->FindClass("java/awt/event/ActionListener");
	jmethodID actionPerformedMethodId = jniEnv->GetMethodID(actionListenerClass ,"actionPerformed","(Ljava/awt/event/ActionEvent;)V");
	jniEnv->CallObjectMethod(listener,actionPerformedMethodId,NULL); // hier entsprechendes java.awt.event.ActionEvent bauen und dies dann statt NULL übergeben...
	*/
}

  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved){
    cout << "JNI_OnLoad" << endl;
//hier Global Hot Key registrieren, beispielsweise über einen Systemweiten Hook
      return JNI_VERSION_1_4;
  }
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

Gruß Tom
 
Hallo zusammen,
ich suche auch schon eine Weile nach einer Lösung für dieses Problem, leider hab ich von C++ keine Ahnung und weiß nicht wie ich mir aus dem Code eine DLL bauen könnte?! :-/
Kann mir jemand vielleicht die DLL schicken, oder einen Link posten, wo ich sie runterladen kann?

Danke im Vorraus
Gruss
d3x
 
interessant wäre, ob gloable hotkeys auch in linux oder mac möglich sind
weiß das zufällig einer?
weil man findet nur ansätze für windows, aber linux oder mac nie
 
Ich habe jetzt mal versucht, den obigen Code mit Visual C++ 2005 Express Edition selber zu compilen, aber ic bekomme folgenden Fehler, irgendwas fehlt wohl noch. Aber ich weiß nicht was oder woher ich es nehmen sollte:
1>..\..\..\..\..\workspace\DLLTest\GlobalHotKeySupport.cpp(3) : fatal error C1083: Datei (Include) kann nicht geöffnet werden: "de_tutorials_GlobalHotKeyExample.h": No such file or directory

Kann mir da jemand weiterhelfen?

Gruss
d3x
 
Habe da gestern (Internet FH München) was von "Keymap" gelesen.
Dies betrifft aber glaube ich nur die zentrale Definiton für Tastaturkürzel in Menüs.
 
@d3x:
Was dir fehlt ist die Header-Datei von der C++ Datei. Die sollte man aber relativ einfach selber schreiben können, dadarin meines Wissens nur die Signaturen der Methoden stehen. Bin mir da aber nicht 100% sicher, da ich mit C++ bisher eher weniger gemacht hab.
mfg flo

Edit:
Ok, ganz so einfach scheints dann doch nicht zu sein. Hab grad gelesen, dass die Header-Datei mit dem Tool javah erstellt werden muss. In Zukunft informier ich mich lieber vorher, bevor ich irgendwelche Vermutungen anstelle :-)
 
Zuletzt bearbeitet:
=)

Mir gehts ähnlich, ich hab von C++ überhaupt keine Ahnung... Aber da wohl keiner mehr diese DLL hat, oder die header Datei werde ich wohl auf die globalen Shortcuts verzichten müssen.
Vielleicht kommt das ja irgendwann für JAVA ^^

Danke und Grüsse
d3x
 
Vielleicht kommt das ja irgendwann für JAVA ^^

hmm, da ein neues Java nur alle 18 Monate kommt und Java 6 erst kam, wirst du wohl noch ewig warten müssen, wenn man mal Dokus über globale Shortcuts für Linux und Mac finden würde, könnte man ja mal nen Jar bauen, was weitestgehend "platformunabhängig" läuft, aber auf den Platformen ist das scheinbar nicht möglich :-(
 
Zurück