Application HOT KEY


I made a simplae application and it uses a tray icon component from JEDI JVCL, so it can be minimized to the tray.

My question now, how can I make an application hot key ? For example, when I press the LEFT SHIFT key TWICE, the application will be RESTORED from the tray again (or bring to the top, got focused).

How can we create a keyboard hook like that in Delphi ?

Who is Participating?
ZhaawZSoftware DeveloperCommented:
There's no need for keyboard hook ;) It can be easily done by using simple hotkeys. Also "double left+shift" is possible, here's complete example:

unit Unit1;


  Windows, Messages, Classes, Forms;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormHotKey(var msg : TMessage); message  wm_hotkey;

  Form1: TForm1;
  LastShiftLeft : cardinal;


{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
// register hotkey
// hotkey must be associated with some existing window (specified as hWnd)
// id must be "unique for a window". usually it can be from $0000 to $bfff
// modifiers can be any combination of mod_alt | mod_control | mod_shift | mod_win
// virtual key-code (vk; last param) can be one of vk_* constants or byte('A'), byte('B') etc
// for example, if you want to register hotkey ctrl+alt+d, it will look like this:
// RegisterHotKey(handle, 100, mod_control or mod_alt, byte('D'));
// in Windows NT4 and Windows 2000/XP key F12 can't be used as a hotkey (it's reserved for use by the debugger)
RegisterHotKey({form1.}handle, 1, mod_shift, vk_left);

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
// when hotkey is not needed anymore, it has to be unregistered
// we specified "1" when registering hotkey, so here we must type "1" too
// all hotkeys should be unregistered
UnregisterHotKey({form1.}handle, 1);

procedure TForm1.FormHotKey(var msg : TMessage);
// msg.wParam is identifier of hotkey (that one which was used when registering hotkey)
case msg.wParam of
  1 : begin
    // check if shift+left is pressed twice in less than 250 miliseconds
    if GetTickCount - LastShiftLeft < 250 then begin
      if IsWindowVisible(Application.Handle) then begin
        ShowWindow(handle, sw_hide);
        ShowWindow(Application.Handle, sw_hide);
      end else begin
        ShowWindow(handle, sw_show);
        ShowWindow(Application.Handle, sw_show);
      LastShiftLeft := 0;
    end else LastShiftLeft := GetTickCount;

I would not recommend using the SHIFT key to do this function as it is also linked to STICKYKEYS within windows.

Does it have to be a keyboard? why not use a popup menu at the tray icon image to restore the pplicaiton.

put this in your forms private section,
procedure ProcessHotKey(var Msg:TWMHotKey); message WM_HOTKEY;

procedure TForm.ProcessHotKey(var Msg:TWMHotKey);
//This will ba called on a hotkey.
//If you have more than one hotkey registered use Msg to find which one was pressed.

register hotkey,
RegisterHotKey(Self.Handle, 1, MOD_CONTROL, VkKeyScan('X'))
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

kapotAuthor Commented:
Thanks for the response.

I dont care with the STICKYKEYS because I dont use it. And this app is for private use only.

I choosed LEFT-SHIFT LEFT-SHIFT just to make it very easy.

I will try this soon. I hope this works :)
I had a go at that heretoread but nothing seems to happen

Is this supposed to register the hotkey system wide to windows?
Im wondering if it isnt working becuase using CTRL+X is the standard windows "cut" message
kapotAuthor Commented:
Here is an example that I found :

But I think, it is not possible to use double LEFT-SHIT with this function.

Can you try to use CTRL + LEFT_SHIFT ?

I am still browsing, no chance to test this in the office :)
ZhaawZSoftware DeveloperCommented:
mikelittlewood, it works fine also with ctrl+x and even with alt+tab (so it's quite easy to make a custom "alt+tab window") ;)

RegisterHotKey(handle, 1, mod_control, byte('X'));

And yes, RegisterHotKey() registers system-wide hotkeys. MS Windows sends wm_hotkey to specified window whenever user presses the combination of specified keys, and it also blocks "default processing" of those keys (like it's in case of alt+tab and ctrl+x combinations).

There still can be some cases when it does not work - I have seen such "problem" in a game that uses DirectX - sometimes it "blocks" hotkeys (and even "standard" keyboard hooks).
ZhaawZSoftware DeveloperCommented:
heretoread, about your RegisterHotKey(Self.Handle, 1, MOD_CONTROL, VkKeyScan('X')) ... If you want to use VkKeyScan(), you should use 'x' as parameter, not 'X' ;) that's because VkKeyScan() returns also state of shift/ctrl/alt/Hankaku keys (don't know what the last one is). Or another way would be taking only last 8 bits of resulting value, i.e.,
  VkKeyScan('X') and $ff

I think that it's much easier to use just byte('X') ;)
ZhaawZ, my bad.

@mikelittlewood, I ignored your comments, as you should to mine if you dont like it, The code i provided works perfect, iv'e used it in my applications with no problem.
ZhaawZSoftware DeveloperCommented:
heretoread, your code did NOT work because of 'vk' parameter
@mikelittlewood, Sorry about last comment, i misread, i took it as you where having a go at me and not the code :P
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.