1) 如果使用旧的MainFormOnTaskbar:= False方式,一切“只是工作”。 使用新的MainFormOnTaskbar:= True,则当主窗体设置为“置顶”时,模态窗体会被隐藏在主窗体后面。 在大多数情况下,建议说:
modalForm.PopupParent := self;
在调用modalForm.ShowModal之前添加Application.ProcessMessages似乎有帮助,但不总是有效。
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;
按照这个顺序执行时,模态表单会正确地显示在主要表单的上方。但是当我颠倒这些行时,模态表单会隐藏在主要表单后面。标记为(1)的行设置了模态表单的属性,导致TRzCheckGroup中的多个复选框被选中或取消选中,该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组件的单独示例应用程序重现该问题。禁用表单、页面控件或TRzCheckGroup对setter的持续时间没有影响。
这似乎不是一个时间问题,因为一旦模态窗口显示隐藏,它就总是这样做。仅通过重新排列代码行来改变行为。
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
,而不是对象实例的方法。发布的代码无法编译,更不用说工作了,无论行的顺序如何。当您不发布真正的代码时,很难解释代码异常。 :) - Ken WhitePopupMode
属性设置为什么了?你将TApplication.ModalPopupMode
属性设置为什么了? - Remy LebeauTSyntaxMemo
,特别是它的Text
属性的setter,并查看它是否对焦点有任何影响。 - Ken White