Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Hotkeyunit - Message auslagern (https://www.delphipraxis.net/90965-hotkeyunit-message-auslagern.html)

xZise 26. Apr 2007 17:12


Hotkeyunit - Message auslagern
 
Ich habe eine Objekt dami ich einfach Hotkeys erstellen kann. Nur werden die Hotkeys nicht erfasst... Wie könnte ich sozusagen die Messages des Mutterprogramms abfragen?
Delphi-Quellcode:
type
  EFailedRegisterHotkey = class(Exception);
  EAlreadyExists = class(Exception);

   THotkeyEvent = procedure (ID : Integer) of object;

   THotkeySet = record
    Hotkey : TShortcut;
    Init : Boolean;
    ID : Word;
  end;

  THotKeyFrontEnd = class(TObject)
  private
     FHandle : THandle;
    FHotkeys : array of THotkeySet;
    FOnHotkey: THotkeyEvent;
    function GetHotkeys(index: Integer): THotkeySet;
      procedure ShortCutToHotKey(HotKey: TShortCut; var Key : Word; var Modifiers: Cardinal);
  public
    property Hotkeys[index : Integer] : THotkeySet read GetHotkeys;
    property OnHotkey : THotkeyEvent read FOnHotkey write FOnHotkey;

    procedure RegisterHotkey(AHotkey : TShortCut);
    procedure ChangeHotkey(index : Integer; ANewHotkey : TShortCut);
    function HotkeysCount : Integer;

    procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;

    constructor Create(AHandle : THandle);
     destructor Destroy; override;
  end;

implementation

{ THotKeyFrontEnd }

procedure THotKeyFrontEnd.ShortCutToHotKey(HotKey: TShortCut; var Key : Word; var Modifiers: Cardinal);
var
  Shift: TShiftState;
begin
  ShortCutToKey(HotKey, Key, Shift);
  Modifiers := 0;
  if (ssShift in Shift) then
    Modifiers := Modifiers or MOD_SHIFT;
  if (ssAlt in Shift) then
    Modifiers := Modifiers or MOD_ALT;
  if (ssCtrl in Shift) then
    Modifiers := Modifiers or MOD_CONTROL;
end;

procedure THotKeyFrontEnd.WMHotKey(var Msg: TWMHotKey);
var
   i : Integer;
begin
   for i := 0 to High(FHotkeys) do
  begin
    if Msg.Msg = FHotkeys[i].ID then
    begin
      if Assigned(FOnHotkey) then
        FOnHotkey(i);
    end;
  end;
end;

procedure THotKeyFrontEnd.ChangeHotkey(index: Integer; ANewHotkey: TShortCut);
var
  key : Word;
  Modifiers : Cardinal;
  b : THotkeySet;
begin
   if (index >= 0) and (index < Length(FHotkeys)) then
  begin
     b := FHotkeys[index];
    if b.Hotkey <> ANewHotkey then
    begin
       b.Hotkey := ANewHotkey;
      if b.init then begin
        UnRegisterHotKey(FHandle, b.ID);
        GlobalDeleteAtom(b.ID);
      end;
      ShortCutToHotKey(ANewHotkey, Key, Modifiers);
      b.ID := GlobalAddAtom(PChar('hk' + IntToStr(index)));
      if not Windows.RegisterHotKey(FHandle, b.ID, Modifiers, Key) then begin
        b.init := false;
        raise EFailedRegisterHotkey.CreateFmt(FAILED_REGISTER_HOTKEY, [ShortCutToText(ANewHotkey)]);
      end else
        b.init := true;
    end else
       raise EAlreadyExists.CreateFmt(ALREADY_EXISTS, [ShortCutToText(ANewHotkey)]);
  end;
end;

constructor THotKeyFrontEnd.Create(AHandle: THandle);
begin
   inherited Create;
  FHandle := AHandle;
end;

destructor THotKeyFrontEnd.Destroy;
var
   i : Word;
begin
  for i := 1 to High(FHotkeys) do
  begin
    if FHotkeys[i].init then begin
      UnRegisterHotKey(FHandle, FHotkeys[i].ID);
      GlobalDeleteAtom(FHotkeys[i].ID);
    end;
  end;
  inherited;
end;

function THotKeyFrontEnd.GetHotkeys(index: Integer): THotkeySet;
begin
   Result := FHotkeys[index];
end;

function THotKeyFrontEnd.HotkeysCount: Integer;
begin
  Result := Length(FHotkeys);
end;

procedure THotKeyFrontEnd.RegisterHotkey(AHotkey: TShortCut);
var
   i : Integer;
  key : Word;
  Modifiers : Cardinal;
  b : THotkeySet;
begin
   for i := 1 to High(FHotkeys) do begin
    if FHotkeys[i].Hotkey = AHotkey then
    begin
       raise EAlreadyExists.CreateFmt(ALREADY_EXISTS, [ShortCutToText(AHotkey)]);
    end;
  end;
  SetLength(FHotkeys, Length(FHotkeys) + 1);
  b := FHotkeys[High(FHotkeys)];
  b.Hotkey := AHotkey;

  ShortCutToHotKey(AHotkey, Key, Modifiers);
  b.ID := GlobalAddAtom(PChar('hk' + IntToStr(Length(FHotkeys))));
  if not Windows.RegisterHotKey(FHandle, b.ID, Modifiers, Key) then begin
    b.init := false;
    raise EFailedRegisterHotkey.CreateFmt(FAILED_REGISTER_HOTKEY, [ShortCutToText(AHotkey)]);
  end else
    b.init := true;
end;

xZise 1. Mai 2007 17:06

Re: Hotkeyunit - Message auslagern
 
Hat keiner eine einigermaßen vernünftige Lösung?

SirThornberry 1. Mai 2007 18:45

Re: Hotkeyunit - Message auslagern
 
Die vernünftigste Lösung ist es nicht ein Handle übergeben zu bekommen sondern mit AllocateHwnd selbst ein Fensterhandle zu erstellen wozu du die Messageprocedure bestimmen kannst und somit auch die Messages auswerten kannst.

xZise 1. Mai 2007 19:08

Re: Hotkeyunit - Message auslagern
 
Zitat:

Zitat von SirThornberry
Die vernünftigste Lösung ist es nicht ein Handle übergeben zu bekommen sondern mit AllocateHwnd selbst ein Fensterhandle zu erstellen wozu du die Messageprocedure bestimmen kannst und somit auch die Messages auswerten kannst.

Und wie komm ich dann an die Messages?
[edit]Und wie soll AllocateHWnd funktionieren? Ich mein, wozu brauch ich ein neues Fenster?[/edit]

SirThornberry 1. Mai 2007 19:09

Re: Hotkeyunit - Message auslagern
 
Hast du dir AllocateHwnd überhaupt schon mal angeschaut? Mir scheint dem nicht so zu sein. Der Funktion musst du als Parameter übergeben an welche MessageMethode die Messages gesendet werden. Und eben in dieser kannst du dann die Messages auswerten.

xZise 1. Mai 2007 19:12

Re: Hotkeyunit - Message auslagern
 
D.h. ich erstelle mir ein neues nicht sichtbares Fenster... Wird dass denn auch dem Programm zugeordnet? Und was bringt mir das HWnd was ich wiederbekomme? Brauch ich dass nur zum "freigeben"?

[edit]Manomann... hab doof reagiert... sry... Aber eine Frage: Ich habe jetzt diese Prozedur... Aber wie komme ich jetzt daran. Ob ein Hotkey ausgelöst wurde?
Ich habe das bisher so:
Delphi-Quellcode:
constructor THotKeyFrontEnd.Create;
begin
  inherited;
  hwnd := AllocateHWnd(HWndProc);
end;

procedure THotKeyFrontEnd.HWndProc(var Message: TMessage);
begin
  if Message.Msg = WM_HotKey then
  begin

  end;
end;
So compiliert er, aber das kanns ja net sein, oder wie komme ich an die Hotkeyid?[/edit]

Apollonius 1. Mai 2007 19:38

Re: Hotkeyunit - Message auslagern
 
Laut MSDN liefert Message.wparam die ID des Hotkeys.

xZise 1. Mai 2007 20:06

Re: Hotkeyunit - Message auslagern
 
Ah danke ! Jetzt funktionierts!


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