0

I have a delphi application with multiple forms. Initially I had tried a setup where each newly opened form was a frame and the "parent" of this form (whichever called to open the form) was hidden as the child was shown with the child being resized and relocated to give a seamless effect of having one window, when the child is closed the parent is relocated and again made visible. All forms have a bsSingle border style for the Windows title block. This approach worked well for positioning however the issue I have is a noticeable flicker as the parent form is closed and the child opened, and as there is a small time period where no form is opened the icon/tray on the start bar would shift around and itself become hidden and visible.

Does anybody have any advice on solving this problem? I thought perhaps if I only had one form with the border within the application and opened each new form within this border it would work better - though I am unsure how exactly to do this.

Any help is much appreciated.

jmc
  • 620
  • 14
  • 24
  • 2
    Sounds like you need to have one form which has multiple children, one of which you show at a time. – David Heffernan Jan 04 '12 at 21:05
  • Are you sure that the flicker would not happen if you were not parenting/docking the forms? In other words, is the flicker definitely caused by docking or hosting a form? These same forms, when shown free-floating have no flicker? Did you test both ways? – Warren P Jan 04 '12 at 21:27
  • Sorry it is unclear how I have worded it - the forms are not parented or docked specifically but I keep track of which form is the "parent" or active at any given time and when a new "child" is opened it gets its position and size from the current parent which is then hidden as the new form is shown. So all forms are free floating at the moment. – jmc Jan 05 '12 at 00:39

2 Answers2

1

It is easy to make one form appear as a child inside another. Create a new form which will contain and create your other forms:

procedure TMainForm.FormCreate(Sender: TObject);
var
  F : TForm;
begin
  F := TOneOfYourChildForms.Create(Self);
  F.Parent := Self;
  F.Show();
end;

Create both your child forms similar to this, then just do Show on the one you want to display and Hide on the other. Set BorderStyle to bsNone on the child forms to remove the caption. Turn off Auto-Create on your forms in project settings if you create them yourself like this instead.

Ville Krumlinde
  • 7,021
  • 1
  • 33
  • 41
  • 1
    You sometimes need to do a little more to make a hosted form work well: http://stackoverflow.com/questions/4385948/how-to-avoid-issues-when-embedding-a-tform-in-another-tform/4386129#4386129 – David Heffernan Jan 04 '12 at 21:23
  • Hi Villie and David, I've had some success with both these approaches and from information found here http://stackoverflow.com/questions/4385948/how-to-avoid-issues-when-embedding-a-tform-in-another-tform/4386129#4386129 however it seems that when setting the child's Parent value - all control is dictated from the parent form? No key presses or mouse clicks are detected in the child form... Is this the standard child-parent behaviour? How can I avoid it? Thanks for your help – jmc Jan 05 '12 at 03:20
1

I've had success with this design, and I think it helped to have the contents of the "main form" within a TFrame as well. When you want to show the main form, you would just perform a frame swap.

John Easley
  • 1,551
  • 1
  • 13
  • 23
  • Thanks for the pointer John - does this kind of technique work when there may be multiple "levels" of parent-child relationships? Eg the main form opens a submenu which may open a third submenu (no more than 3 at a time however). – jmc Jan 05 '12 at 00:41
  • I don't see why not. I'd create a controller class in the main form that handles all of the swaps.. – John Easley Jan 05 '12 at 12:52