Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Diese Sache mit den globalen Hooks... (https://www.delphipraxis.net/54265-diese-sache-mit-den-globalen-hooks.html)

CalganX 30. Sep 2005 22:12


Diese Sache mit den globalen Hooks...
 
Hi,
ich wollte jetzt in eines meiner Programme einen systemweiten Hotkey einbinden. Folglich also einen globalen Hook. Soweit so gut. ;)

Ich habe mir das Tutorial von Olli mal angesehen (leider ist natürlich genau jetzt der Server down -.-), aber irgendwie ist mir da noch was nicht ganz schleierhaft... ;)
Zum Beispiel habe ich in der Doku nirgendwo einen Hinweis darauf gefunden, wie welche Tasten als Hook registriert werden.

Kann vielleicht jemand kurz und pregnant umreißen wie das mit den Hooks funktioniert? Ich würde gerne so wenig Aufwand wie möglich darein investieren, da mein Programm nicht nur aus Hooks besteht. *g*

Danke für jede Hilfe,
Chris

Flocke 30. Sep 2005 22:34

Re: Diese Sache mit den globalen Hooks...
 
Zitat:

Zitat von Chakotay1308
Hi,
ich wollte jetzt in eines meiner Programme einen systemweiten Hotkey einbinden. Folglich also einen globalen Hook.

Hotkeys und Hooks haben so erst einmal nichts miteinander zu tun. Einen Hotkey kannst du z.B. für eine Verknüpfung im Startmenü anlegen, indem du unter Eigenschaften dafür eine Tastenkombination hinterlegst.

CalganX 30. Sep 2005 22:39

Re: Diese Sache mit den globalen Hooks...
 
Hi Volker,
huch... wusste nichtmal, dass es sowas gibt. :zwinker:

Aber was ich meine sind defintiv Hooks. Habs ja nochmal erklärt: Tastenkombination im Laufenden Programm soll einfach mein Programm benachrichtigen. :arrow: Hook. ;)

Chris

Olli 1. Okt 2005 09:52

Re: Diese Sache mit den globalen Hooks...
 
Moin Chris,

Zitat:

Zitat von Chakotay1308
Aber was ich meine sind defintiv Hooks. Habs ja nochmal erklärt: Tastenkombination im Laufenden Programm soll einfach mein Programm benachrichtigen. :arrow: Hook. ;)

Du willst also nur eine bestimmte Kombo abfangen? In diesem Falle solltest du entsprechend ein case-Statement einfügen und dort auf die von dir gewünschten virtuellen Tastencodes testen, denke ich. Oder habe ich da wieder was mißverstanden. Zeige mal, welchen Code du bisher hast.

Jaja, das Tut schreit förmlich nach einer Aktualisierung

tommie-lie 1. Okt 2005 10:40

Re: Diese Sache mit den globalen Hooks...
 
Ist mir bei der Problembeschreibung irgendwas entgangen, oder wird MSDN-Library durchsuchenRegisterHotKey nicht mehr gern gesehen?

Edit: Register heeßt des Teil :stupid:

SirThornberry 1. Okt 2005 10:43

Re: Diese Sache mit den globalen Hooks...
 
dafür muss man doch nicht gleich einen Hook nehmen, schließlich gibt es dafür "RegisterHotKey"
[Edit]Na toll, da war der rote Kasten mal nicht da[/Edit]

CalganX 1. Okt 2005 12:08

Re: Diese Sache mit den globalen Hooks...
 
Hi,
@Olli: An Code für einen Hook habe ich bisher noch gar nichts. :?

@tommie und Thornberry: ja, das klingt gut, danke! :thumb: Aber irgendwie funktioniert das noch nicht so ganz...
Habe mir auf die Schnelle das schnell in eine Klasse gepackt:
Delphi-Quellcode:
unit uGlobalHotKey;

interface

uses
  Windows, Classes, Forms, Menus, Messages;

type
  TGlobalHotKey = class(TObject)
  private
    FHotKey: TShortCut;
    FOnHotKey: TNotifyEvent;

  protected
    procedure WMHotKey(var msg: TMessage); message WM_HOTKEY;

  public
    constructor Create;
    destructor Destroy; override;

    function RegisterKey: boolean;
    function UnregisterKey: boolean;

  published
    property HotKey: TShortCut read FHotKey write FHotKey;
    property OnHotKey: TNotifyEvent read FOnHotKey write FOnHotKey;

  end;

implementation

{ TGlobalHotKey }

constructor TGlobalHotKey.Create;
begin
  inherited;

  // Nothing to do
end;

destructor TGlobalHotKey.Destroy;
begin
  // Hotkey wieder freigeben
  UnregisterKey;

  inherited;
end;

function TGlobalHotKey.RegisterKey: boolean;
var
  uModifier, uKey: Word;
  sShiftState: TShiftState;
begin
  Result := false;

  // Kombination zugewiesen?
  if FHotKey = 0 then Exit;

  // Kombination entschlüsseln
  ShortCutToKey(FHotKey, uKey, sShiftState);

  uKey := Ord('A');

  // Modifier-Key rausfinden
  uModifier := 0;
  if ssAlt in sShiftState then
    uModifier := uModifier or MOD_ALT;
  if ssCtrl in sShiftState then
    uModifier := uModifier or MOD_CONTROL;
  if ssShift in sShiftState then
    uModifier := uModifier or MOD_SHIFT;

  // Kombination registrieren
  Result := RegisterHotKey(Application.Handle, $BFFF, uModifier, uKey);
end;

function TGlobalHotKey.UnregisterKey: boolean;
begin
  // HotKey deregistrieren
  Result := UnregisterHotKey(Application.Handle, $BFFF);
end;

procedure TGlobalHotKey.WMHotKey(var msg: TMessage);
begin
  // Nachricht erhalten und Event auslösen
  if Assigned(FOnHotKey) then
    FOnHotKey(self);
end;

end.
Nun wird allerdings mein Ereignis nie ausgelöst. Und auch wenn ich über Application.OnMessage versuche die Nachricht WM_HOTKEY abzufangen warte ich relativ ewig... :? Habe schon geguckt... rein theoretisch müsste es funktioniert (Einzelschritt sagt mir, dass [CTRL]+[ALT]+[A] registriert wurde). :gruebel:

Habt ihr eine Idee?

Chris

SirThornberry 1. Okt 2005 12:18

Re: Diese Sache mit den globalen Hooks...
 
wenn du die Message auf diese Weise
Delphi-Quellcode:
 procedure WMHotKey(var msg: TMessage); message WM_HOTKEY;
abfangen willst so muss die klasse auch ein Handle haben um die message auch empfangen zu können und dementsprechend müsstest du dann bei RegisterHotkey das Handle dieser Klasse angeben

CalganX 1. Okt 2005 12:26

Re: Diese Sache mit den globalen Hooks...
 
Hi,
hm. Das habe ich mir gedacht, deswegen habe ich ja nochmal per Application.OnMessage versucht abzufangen (gebe ja auch das Handle der Anwendung weiter). Aber das hat ja auch nicht funktioniert... :gruebel:

Chris

SirThornberry 1. Okt 2005 12:53

Re: Diese Sache mit den globalen Hooks...
 
so gehts
Delphi-Quellcode:
  THotkeyObj = class(TObject)
  private
    fHandle: Cardinal;
    procedure FMsgProc(var AMsg: TMessage);
  public
    constructor Create;
    destructor Destroy; override;
  end;
[...]
constructor THotkeyObj.Create;
begin
  inherited;
  fHandle := classes.AllocateHWnd(FMsgProc);
  RegisterHotKey(fHandle, 0, MOD_CONTROL, VKKeyScan('a'));
end;

destructor THotkeyObj.Destroy;
begin
  UnregisterHotKey(fHandle, $0);
  classes.DeallocateHWnd(fHandle);
  inherited;
end;

procedure THotkeyObj.FMsgProc(var AMsg: TMessage);
begin
  with AMsg do
  begin
    if AMsg.Msg = WM_HOTKEY then
      //hotkey was pressed
    else
      Result := DefWindowProc(fHandle, Msg, wParam, lParam);
  end;
end;

CalganX 1. Okt 2005 13:28

Re: Diese Sache mit den globalen Hooks...
 
Hi,
ne... irgendwie funktioniert das noch nicht. :?
Die MsgProc wird nie aufgerufen, d.h. ich bekomme irgendwie keine Nachricht... aber dem Rückgabewert von RegisterHotKey zu Folge wurde der HotKey registriert... :gruebel:

Mein Test-Source sieht im Moment so aus (ist eine einfache Konsolen-Anwendung):
Delphi-Quellcode:
  idx := TextToShortCut('STRG+ALT+A');
  hkKey := TGlobalHotKey.Create;
  evtHandler := TEventHandler.Create;
  try
    hkKey.HotKey := idx;
    hkKey.OnHotKey := evtHandler.HotKeyPressed;
    if not hkKey.RegisterKey then
      MessageDlg('HotKey wurde nicht registriert.', mtError, [mbOK], 0);
    readln;
    hkKey.UnregisterKey;
  finally
    hkKey.Free;
    evtHandler.Free;
  end;
Chris

Basilikum 1. Okt 2005 13:46

Re: Diese Sache mit den globalen Hooks...
 
mit einem simplen "readln" gibst du den Window-Messages gar nie eine Chance, bearbeitet zu werden.... (Message Dispatcher fehlt)

CalganX 1. Okt 2005 14:26

Re: Diese Sache mit den globalen Hooks...
 
Hi,
:wall:

Okay, das funktioniert jetzt, danke! :)

Chris


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:23 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