AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Global Keyboard Hook

Ein Thema von G-Baumstamm · begonnen am 9. Jun 2012 · letzter Beitrag vom 10. Jun 2012
Antwort Antwort
G-Baumstamm

Registriert seit: 9. Jan 2010
63 Beiträge
 
Delphi 7 Enterprise
 
#1

Global Keyboard Hook

  Alt 9. Jun 2012, 13:30
Heyho,

mein Programm muss in der Lage sein, Tastendrucke egal in welchem Programm abzufangen & entsprechend darauf zu reagieren.

Dazu benutze ich folgende Prozeduren (habe ich vor ner Weile mal irgendwo gefunden, weiß die Quelle leider gerade nicht mehr, scheint aber was relativ häufig verwendetes zu sein):

Delphi-Quellcode:
procedure TMainForm.FormCreate(Sender: TObject);
begin
  // ...
  InstallHook(Handle);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  // ...
  UninstallHook;
end;

function InstallHook(Hwnd: Cardinal): Boolean; stdcall;
begin
  Result := False;
  if HookHandle = 0 then
  begin
    HookHandle := SetWindowsHookEx(13, LowLevelKeyboardProc, 0, 0);
    WindowHandle := Hwnd;
    Result := HookHandle <> 0;
  end;
end;

function UninstallHook: Boolean; stdcall;
begin
  Result := UnhookWindowsHookEx(HookHandle);
  HookHandle := 0;
end;

function LowLevelKeyboardProc(nCode: Integer; wParam: wParam;
    lParam: lParam): LRESULT; stdcall;
  var vkCode: Cardinal;
begin
  if (nCode >= 0) and (wParam = WM_KEYDOWN) then
  begin
    vkCode := PKbdDLLHookStruct(lParam)^.vkCode;
    // meine Anweisungen
  end;
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;
Das ganze funktioniert am Anfang soweit auch. Allerdings habe ich das Problem, dass es das irgendwann einfach nicht mehr tut. Keine Ahnung womit das zusammenhängt. Ich hab das Gefühl, das es eher auftritt wenn das Programm schon ne ganze Weile läuft, es könnte aber genauso gut irgendwas anderes der Auslöser sein.

Also, kann sich irgendwer von euch ein Szenario vorstellen, in dem diese ganze Konstruktion, obwohl sie vorher einwandfrei funktioniert hat, einfach nichts mehr macht (LowLevelKeyboardProc wird nicht mehr aufgerufen) ? Am versehentlichen Aufrufen des Uninstalls kanns nicht liegen, das steht wirklich nur im OnDestroy. Wenn ich, nachdem es nicht mehr geht, allerdings einfach Uninstall und Install hintereinander aufrufe gehts übrigens wieder.

Seltsam ...
Daniel NR
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: Global Keyboard Hook

  Alt 10. Jun 2012, 06:04
Tritt das Problem auch auf, wenn du deine eigenen Anweisungen auskommentierst, also nur den hier geposteten Code verwendest?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
G-Baumstamm

Registriert seit: 9. Jan 2010
63 Beiträge
 
Delphi 7 Enterprise
 
#3

AW: Global Keyboard Hook

  Alt 10. Jun 2012, 11:32
Hey,

kann ich nicht testen, da dann mein Programm überhaupt nicht mehr funktionieren würde. Allerdings kann der Code, der noch im Create & Destroy ist, dafür nicht verantwortlich sein, da es anfangs ja funktioniert.

An meinem Code in der LowLevelKeyboardProc kann es auch nicht liegen, ich habe überprüft, dass sie ab einem Zeitpunkt garnicht mehr aufgerufen wird. Ansonsten ist alles was ich da mache sowieso nur, auf eine bestimmte Taste zu prüfen und ggf. nen Timer zu starten.

//Edit: konkret sieht das so aus:

Delphi-Quellcode:
function LowLevelKeyboardProc(nCode: Integer; wParam: wParam;
    lParam: lParam): LRESULT; stdcall;
  var vkCode: Cardinal;
begin
  if (nCode >= 0) and (wParam = WM_KEYDOWN) then
  begin
    vkCode := PKbdDLLHookStruct(lParam)^.vkCode;
    if (vkCode = Hotkey) and not working then //Hotkey = vorher defnierte Taste
    begin
      BitmapCount := Project.GetFilesCount(SearchDir, '*.bmp');
      MainForm.StartTimer.Enabled := true;
    end;
  end;
  Result := CallNextHookEx(HookHandle, nCode, wParam, lParam);
end;

function TProject.GetFilesCount(Folder, WildCard: string): Integer;
var
  intFound: Integer;
  SearchRec: TSearchRec;
begin
  Result := 0;
  if (Folder <> '') and (Folder[Length(Folder)] <> '\') then
    Folder := Folder + '\';
  intFound := FindFirst(Folder + WildCard, faAnyFile, SearchRec);
  while (intFound = 0) do
  begin
    if not (SearchRec.Attr and faDirectory = faDirectory) then
      Inc(Result);
    intFound := FindNext(SearchRec);
  end;
  FindClose(SearchRec);
end;

procedure TMainForm.StartTimerTimer(Sender: TObject);
  var CurrBitmapCount: integer;
begin
  inc(TimerCount);
  CurrBitmapCount := Project.GetFilesCount(SearchDir, '*.bmp');
  if CurrBitmapCount > BitmapCount then
  begin
    Sleep(200);
    Project.StartWorking(false);
    TimerCount := 0;
    StartTimer.Enabled := false;
  end;
  if TimerCount >= 40 then
  begin
    TimerCount := 0;
    StartTimer.Enabled := false;
  end;
end;
Es soll also überprüft werden, ob ein Screenshot erstellt wurde, indem im entsprechenden Verzeichnis geschaut wird, ob eine neue .bmp dazugekommen ist. Keine Ahnung ob man das eleganter machen könnte, aber so funnktionierts zumindest ...
Daniel NR

Geändert von G-Baumstamm (10. Jun 2012 um 11:38 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von ConnorMcLeod
ConnorMcLeod

Registriert seit: 13. Okt 2010
Ort: Bayern
440 Beiträge
 
Delphi 10.3 Rio
 
#4

AW: Global Keyboard Hook

  Alt 10. Jun 2012, 12:05
*) zum Thema globaler Keyboardhook gibt es erschöpfend zu lesen, auch hier im Forum - Stichwort DLL.
*) wenn es einzig darum geht, ein Verzeichnis auf Änderungen zu überwachen, empfehle ich TRxFolderMonitor aus den RX-Tools.
Nr.1 Delphi-Tool: [F7]
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Global Keyboard Hook

  Alt 10. Jun 2012, 12:28
Bei der Verwendung von Hooks ist man gut beraten wenn man diesen Hook nur minimal bremst.
Die Suche nach Dateien direkt innerhalb des Hooks aufzurufen ist eher kontraproduktiv und sollte daher in einem Thread ausgelagert werden.

EDIT: Hier ein interessanter Artikel zu Hooks und Windows 7 bzgl. TimeOuts, also wenn es dem System zu lange dauert, bis die Nachricht verarbeitet wurde. Das sollte dann auch erklären, warum es zunächst funktioniert
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (10. Jun 2012 um 12:34 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf