gpt4 book ai didi

Delphi 2007 - 如果设置 "system-wide",则系统范围热键不是 "MainFormOnTaskBar := True"

转载 作者:行者123 更新时间:2023-12-03 14:43:13 26 4
gpt4 key购买 nike

我有一个 Delphi 2007 项目,多年来一直在 Windos XP、Vista 和“7”上运行良好。它是 Delphi 5 的升级版,因此默认情况下“MainFormOnTaskBar”为“false”(我从未在 DPR 中更改过它)。在这种情况下,系统范围的热键在“系统范围”内工作,并在主窗体的 OnCreate 事件处理程序中使用以下代码。

HotKey_xyz := GlobalAddAtom('Hotkey_xyz');
if NOT RegisterHotKey(Self.Handle, HotKey_xyz, MOD_CONTROL, VK_F12) then
ShowMessage('Unable to register Control-F12 as system-wide hot key') ;

(I have GlobalDeleteAtom() and UnregisterHotKey() in Form.OnDestroy as expected.)

现在,我需要一个表单在任务栏上显示自己的按钮,因此我在 DPR 中设置“Application.MainFormOnTaskBar := True”。这按预期工作。但是,这有一个副作用,即 Control-F12 不能在系统范围内工作,它仅在我的应用程序具有焦点时才有效(因此,它不再是“系统范围”。)

我在网上进行了广泛的搜索,发现了许多关于“MainFormOnTaskBar”如何/为什么影响某些子表单/模态表单行为的文章。但是,我没有发现任何关于它对我上面描述的“系统范围热键”问题的影响。我已经测试并重新测试了我的应用程序,将 MainFormOnTaskBar 设置为 true 和 false,而其他所有内容都保持完全相同。我可以肯定地验证上述系统范围热键问题与 MainFormOnTaskBar 标志有关。

我将非常感谢任何有关解决方法的指导。我确实需要两者 - 系统范围的热键和任务栏上有自己的按钮的表单。

非常感谢。

最佳答案

TApplication.MainFormOnTaskbar 对系统范围的热键根本没有影响。我可以肯定地证实这一点。无论 MainFormOnTaskbar 设置为多少,无论应用程序是否聚焦等,我都能够接收 WM_HOTKEY 消息。因此,您所看到的并不是您所看到的认为正在发生。

最有可能的是,在您调用 RegisterHotKey() 之后,表单的 Handle 只是在您背后重新创建,因此您丢失了 HWND将接收 WM_HOTKEY 消息。您应该重写表单的 CreateWindowHandle()DestroyWindowHandle() 方法,而不是使用 OnCreate 事件,以确保热键始终注册对于表单当前的 HWND,无论发生什么情况(每当您将任何类型的数据绑定(bind)到表单的 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 仅用于处理热键消息(然后您可以使用 OnCreateOnDestroy 事件再次),例如:

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;

关于Delphi 2007 - 如果设置 "system-wide",则系统范围热键不是 "MainFormOnTaskBar := True",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10220071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com