Delphi 应用主窗体暂时弹到最前面
Posted
技术标签:
【中文标题】Delphi 应用主窗体暂时弹到最前面【英文标题】:Delphi Application Main Form temporarly flicking to the front 【发布时间】:2017-02-20 16:04:36 【问题描述】:我们有一个 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 热键时,主窗体会弹到前面然后再回来。如果处理了热键,则不会发生此行为,可能是因为热键被吞了。
有没有其他人经历过这种行为并且可以提出解决方法。
谢谢
【问题讨论】:
当MainFormOnTaskbar
为真时,您不需要像那样覆盖CreateParams()
。基本实现已经为您设置了相同的值。单击MainForm
应该会在单击时将其置于顶部,这是正常的窗口行为。
@Remy - 当 MainFormOnTaskbar 为真时,所有辅助表单都归主表单所有。这可以防止主要形式出现在次要形式之前。
您可能还会遇到其他问题。一个在解决方法部分提到了here。可能还有其他人......
@SertacAkyuz:“当 MainFormOnTaskbar 为 true 时,所有辅助表单都归主表单所有”——这是一个很好的观点,我忘记了。在这种情况下,您必须在辅助表单上覆盖 CreateParams()
以破坏该所有权。
【参考方案1】:
观察到的行为是 VCL 加速器支持主窗体上可能的主菜单的结果,因此即使在另一个窗体处于活动状态时,您也可以从主窗体的菜单中选择菜单项。
主窗体的激活是通过在主窗体的句柄上调用SetFocus
来实现的,而“应用程序”正在处理从“WinControl”的WM_SYSCOMMAND
处理程序发送的CM_APPSYSCOMMAND
消息(辅助窗体)当命令类型为SC_KEYMENU
(窗口菜单激活 - 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;
当然你可以根据参数进行微调以有条件地返回 true。
【讨论】:
以上是关于Delphi 应用主窗体暂时弹到最前面的主要内容,如果未能解决你的问题,请参考以下文章
delphi 怎样绘制半透明窗体,只让窗体背景半透明,而窗体里面的控件 不透明
delphi 让子窗体在主窗体内,其在主窗体内最大化,但又不遮盖主窗体的菜单栏