Delphi XE2,如何在更改VCL样式后保持窗体置顶

7

我在XE2中遇到了一个奇怪的问题:

我使用SetWindowPos和HWND_TOPMOST把我的窗体放在最上面,但是如果我在运行时切换VCL样式,窗口就不再是最上面的了,取消/重新设置也不能解决这个问题。

有没有什么方法可以解决这个问题?


听起来像是个 bug。你应该向 QC 报告此问题。 - Mason Wheeler
@MasonWheeler 这不是一个 bug,这是 vcl 样式工作的方式,每次更改 vcl 样式时,表单的句柄都会重新创建。 - RRUZ
@RRUZ:根据OP最初的描述,如果在样式启用时重新设置属性不起作用,那么这肯定是一个错误。 (请参见OP对Sertac答案的评论,以获得更好地解释实际发生的情况。) - Mason Wheeler
3个回答

8

你的问题在于表单因为样式变化而被重新创建,导致VCL无法识别其最顶部的样式。可以使用以下方法解决:

FormStyle := fsStayOnTop; 

或者覆盖 CreateWindowHandle 方法,以便在每次重建窗体时调用 SetWindowPos

type
  TForm1 = class(TForm)
    ..
  protected
    procedure CreateWindowHandle(const Params: TCreateParams); override;
  ..

procedure TForm1.CreateWindowHandle(const Params: TCreateParams);
begin
  inherited;
  SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE or SWP_NOMOVE);
end;


顺便说一下,我无法复制"取消设置/重新设置不能解决问题"。通过我的测试,再次调用SetWindowPos函数就可以修复它。


谢谢。您是正确的,重新设置确实起作用。问题在于窗口句柄不同,因为我在更改VCL样式后调用了RecreateWnd来解决另一个问题,所以我使用了现在无效的句柄来调用SetWindowPos。 - hikari

5

在控件上设置新样式会导致控件的窗口句柄被重新创建,因此需要重新应用HWND_TOPMOST


0
经过长时间在互联网和Delphi帮助中的搜索,我尝试了几种不同的代码、几个提示,但都没有任何效果,问题仍然存在。在查看帮助文件后,我决定测试下面这个简单的代码,它对我来说完美地解决了问题。
procedure TForm1.FormShow(Sender: TObject);
begin
  Application.RestoreTopMosts;
end;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接