Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-01-2004
wallesis wallesis is offline
Miembro
 
Registrado: dic 2004
Posts: 25
Poder: 0
wallesis Va por buen camino
Hola.
Es un documento de Word con texto y imagenes en jpg. Su tamaño es de 365 Kb (comprimido) y cuando intento subirlo me pone este mensaje:

MDI.zip:
File Too Large. Limit for this filetype is 1,0 KB. Your file is 364,4 KB.

Tambien he intentado subirlo sin comprimir y por su puesto su respuesta fue la misma.
Responder Con Cita
  #2  
Antiguo 16-01-2004
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
la verdad es qie me dejas dsconcertado, necesitariamos ayuda de uno de los moderadores o alguien que sepa por que si el limite es 1kb es algo pequeño
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #3  
Antiguo 16-01-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Estás utilizando las variables globales que se crean por defecto con los formularios. Pero por la forma en que creas dinamicamente los formularios MDI hijos, no debes inicializar esas variables.

Cuando creas un formulario :

TVentana_Hija.Create(Application); // Supongo que harás esto o algo parecido

Cámbialo para asignar también la variable global :

Ventana_Hija := TVentana_Hija.Create(Application);

Aunque te puedes encontrar con varios problemas.
  • Puede ser el formulario Ventana_Hija aún no se haya creado, o bien que si se haya creado en su momento pero ya ha sido cerrado. En ambos casos la variable Ventana_Hija no puede apuntar a ninguna parte, y obtendrás un error.
Solución : Antes de usar la variable Ventana_Hija, comprueba que tiene algún valor.

if Assigned(Ventana_Hija) then Ventana_Hija.Componente.Caption := 'Hola';

Aunque esto solo sirve, para detectar que un formulario aún no ha sido creado. Para detectar si un formulario creado anteriormente ha sido cerrado, cuando cierras el formulario (por el ejemplo en el evento OnDestroy) debes poner asignar la variable a Nil. (Sinó lo haces, sigue teniendo la dirección del formulario anterior, que ya no es válida)
  • Puedes tener dos formularios de la clase TVentana_Hija, de forma que la variable Ventana_Hija siempre apuntará al último creado (el último que ha puesto su dirección en la variable global).
Solución : No utilizes esas variables globales (yo es lo primero que borro al crear un formulario). En lugar de ello, intenta utilizar variables locales que apunten siempre al formulario que quieres modificar :

Ejplo. :

Código:
proc LoQueSea;
var Ventana_Hija: TVentana_Hija;
begin
   Ventana_Hija := TVentana_Hija.Create(Application);
   // Hacemos otras cosas
   Ventana_Hija.MiComponente.Caption := Hola;
end;
O bien utiliza la colección MDIChildren del formulario principal.

Código:
for i := 1 to Application.MainForm.MDIChildCount do begin
  if Application.MainForm.MDIChildren[i] is TVentana_Hija then begin
	(Application.MainForm.MDIChildren[i] As TVentana_Hija).Componente.Caption := Hola;
  end;
end;
Por cierto, no te recomiendo acceder directamente a los componentes de un formulario, desde otro. Soy de la opinión que los componentes del formulario deberían ser protected es decir, no verse desde otros formularios. De esta forma ganas modularidad.

Seria mejor declarar un método public en el formulario, que sea el que accede al componente, y desde los otros formularios unicamente llamamos al método.

O sea, en la sección public del formulario declaras :

procedure CambiarTitulo(Mensaje: String);

y en la sección implementation, lo defines como :

Código:
procedure TVentana_Hija.CambiarTitulo(Mensaje: String);
begin
  Componente.Caption := Mensaje;
end;
Ahora cuando desde otro formulario, quieres cambiar el Caption de ese formulario, lo que haces es llamar al método correspondiente :

Ventana_Hija.CambiarTitulo('Hola');

Espero que te sea de utilidad.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #4  
Antiguo 16-01-2004
wallesis wallesis is offline
Miembro
 
Registrado: dic 2004
Posts: 25
Poder: 0
wallesis Va por buen camino
Hola.
A ver si puedo explicarlo un poco mejor.

Para empezar quiero decir que las unidades están colocadas bien y en ambos códigos:

Estos son los procedimientos para crear las ventanas hijas (por cierto se trata de un editor), en concreto los procedimientos Nuevo, Abrir y uno privado.

procedure TPrincipal.Crear_Ventana(Nombre: String; Modificado: Boolean);
var
ventana: TVentana_Hija;
begin

ventana := TVentana_Hija.Create(Self);
ventana.Caption := Nombre ;
SB_Barra.Panels[1].Text := ventana.Caption;
ventana.Show;

end;

procedure TPrincipal.Nueva_VentanaExecute(Sender: TObject);
begin
Crear_Ventana('Sin título '+ inttostr(MDIChildCount+1), False);

TB_Alin_IzquClick(nil);//Para comenzar con la alineacion a la izquierda
// en cada ventana.
end;

procedure TPrincipal.Abrir_FicheroExecute(Sender: TObject);
begin
if (OD_Abrir_Fichero.Execute) then
if (FileExists(OD_Abrir_Fichero.FileName)) then
begin
Crear_Ventana(OD_Abrir_Fichero.FileName, False);
With ActiveMDIChild as TVentana_Hija do
begin
RE_Editor.Lines.LoadFromFile(OD_Abrir_Fichero.FileName);
RE_Editor.Modified := False;
end;
end;
end;

Resumiendo un poco. Hay dos cosa que no me salen bien:
1.- No se o no puedo llamar a un objeto ubicado en la ventana hija desde el código de la ventana principal (codigo_Principal) , sin utilizar la sentencia
with (ActiveMDIChild as Tventana_Hija) do
Por ejemplo. En el procedimiento abrir, que he puesto antes, si yo quito la sentencia With ActiveMDIChild as TVentana_Hija do y coloco:

...............
begin
Ventana_Hija.RE_Editor.Lines.LoadFromFile(OD_Abrir_Fichero.FileName);
Ventana_Hija.RE_Editor.Modified := False;
end;


Esto me compila bien pero da un error en ejecución

¿Por que al anular la sentencia with (ActiveMDIChild as Tventana_Hija) do e incluir el nombre de la ventana hija (que se llama también Ventana_Hija) delante del componente RE_Editor, no me funciona y me da el error en tiempo de ejecución que veis en la imagen?
Este mismo sistema aplicado al reves si que funciona. Es decir desde el codigo de la ventana hija llamar o utilizar a un componente de la ventana padre. Simplemente hago lo mismo coloco Ventana_Principal.Componente....


2.-Segundo problema. No se como llamar a los procedimientos que incluyen parámetros por referencia, desde ambos códigos.
Por ejemplo:
Yo quiero llamar desde el código de la ventana padre (que lo he llamado codigo_Principal) a un procedimiento ubicado en el código de la ventana hija (Codigo_Hija), por ejemplo el de cerrar las ventanas.
Este sería el código de cerrar ventanas que estaría ubicado en el código de la ventana hija:

procedure TVentana_Hija.FormCloseQuery(Sender: TObject;var CanClose: Boolean);
begin
......
end;

Y yo lo que quiero es llamarlo desde el código de la ventana padre.Yo he intentado llamarlo de esta forma, que me imagino que sea incorrecto:
Ventana_Hija.FormCloseQuery(nil; var CanClose);

Y estos son los errores en la compilación:
“ Not enough actual parameters”
Es decir, que no lo he puesto bien....


Estos son las dos cosas que no se hacer. Perdonar todo este rollo que os he metido, creo que no me olvido de nada. Muchas gracias por vuestra ayuda.
Salu2
Responder Con Cita
  #5  
Antiguo 16-01-2004
Avatar de eduarcol
[eduarcol] eduarcol is offline
Miembro Premium
 
Registrado: ago 2003
Ubicación: En los estados Zulia y Merida de Venezuela
Posts: 4.151
Poder: 25
eduarcol Va por buen camino
Mira lo que pude observar es qe tienes una pequeña confusion, te explico cuando haces with ActiceMdiChild as TVentana_Hija estas haciendo un type cast de la clase TVentanaHija, pero cuando haces Ventana_Hija.Caption te da el error debido a que la variable Ventana_Hija no ha sido incializado porq en el procedimiento creas una variable denominada Ventana no ventana_Hija, alli esta tu primer problema...

lo segundo es que para pasar una variable por referencia no se lo indicas al momento de Llamarla solo cuando la defines por ejemplo
esta bien hecho cuando lo defines
procedure TVentana_Hija.FormCloseQuery(Sender: TObject;var CanClose: Boolean);
begin
......
end

pero cuando lo llames no le digas

Ventana_Hija.FormCloseQuery(nil; var CanClose);

dile Ventana_Hija.FormCloseQuery(nil; CanClose);

asumiendo que canclose es una variable que tienes definida
y no estoy seguro pero creo que tienes que pasarle tambien el form que estas cerrando y no un puntero nil
__________________
...Yo naci en esta ribera del arauca vibr@d0r
Soy hermano de la espuma,
de la garza, de la rosa y del sol...
Viva Venezuela
Responder Con Cita
  #6  
Antiguo 16-01-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Veamos el primer problema.

El error está, como he comentado en el mensaje anterior, en la variable que utilizas para referenciar el formulario.

Durante la creación que haces del formulario :

Código:
procedure TPrincipal.Crear_Ventana(Nombre: String; Modificado: Boolean);
var
ventana: TVentana_Hija;
begin

ventana := TVentana_Hija.Create(Self);
ventana.Caption := Nombre ;
SB_Barra.Panels[1].Text := ventana.Caption;
ventana.Show;

end;
Estás accediendo al formulario (El Caption del Formulario), y funciona bien ¿ verdad ?.

Si aquí mismo hicieras :

Código:
Ventana.RE_Editor.Lines.LoadFromFile(OD_Abrir_Fichero.FileName);
Ventana.RE_Editor.Modified := False;
Funcionaria correctamente. Esto es porqué referencias al formulario mediante una variable local, como propongo al final de mi mensaje.

En cambio, en tu código, una vez creado el formulario, finaliza el procedimiento y desaparece la variable Ventana con que lo has referenciado. Cuando quieres volver a acceder a ella, utilizas la variable Ventana_Hija, cosa que el compilador accepta puesto que es del tipo adecuado, pero como no está inicializada con ningún valor, da un error en ejecución al usarla.

Para solucionarlo, una posiblidad es poner todo el código en un solo procedimiento que mantenga una referencia Ventana válida :

Código:
procedure TPrincipal.Abrir_FicheroExecute(Sender: TObject);
var Ventana: TVentana_Hija;
begin
  if not OD_Abrir_Fichero.Execute then Exit;
  if not FileExists(OD_Abrir_Fichero.FileName) then Exit;

  ventana := TVentana_Hija.Create(Self);
  ventana.Caption := OD_Abrir_Fichero.FileName;
  SB_Barra.Panels[1].Text := OD_Abrir_Fichero.FileName;

  Ventana.RE_Editor.Lines.LoadFromFile(OD_Abrir_Fichero.FileName);
  Ventana.RE_Editor.Modified := False;
end;
En todo caso, creo que es conveniente que te leas todo mi mensaje anterior, puesto que hay más casos comentados.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #7  
Antiguo 16-01-2004
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Veamos ahora el segundo problema :

Como han comentado, no hace falta que uses la directiva var al pasar por referencia un parámetro. Esa directiva solo se pone en la definición del parámetro, pero en el momento de llamar a la función, en el parámetro tienes que poner una variable (como podrías hacer perfectamente en una parámetro pasado por valor).

Tienes que poner una variable porqué, una vez ejecutado el procedimiento, si se ha modificado el valor, solo tienes que leer el contenido de la variable para conocer el valor modificado.

Así pues, la llamada te quedaría :

Código:
var PuedeCerrar: boolean;
begin
  PuedeCerrar := True;
  Ventana.FormCloseQuery(Ventana; PuedeCerrar);
end;
Como puedes ver, tienes que referenciar el formulario con una variable que apunte a él. (Al igual que pasaba con los componentes, sinó tendrías el mismo problema al intentar ejecutar el procedimiento).

Como comenté en el primer mensaje, no es nada aconsejable programar de esta forma, accediendo directamente a componentes y llamando a eventos de otros formularios. Esto te complica mucho el mantenimiento del programa, hacer modificaciones, ver donde falla, etc .... Seria mucho mejor que todo lo que quieras hacer sobre un formulario, lo pongas en unos métodos públicos que sean lo único a lo que se accede desde fuera del formulario.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #8  
Antiguo 20-01-2004
wallesis wallesis is offline
Miembro
 
Registrado: dic 2004
Posts: 25
Poder: 0
wallesis Va por buen camino
Entiendo muy bien lo de las variables locales y globales y como puedo haceder a un formulario desde el mismo codigo.
Guillotmarc escribio:
Code:
procedure TPrincipal.Abrir_FicheroExecute(Sender: TObject);
var Ventana: TVentana_Hija;
begin
if not OD_Abrir_Fichero.Execute then Exit;
if not FileExists(OD_Abrir_Fichero.FileName) then Exit;

ventana := TVentana_Hija.Create(Self);
ventana.Caption := OD_Abrir_Fichero.FileName;
SB_Barra.Panels[1].Text := OD_Abrir_Fichero.FileName;

Ventana.RE_Editor.Lines.LoadFromFile(OD_Abrir_Fichero.FileName);
Ventana.RE_Editor.Modified := False;
end;

Pero que pasa cuando quieres haceder a cualquier formulario, ya creado,para poder hacer cosas en el. Porque en el ejemplo anterior lo que hacemos es crear un formulario nuevo y a la vez aprobechamos para actualizarle.
Tambien dices que no recomiendas acceder a otros formularios desde otros. Pero es imposible, por ejemplo:
En este editor de texto dispongo de una barra de herramientas y un menú, que están ubicados en la ventana padre o principal. El principal componente de este programa lógicamente es un editor de típo TrichEditor y este componente está en la ventana hija. Cuando yo pulso el botón cerrar ventanas que está ubicado en la ventana principal o padre, me estoy refiriendo o deseo referirme a una ventana hija, que pertenece a otro formulario.
Mi problema en concreto es en la parte de cerrar ventanas.En el formulario de la ventana hija he utilizado el evento:
procedure TVentana_Hija.FormCloseQuery(Sender: TObject;var CanClose: Boolean);
Y lo he codificado tal y como me sugieres pero me da error en la ejecución.
Pero tambien en la ventana padre, en la barra de herramientas, he incluido un boton para cerrar ventanas y lo que yo pretendia es desde el procedimiento de ese boton(codigo padre) hacer una llamada al procedimiento anteriormente citado de cerrar ventanas, situado en el formulario de la ventana hija.
He realizado lo de poner el procedimiento en la sección public y he conseguido ejecutar el programa pero no ejecuta bien el procedimineto ya que no cierra ventanas.
Tal vez una solucción sería hacer codigos independientes para cada botón?
De todas formas voy a seguir estudiando el tema y ya os contaré.
Salu2
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 20:18:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi