如果设置“MainFormOnTaskBar:= True”,Delphi 2007 – 系统范围热键不是“系统范围”

前端之家收集整理的这篇文章主要介绍了如果设置“MainFormOnTaskBar:= True”,Delphi 2007 – 系统范围热键不是“系统范围”前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个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.)

现在,我需要一个窗体在Taskbar上显示自己的按钮,所以在DPR中设置“Application.MainFormOnTaskBar:= True”.这样可以预期.然而,这对Control-F12不起作用,它的作用只有在我的应用程序具有重点的情况下(因此它不再是“系统范围”).

我已经广泛搜索了“Net发现了许多关于如何/为什么”MainFormOnTaskBar“影响某些子窗体/模态形式行为的文章.但是,我对上述我所描述的“系统热键”问题的影响没有发现.我已经测试和重新测试我的应用程序与MainFormOnTaskBar设置为true和false,而其他所有的保持完全一样.我可以肯定地验证上述与系统范围热键相关的问题与MainFormOnTaskBar标志有关.

我将非常感谢任何关于解决方案的指导.我需要BOTH – 一个系统范围的热键AND一个表单,其任务栏上带有自己的按钮.

非常感谢你.

解决方法

TApplication.MainFormOnTaskbar根本不影响系统范围的热键.我可以肯定地确认.无论什么MainFormOnTaskbar被设置为无论该应用程序是否集中,我都可以收到WM_HOTKEY消息,所以无论你看到什么都不是你所想的.

调用RegisterHotKey()之后,很可能,Form的Handle正好在后面被重新创建,所以你丢失了会收到WM_HOTKEY消息的HWND.而不是使用OnCreate事件,您应该重写Form的CreateWindowHandle()和DestroyWindowHandle()方法,以确保始终为窗体的当前HWND注册热键,无论它发生什么(您应该始终这样做,当你绑定表格的句柄的一些数据),例如:

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,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和OnDestroy事件),例如:

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,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相关文章