Title: Creating a system wide shortcut or hotkey
Question: How to create and handle a system wide shortcut or hotkey (one that is handled beyond the application)
Answer:
{**********************************************************
Copyright © by Jim McKeeth
Licensed under LGPL
( http://www.gnu.org/licenses/licenses.html#LGPL )
Demo of creating a system wide hotkey
or shortcut
This was written in Delphi 7,
but should work in most other versions
(but obviously not Kylix)
You need a form with
1) a THotKey named HotKey1
2) a TCheckBox named CheckBox1
To demo
1) Change the hotkey in the value
2) Check the box
3) Minimize the application
4) Press the hot key
5) Be impressed
**********************************************************}
unit SystemHotKeyUnit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, StdCtrls, ComCtrls, Dialogs,
// Menus need to be added for calls in the code
Menus;
type
TForm1 = class(TForm)
HotKey1: THotKey;
CheckBox1: TCheckBox;
procedure FormCreate(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
protected
// Handle the global hot key messages when they are sent to the window
procedure HotyKeyMsg(var msg:TMessage); message WM_HOTKEY;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
var
myAtom: integer;
function ShiftState2Modifier(const Shift: TShiftState):Word;
begin
Result := 0;
if ssShift in Shift then
Result := Result or MOD_SHIFT;
if ssAlt in Shift then
Result := Result or MOD_ALT;
if ssCtrl in Shift then
Result := Result or MOD_CONTROL;
end;
function GetShortCutKey(ShortCut: TShortCut):Word;
var
shift: TShiftState;
begin
ShortCutToKey(ShortCut,Result,shift); // call in Menus!
end;
function GetShortCutModifier(ShortCut: TShortCut):Word;
var
key: Word;
shift: TShiftState;
begin
ShortCutToKey(ShortCut,key,shift); // call in Menus!
Result := ShiftState2Modifier(shift);
end;
function RegisterHotShortCut(const h:THandle; const Atom: integer; const ShortCut: TShortCut):Boolean;
var
key : Word;
Shift: TShiftState;
begin
UnregisterHotKey(h,Atom); // call in Windows
ShortCutToKey(ShortCut,key,shift);
Result := RegisterHotKey(h,Atom,ShiftState2Modifier(Shift),key);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
// you need to type cast it as a pChar if you are using a string
myAtom := GlobalAddAtom(pchar('HotKeyDemo'));
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
UnregisterHotKey(Handle,myAtom);
GlobalDeleteAtom(myAtom);
end;
procedure TForm1.CheckBox1Click(Sender: TObject);
begin
if CheckBox1.Checked then
RegisterHotShortCut(Handle,myAtom,HotKey1.HotKey)
else
UnregisterHotKey(Handle,myAtom);
end;
procedure TForm1.HotyKeyMsg(var msg: TMessage);
begin
if (msg.LParamLo=GetShortCutModifier(HotKey1.HotKey))
and (msg.LParamHi=GetShortCutKey(HotKey1.HotKey)) then
begin
Application.BringToFront;
Showmessage('Hey, now that is a system wide hot key!')
end;
end;
end.