TApplication.MainFormOnTaskbar
对系统范围的热键完全没有影响。我可以肯定地证实这一点。无论设置为什么,无论应用程序是否聚焦等,我都能够接收WM_HOTKEY
消息。因此,无论您看到什么,都不是您认为正在发生的事情。MainFormOnTaskbar
最有可能的Handle
是,表单只是在您调用后在您背后重新创建RegisterHotKey()
,因此您丢失了HWND
将接收WM_HOTKEY
消息的表单。除了使用OnCreate
事件,您应该覆盖表单的CreateWindowHandle()
和方法,以确保无论发生什么情况,DestroyWindowHandle()
始终为表单的当前注册热键(每当您将任何类型的数据绑定到表单时,您都应该这样做),例如:HWND
Handle
type
TForm1 = class(TForm)
private
HotKey_xyz: WORD;
procedure WMHotKey(var Message: TMessage); message WM_HOTKEY;
protected
procedure CreateWindowHandle(const Params: TCreateParams); override;
procedure DestroyWindowHandle; override;
end;
procedure TForm1.CreateWindowHandle(const Params: TCreateParams);
begin
inherited;
HotKey_xyz := GlobalAddAtom('Hotkey_xyz');
if HotKey_xyz <> 0 then
RegisterHotKey(Self.Handle, HotKey_xyz, MOD_CONTROL, VK_F12);
end;
procedure TForm1.DestroyWindowHandle(const Params: TCreateParams);
begin
if HotKey_xyz <> 0 then
begin
UnregisterHotKey(Self.Handle, HotKey_xyz);
GlobalDeleteAtom(HotKey_xyz);
HotKey_xyz := 0;
end;
inherited;
end;
procedure TForm1.WMHotKey(var Message: TMessage);
begin
...
end;
更好的选择是使用AllocateHWnd()
分配一个单独的专用HWND
仅用于处理热键消息(然后您可以再次使用OnCreate
andOnDestroy
事件),例如:
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
HotKey_xyz: WORD;
HotKeyWnd: HWND;
procedure HotKeyWndProc(var Message: TMessage);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
HotKeyWnd := AllocateHwnd(HotKeyWndProc);
HotKey_xyz := GlobalAddAtom('Hotkey_xyz');
if HotKey_xyz <> 0 then
RegisterHotKey(HotKeyWnd, HotKey_xyz, MOD_CONTROL, VK_F12);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if HotKey_xyz <> 0 then
begin
UnregisterHotKey(HotKeyWnd, HotKey_xyz);
GlobalDeleteAtom(HotKey_xyz);
HotKey_xyz := 0;
end;
if HotKeyWnd <> 0 then
begin
DeallocateHWnd(HotKeyWnd);
HotKeyWnd := 0;
end;
end;
procedure TForm1.HotKeyWndProc(var Message: TMessage);
begin
if Message.Msg = WM_HOTKEY then
begin
...
end else
Message.Result := DefWindowProc(HotKeyWnd, Message.Msg, Message.WParam, Message.LParam);
end;