In Delphi XE Update 1, I’m getting seemingly random behavior of modal forms if the parent (main) form’s FormStyle is set to fsStayOnTop.
1) With MainFormOnTaskbar := False (the old way), everything “just works”. With the new MainFormOnTaskbar := True, modal forms get hidden behind the main form when the main form is set to “stay on top”. In most cases saying
modalForm.PopupParent := self;
just before the call to modalForm.ShowModal seems to help. But not always.
2) All my modal forms are simple, no frills, positioned at MainFormCenter, not using form inheritance, etc. And yet the PopupParent fix only works for about half of them, while the other half still get hidden behind the main form. Strangest of all, in one case the ordering of unrelated lines of code breaks or makes it. See lines marked (1) and (2) in this code:
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;
When executed in this order, the modal form shows correctly on top of the main form. But when I reverse the lines, the modal form hides behind main. The line marked (1) sets a property of the modal form, which results in several checkboxes being checked on unchecked in a TRzCheckGroup, sitting on a TRzPageControl (from Raize components). This is the setter method that runs when line (1) above executes:
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;
This is enough for the modal form to show behind the main form if the order of the lines (1) and (2) is reversed.
This might point to TRzCheckGroup (which gets manipulated when the setter code runs), but I have two other forms that show the same problem and do not use TRzCheckGroup (or TRzPageControl). And I could not reproduce the problem with a separate sample app using Raize components. Disabling the form, the pagecontrol or the TRzCheckGroup for the duration of the setter has no effect.
It does not appear to be a timing issue, because when the modal form shows hidden once, it always does. The change in behavior only comes from rearranging the lines of code.
3) One last observation: my modal forms are fairly simple, so they get displayed pretty much instantly, with no visible delay. But when the main form is fsStayOnTop, then very often I can see the modal form show on top of it, then see it get “pushed” behind. Then, on hitting Esc, the (invisible) modal form shows on top of the main form for a fraction of a second, then gets closed.
Either I‘m missing something that’ll seem obvious in hindsight, or this is a call for psychic debugging, I don’t know. Any ideas, please?
UPDATE. I’ve tried to track down the problem on another form where it occurs. It has a few buttons (Raize) and a TSyntaxMemo (an enhanced memo component from eControl.ru). This form has almost nothing in common with the other forms that experience the problem. After removing parts of the code and testing, I can now reproduce the problem by making a tiny change in a method that assigns a string to the memo component:
This is my original code, which causes the form containing the editor to hide behind the main form:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := Value;
end;
When I change the assignment to an empty string, the form displays correctly:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := ''; // CRAZY! Problem goes away
end;
When I assign a single character to the editor, the form starts hiding again:
procedure TEditorForm.SetAsText(const Value: string);
begin
Editor.Text := 'a'; // Problem is back
end;
Of course the other two problematic forms do not use this editor component or any of its units.
I've tried deleting the memo control and adding it again (think creation order etc.), but it had no effect. Same if I create the memo in code. The form hides as soon as a non-empty string is assigned to the memo's Text property.
Self
without being a method of an object instance. The code as posted won't compile, much less work, regardless of the ordering of the lines. It's hard to explain code anomalies when you don't post real code. :) – ThinkingPopupMode
property set to? What do you have theTApplication.ModalPopupMode
property set to? – CarreonTSyntaxMemo
, specifically it's setter for theText
property, and see what (if anything) it does with focus. – Thinking