如何设置热键(“win + Key”)组合来调用应用程序?

时间:2010-09-10 20:49:11

标签: delphi keyboard-shortcuts

我需要在操作系统级别设置一个热键,一旦设置将调用我告诉它调用的任何内容。 热键设置必须从我的首选项选项中完成,但不必打开应用程序以使热键有效。

6 个答案:

答案 0 :(得分:14)

这就是你想要的。

首先,您需要一个在后台运行的程序,并监听并响应击键。像这样:

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.

(要创建此程序,请选择New / VCL Forms Application,然后从项目中删除主窗体。然后选择Project / View Source并删除Application.Initialize废话。程序应如上所示。 )

上述程序侦听注册新Windows热键的消息WM_SETHOTKEYWM_UNSETHOTKEY删除以前注册的热键,以及注册热键时Windows发送的WM_HOTKEY由最终用户激活。前两条消息由我在此应用程序中定义。

要注册热键,请将消息WM_SETHOTKEY发送到W窗口。消息的wParam应该是要启动的程序的索引(在FileNames数组中)。 lParam的格式应为$ MMMMKKKK,其中$ MMMM是修饰符( Ctrl Alt Shift )和$ KKKK热键的虚拟键代码。要删除热键,请将WM_UNSETHOTKEY消息的程序索引发送为wParamW

样本用法

任何应用程序,你可以做(​​假设Project1.exe在后台运行)

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;

现在,即使你关闭这个新程序,notepad.exe和pbrush.exe也会在 Ctrl + Alt + N 上启动 Ctrl + Alt + P

更多讨论

请注意,编译时,Project1.exe只有20 kB小!对于Delphi中的应用程序,这是 tiny

要取消注册以前注册的热键,请执行

PostMessage(w, WM_UNSETHOTKEY, N, 0);

其中N,在本例中,对于记事本是= 0,对于pbrush是= 1.

要退出project1.exe,请执行

PostMessage(w, WM_QUIT, 0, 0);

但是,当然,如果您退出project1.exe,Windows将取消注册所有热键。

您可能想要

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;

如果找不到窗口,甚至可以启动project1.exe。

答案 1 :(得分:4)

我认为您正在寻找RegisterHotKey功能。

答案 2 :(得分:4)

如果按下热键(在使用RegisterHotKey注册后),您需要一个正在监听热键的应用程序实例,或者系统将发送的消息。因此,您的应用程序要么自己监听并且被激活/来到前面,要么您有一个热键监听器来启动第二个应用程序。

虽然Windows shell(explorer.exe)允许您定义启动程序的快捷键,但是无法使用 Win 键(也不在Windows 7下),因为ISHellLink interface仅通过SetHotKey方法支持 Alt Ctrl Shift 。可能这就是为什么像WinKey这样的应用程序存在的原因。

答案 3 :(得分:3)

桌面或“开始”菜单层次结构中的快捷方式(.LNK文件)可以为其分配“快捷键”(热键)。 [1,2]

“属性”对话框(至少在XP下)不允许 Win 组合键,但您可以通过编程方式创建它们。 JCL有一个函数ShellLinkCreate()来创建快捷方式。请注意,以编程方式创建快捷方式后,资源管理器不会自动获取您设置的热键。显然你可以重启资源管理器(可以干净利落地完成而无需注销[3,4]) 或者你可能只是为.lnk文件调用SHChangeNotify,或者可能正在播放WM_SETTINGCHANGE消息。

[1] Start a program using a keyboard shortcut
[2] How to create a keyboard shortcut for a program in Windows XP
[3] Hidden Trick to Exit Windows Explorer Using Shutdown Dialog Box in Windows XP
[4] Hidden Trick to Exit Windows Explorer Using Start Menu in Windows Vista and Server 2008

答案 4 :(得分:3)

使用 Windows 密钥违反了Microsoft的用户体验指南。有关此问题的详细评论,请参阅mghie's answer to "THotkey with win-key support"

如果你看一下MSDN's writeup for RegisterHotKey,你会看到即使他们允许MOD_WIN值,他们也明确指出:

  

“保留使用涉及WINDOWS键的键盘快捷键   由操作系统。“

Windows允许程序的快捷键。您可以在可执行文件的“属性页”上添加快捷方式。这正是您想要在程序中执行的操作。在属性页面上,它们允许您设置 Ctrl 键, Shift 键和 Alt 键以及最多三个键与另一个键的组合作为你的捷径。但是当你尝试使用Windows键时,它不会让你使用它,而是会建议 Crtl + Alt

你可以使用RegisterHotKey,亚历山大首先回答这个问题。 Here's a Delphi example如何做到这一点。

但我强烈建议您不要使用 Windows 键作为快捷方式。

答案 5 :(得分:1)

这样做(uses ComObj, ActiveX, ShlObj):

procedure TForm1.Button1Click(Sender: TObject);
var
  IObject: IUnknown;
  ISLink: IShellLink;
  IPFile: IPersistFile;
const
  HOTKEY_CONTROL = 512;
  HOTKEY_ALT = 1024;
begin
  // Creates a shell link (*.lnk) to C:\WINDOWS\notepad.exe in the directory of this exe;
  // the link has keyboard shortcut CTRL+ALT+N.
  IObject := CreateComObject(CLSID_ShellLink);
  ISLink := IObject as IShellLink;
  IPFile := IObject as IPersistFile;
  ISLink.SetPath('C:\WINDOWS\notepad.exe');
  ISLink.SetHotkey(Ord('N') + HOTKEY_CONTROL + HOTKEY_ALT);
  IPFile.Save(PChar(ExtractFilePath(Application.ExeName) + 'Shortcut to Notepad.lnk'), false);
end;

但是,如果您只想从应用程序启动另一个应用程序,只需使用ShellExecuteuses ShellAPI):

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShellExecute(Handle, nil, 'C:\WINDOWS\notepad.exe', nil, nil, SW_SHOWNORMAL);
end;

当然,使用TActionListTMainMenu,您可以为任何Delphi函数或过程分配任何键盘快捷键。