![]() |
![]() |
| Paypal | FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
|
|
#1
|
||||
|
||||
|
Cita:
Algo aí:
__________________
Germán Estévez => Web/Blog Guía de estilo, Guía alternativa Utiliza TAG's en tus mensajes. Contactar con el Clubdelphi ![]() P.D: Más tiempo dedicado a la pregunta=Mejores respuestas. |
|
#2
|
||||
|
||||
|
Muchas gracias colegas por sus comentarios.. me han sido de gran ayuda y me han dado una idea mas clara.
Pues bien, antes de tratar de que mi rutina quede como la necesito, decidí hacer un componente con el que cual he probado todo lo aqui explicado. Y el ejemplo trata solamente de enviar el mensaje de advertencia para que el usuario decida si desea cerrar el form. Les comento que el objetivo se ha conseguido... ejecutar el codigo del componente y también el código que se asigna en modo diseño del form. El codigo del componente envia el mensaje de advertencia y el codigo del evento OnCloseQuery del form envia un simple mensaje. Aqui les dejo el código...claro que es sencillo, pero ilustra el objetivo y puede servir como referencia si alguien necesita algo similar. Nota: Al final explico el único detalle que se me presenta Esta es declaración de la clase Código:
//---------------------------------------------------------------------------
#ifndef CloseQueryH
#define CloseQueryH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class PACKAGE TCloseQuery : public TComponent
{
private:
TForm *FForm;
TCloseQueryEvent FOldCloseQuery;
protected:
virtual void __fastcall MiCloseQuery(TObject *Sender, bool &CanClose);
DYNAMIC void __fastcall ValidateContainer(TComponent *AComponent);
void __fastcall Loaded();
public:
__fastcall TCloseQuery(TComponent* Owner);
__published:
};
//---------------------------------------------------------------------------
#endif
Código:
//---------------------------------------------------------------------------
#include <basepch.h>
#pragma hdrstop
#include "CloseQuery.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TCloseQuery *)
{
new TCloseQuery(NULL);
}
//---------------------------------------------------------------------------
__fastcall TCloseQuery::TCloseQuery(TComponent* Owner)
: TComponent(Owner)
{
/* Si el Owner hereda da un clase tipo TForm
asignamos la referencia al formulario (aunque tal vez
no seria necesario verificar ya que existe la función que
válida el tipo de contenedor, que en este caso debe ser un form) */
if ( Owner->InheritsFrom(__classid(TForm)) )
FForm = (TForm*)Owner;
}
//---------------------------------------------------------------------------
namespace Closequery
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TCloseQuery)};
RegisterComponents("Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
/* Nuestro evento CloseQuery */
void __fastcall TCloseQuery::MiCloseQuery(TObject *Sender, bool &CanClose)
{
/* Se si a asignado un evento en modo de diseño del form
este debe ejecutarse */
if ( FOldCloseQuery != NULL)
FOldCloseQuery(FForm, CanClose);
if ( Application->MessageBoxA("¿Desea salir?",
"Confirme", MB_ICONQUESTION | MB_YESNO ) != IDYES )
CanClose = false;
}
/* Se valida el contender del componente */
void __fastcall TCloseQuery::ValidateContainer(TComponent *AComponent)
{
if ( ! AComponent->InheritsFrom(__classid(TForm)) )
throw Exception("Este componente sólo puede insertarse en un formulario");
}
/*
La VCL llama al método Loaded cuando ha terminado de leer el dfm
del formulario. Entonces podemos estar seguros de que ya se dispone
del evento CloseQuery asignado en el diseño. Esto no podría asegurarse
en el constructor. (Texto extraido de la constestación de roman. Gracias)
*/
void __fastcall TCloseQuery::Loaded()
{
//TComponent::Loaded();
if ( FForm != NULL )
{
FOldCloseQuery = FForm->OnCloseQuery;
FForm->OnCloseQuery = MiCloseQuery;
}
}
Basta con volver a hacer doble click sobre el evento para que vuelva a tomar la referencia....pero si lo cierro y lo vuelvo a abrir, nuevamente se pierde. Es un extraño comportamiento que no "afecta" el funcionamiento dado que se ejecutan ambos códigos. Nota: utilizo C++ Builder 6.0 Les agradezco su atención y consejos. Ahora a investigar sobre este "extraño comportamiento..." Saludos!!! Última edición por buildero_d fecha: 09-02-2007 a las 19:25:20. |
|
#3
|
||||
|
||||
|
Debí preveerlo
El comportamiento no es extraño: el dfm se carga cada vez que abres el proyecto, se ejecuta Loaded y se hace el reemplazo del evento, y como apunta a algo que no está publicado (published), el inspector de objetos no sabe qué poner. No sé yo si pueda tener consecuencias pero me late que sí. Tampoco sé cómo solucionarlo pero prueba poner el Loaded así:
No estoy seguro que funcione pero en principio, ahora verifica que no se esté en modo de diseño antes de hacer la reasignación del evento. // Saludos |
|
#4
|
||||
|
||||
|
Asi es roman... es correcta tu teoría. Al cargar la definición del form intentaba asignar a algo "inexistente". Fue suficiente con verificar que antes de reasignar el evento no se este en modo diseño.
Saludos y gracias a todos por sus aportes. |
![]() |
| Herramientas | Buscar en Tema |
| Desplegado | |
|
|
Temas Similares
|
||||
| Tema | Autor | Foro | Respuestas | Último mensaje |
| Llamar evento desde otro evento | nachito_tuc | OOP | 1 | 23-08-2006 21:37:43 |
| Override eventos On... | lento manu | OOP | 12 | 08-10-2005 11:37:31 |
| Procedure SetVisible... ; override | elcigarra | OOP | 3 | 22-07-2005 19:27:27 |
| Qué Evento Programar | andresenlared | Conexión con bases de datos | 1 | 30-12-2003 20:57:18 |
| evento OnRecordChange? | pepe2000 | Tablas planas | 3 | 18-12-2003 15:59:34 |
|