![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|||||||
| Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
|
Herramientas | Buscar en Tema | Desplegado |
|
#18
|
||||
|
||||
|
Vamos a intentar aclarar un poco las cosas.
El primer paso, aunque parezca un poco pesado, es que aprendas a utilizar la etiqueta [ code ] para escribir código en tus mensajes. Esta etiqueta te permite preservar las indentaciones en las líneas que escribes lo cual facilita muchísimo la lectura: Código:
if UsoEtiquetaCode then
LasLineasPreservanLaIndentacion;
{
Lo anterior fue escrito así:
[ code ]
if UsoEtiquetaCode then
LasLineasPreservanLaIndentacion;
[ /code ]
}
Ahora bien, hay que tener claras algunas cosas. En algún momento preguntaste por cómo llamar a un procedimiento que tiene un parámetro por referencia. Tu pregunta se originó por tu deseo de llamar desde la ventana padre al procedimiento para cerrar la ventana hija. Aquí hay una confusión de conceptos. El procedimiento para cerrar una ventana es Close mientras que OnCloseQuery es el evento que se genera cuando se intenta cerrar una ventana, sea cual sea el método con el que se cierre (procedimiento Close, hacer click en el cuadrito de la cruz, oprimir Alt-F4, etc.) Por regla general los eventos no deben llamarse explícitamente ya que no es esa su funcionalidad. Para entender esto conviene separar estos dos conceptos:
El evento lo genera "el sistema" y el manejador es el código que responde al evento. Tu parte como programador es escribir el manejador y dejar que el sistema genere el evento (es decir, que sea el sistema el que llame a tu manejador). Para concretizar pensemos en el evento en particular de CloseQuery: Cuando un usuario quiere cerrar una ventana (sea cual sea el método que utilice) el sistema (en este caso Windows) manda la señal WM_CLOSE a la ventana. Delphi intercepta esta señal y toma uno de dos caminos:
Con esto verás que es inútil que tú intentes llamar directamente al manejador ya que es Delphi y no tú quien puede aprovechar el valor de CanClose. Aplicando esto a tu problema específico: según me da la impresión tu intentas o intentabas usar el manejador OnCloseQuery de una ventana hija desde la ventana padre para controlar si el editor está o no modificado y en su caso presentar un mensaje. Pero esta no es labor de la ventana padre. Es la ventana hija (cada ventana hija) la encargada de determinar esto. Por eso tu código: Código:
with (ActiveMDIChild as TVentana_Hija) do
begin
if (RE_Editor.Modified) then
begin
Respuesta := Application.MessageBox('¿Desea guardar los cambios? ',
' Guardar',mb_IconWarning + mb_yesNoCancel);
Case Respuesta of
idYes:
begin
SD_Guardar_Fichero.Filename := Caption;
if (FileExists (SD_Guardar_Fichero.Filename)) then
begin
RE_Editor.Lines.SaveToFile(SD_Guardar_Fichero.Filename);
Close;
end
else
etc
Todo el código para determinar si el editor tiene cambios o no, presentar un mensaje, guardar en su caso los cambios, etc. es labor de la ventana hija que esté a punto de cerrarse. Todo esto debe ir en el manejador de CloseQuery. Piénsalo de esta forma: la ventana hija es un ente independiente de su padre. Es una ventana cuya función en la vida es permitir la edición de textos. Si el padre desaparece (por ejemplo si el día de mañana decides que tu aplicación sólo edite un archivo a la vez) la ventana hija sigue estando lista para hacer todo el trabajo relacionado con el archivo a editar. La labor del padre es controlar a las hijas independientemente de qué hagan estas hijas: podrías tener distintos tipos de ventanas hijas (editores, calculadoras, gráficos, etc.) y con tú método el padre tendría que ocuparse de todos los posibles casos lo que a todas luces es inconveniente. El control del padre radica, por ejemplo, en acomodar a las ventanas dentro de su área, mantener una lista de las ventanas abiertas, etc. También se puede encargar de mandar comandos a las ventanas pero dejar que ellas hagan su trabajo. Así por ejemplo, cuando en Word el usuario oprime el botón de guardar, la ventana padre manda llamar al procedimiento Guardar de la ventana activa (ActiveMdiChild) pero nada más; es ésta ventana activa la que se encarga de preguntar al usuario el nombre del archivo, etc. Si el usuario usa el menú Archivo|Cerrar, la ventana padre se limita a llamar a algún procedimiento de la ventana hija activa del estilo de Close y es ésta última quien se encarga de todo lo demás. Otro punto de vista para aclarar: ¿Qué pasa cuando el usuario desea apagar la PC? Puedes considerar a Windows como la ventana padre. Como tal, él se encarga de llamar al procedimiento Close de cada ventana abierta pero estarás de acuerdo que es cada una de éstas, y no Windows, quien hace el trabajo de limpieza (guardar, advertir de cambios, etc.) Así pues, si deseas que la ventana padre cierre a una hija limítate a llamar al método Close de la hija y deja que ésta haga todo (bueno, tú pero a través de ella). Yo sé que todo esto es un rollazo pero espero que te sirva para entender que en ocasiones tenemos muchos problemas con el código por la "simple" razón de que estamos enfocando mal el problema. El resumen aquí podría ser: Si quieres hacer un editor de textos mdi piensa primero en el problema más sencillo de cómo hacer un editor de una sóla ventana. Programas esta ventana, te peleas con todos los problemas que salgan, etc. Una vez que lo dominas, le pones a la ventana la propiedad MdiChild y la insertas en un proyecto Mdi. Todo, absolutamente todo (te lo aseguro) será mucho más sencillo. // Saludos |
|
|
|