?
Solved

trapping messages

Posted on 2004-09-11
4
Medium Priority
?
301 Views
Last Modified: 2010-04-05
Hi. I want to register a systemwide hotkey as shown in this article:
http://www.swissdelphicenter.ch/torry/showcode.php?id=147

The problem is that I want to do it from a DLL. How do I trap the WM_HOTKEY messages from the DLL?

Thanks.
0
Comment
Question by:lopardo2003
  • 3
4 Comments
 
LVL 4

Expert Comment

by:Evarest
ID: 12035459
You might want to try http://gajits.coogara.com/delphihooks.asp and download the sample code from http://www.gajits.com/zips/grabbag/hookdemo.zip

This comes with a nice example and will explain to you how to set hooks, also for WM_HOTKEY...

Hope this helps!
Evarest
0
 
LVL 10

Expert Comment

by:Jacco
ID: 12037448
Hi there,

I think you are looking for something like this:

library Project2;

uses
  SysUtils,
  Classes,
  Windows,
  Messages;

{$R *.res}

type
  THotKeyHandler = class
  private
    fHandle: HWND;
    fAtomID: Integer;
  public
    procedure WndProc(var Message: TMessage);
  end;

var
  fHandler: THotKeyHandler;

{ THotKeyHandler }

procedure THotKeyHandler.WndProc(var Message: TMessage);
begin
  if Message.Msg = WM_HOTKEY then
  begin
    with TWMHotKey(Message) do
    begin
      if HotKey = fAtomID then
        MessageBeep(20);
    end;
  end;
end;

procedure RegisterKey;
begin
  fHandler := THotKeyHandler.Create;
  fHandler.fHandle := AllocateHWND(fHandler.WndProc);
  fHandler.fAtomID := GlobalAddAtom('Hotkey1');
  RegisterHotKey(fHandler.fHandle, fHandler.fAtomID, MOD_CONTROL, Ord('A'));
end;

exports
  RegisterKey;

begin

end.

You can also put the important code (RegisterKey) in a separate unit and use unit initialization/finalization to Register and UnRegister the hotkey. You don't have to export the functions then.

Regards Jacco
0
 
LVL 10

Accepted Solution

by:
Jacco earned 500 total points
ID: 12037490
To make it a bit prettier here is a unit i made that does thing in a OO fashion:

*** start of unit ***
unit uHotKeys;

interface

uses
  Windows, Classes, Messages;

type
  THandler = procedure;

  THotKeyHandler = class
  private
    fHandle: HWND;
    fAtomID: Integer;
    fKeyNames: TStringList;
    fKeyHandlers: TStringList;
    procedure WndProc(var Message: TMessage);
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddHotKey(const Name: string; Modifiers, Key: Cardinal; Handler: THandler);
    procedure RemoveHotKey(const Name: string);
  end;

function HotKeyHandler: THotKeyHandler;

implementation

uses
  SysUtils;

var
  fHotKeyHandler: THotKeyHandler = nil;

function HotKeyHandler: THotKeyHandler;
begin
  if not Assigned(fHotKeyHandler) then
    fHotKeyHandler := THotKeyHandler.Create;
  Result := fHotKeyHandler;
end;

{ THotKeyHandler }

constructor THotKeyHandler.Create;
begin
  inherited Create;
  fHandle := AllocateHWND(WndProc);
  fKeyNames := TStringList.Create;
  fKeyHandlers := TStringList.Create;
end;

destructor THotKeyHandler.Destroy;
var
  Key: Integer;
begin
  fKeyNames.Free;
  fKeyHandlers.Free;
  DeallocateHWnd(fHandle);
  inherited Destroy;
end;

procedure THotKeyHandler.AddHotKey(const Name: string; Modifiers, Key: Cardinal; Handler: THandler);
var
  AtomID: Integer;
begin
  AtomID := GlobalAddAtom(PChar(Name));
  fKeyNames.AddObject(Name, Pointer(AtomID));
  fKeyHandlers.AddObject(IntToStr(AtomID), @Handler);
  RegisterHotKey(fHandle, AtomID, Modifiers, Key);
end;

procedure THotKeyHandler.RemoveHotKey(const Name: string);
var
  Index, AtomID: Integer;
begin
  Index := fKeyNames.IndexOf(Name);
  if Index >= 0 then
  begin
    AtomID := Integer(fKeyNames.Objects[Index]);
    fKeyNames.Delete(Index);
    Index := fKeyHandlers.IndexOf(IntToStr(AtomID));
    fKeyHandlers.Delete(Index);
    UnRegisterHotKey(fHandle, AtomID);
    GlobalDeleteAtom(AtomID);
  end;
end;

procedure THotKeyHandler.WndProc(var Message: TMessage);
var
  Index: Integer;
begin
  if Message.Msg = WM_HOTKEY then
  begin
    with TWMHotKey(Message) do
    begin
      Index := fKeyHandlers.IndexOf(IntToStr(HotKey));
      if Index >= 0 then
        THandler(fKeyHandlers.Objects[Index]);
    end;
  end;
end;

initialization
finalization
  fHotKeyHandler.Free;
end.
*** end of unit ***

Your DLL code can now look like this:

*** start of code ***
library Project2;

uses
  Windows,
  uHotKeys in 'uHotKeys.pas';

{$R *.res}

procedure DoSomething;
begin
  MessageBeep(20);
end;

begin
  HotKeyHandler.AddHotKey('Test', MOD_CONTROL, Ord('A'), DoSomething);
end.
*** end of code ***

Nothing needs to be exported a LoadLibrary is enough to register the hotkey!

Regards Jacco
0
 
LVL 10

Expert Comment

by:Jacco
ID: 12037495
Oops forgot to remove the registered keys

destructor THotKeyHandler.Destroy;
var
  Key: Integer;
begin
  while fKeyNames.Count > 0 do
    RemoveHotKey(fKeyNames[0]);
  fKeyNames.Free;
  fKeyHandlers.Free;
  DeallocateHWnd(fHandle);
  inherited Destroy;
end;
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses
Course of the Month15 days, 14 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question