在 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(它在设置器代码运行时被操纵),但我有两种其他形式显示相同的问题并且不使用 TRzCheckGroup(或 TRzPageControl)。而且我无法通过使用 Raize 组件的单独示例应用程序重现该问题。在设置器的持续时间内禁用表单、页面控件或 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 属性,表单就会隐藏。