Entwickler-Ecke

Windows API - Globaler Keyboard-Hook: Fehler bei dynamischer DLL-Einbind.


Markus123 - Mo 14.03.11 11:42
Titel: Globaler Keyboard-Hook: Fehler bei dynamischer DLL-Einbind.
Hallo zusammen,

ich bin seit letzter Woche der Verzweiflung nahe. Ich brauche einen globalen Keyboard-Hook, der Windows-Funktionstasten unterdrückt. Nach ein wenig Suche habe ich unter http://www.swissdelphicenter.ch/de/showcode.php?id=1212 ein Beispiel gefunden, welches in dieser Form auch wunderbar funktioniert.

Verwende ich die DLL-Einbindung statisch wie folgt (aus Übersichtsgründen im Beispiel keine Fehlerprüfung, usw.), funktioniert das auch wunderbar:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
interface
function SetHook(WinHandle: HWND; MsgToSend: Integer): Boolean; stdcallexternal 'GlobalKeyHook.dll';
function FreeHook: Boolean; stdcallexternal 'GlobalKeyHook.dll';
(...)
implementation
procedure Form.StarteHook;
begin
  SetHook(Handle, WM_USER + 300);
end;


Jetzt das Problem: Nachdem ich die Funktionalität nicht immer brauche, würde ich hier gerne dynamisch arbeiten:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
interface 
type
  FunctionSetHook = function(WinHandle: HWND; MsgToSend: Integer): Boolean;
var
  funcSetHook: FunctionSetHook;
(...)
implementation
procedure Form.StarteHook;
var
  b: boolean;
  hKeyboardHook: THandle;
begin
  if FileExists('GlobalKeyHook.dll'then
  begin
    hKeyboardHook:= LoadLibrary('GlobalKeyHook.dll');
    if hKeyboardHook > 0 then
    begin
      @funcSetHook:= GetProcAddress(hKeyboardHook, 'SetHook');
      b:= false;
      if Assigned(funcSetHook) then
        b:= funcSetHook(Handle, WM_USER + 300);
      if not b then
      begin
        ShowMessage(GetErrorString(GetLastError));
        FreeLibrary(hKeyboardHook);
        hKeyboardHook:= 0;
      end;      
    end;
  end;
end;


Nun wird die DLL geladen, SetHook aufgerufen und auch das Ergebnis des Aufrufes ist true. Nach Verlassen der Prozedur steht nun aber nur noch Müll im Speicher und mein Programm geht dann verständlicherweise vor die Hunde.

Hat jemand spontan eine Idee an was das liegen könnte? Ich habe absolut keine Ahnung wo das Problem sein soll...

Vielen Dank für Eure Hilfe
Markus

P.S: Ich habe Delphi 2007 R2 unter WindowsXP im Einsatz...


elundril - Mo 14.03.11 11:52

Ich kenn mich in dem Thema offen und ehrlich gesagt nicht aus aber probier mal den THandle auf den Hook als private-Variable von Form zu deklarieren und nicht als lokale Variable in einer Methode von Form.

lg elundril


Markus123 - Mo 14.03.11 12:03

Hallo elundril,

user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
Ich kenn mich in dem Thema offen und ehrlich gesagt nicht aus aber probier mal den THandle auf den Hook als private-Variable von Form zu deklarieren und nicht als lokale Variable in einer Methode von Form.

hat leider nicht geholfen, danke aber trotzdem...

Grüße
Markus


jaenicke - Mo 14.03.11 12:09

Du hast das stdcall vergessen.
user profile iconMarkus123 hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
interface 
type
  FunctionSetHook = function(WinHandle: HWND; MsgToSend: Integer): Boolean;


Nebenbei: Für Tastatur- und Maus-Hooks brauchst du keine externe DLL. Diese beiden Hooktypen funktionieren auch direkt.


Markus123 - Mo 14.03.11 12:38

Hallo Jaenicke,

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Du hast das stdcall vergessen

Aahhh! Da hätte ich auch selbst darauf kommen können! Eine neue Brille hätte so ihre Vorteile :lupe:

Zitat:
Nebenbei: Für Tastatur- und Maus-Hooks brauchst du keine externe DLL. Diese beiden Hooktypen funktionieren auch direkt.

Hmmm... So wie ich das verstanden habe, ist für globale Hooks eine eigene DLL notwendig. Ansonsten würde z.B. bei der Windowstaste das Betriebssystem trotzdem darauf reagieren.

Vielen Dank für die Hilfe! :wave:

Grüße
Markus


jaenicke - Mo 14.03.11 13:31

user profile iconMarkus123 hat folgendes geschrieben Zum zitierten Posting springen:
Hmmm... So wie ich das verstanden habe, ist für globale Hooks eine eigene DLL notwendig. Ansonsten würde z.B. bei der Windowstaste das Betriebssystem trotzdem darauf reagieren.
Das steht überall, ist aber falsch. Das gilt nur für andere Hooktypen. ;-)
Wobei ich die Windowstaste nicht ausprobiert habe, aber generell ein globaler Tastaturhook funktioniert.