2009. szeptember 3., csütörtök

Creating a system wide shortcut or hotkey


Problem/Question/Abstract:

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.

Nincsenek megjegyzések:

Megjegyzés küldése