?
Solved

trapping messages

Posted on 2004-09-11
4
Medium Priority
?
293 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…
In this video, Percona Solution Engineer Rick Golba discuss how (and why) you implement high availability in a database environment. To discuss how Percona Consulting can help with your design and architecture needs for your database and infrastr…

765 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