我需要在操作系统级别设置一个热键,一旦设置将调用我告诉它调用的任何内容。 热键设置必须从我的首选项选项中完成,但不必打开应用程序以使热键有效。
答案 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_SETHOTKEY
,WM_UNSETHOTKEY
删除以前注册的热键,以及注册热键时Windows发送的WM_HOTKEY
由最终用户激活。前两条消息由我在此应用程序中定义。
要注册热键,请将消息WM_SETHOTKEY
发送到W
窗口。消息的wParam
应该是要启动的程序的索引(在FileNames
数组中)。 lParam
的格式应为$ MMMMKKKK,其中$ MMMM是修饰符( Ctrl , Alt , Shift )和$ KKKK热键的虚拟键代码。要删除热键,请将WM_UNSETHOTKEY
消息的程序索引发送为wParam
至W
。
从任何应用程序,你可以做(假设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;
但是,如果您只想从应用程序启动另一个应用程序,只需使用ShellExecute
(uses ShellAPI
):
procedure TForm1.Button2Click(Sender: TObject);
begin
ShellExecute(Handle, nil, 'C:\WINDOWS\notepad.exe', nil, nil, SW_SHOWNORMAL);
end;
当然,使用TActionList
或TMainMenu
,您可以为任何Delphi函数或过程分配任何键盘快捷键。