Solved

trapping messages

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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Best Firemonkey component pack 1 104
FMX enumerated colours 2 100
how to center only a line in richedit? 4 57
Moving (cutting/pasting) controls in a TTabbedNotebook... 7 34
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
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…

773 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