delphi - "Stay on top"Delphi XE中的主窗体和模式对话框

标签 delphi modal-dialog stayontop

在 Delphi XE Update 1 中,如果父(主)表单的 FormStyle 设置为 fsStayOnTop,我会得到模态表单看似随机的行为

1) 使用 MainFormOnTaskbar := False (旧方法),一切都“正常工作”。使用新的 MainFormOnTaskbar := True,当主窗体设置为“保持在顶部”时,模式窗体将隐藏在主窗体后面。大多数情况下说

modalForm.PopupParent := self;

就在调用 modalForm.ShowModal 之前似乎有帮助。 但并非总是如此。

2) 我所有的模态表单都很简单,没有多余的装饰,位于 MainFormCenter,不使用表单继承等。然而 PopupParent 修复仅适用于其中大约一半,而另一半仍然隐藏在主窗体后面。最奇怪的是,在一种情况下,不相关的代码行的顺序会破坏或成功。请参阅此代码中标记为 (1) 和 (2) 的行:

procedure TEchoMainForm.DBMaintenancePrompt( actions : TMaintenanceActions );
var
  frm : TDBMaintenanceForm;
begin
  frm := TDBMaintenanceForm.Create( self );
  try
    frm.Actions := actions; // (1)
    frm.PopupParent := self; // (2)
    frm.ShowModal;
  finally
    frm.Free;
  end;
end;

按此顺序执行时,模态窗体会正确显示在主窗体的顶部。 但是当我反转这些行时,模态表单隐藏在 main 后面。 标记为 (1) 的行设置了模态表单的属性,这会导致 TRzCheckGroup 中的多个复选框在未选中状态下被选中,位于TRzPageControl(来自 Raize 组件)。这是上面第 (1) 行执行时运行的 setter 方法:

procedure TDBMaintenanceForm.SetActions(const Value: TMaintenanceActions);
var
  ma : TMaintenanceAction;
begin
  for ma := low( ma ) to high( ma ) do
    cgMaintActions.ItemChecked[ ord( ma )] := ( ma in Value );
  end;
end;

如果行 (1) 和 (2) 的顺序颠倒,这足以使模态窗体显示在主窗体后面。

这可能指向TRzCheckGroup(当setter代码运行时它会被操纵),但我有另外两种形式显示相同的问题并且不使用TRzCheckGroup(或TRzPageControl)。我无法使用 Raize 组件使用单独的示例应用程序重现该问题。在 setter 的持续时间内禁用表单、页面控件或 TRzCheckGroup 没有任何效果。

这似乎不是时间问题,因为当模态表单显示隐藏一次时,它总是如此。行为的改变仅来自于重新排列代码行。

3) 最后一个观察:我的模态形式相当简单,因此它们几乎立即显示,没有明显的延迟。但是,当主窗体是 fsStayOnTop 时,我经常可以看到模态窗体显示在其顶部,然后看到它被“推”到后面。然后,按 Esc 键时,(不可见的)模态窗体会在主窗体顶部显示一小会儿,然后关闭。

要么我错过了一些事后看来显而易见的东西,要么这是对心灵调试的呼吁,我不知道。请问有什么想法吗?

<小时/>

更新。我试图通过另一种形式来追踪问题发生的地方。它有几个按钮 (Raize) 和一个 TSyntaxMemo(来自 eControl.ru 的增强型备忘录组件)。这种形式与遇到该问题的其他形式几乎没有任何共同之处。删除部分代码并进行测试后,我现在可以通过对将字符串分配给备忘录组件的方法进行微小更改来重现问题:

这是我的原始代码,它导致包含编辑器的表单隐藏在主表单后面:

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := Value;
end;

当我将分配更改为空字符串时,表单会正确显示:

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := ''; // CRAZY! Problem goes away
end;

当我向编辑器分配单个字符时,表单再次开始隐藏:

procedure TEditorForm.SetAsText(const Value: string);
begin
  Editor.Text := 'a'; // Problem is back
end;

当然,其他两个有问题的表单不使用此编辑器组件或其任何单元。

我尝试删除备忘录控件并再次添加它(想想创建顺序等),但没有效果。如果我在代码中创建备忘录也是如此。一旦将非空字符串分配给备忘录的 Text 属性,表单就会隐藏。

最佳答案

我前段时间也遇到过同样的问题。我的解决方案是将 Self.BringToFront; 添加到模态表单的 OnShow 事件中。

关于delphi - "Stay on top"Delphi XE中的主窗体和模式对话框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7517882/

相关文章:

delphi - 控件放在最上面,像TPanel 可以吗?

delphi - 什么是内部错误E5912

delphi - TIdSSLIOHandlerSocketOpenSSL 和 TLS 协议(protocol)

delphi - Delphi 6之后GetTickCount在哪里?

php - 来自另一个站点的内容的 jQuery 对话框

javascript - 错误 : [$injector:unpr] Unknown provider: modalInstanceProvider <- modalInstance <- modalCtrl with the latest ui bootstrap

c# winforms - 在模式窗体之间传递参数

python - PyQt4 : How can i toggle the "Stay On Top" behavior?

android - 在通话期间显示交互式 float 布局

delphi - 为什么 Delphi zlib 和 zip 库在 64 位下如此慢?