Application HOT KEY

Hi,

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 ?

Thanks
kapotAsked:
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;

interface

uses
  Windows, Messages, Classes, Forms;

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

var
  Form1: TForm1;
  LastShiftLeft : cardinal;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
// 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);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// 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);
end;

procedure TForm1.FormHotKey(var msg : TMessage);
begin
// 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);
      end;
      LastShiftLeft := 0;
    end else LastShiftLeft := GetTickCount;
  end;
end;
end;

end.
0
 
mikelittlewoodCommented:
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.
0
 
heretoreadCommented:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/userinput/keyboardinput/keyboardinputreference/keyboardinputfunctions/registerhotkey.asp

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


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


register hotkey,
RegisterHotKey(Self.Handle, 1, MOD_CONTROL, VkKeyScan('X'))
0
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 :)
0
 
mikelittlewoodCommented:
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
0
 
kapotAuthor Commented:
Here is an example that I found :

http://www.swissdelphicenter.ch/torry/showcode.php?id=2375

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 :)
0
 
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).
0
 
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.,
  byte(VkKeyScan('X'))
or
  VkKeyScan('X') and $ff

I think that it's much easier to use just byte('X') ;)
0
 
heretoreadCommented:
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.
0
 
ZhaawZSoftware DeveloperCommented:
heretoread, your code did NOT work because of 'vk' parameter
0
 
heretoreadCommented:
@mikelittlewood, Sorry about last comment, i misread, i took it as you where having a go at me and not the code :P
0
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.