hola, tengo un form MDI el cual tiene varios childs, lo que quiero es detectar el evento onMin. y onRes. de los childs pero no me sale, hay un componente que se llama AppEvents el cual me permite trabajar con estos eventos pero lo hace con el form main, lo que yo quiero es agregarle ese evento a cada uno de mis forms hijos. ¿alguien me hecha una mano?
saludos!
onMinimize & onRestore
Comenzado por
look
, ago 27 2010 09:30
7 respuestas en este tema
#1
Escrito 27 agosto 2010 - 09:30
#2
Escrito 28 agosto 2010 - 11:18
He decidido crear un minitutorial para novatos de como hacer que nuestra aplicación MDI funcione bien, haciendo uso de la Herencia.
He agregado una "chapuza" (debidamente comentada) para lograr lo que el amigo Look quiere, esta se implementa haciendo una triangulación creando una Unit de nombre UGlobal que servira de pivot (para evitar las referencias circulares entre el Form principal y los hijos) en donde declaramos 2 variables de tipo string (Aform y Accion) que recogerán los eventos de los Forms hijos, para luego transmitirlos a 2 TEdits del form principal.
Iniciamos creando nuestro form Principal al cual como es obvio configuramos su propiedad FormStyle a fsMDIForm, a este agregamos un TActionList, al que a su vez agreamos las acciones standar de la categoría Window, que son las que nos van a ayudar a manejar las ventanas MDI. Luego agregamos al form principal un TMainMenu, en este agregamos un MenuItem cuyo Caption sea "Ventana" y su nombre miVentana , debajo de ventana agregamos tantos MenuItems como Acciones de la categoría Window del TActionList hayan, a cada MenuItem creado le vamos asignando en su propiedad Action cada una de las acciones del TActionList.
Posteriormente a la propiedad WindowMenu del Form principal asignamos miVentana (creado anteriormente).
Próximo post : Crear un form que sirva de base para todos los Forms hijos.
PD: En el proximo post agregaré el código fuente del ejemplo.
He agregado una "chapuza" (debidamente comentada) para lograr lo que el amigo Look quiere, esta se implementa haciendo una triangulación creando una Unit de nombre UGlobal que servira de pivot (para evitar las referencias circulares entre el Form principal y los hijos) en donde declaramos 2 variables de tipo string (Aform y Accion) que recogerán los eventos de los Forms hijos, para luego transmitirlos a 2 TEdits del form principal.
delphi
unit UGlobal; interface procedure Informar; var Aform, Accion :String; implementation uses UPpal; procedure Informar ; begin Ppal.edAccion.Text := Accion; PPal.edForm.Text := Aform; end; end.
Iniciamos creando nuestro form Principal al cual como es obvio configuramos su propiedad FormStyle a fsMDIForm, a este agregamos un TActionList, al que a su vez agreamos las acciones standar de la categoría Window, que son las que nos van a ayudar a manejar las ventanas MDI. Luego agregamos al form principal un TMainMenu, en este agregamos un MenuItem cuyo Caption sea "Ventana" y su nombre miVentana , debajo de ventana agregamos tantos MenuItems como Acciones de la categoría Window del TActionList hayan, a cada MenuItem creado le vamos asignando en su propiedad Action cada una de las acciones del TActionList.
Posteriormente a la propiedad WindowMenu del Form principal asignamos miVentana (creado anteriormente).
Próximo post : Crear un form que sirva de base para todos los Forms hijos.
PD: En el proximo post agregaré el código fuente del ejemplo.
#3
Escrito 28 agosto 2010 - 11:34
Para esto creamos un nuevo formulario en nuestro proyecto al cual le daremos por nombre Padre y su respectiva Unit UPadre.
En la sección public de nuestro form vamos a agregar dos métodos de clase en este caso dos funciones, una de nombre Instancia que devuelve un form de la clase TPadre (que es la que estamos trabajando), esta función nos ayudará a saber si ya hay creada una Instancia de un determinado Formulario hijo. La segunda función tiene el nombre Mostrar y también devuelve un TPadre, pero además comprueba si existe un específico form hijo, en caso de existir lo activa y lo trae al frente de lo contrario lo crea y obviamente lo muestra.
Configuramos su propiedad FormStyle a fsMDIChild y en su evento OnClose colocamos (Action := caFree).
Las otras acciones que hay en Onclose, OnResize y OnCreate, son solo para cumplir los requerimientos (chapuza) del amigo Look y no hacen parte de lo fundamental para este tipo de aplicación.
En la sección public de nuestro form vamos a agregar dos métodos de clase en este caso dos funciones, una de nombre Instancia que devuelve un form de la clase TPadre (que es la que estamos trabajando), esta función nos ayudará a saber si ya hay creada una Instancia de un determinado Formulario hijo. La segunda función tiene el nombre Mostrar y también devuelve un TPadre, pero además comprueba si existe un específico form hijo, en caso de existir lo activa y lo trae al frente de lo contrario lo crea y obviamente lo muestra.
Configuramos su propiedad FormStyle a fsMDIChild y en su evento OnClose colocamos (Action := caFree).
Las otras acciones que hay en Onclose, OnResize y OnCreate, son solo para cumplir los requerimientos (chapuza) del amigo Look y no hacen parte de lo fundamental para este tipo de aplicación.
delphi
unit UPadre; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs; type TPadre = class(TForm) procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormResize(Sender: TObject); private public class function Instancia: TPadre; class function Mostrar: TPadre; { Public declarations } end; implementation uses UGlobal; //Chapuza {$R *.dfm} { TPadre } class function TPadre.Instancia: TPadre; { Esta función nos ayuda a comprobar si un form específico de la clase TPadre está abierto } var I: Integer; begin for I := Screen.FormCount - 1 downto 0 do begin TForm(Result) := Screen.Forms[I]; if Result.ClassType = Self then Exit; end; Result := nil; end; class function TPadre.Mostrar: TPadre; { Esta función nos devuelve un form de la clase TPadre, si es necesario crea una instancia, luego comprueba su propiedad WindowsState para finalmente traerlo al frente } begin Result := Instancia; LockWindowUpdate(Application.MainForm.ClientHandle); // Evita un molesto efecto // a la hora de mostrarlo ante todo en WinXP try if Assigned(Result) then // Comprueba si existe una instancia begin if Result.WindowState = wsMinimized then ShowWindow(Result.Handle, SW_RESTORE); Result.BringToFront; // lo trae al frente end else begin Result := Create(Application.MainForm); // Crea una instancia(sinó existe) Result.Show; end; finally LockWindowUpdate(0); end; end; procedure TPadre.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; //Inicio de chapuza Aform := Self.Name; Accion := 'Cerrado'; Informar; //Fin de chapuza end; procedure TPadre.FormCreate(Sender: TObject); begin //Inicio de chapuza Aform := Self.Name; Accion := 'Creado'; Informar; //Fin de chapuza end; procedure TPadre.FormResize(Sender: TObject); begin //Inicio de chapuza Self.UpdateWindowState; Aform := Self.Name; if Self.WindowState = wsMinimized then Accion := 'Minimizado' else Accion := 'Restaurado'; Informar //Fin de chapuza end; end.
#4
Escrito 28 agosto 2010 - 11:50
Ahora ya podemos empezar a crear cuantos descendinetes de TPadre necesitemos, para esto hacemos lo siguiente:
En D7 vamos a Flie > New > Other > (Buscamos el Tab con el nombre de nuestro proyecto) entonces hacemos dobleclick en Padre.
En D2010 Flie > New > Other > Inheritable Items > entonces hacemos dobleclick en Padre.
Nuestros nuevos forms serán del tipo TPadre y heredarán todas sus propiedades y métodos.
Podemos remover la parte de la interface que dice var Padre1: TPadre1; como también debemos quitarlo de la creación automática de forms: Project > Options > Forms
Próximo Post : Llamando a los descendientes de TPadre y código completo del ejemplo.
En D7 vamos a Flie > New > Other > (Buscamos el Tab con el nombre de nuestro proyecto) entonces hacemos dobleclick en Padre.
En D2010 Flie > New > Other > Inheritable Items > entonces hacemos dobleclick en Padre.
Nuestros nuevos forms serán del tipo TPadre y heredarán todas sus propiedades y métodos.
Podemos remover la parte de la interface que dice var Padre1: TPadre1; como también debemos quitarlo de la creación automática de forms: Project > Options > Forms
Próximo Post : Llamando a los descendientes de TPadre y código completo del ejemplo.
#5
Escrito 28 agosto 2010 - 12:04
Para esto en la clusula uses de la implementación de nuestro form principal agregamos las Units de los forms hijos que hayamos creado, agregamos los botones correspondientes y entonces; para llamar a un Form descendiente de TPadre de nombre Hijo1 entoneces solo tecleamos en el evento OnClick del botón:
THijo1.Mostrar y así con todos los demás, al cerrarlos ellos se librerarán autoáticamente puesto que en en el evento OnClose de su Padre ya previamente definimos action := caFree.
Lo siguiente es solo para Look:
Finalmente en el evento OnChange del TEdit edForm podrías manejar lo que necesites, porque es allí en donde se capturan los eventos OnResize de todos los hijos, por ejemplo:
THijo1.Mostrar y así con todos los demás, al cerrarlos ellos se librerarán autoáticamente puesto que en en el evento OnClose de su Padre ya previamente definimos action := caFree.
delphi
unit UPpal; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, ExtCtrls, StdActns, ActnList; type TPpal = class(TForm) MainMenu: TMainMenu; miVentana: TMenuItem; miArchivo: TMenuItem; MiCerrar: TMenuItem; ActionList: TActionList; WindowClose: TWindowClose; WindowCascade: TWindowCascade; miCascade: TMenuItem; MiClose: TMenuItem; Panel1: TPanel; bnHijo1: TButton; bnOtroHijo: TButton; Label1: TLabel; edForm: TEdit; edAccion: TEdit; procedure MiCerrarClick(Sender: TObject); procedure bnHijo1Click(Sender: TObject); procedure bnOtroHijoClick(Sender: TObject); procedure edFormChange(Sender: TObject); private { Private declarations } public { Public declarations } end; var Ppal: TPpal; implementation uses UHijo1, UOtroHijo; {$R *.dfm} procedure TPpal.MiCerrarClick(Sender: TObject); begin Close; end; procedure TPpal.bnHijo1Click(Sender: TObject); begin THijo1.Mostrar; end; procedure TPpal.bnOtroHijoClick(Sender: TObject); begin TOtroHijo.Mostrar; end; procedure TPpal.edFormChange(Sender: TObject); begin //Lo que quieras end; end.
Lo siguiente es solo para Look:
Finalmente en el evento OnChange del TEdit edForm podrías manejar lo que necesites, porque es allí en donde se capturan los eventos OnResize de todos los hijos, por ejemplo:
delphi
if (edForm.Text = 'Hijo1') and (edAccion.Text = 'Minimizado') then //HacerCosas
Archivos adjuntos
#6
Escrito 28 agosto 2010 - 12:07
Muchas gracias Wilson, excelente explicación
Salud OS
Salud OS
#7
Escrito 28 agosto 2010 - 01:19
Este tutorial me viene muy bien.
¡Muchas gracias Wilson!
Un saludo
¡Muchas gracias Wilson!
Un saludo
#8
Escrito 30 agosto 2010 - 12:23
hola, muchas gracias compañero!....
saludos!
saludos!