Solved

trapping messages

Posted on 2004-09-11
4
279 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 125 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

856 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