Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a child window exists?

Tags:

delphi

I have a main form (MainForm) and a MDI child window (TFormChild). I want to create multiple TFormChild forms, but the first one must behave in a certain way so I need to detect if a TFormChild window already exists.

I use this code but it is not working:

function FindChildWindowByClass(CONST aParent: HWnd; CONST aClass: string): THandle;   
begin
  Result:= FindWindowEx(aParent, 0, PChar(aClass), NIL);
end;

I call it like this:

Found:= FindChildWindowByClass(MainForm.Handle, 'TFormChild')> 0;   
like image 957
Server Overflow Avatar asked Jul 27 '11 13:07

Server Overflow


3 Answers

In a form, you can refer to the MDIChildCount and MDIChildren properties.

for example :

var
  i: integer;
begin
  for i:= 0 to MainForm.MDIChildCount-1 do
  begin
    if MainForm.MDIChildren[i] is TFormChild  then
    ...
  end;
  ...
end;
like image 74
Hasan S Avatar answered Oct 19 '22 17:10

Hasan S


Call it like

Found:= FindChildWindowByClass(MainForm.ClientHandle, 'TFormChild')> 0;  

MDI child windows are children of the 'MDICLIENT', ClientHandle property of TCustomFrom holds the handle.

like image 44
Sertac Akyuz Avatar answered Oct 19 '22 18:10

Sertac Akyuz


The best way to accomplish this is to have the form you want to open actually check to see if it already exists. To do so your, form must declare a class procedure. Declared as a class procedure, the proc can be called regardless of whether the form exists or not.

Add to your form's public section

class procedure OpenCheck;

then the procedure looks like this

Class procedure TForm1.OpenCheck;
var
f: TForm1;
N: Integer;
begin
   F := Nil;
   With Application.MainForm do
   begin
      For N := 0 to MDIChildCount - 1 do
      begin
         If MDIChildren[N] is TForm1 then
            F := MDIChildren[N] as TForm1;
      end;
   end;
   if F = Nil then //we know the form doesn't exist
      //open the form as the 1st instance/add a new constructor to open as 1st
   else
      //open form as subsequent instance/add new constructor to open as subsqt instance
end;

Add Form1's unit to your mdiframe's uses clause.

To open the form, call your class procedure, which in turn will call the form's constructor.

TForm1.OpenCheck;

One word of warning using class procedures, do not access any of the components/properties of the form. Since the form does not actually have to be instantiated, accessing them would produce an access violation/that is until you know F is not nil. Then you can use F. to access form components/properties.

like image 24
A Lombardo Avatar answered Oct 19 '22 19:10

A Lombardo