delphi sql server asp java coldfusion web developer training course class uk floridadelphi asp java coldfusion sql server web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk florida
delphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk floridadelphi sql server asp java coldfusion web developer training course class uk florida

 

Forms Have Parents Too
written by Rick Spence

Designing forms in Delphi is easy. Drop the controls onto the forms and write event handlers. End of story. But how you present those forms to the user is another issue. Do you display them as normal free floating forms (SDI), as MDI children, or some other way?

Recently, I've been developing applications where the forms themselves are displayed inside some sort of container. I have a main form which contains a panel, for example, then when the user requests a sub form I display it inside that panel. You can also use a page control and tabSheets, and this allows you to have several sub forms available - one in each tabSheet. To implement this approach you need to understand a couple of important concepts - owners and parents. Let's start with ownership.

All controls and forms have an owner property. A control's (or form's) owner is another component responsible for destroying that control. With controls on a form, the owner is nearly always the form itself. This is always the case if you drop a component onto a form in the designer, but if you create controls dynamically then you must specify the owner when you create it. When you create forms dynamically, of course, you specify the owner when you instantiate it. You will either have the global Application variable as the form's owner, or another form. The important point about ownership is that the owner will destroy all the things it owns when it is destroyed.

Controls and forms also have a property called parent. The concept of parent has to do with screen real estate. A control's parent is the control whose screen area this control uses, and the control's location is relative to its parent. A control at the leftmost side of a groupbox, for example, has its left property set to 0. A control's parent can also be the form itself of course, in which case its left and top properties are relative to the form.

Now, forms also have a parent property, and usually it is nil. However, you can set it to reference some container control, then the form appears within that container. For example, imagine you have a main form called frmMain containing a panel called panel1. To create an instance of a form called frmCustomers and have that form displayed within the panel simply write:
frmCustomers := TFrmCustomers.Create( Application );
frmCustomers.parent := frmMain.panel1;
This works, but one undesirable effect is that the user can move this form within the panel, which you probably don't want. Another undesirable effect is that you see the form's border as well. To overcome these minor issues, set the form's align property to alClient, and its borderStyle property to bsNone, as in:
frmCustomers := TFrmCustomers.Create( Application );
frmCustomers.parent := frmMain.panel1;
frmCustomers.borderStyle := bsNone;
frmCustomers.align := alClient;
You can use the same code to display a form within a tabSheet, but if you are also going to create the tabSheets dynmically (so you can have multiple forms open), there are two things to be careful of. The first is when creating tabSheets dynamically, you must set the tabSheet's pageControl property to reference the pageControl it is contained within:
// Assume pageControl called PageControl1
tabSheet1 := TTabSheet.Create( Application );
tabSheet1.Parent := frmMain.PageControl1;
tabSheet1.pageControl := frmMain.PageControl1;
If you don't set the pageControl property you won't see the tabSheet. The second thing to be aware of is
you need to ensure the tabSheet is destroyed when the form is destroyed. The easiest way to do this is to have the form as the owner of the TabSheet, as in:
frmCustomers := TFrmCustomers.Create( Application );
tabSheet1 := TTabSheet.Create( frmCustomers ); // Note owner here
tabSheet1.Parent := frmMain.PageControl1;
tabSheet1.pageControl := frmMain.PageControl1;
frmCustomers.parent := tabSheet1;
Some developers like to use multiple individual forms which they display in tabSheets (as we showed here) instead of forms with multiple tabSheets. This way you can work on the forms independently.

Until next month!