[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 419
  • Last Modified:

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
0
kapot
Asked:
kapot
  • 4
  • 3
  • 2
  • +1
1 Solution
 
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
 
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
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:
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
 
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

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.

  • 4
  • 3
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now