Delphi 应用程序主窗体暂时轻弹到最前面

Delphi Application Main Form temporarly flicking to the front

我们有一个 Delphi 2007 应用程序,并且最近启用了 MainFormOnTaskBar 以更好地支持 Windows Aero。但是,由于单击时主窗体不会出现在所有子窗体的顶部,因此我们添加了以下代码。

procedure TBaseForm.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);

  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
  Params.WndParent := 0; 
end;

这样做的一个副作用是,当在不处理特定热键的子窗体上按下 Alt + key 热键时键主窗体轻弹到前面,然后再次返回。如果处理了热键则不会发生此行为,可能是因为热键被吞没了。

有没有其他人遇到过这种行为并且可以建议解决方法。

谢谢

观察到的行为是 VCL 的加速器支持主窗体上可能的主菜单的结果,因此即使在另一个窗体处于活动状态时,您也可以从主窗体的菜单中 select 菜单项。

在 "Application" 处理从 WM_SYSCOMMAND 当命令类型为 SC_KEYMENU 时 "WinControl"(二级形式)的处理程序(window 菜单激活 - Alt 键)。

请注意,此行为不是使用 MainFormOnTaskBar 然后覆盖 CreateParams 以获得可以置于最前面的表单的副作用。无论 MainFormOnTaskBar 的设置如何,都会发生相同的行为。唯一不同的是,激活的主窗体在设置的时候不能排在副窗体前面,但是主窗体是一样被激活的。

您可以在许多地方进行拦截以修改行为,例如辅助表单上的 WM_SYSKEYDOWN 处理程序,或辅助表单的 OnKeyDown 中的处理程序。语义上更正确的覆盖,IMO,应该在次要形式的 IsShortCut 上完成。正如您所发现的,当辅助表单处理组合键时,系统键的处理将终止。然后,您可以告诉 VCL 您的表单需要密钥:

type
  TSecondaryForm = class(TForm)
    ..
  public
    function IsShortCut(var Message: TWMKey): Boolean; override;

...

function TSecondaryForm.IsShortCut(var Message: TWMKey): Boolean;
begin
  Result := True;
end;

当然你可以根据参数有条件地微调return真