2011-07-27 41 views
6

Tengo un formulario principal (MainForm) y una ventana secundaria MDI (TFormChild). Quiero crear múltiples formularios TFormChild, pero el primero debe comportarse de cierta manera, así que necesito detectar si ya existe una ventana TFormChild.¿Cómo comprobar si existe una ventana hija?

Puedo usar este código, pero que no está funcionando:

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

me llaman así:

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

¿Por qué estás probando '> 0'? Seguramente la lógica correcta es '<> 0'. No es que ese sea tu problema, solo un lado. –

+0

@David, a partir de Delphi 4, con la introducción de un tipo entero sin signo de 32 bits, los identificadores en Delphi no están firmados, por lo que técnicamente no hace diferencia. –

+2

@Rob Sé que no importa el comportamiento, pero lógicamente es muy diferente. '> 0' implica que el orden es importante. '<> 0' indica que' 0' es un valor centinela. –

Respuesta

7

llamar así

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

ventanas secundarias MDI son hijos de la 'MDICLIENT', ClientHandle propiedad de TCustomFrom sujeta el mango.

+0

Acepté su respuesta porque responde mi pregunta específicamente. Sin embargo, también quiero darle crédito a Hasan ya que usaré su solución más similar a Delphi. – Ampere

+2

@Altar - Usted formuló una pregunta clara que tanto esta como la respuesta de Hasan proporcionan una solución. Puede aceptar el que más le convenga. Estoy de acuerdo con el voto que ha emitido sobre esta respuesta. :) –

13

En una forma, puede hacer referencia a las propiedades MDIChildCount y MDIChildren.

por ejemplo:

var 
    i: integer; 
begin 
    for i:= 0 to MainForm.MDIChildCount-1 do 
    begin 
    if MainForm.MDIChildren[i] is TFormChild then 
    ... 
    end; 
    ... 
end; 
+0

+1; pero no es suficiente para comprobar 'if MainForm.MDIChildCount> 0 then' si OP quiere esperar la creación del primer formulario? –

+0

@daemon_x puede haber hijos MDI de una clase diferente –

+0

@David - Recibí la oración 'Quiero crear múltiples formularios TFormChild, pero el primero debe comportarse de cierta manera, así que necesito detectar si ya existe una ventana TFormChild 'como OP está creando solo ventanas TFormChild y quiere verificar si se ha creado el primero, pero quién sabe ... –

3

La mejor manera de lograr esto es hacer que la forma que desea abrir se compruebe realmente para ver si ya existe. Para hacerlo, tu formulario debe declarar un procedimiento de clase. Declarado como un procedimiento de clase, el proceso puede invocarse independientemente de si el formulario existe o no.

Añadir a la sección pública de su forma

class procedure OpenCheck; 

entonces el procedimiento se parece a esto

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; 

Añadir unidad de Form1 a la cláusula usos de su mdiframe.

Para abrir el formulario, llame al procedimiento de su clase, que a su vez llamará al constructor del formulario.

TForm1.OpenCheck; 

Una palabra de advertencia usando procedimientos de la clase, no tienen acceso a cualquiera de los componentes/propiedades de la forma. Dado que el formulario en realidad no tiene que ser instanciado, acceder a ellos produciría una violación de acceso/eso es hasta que sepa que F no es nulo. Luego puede usar F. para acceder a los componentes/propiedades del formulario.