![]() |
registerHotKey funktioniert nicht
Hi,
ich hab im moment ein Problem mit der Funktion "registerHotKey". Ich habe in meinem Programm ein paar Numpad Tasten als HotKeys registriert, die funktionieren komischweise auch überall, nur irgendwie nicht da wo sie sollten, denn das Programm ist eine Hilfe für ein Spiel. Durch druck auf eine HotKey soll eigentlich ein Timer gestartet werden, das klappt in jedem anderen Spiel nur nicht in dem wo es sollte (es handelt sich hierbei um League of Legends). Die HotKeys scheinen einfach nicht in meinem Programm anzukommen wenn das Spiel im Vordergrund ist, sobald ich aber wieder mein Programm in den Vordergrund rücke gehen die Tasten wieder. Wie gesagt in jedem anderen Spiel funktioniert es. Gibt es vielleicht eine andere Methode, hab z.B. von GetAsyncKeyState gehört? Hier ein paar Code Ausschnitte: FormCreate
Delphi-Quellcode:
Private Deklaration
procedure TForm1.FormCreate(Sender: TObject);
begin // HotKey Own Blue Buff id1 := GlobalAddAtom('Hotkey1'); RegisterHotKey(Handle, id1, 0, VK_NUMPAD7); // HotKey Own Red Buff id2 := GlobalAddAtom('Hotkey2'); RegisterHotKey(Handle, id2, 0, VK_NUMPAD8); // HotKey Enemy Blue Buff id3 := GlobalAddAtom('Hotkey3'); RegisterHotKey(Handle, id3, 0, VK_NUMPAD4); // HotKey Enemy Red Buff id4 := GlobalAddAtom('Hotkey4'); RegisterHotKey(Handle, id4, 0, VK_NUMPAD5); // HotKey Enemy Red Buff id5 := GlobalAddAtom('Hotkey5'); RegisterHotKey(Handle, id5, 0, VK_NUMPAD1); // HotKey Enemy Red Buff id6 := GlobalAddAtom('Hotkey6'); RegisterHotKey(Handle, id6, 0, VK_NUMPAD2); end;
Delphi-Quellcode:
HotKey Prozedur
private
{ Private declarations } id1, id2, id3, id4, id5, id6: Integer; procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
Delphi-Quellcode:
procedure TForm1.WMHotKey(var Msg: TWMHotKey);
begin if (Msg.HotKey = id1) then Button1.Click; if (Msg.HotKey = id2) then Button2.Click; if (Msg.HotKey = id3) then Button3.Click; if (Msg.HotKey = id4) then Button4.Click; if (Msg.HotKey = id5) then Button5.Click; if (Msg.HotKey = id6) then Button6.Click; end; |
AW: registerHotKey funktioniert nicht
Nicht umsonst lieft RegisterHotKey einen Rückgabewert zurück. ;)
|
AW: registerHotKey funktioniert nicht
Zitat:
|
AW: registerHotKey funktioniert nicht
Wieso? Weißt du nicht was ein Rückgabewert ist oder wo liegt das Problem?
Mehr zum Rückgabewert und ggf. zur Fehlerauswertung findest du jedenfalls in der Dokumentation zu RegisterHotkey: ![]() // EDIT: Funktioniert es denn bei anderen Programmen im Vordergrund? Dann liegt es vermutlich einfach daran, dass das Programm DirectInput verwendet. Da funktioniert das nicht so einfach, da braucht man vermutlich einen DirectX Hook (wie du ja selbst ![]() |
AW: registerHotKey funktioniert nicht
Also bei registerHotKey weiß ich soviel das wenn die Prozedur erfolgreich ist der Rückgabewert nicht 0 ist und wen sie nicht erfolgreich ist, ist sie 0. Aber in wieweit hilft mir das bei meinem Problem weiter? Sry ich steh gerade ein bisschen auf dem Schlauch versuche schon ziemlich lange das Problem zu lösen.
Zitat:
Edit: Ich hab bisher woanders immer nur Keyboard Hook gehört, wo ist der Unterschied zu DX Hook und gibts da möglicherweise Code Snippets oder Tuts? |
AW: registerHotKey funktioniert nicht
Dann funktioniert RegisterHotkey an sich. Dann wirst du damit aber in deinem Fall nicht weiterkommen.
Du könntest es mit einem normalen Keyboard Hook mit SetWindowsHookEx versuchen. Aber ich vermute das geht auch nicht. Dann bleibt nur noch der DirectX Hook. Wie das geht, steht hier: ![]() |
AW: registerHotKey funktioniert nicht
Das ist für jemanden der noch nicht alzu lang dabei ist leider nur schwer verständlich, gibts
noch eine einfachere Methode oder eventuell sogar jemanden der so einen Hook schon geschrieben hat bzw. eine Source? Edit: Zudem wird in deinem Link glaube ich mit C++ gearbeitet? |
AW: registerHotKey funktioniert nicht
Dass da mit C++ gearbeitet wird, ist üblich. ;-)
Die Aufrufe sind allerdings die selben wie dann auch in Delphi, da das Windows API verwendet wird. Dass es einfach ist, würde ich auch nicht behaupten. Auch für mich nicht. ;-) Leider habe ich auch nicht die Zeit es mir genauer anzuschauen. Ja, es haben sich hier im Forum schon andere damit beschäftigt, wie du sicher schon über die Suche gefunden hattest, oder? ![]() ![]() Quelltexte für Delphi habe ich in der Richtung allerdings nicht gefunden. |
AW: registerHotKey funktioniert nicht
Da ich noch relativ nah am Anfang bin ist es für mich fast unmöglich einen Code von C++ auf Delphi zu
übertragen, auch wenn es die selbe API ist. Ich wollte das ganze aber vielleicht auch erst noch einmal mit SetWindowsHookEx versuchen um zu schauen obs wirklich nicht klappt, allerdings komm ich da auch nicht ganz zum Ende. Ich hab auch einige Sachen diesbezüglich gefunden, auch z.B. ein komplettes Tutorial dazu, wo sich bei mir allerdings der Fehler auftut das mein Programm die DLL anscheind überhaupt nicht versucht zu laden trotz den Funktionen (welche statisch ist):
Delphi-Quellcode:
auch wenn die DLL nicht im Verzeichniss ist startet das Programm, was es ja eigentlich gar nicht dürfte.
function InstallHook(Hwnd: THandle): Boolean; stdcall;
external 'keyboardhook.dll'; function UninstallHook: Boolean; stdcall; external 'keyboardhook.dll'; Also falls jemand Erfahrung in die Richtung hat bitte melden :) MfG |
AW: registerHotKey funktioniert nicht
Sry für diesen Doppelpost aber durch editieren hätte das wascheinlich nie jemand bemerkt^^
Ich habe jetzt nach Tutorials von Assarbad einen Keyboard Hook gebaut, jetzt habe ich nurnoch ein Problem. Ich würde gerne aus der DLL aus meine Buttons auf der Form ansteuern wenn ein HotKey betätigt wird. Hier wie ich es versuche aber es nicht geht:
Delphi-Quellcode:
library KeyboardHook;
uses Windows, Dialogs, Main, Messages; var HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0; function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: Exit; FALSE: if (wParam = VK_NUMPAD7) then Main.Form1.Button1.Click; end; end; |
AW: registerHotKey funktioniert nicht
Deine DLL kommt so nicht an das Formular heran. Was du da versuchst anzusprechen ist ein zweites Formular, das in der DLL existieren würde. Da das aber nie erzeugt wurde, geht das ganz schief.
Die DLL hat einen ganz anderen Speichermanager usw., deshalb kommst du an die Objekte deiones hauptprogramms nicht heran. Du kannst nur Callbackfunktionen definieren und der DLL übergeben, die du dann dort aufrufen kannst oder Messages an das Fenster schicken, wenn du das Handle dafür an die DLL übergibst. Du brauchst für einen Keyboard-Hook aber gar keine DLL, das ist ein Mythos... das kannst du auch direkt in deinem Programm implementieren. Der Vorteil der DLL-Lösung ist nur, dass dann nur diese als Virus bzw. verdächtiges Programm erkannt wird und nicht das ganze Programm. |
AW: registerHotKey funktioniert nicht
Zitat:
Und d.h. ich kann einfach den Code meiner DLL in meine eigentliche Form übertragen? |
AW: registerHotKey funktioniert nicht
Nicht alle systemweiten Hooks müssen in einer DLL implementiert sein.
|
AW: registerHotKey funktioniert nicht
Zitat:
Und wenn ich den DLL Source Code jetzt in meine Main Unit einfüge, also praktisch direkt ins Programm wo auch die Buttons sind, funktioniert es nicht (natürlich^^). Was genau muss ich denn jetzt noch für Anpassungen vornehmen, weil so langsam verliere ich den Überblick bei den ganzen neuen Sachen. Source: Steht nicht alles drin, nur das wichtigste halt!
Delphi-Quellcode:
unit Main;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, sSkinManager, ExtCtrls, mmSystem; type TForm1 = class(TForm) ... <- Hier die ganzen Objekte procedure Button1Click(Sender: TObject); procedure TimerBlueOwnTimer(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button6Click(Sender: TObject); procedure TimerRedOwnTimer(Sender: TObject); procedure TimerBlueEnemyTimer(Sender: TObject); procedure TimerRedEnemyTimer(Sender: TObject); procedure TimerDragonTimer(Sender: TObject); procedure TimerBaronTimer(Sender: TObject); procedure Button8Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; HookHandle: Cardinal = 0; WindowHandle: Cardinal = 0; implementation uses Unit2; // Nur ein Info Fenster {$R *.dfm} function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: if (wParam = VK_NUMPAD7) then ShowMessage('TEST'); end; end; function InstallHook(Hwnd: Cardinal): Boolean; stdcall; begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc, HInstance, 0); WindowHandle := Hwnd; Result := TRUE; end; end; function UninstallHook: Boolean; stdcall; begin Result := UnhookWindowsHookEx(HookHandle); HookHandle := 0; end; procedure TForm1.FormCreate(Sender: TObject); begin InstallHook(Handle); end; procedure TForm1.FormDestroy(Sender: TObject); begin UninstallHook; end; |
AW: registerHotKey funktioniert nicht
In dem man in der Hilfe nachguck:
![]() |
AW: registerHotKey funktioniert nicht
Also das installieren des Hooks scheint auf jedenfall zu funktionieren, das hab ich ganz einfach so überprüft:
Delphi-Quellcode:
Und er zeigt mir die Message auch an, also muss der Fehler doch praktisch, das mein HotKey nicht funktioniert, in diesem Teil
procedure TForm1.FormCreate(Sender: TObject);
begin InstallHook(Handle); if (InstallHook(Handle) = True) then ShowMessage('Hook ist drin!'); end;
Delphi-Quellcode:
liegen oder?
function KeyboardHookProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of TRUE: exit; FALSE: if (wParam = VK_NUMPAD7) then ShowMessage('TEST'); end; end; |
AW: registerHotKey funktioniert nicht
Was ist denn das
Delphi-Quellcode:
für ein Unsinn? Warum rufst du InstallHook zwei mal auf? Außerdem ist das etwas sinnfrei eine Meldung auszugeben, wenn es funktioniert hat. Sinnvoller wäre es, eine Meldung auszugeben, wenn es zu einem Fehler gekommen ist und die Fehlermeldung auszugeben, damit man weiß, warum es zu einem Fehler gekommen ist.
InstallHook(Handle);
if (InstallHook(Handle) = True) then ShowMessage('Hook ist drin!');
Delphi-Quellcode:
if not InstallHook(Handle) then
ShowMessage(SysErrorMessage(GetLastError)); |
AW: registerHotKey funktioniert nicht
Mit deiner Variante wird aber kein Fehler angezeigt, also muss es ja eigentlich an der KeyboardHookProc Funktion liegen.
|
AW: registerHotKey funktioniert nicht
Zitat:
Das Problem ist hier ganz einfach: Du benutzt WH_KEYBOARD statt WH_KEYBOARD_LL. Damit würdest du die Daten, die per WM_KEYDOWN und WM_KEYUP weitergegeben werden sollen abfangen. Da das aber im Fenstermanager passiert, brauchst du dafür in der Tat eine DLL. Du willst aber die direkten Tastatureingaben. Und dafür brauchst du einen LowLevel-Hook. Der braucht auch keine DLL. Du musst also nur WH_KEYBOARD durch WH_KEYBOARD_LL ersetzen. |
AW: registerHotKey funktioniert nicht
Zitat:
Zum anderen versteht mich nicht falsch, wenn ich
Delphi-Quellcode:
verwende bekomme ich eine Meldung, allerdings nur "Der Vorgang wurde erfolgreich beendet", halt als ShowMessage und dann startet mein Programm.
if not InstallHook(Handle) then
ShowMessage(SysErrorMessage(GetLastError)); |
AW: registerHotKey funktioniert nicht
Naja, wenn du einen Haltepunkt auf die erste Zeile der Hookprozedur setzt, wirst du dort vermutlich ankommen. Dass es nicht klappen kann, ist klar, denn wenn du einmal in die Dokumentation geschaut hättest, hättest du gesehen, dass die LowLevel-KeyboardProc anders aussieht:
![]() Aber wie gesagt: Du setzt in InstallHook Result immer auf True, egal ob das Setzen des Hooks erfolgreich war oder nicht. |
AW: registerHotKey funktioniert nicht
Das scheint einfach nicht mein Gebiet zu sein, also ich hab den LowLevelKeyboardProc und den KeyboardProc mal verglichen und bis auf wParam und lParam scheinen beide Funktionen gleich zu sein, es sei denn ich übersehe was, oh man, Hilfe ich komm nicht mehr klar xD
Delphi-Quellcode:
Der Code müsste jetzt so richtig sein?
function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, HInstance, 0); WindowHandle := Hwnd; end; end; |
AW: registerHotKey funktioniert nicht
Also wenn die Funktion immer False zurückgeben soll...
|
AW: registerHotKey funktioniert nicht
Zitat:
Aber trotzdem weiß ich einfach nicht wie ich jetzt mit dem LowLevelKeyboardProc weitermachen soll. Ich hab mir eigentlich fast alles relevantes zu SetWindowsHooxEx und LowLevelHook durchgelesen was ich in der MSDN gefunden habe, aber ich werde einfach nicht draus schlau wo bei mir der Fehler ist. |
AW: registerHotKey funktioniert nicht
Jetzt gibt sie gar nichts zurück. Liest du eigentlich die Compiler Warnungen?
|
AW: registerHotKey funktioniert nicht
wenn du schon Boolean; stdcall;
also rückgabe definierst dann prüfe auch darauf.. Result := "sollte dann einen wert True/False liefern. gruss |
AW: registerHotKey funktioniert nicht
Zitat:
Auf diese Weise konnte ich zumindest schonmal einen kleinen anderen Fehler ausmerzen. Ich bin leider im moment total überfordert und hab glaube ich keine Ahnung was ich gerade machen soll, ob nun Result := True/False da hin muss oder doch was anderes was ich wie immer mal wieder übersehe. |
AW: registerHotKey funktioniert nicht
InstallHook liefert einen Boolean zurück so wie es deklariert ist.
also dann prüfe doch einfach auf das Ergebnis von HookHandle Result := HookHandle <> 0; anstelle von WindowHandle := Hwnd; Ist der wert mehr dann liefert diese Funktion ein true zurück andernfalls ein False. So kannst du prüfen ob die Installation erfolgreich war. gruss |
AW: registerHotKey funktioniert nicht
Delphi-Quellcode:
function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin Result := False; if HookHandle = 0 then begin HookHandle := SetWindowsHookEx(WH_KEYBOARD_LL, @LowLevelKeyboardProc, HInstance, 0); WindowHandle := Hwnd; Result := HookHandle <> 0; end; end; |
AW: registerHotKey funktioniert nicht
Jetzt habt ihr beide Unterschiedliche Codes gepostet, sind jetzt beide richtig?^^
Und trotzdem hat das ja noch nicht mein Problem gelöst das mein Hotkey immernoch nicht funktioniert, leider. |
AW: registerHotKey funktioniert nicht
Wie sieht denn deine Hook Prozedur mittlerweile aus?
|
AW: registerHotKey funktioniert nicht
Zitat:
Delphi-Quellcode:
function LowLevelKeyboardProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin //es ist ebenfalls moeglich die Bearbeitung an eine Bedingung zu knuepfen //it's possible to call CallNextHookEx conditional only. Result := CallNextHookEx(HookHandle, nCode, wParam, lParam); case nCode < 0 of True: exit; False: if (wParam = VK_NUMPAD7) then Form1.Button1.Click; end; end; |
AW: registerHotKey funktioniert nicht
Ist der Code jetzt in einer DLL?
|
AW: registerHotKey funktioniert nicht
Nein direkt in der Unit
|
AW: registerHotKey funktioniert nicht
Das ist klar, dass der Quellcode in einer Unit liegt. Aber wird das zu einer DLL kompiliert?
|
AW: registerHotKey funktioniert nicht
Ich meine in der Main Unit, also das was zum Programm kompiliert wird^^
|
AW: registerHotKey funktioniert nicht
Zitat:
Ich sehe exakt den gleichen Quelltext (Zeile) Result := HookHandle <> 0; gruss |
AW: registerHotKey funktioniert nicht
Wo der Code steht ist im Grunde egal, denn da der Code immer noch rein gar nichts mit der LowLevel-Hookprozedur zu tun hat, zu deren Definition ich den Link gepostet habe, kann es so oder so nicht gehen. :roll:
![]() Dass die Werte genauso heißen, ist vollkommen egal, das Interessante ist deren Inhalt... |
AW: registerHotKey funktioniert nicht
Muss ich nicht eine MessageLoop haben damit der LowLevel Hook funktioniert?
|
AW: registerHotKey funktioniert nicht
Kann oder will mir jetzt niemand mehr helfen?
Ich hab mir einfach alles was es zu Hooks gibts in der MSDN durchgelesen aber ich blick da einfach nicht durch. Sry für den Doppelpost. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz