Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.0k views
in Technique[技术] by (71.8m points)

delphi - How can I set a hot key ("win+Key") combination to call an application?

I need to set a hot key at the operating system level, that once set will call whatever I tell it to call. The hot key set must be done from inside my preference option, but the application must not have to be open so that the hot key works.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This does what you want.

First, you need a program that runs in the background and listens to, and responds to, keystrokes. Like this:

program Project1;

uses
  Windows, Messages, ShellAPI;

var
  W: HWND;
  M: MSG;

const
  WM_SETHOTKEY = WM_APP + 1;
  WM_UNSETHOTKEY = WM_APP + 2;
  AppName = 'Rejbrand Hot Key Listener';

const
  FileNames: array[0..1] of string = ('notepad.exe', 'pbrush.exe');

begin

  if FindWindow('STATIC', PChar(AppName)) <> 0 then
    Exit;


  W := CreateWindow('STATIC', PChar(AppName), 0, 0, 0, 100, 100, HWND_MESSAGE, 0, HInstance, nil);

  while GetMessage(M, W, 0, 0) do
    case M.message of
      WM_HOTKEY:
        ShellExecute(0, nil, PChar(FileNames[M.wParam]), nil, nil, SW_SHOWNORMAL);
      WM_SETHOTKEY:
        RegisterHotKey(W, M.wParam, M.lParam shr 16, M.lParam and $FFFF);
      WM_UNSETHOTKEY:
        UnregisterHotKey(W, M.wParam);
    end;

end.

(To create this program, select New/VCL Forms Application, and then remove the main form from the project. Then select Project/View Source and remove the Application.Initialize nonsense. The program should look like the above.)

The above program listens to the messages WM_SETHOTKEY that registers a new Windows hotkey, WM_UNSETHOTKEY that removes a previously registered hotkey, and WM_HOTKEY that is sent by Windows when a registered hotkey is activated by the end-user. The first two messages are defined by me, in this application.

To register a hotkey, send the message WM_SETHOTKEY to the window W. The wParam of the message should be the index (in the FileNames array) of the program to start. The lParam should be of the form $MMMMKKKK where $MMMM are the modifiers (Ctrl, Alt, Shift) and $KKKK the virtual-key code of the hotkey. To remove a hotkey, send a WM_UNSETHOTKEY message with the program index as wParam to W.

Sample usage

From any application, you can do (assuming that Project1.exe is running in the background)

const
  WM_SETHOTKEY = WM_APP + 1;
  WM_UNSETHOTKEY = WM_APP + 2;

const
  MODIFIER_ALT = MOD_ALT shl 16;
  MODIFIER_CTRL = MOD_CONTROL shl 16;
  MODIFIER_SHIFT = MOD_SHIFT shl 16;

procedure TForm1.RegisterHotkeys;
var
  w: HWND;
begin
  w := FindWindow('STATIC', 'Rejbrand Hot Key Listener');
  PostMessage(w, WM_UNSETHOTKEY, 0, MODIFIER_CTRL + MODIFIER_ALT + ord('N'));
  PostMessage(w, WM_SETHOTKEY, 1, MODIFIER_CTRL + MODIFIER_ALT + ord('P'));
end;

Now, even if you close this new program, notepad.exe and pbrush.exe will start on Ctrl + Alt + N and Ctrl + Alt + P, respectively.

Some more discussion

Notice that, when compiled, Project1.exe is only 20 kB small! This is tiny for an application made in Delphi!

To unregister a previously registered hotkey, do

PostMessage(w, WM_UNSETHOTKEY, N, 0);

where N, in this example, is = 0 for notepad and = 1 for pbrush.

To quit project1.exe, do

PostMessage(w, WM_QUIT, 0, 0);

But, of course, if you quit project1.exe, all hotkeys are unregistered by Windows.

You might want to do

procedure TForm1.RegisterHotkeys;
var
  w: HWND;
begin
  w := FindWindow('STATIC', 'Rejbrand Hot Key Listener');
  if w = 0 then
    MessageBox('Error: Rejbrand Hot Key Listener not running!');
  PostMessage(w, WM_UNSETHOTKEY, 0, MODIFIER_CTRL + MODIFIER_ALT + ord('N'));
  PostMessage(w, WM_SETHOTKEY, 1, MODIFIER_CTRL + MODIFIER_ALT + ord('P'));
end;

or even start project1.exe if you cannot find the window.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...