Tasten nach Hook nicht weiterreichen
-
Ich habe nun nach etlichem hin und her bei google und auch hier im Forum,
die Hoffnung aufgegeben die Antwort auf diese Frage selbst zu finden.Meine Situation:
-einfaches Konsolen Programm
-installiert ein GlobalHook
-gibt gedrückte tasten im Konsolenfenster aus
--[Hardware: Logitech G15 Bluelight]Frage:
Wie verhindere ich, dass die Taste weitergereicht wird?
Antwort:
Rückgabewert der LowLevelKeyboardProc() größer als null setzen;[Erste Frage hat sich schon Erledigt]
Wie komme ich an die Sondertasten (Der G15 z.B Makro Record oder Display Menütasten)?Mein ziel ist es, quasi einen eigenen Profiler zu schreiben und auch eine App, welche es mir erlaubt ingame zu chatten bzw auf meinem 2 Monitor zu arbeiten.
#include <windows.h> #include <iostream> using namespace std; void UpdateKeyState(BYTE *keystate, int keycode) { keystate[keycode] = GetKeyState(keycode); } LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; //BYTE keyboard_state[256]; if (nCode == HC_ACTION) { switch (wParam) { case WM_KEYDOWN: { cout << (char)p->vkCode << " Pressed, scancode: " << (p->scanCode) << endl; } case WM_SYSKEYDOWN: { //Show on the console that the key was pressed... cout << (char)p->vkCode << " Pressed, scancode: " << (p->scanCode) << endl; nCode = 0; break; } case WM_KEYUP: case WM_SYSKEYUP: { cout << (char)p->vkCode << " Released, scancode: " << (p->scanCode) << endl; } } } //Call the next hook if the key isn't going to be dropped... //return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam)); //return NULL; return CallNextHookEx ( NULL, nCode, wParam, lParam ); } LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx ( NULL, nCode, wParam, lParam ); } int main ( void ) { // Install the low-level keyboard & mouse hooks HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0); HHOOK hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, NULL, 0); // Keep this app running until we're told to stop MessageBox(NULL, TEXT("Click \"Ok\" to terminate this application."), TEXT("Disable Low-Level Keys"), MB_OK); UnhookWindowsHookEx(hhkLowLevelKybd); return(0); }
Ich danke schonmal für hilfreiche Antworten und bitte zu bedenken, dass ich noch nicht wirklich tief mit der Materie vertraut bin und somit Fachterminus mir quasi fremd ist.
-
So wie ich das verstehe, hookst du dich zwischen Tastatur und System ein UND du Peeks die Messages sozusagen nur. Da du jetzt aber nicht an das Handle deines Fensters kommst, an welches die Message gerichtet ist, kannst du auch kein GetMessage aufrufen, falls das überhaupt Sinn machen würde (war nur ein Gedanke von mir). Für das was du machen willst, musst du dich zwischen System und Window einhooken und die Message abfangen.
EDIT:
Hab hier noch was gutes gefunden:
http://madcoderspeak.blogspot.de/2009/06/how-to-create-global-system-windows.html
-
Leider verstehe ich deine Aussage nicht so ganz, also ich habe es schon hinbekommen die Tastenanschläge quasi in meinem Programm zu fangen, jedoch passiert beim drücken der G-Tasten und der M-Tasten nichts.
Um zu schauen ob per Message irgendwas rein kommt habe ich nochmal folgendes hinzu gefügt:
LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { cout << ((MSG*)lParam)->message; return CallNextHookEx ( NULL, nCode, wParam, lParam ); }
Ganzer Code:
#include <windows.h> #include <iostream> using namespace std; void UpdateKeyState(BYTE *keystate, int keycode) { keystate[keycode] = GetKeyState(keycode); } LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT) lParam; if (nCode == HC_ACTION) { switch (wParam) { case WM_KEYDOWN: {} case WM_SYSKEYDOWN: { //Show on the console that the key was pressed... cout << (char)p->vkCode << " Pressed, scancode: " << (p->scanCode) << endl; } case WM_KEYUP: {} case WM_SYSKEYUP: { cout << (char)p->vkCode << " Released, scancode: " << (p->scanCode) << endl; } } } //Gib einen Wert größer 0 zurück, wenn die Tasten nicht weiter durchgereicht werden sollen return CallNextHookEx(NULL, nCode, wParam, lParam); //return 1; } LRESULT CALLBACK LowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam) { cout << ((MSG*)lParam)->message; return CallNextHookEx ( NULL, nCode, wParam, lParam ); } LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { return CallNextHookEx ( NULL, nCode, wParam, lParam ); } int main ( void ) { // Install the low-level keyboard & mouse & massage hooks // Der NULL Parameter ist dafür da, dass keine Externe DLL benötigt wird // Der Letzte Parameter verweist auf die Thread ID, in diesm Fall Global, also alle Threads // Tastatur HHOOK hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, 0); // Maus HHOOK hhkLowLevelMouse = SetWindowsHookEx(WH_MOUSE_LL, LowLevelMouseProc, NULL, 0); // Nachrichten HHOOK hhkLowLevelMsg = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc,NULL,0); // Keep this app running until we're told to stop MessageBox(NULL, TEXT("Click \"Ok\" to terminate this application."), TEXT("Disable Low-Level Keys"), MB_OK); UnhookWindowsHookEx(hhkLowLevelKybd); return(0); }
-
Windoof sendet Messages an die Fenster und dieses Fenster handeln diese dann. Was du machen willst, ist eine dieser Messages abfangen. Dazu musst du dich zwischen System und Fenster einhooken, du hookst dich aber zwischen Tastatur und System ein und schaust, welche Daten von deiner Tastatur an das System gehen oder so ähnlich. Ich hab das ganze jetzt so hinbekommen (fängt allerdings alle Tastatureingaben ab):
// SetWindowsHookDll.dll #include <Windows.h> #define DLLEXPORT extern "C" __declspec(dllexport) extern "C" { #pragma data_seg (".MY_HOOK_DATA") _declspec(dllexport) HHOOK g_hookHandle = 0; #pragma data_seg() } DLLEXPORT LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= 0) { MSG* msg = (MSG*)lParam; switch (msg->message) { case WM_KEYDOWN: GetMessage(msg, msg->hwnd, NULL, NULL); break; } } return CallNextHookEx(g_hookHandle, nCode, wParam, lParam); }
// SetWindowsHook.exe #include <Windows.h> int main () { HINSTANCE hCurrentDll = LoadLibraryA("SetWindowsHookDll.dll"); FARPROC proc = GetProcAddress((HMODULE)hCurrentDll, "_GetMsgProc@12"); HHOOK* g_hookHandle = ((HHOOK*)GetProcAddress((HMODULE)hCurrentDll, "g_hookHandle")); *g_hookHandle = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)proc, hCurrentDll, NULL); MessageBox(NULL, TEXT("Click \"Ok\" to terminate this application."), TEXT("Disable Low-Level Keys"), MB_OK); UnhookWindowsHookEx(*g_hookHandle); return(0); }
Die DLL ist nötig, da die Funktion in die Prozesse injected wird oder so, wenn du jedenfalls versuchst, eine Funktion bei SetWindowsHookEx, welche nicht in einem anderen Modul liegt, als das Modul, aus welcher du die SetWindowsHookEx Funktion aufrufst, zu übergeben, bekommst du bei SetWindowsHookEx nen Error. Aber das kannst du eigentlich am besten auf der Seite von meinem Link lesen.
-
Aber ich möchte ja genau das wissen was mir die Tastatur sendet, denn eine Logitech G15 ist ja eine Tastatur, welche noch extra Funktionen bietet und um halt zu verhindern, dass meine Tastatur das Eigentliche Spiel unterbricht möchte ich quasi ein Global hook der Tastatureingaben einhaken um diese auf Befehl zu fangen bzw wieder freigeben zu können. Ich würde halt nur gerne wissen wie ich an den gesendeten Code der Tastatur für die Sondertasten ran komme.
Oder verstehe ich da wieder was falsch?
-
Jedes Window hat bei Windows eine Message-Queue, dort werden einfach alle Messages, welche an dieses Window gehen sollen drauf gelegt (auch alle KeyBoard- oder Mouse-Messages). Jetzt kannst du einen Hook vor dem dein Window die Message erhält platzieren. Dort kannst du jetzt die unerwünschten Messages welche nicht weitergeleitet werden sollen, von der Message-Queue mittels GetMessage runternehmen.
Die DLL könnte dann so aussehen:
#include <Windows.h> #define DLLEXPORT extern "C" __declspec(dllexport) extern "C" { #pragma data_seg (".MY_HOOK_DATA") _declspec(dllexport) HHOOK g_hookHandle = 0; #pragma data_seg() } DLLEXPORT LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode >= 0) { MSG* msg = (MSG*)lParam; switch (msg->message) { case WM_KEYDOWN: HWND hwnd = FindWindowA(NULL, "WindowName"); if (hwnd != msg->hwnd) { break; } int codeFuerIrgendeineTaste = 0x20; if (msg->wParam == codeFuerIrgendeineTaste) { GetMessage(msg, msg->hwnd, NULL, NULL); } break; } } return CallNextHookEx(g_hookHandle, nCode, wParam, lParam); }
Allerdings weiß ich nicht, wie das mit den Sondertasten funktioniert. Da suchst du vermutlich auch falsch, möchte nämlich behaupten, dass dies treiberspezifisch ist. Du könntest ja mal das hier ausprobieren:
for (int i = 0; i <= 0xFF i++) if (GetAsyncKeyState(i) < 0) std::cout << i << std::endl;
-
Sondertasten von Tastaturen (auch bei Laptops) werden oft mit einem eigenen Treiber Interface des Herstellers behandelt.
Die sieht Dein Hook gar nicht.
-
Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Liegen die Messages dann nicht auch auf der Queue? Schreib dir doch mal ein kleines Programmchen, welches einfach nur ein Window öffnet. Im Callback deines Windows lässt du dann all deine Messages ausgeben. Dann fängst du an rum zu probieren und lässt einzelne Messages einfach nicht mehr durch, oder anderst rum (du lässt zuerst nur eine Message durch), drückst deine G-Tasten und schaust ob irgendwas ankommt. Bin mir ziemlich sicher dass es so klappt, dein Treiber muss ja auch irgendwie mit den Anwendungen kommunizieren.