
How it works...
The project is composed of a bunch of forms. The main form has TTabControl, which allows us to switch between the active forms. All embedded forms inherit from EmbeddableForm. The most important one is the Show method shown here:
procedure TEmbeddableForm.Show(AParent: TPanel); begin Parent := AParent; BorderStyle := bsNone; BorderIcons := []; Align := alClient; Show; end;
All the other forms descend from EmbeddableForm and are added to TTabControl on the main form, with a line of code similar to the following one:
procedure TMainForm.MenuOrdersClick(Sender: TObject); begin AddForm(TForm1.Create(self)); end;
The AddForm method is in charge of adding an actual instance of a form into the tabs, keeping a reference to it. The following code shows how it is done:
// Add a form to the stack procedure TMainForm.AddForm(AEmbeddableForm: TEmbeddableForm); begin AEmbeddableForm.Show(Panel1); // each tab show the caption of the containing form and // hold the reference to it TabControl1.Tabs.AddObject(
AEmbeddableForm.Caption, AEmbeddableForm); ResizeTabsWidth; ShowForm(AEmbeddableForm); end;
Other methods are in charge of bringing an already created form to the front when a user clicks on the Related tab, and then to close a form when the Related tab is removed (check out the ShowForm and WMEmbeddedFormClose methods).
There is a bit of code, but the concepts are simple:
- When we need to create a new form, we add it in the TabControl1.Tabs property. The caption of the form is the caption of the tab, and the object is the form itself. This is what the AddForm method does with the following line:
TabControl1.Tabs.AddObject(AEmbeddableForm.Caption, AEmbeddableForm);
- When a user clicks on a tab, we have to find the associated form by cycling through the TabControl1.Tabs.Objects list and bringing it to the front.
- When a form asks to be closed (sending a WM_EMBEDDED_CLOSE message), we have to set the ParentWantClose property and then call the Close method of the correspondent form.
- If the user wants to close a form by closing the corresponding tab (in the recipe code, there is TPopMenu connected to TabControl, which is used to close a form with a right-click), we have to call the Close method on the corresponding form.
- Every form frees itself in the OnClose event handler. This is done once for
all the forms in the TEmbeddableForm.CloseForm event handler, using the caFree action.