Title: Using MDI technology while TMDIForm is not the mainform of an application
Question: How to use MDI technology if you don't want to use TMDIForm as your mainform of the application?
You want to use TMDIForm that you open/create somewhere during runtime and is not the mainform of your application, but Delphi doesn't allow creating TMDIChild if the TMDIForm is not the mainform of your application.
Answer:
When I wanted to use TMDIForm that wasn't the mainform of the project and then create TMDIChild in that form, I got an error. Delphi didn't allow creation of TMDIChild as long as the mainform wasn't the TMDIForm. So I tweaked the FORMS.PAS a little bit.
1st. You have to add a global variable in Forms.PAS.
----- snip -----
interface
....
var uMDIForm : TForm;
implementation
...
----- snip -----
2nd. You have to change CreateWindowHandle and DestroyWindowHandle procedures a little bit.
Here are the code posts of the changed procedures.
----- snip -----
procedure TCustomForm.CreateWindowHandle(const Params: TCreateParams);
var
CreateStruct: TMDICreateStruct;
begin
if (FormStyle = fsMDIChild) and not (csDesigning in ComponentState) then
begin
(* add the check if the uMDIForm is set and if it is TMDIForm
if it is not, then raise an exception *)
if ((uMDIForm = nil) or (uMDIForm.ClientHandle = 0)) and
((Application.MainForm = nil) or (Application.MainForm.ClientHandle = 0)) then
raise EInvalidOperation.Create(SNoMDIForm);
with CreateStruct do
begin
szClass := Params.WinClassName;
szTitle := Params.Caption;
hOwner := HInstance;
X := Params.X;
Y := Params.Y;
cX := Params.Width;
cY := Params.Height;
style := Params.Style;
lParam := Longint(Params.Param);
end;
(* check if uMDIForm is set if not then use the MAINFORM of the application
as TMDIForm *)
if uMDIForm = nil then
WindowHandle := SendMessage(Application.MainForm.ClientHandle,
WM_MDICREATE, 0, Longint(@CreateStruct))
(* else use the form specified in uMDIForm *)
else
WindowHandle := SendMessage(uMDIForm.ClientHandle,
WM_MDICREATE, 0, Longint(@CreateStruct));
Include(FFormState, fsCreatedMDIChild);
end else
begin
inherited CreateWindowHandle(Params);
Exclude(FFormState, fsCreatedMDIChild);
end;
end;
procedure TCustomForm.DestroyWindowHandle;
begin
if fsCreatedMDIChild in FFormState then
begin
(* again check if uMDIForm is not set and if then destroy TMDIChild from
mainform *)
if uMDIForm=nil then
SendMessage(Application.MainForm.ClientHandle, WM_MDIDESTROY, Handle, 0)
else
(* else destroy the TMDIChild in uMDIForm *)
SendMessage(uMDIForm.ClientHandle, WM_MDIDESTROY, Handle, 0);
end else
inherited DestroyWindowHandle;
FClientHandle := 0;
end;
----- snip -----
Now before you create any TMDIChild forms you have to set uMDIForm variable to that form that you have set as TMDIForm.
Hope this is usefull to anyone.
If someone has any idea how this could be done by passing a new variable to TApplication or something similar, please contact me.