PDA

Ver la Versión Completa : Usar eventos en un VCL


Sonic
27-05-2004, 11:43:49
Tengo diseñado una primera versión funcional de un TRichEdit que reconoce la sintaxis de lo que se esta escribiendo y resalta mediante el formato del texto escrito diversas secciones del texto. Se me ocurrió que con este código podría crear un componente VCL para poder usarlo en otros proyectos. Pero no he conseguido realizar una buena gestión de los eventos. Me explico:
En mi componente uso eventos como OnSelectionChange y OnChange, pero el en VCl no sé muy bien como hacer uso de esto. Ya que si suplanto el manejador del evento, el usuario final de mi componente no podrá usarlo.

La solución que encontré fue suplantar el proceso WndProc y esperar a recibir un mensaje concreto (que sinceramente no se cuál es 45109) pero, a partir del cual puedo compobar si el usuario final ha colocado un manejador de evento, si es así tomo la dirección de este manejador y lo suplanto por una función propia que ejecuta el código que yo necesito y posteriormente usa el puntero para llamar a la función del usuario.

Me pareció una buena solución, de hecho es justo lo que necesito, pero lo que no sabía es que el componente VCL se ejecuta cuando estás en fase de diseño de la aplicación, borrando la casilla del inspector de objetos en la se pone el nombre de la función que el usuario quiere que responda. En principio se comporta bien pero si guardas el proyecto ya se guarda con esa casilla borrada y mi componente piensa que el usuario no ha asignado ninguna funcion y por tanto solo ejecuta la interna.

Por favor, cualquier idea al respecto me resultará útil. Gracias

marto
27-05-2004, 12:01:19
Dos cosas:

-Dices que quieres hacer que tu componente sea VCL... ¿Ahora no lo es?¿entonces qué es?

-Si te he entendido bien, todo funciona Ok excepto la asignación del evento.. ¿por qué no nos pones el código donde lo haces y vemos si hay algun problema?

Lepe
27-05-2004, 12:32:32
Sonic, creo que el propio delphi puede sacarte de ese apuro, por supuesto tambien un buen manual de POO, pero bueno, al grano.

inserta un combobox (por ejemplo) en un form, y despues en la zona de declaración: mantén la tecla CTRL presionada y pulsa en lo subrayado.


type Form1 = Tform
combobox1:Tcombobox


Así accedes a la declaración del combobox. Verás que ese combo hereda de TCustomComboBox, que tambien tiene eventos con el mismo nombre y que hace un override de esos métodos. Creo entender que es lo que necesitas, pero la creación de componentes es una tarea árdua si no se tienen los conocimientos. (hay monton de cursillos en internet sobre ello, pero se necesita tiempo).

Una alternativa rápida para reutilizar componentes es crear un TFrame o un Component Template.

Saludos

Sonic
27-05-2004, 12:34:09
Supongo que no me explicado muy bien, suele ocurrirme a menudo, es que aprendí builder por mi cuenta y es muy probable que no esté usando los términos correctos, veras:

Cuando digo que mi componente lo quiero hacer VCL lo que quiero decir es que lo quiero incrustar en las barras de herramientas, ahora mismo lo tengo en la barra Samples (lo llamo TSRichEdit y hereda obviamente de TRichEdit), disponible para poder ser arrastrado a la aplicación de cualquier usuario.

Según tenía entendido eso es un componente VCL, pero ya te digo si no es así agradecería una aclaración.

Mi problema no es la asignación del evento, para asignarlo uso órdenes como:

Puntero_a _funcion_de_usuario =OnSelectionChange;
OnSelectionChange=MiFuncion;

Y el evento se asigna correctamente.

Lo que yo quiero es que mi componente, cuando alguién lo "pegue" en su aplicación responda al evento OnSelectionChange, primero mediante mi funcion y despus mediante la que él tenga especificada en el Inspector de Objetos.

Para ello, la última linea del código de MiFuncion es :

Puntero_a _funcion_de_usuario (Owner);

Y así se ejcuta primero mi función y luego la del usuario.

Y ahora cuento de nuevo el problema:

Cuando, como usuario, del Componente VCL abro un proyecto, que contiene ese nuevo componente, pegado desde la barra de herramientas Samples. Éste entra en estado de ejecucíón (en la versión anterior del componente, la que no está integrada en la barra SAMPLES no se ejecuta el código del componente hasta que no se ejecuta el proyecto completo por eso me refiero a uno como VCL (Visual Component Library) y al otro como componente o clase a secas). Al ajecutarse el código del componente se llega a las lineas:

Puntero_a _funcion_de_usuario =OnSelectionChange;
OnSelectionChange=MiFuncion;

En concreto la última borra automáticamente en el inspector de objetos la casilla donde antes ponía SRichEdit1SelectionChange (por ejemplo) y me la deja vacía.
La función SRichEdit1SelectionChange sigue existiendo en el código pero el vículo se ha roto.

Cuando posteriormente le doy a ejecutar, la aplicación se ejecuta sin problemas, ya que el componente tiene capturada la dirección de la funcion del usuario (SRichEdit1SelectionChange). Pero, si guardo el proyecto, esta vez se guarda sin el vículo a la función de usuario (es decir con la casilla del Inspector de Objetos vacía). De modo que al cerrar y abrir el proyecto otra vez, cuando mi componente va a guardar en la variable
Puntero_a _funcion_de_usuario la dirección de la funcion de usuario que atiende a OnSelectionChange se encuentra con que esta dirección es NULL (el vínculo hora no existe) y posteriomente cuando se ejecuta el proyecto completo al producirse el evento OnSelectionChange solo se ejecuta mi función y no la del usuario pese a que está esta escrita.

Espero que esta vez haya quedado un poco más claro que es lo que quiero hacer y cuál es mi problema, y espero que ahora sí me podaís ayudar.

Gracias

Sonic
27-05-2004, 12:40:51
Muchas gracias Lepe ya he mirado muchos manuales y creo haberlos entendido, lo que quiero hacer es algo parecido a lo que me comentas del override. Lo que en realidad quiero es que mi manejador de evento se ejecute siempre, ponga o no ponga el usuario uno propio, por eso hago el override pero al final en mi función (la propia) hago una llamada a la función del usuario.

Creo que en mi post anterior te puede quedar un poco más claro lo que quiero, no obstante cualquier alternativa es de considerar, a si que te agradecería que me explicaras un poco mejor lo del TFrame y el Component Template, pero te aviso que es impresindible que se pueda disponer de mi componente en la barra de herramientas.

Muchas Gracias

__cadetill
27-05-2004, 12:51:55
Aunque te ponga código Delphi espero que lo entiendas :p

El ejemplo muestra como lanzar (en un TDbGrid) el evento OnCellClick siempre (y si lo tiene, luego el del usuario).


TExtendedGrid = class(TDbGrid)
private
FOldCellClick: TDBGridClickEvent; // Evento antiguo de DBGridClick
protected
procedure ClicCelda(Column: TColumn);

property OldCellClick: TDBGridClickEvent read FOldCellClick write FOldCellClick;
public
constructor Create(AOwner: TComponent); override;
end;

implementation

constructor TExtendedGrid.Create(AOwner: TComponent);
begin
inherited;

if Assigned(OnCellClick) then
OldCellClick := OnCellClick // si tiene, lo guardo
else
OldCellClick := nil;
OnCellClick := ClicCelda; // le asigno mi procedimiento
end;

procedure TExtendedGrid.ClicCelda(Column: TColumn);
begin
// Hago lo que sea..........

// Si tenía evento asociado.... lo lanzo
if Assigned(OldCellClick) then
OldCellClick(Column);
end;



Espero te sirva

marto
27-05-2004, 12:54:26
Cuando digo que mi componente lo quiero hacer VCL lo que quiero decir es que lo quiero incrustar en las barras de herramientas, ahora mismo lo tengo en la barra Samples (lo llamo TSRichEdit y hereda obviamente de TRichEdit), disponible para poder ser arrastrado a la aplicación de cualquier usuario.
Vale, ahora te entiendo. Por lo que dices, imagino que lo que ahota tienes es un component template, que lo que hace es pegar el código asignado a los eventos el form donde lo sueltas. Lo que quieres hacer es un componente nuevo que encapsule ese comportamiento.


Lo que yo quiero es que mi componente, cuando alguién lo "pegue" en su aplicación responda al evento OnSelectionChange, primero mediante mi funcion y despus mediante la que él tenga especificada en el Inspector de Objetos.

Ok, entonces tienes que cambiar un poco la filosofía. Te pongo un ejemplo en Delphi porque el CB no lo tengo a mano, pero la traducción no es complicada.

unit richEdit1;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls, ComCtrls, Dialogs;
type
trichEdit1 = class(trichedit)
private
{ Private declarations }
protected
//este método se declara en TCustomRichEdit y es el encargaado de lanzar el evento
procedure SelectionChange; override;
public
{ Public declarations }
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('NexContr', [trichEdit1]);
end;
{ trichEdit1 }
procedure trichEdit1.SelectionChange;
begin
ShowMessage('hola');
//Aquí va tú código, que se ejecutará antes que el que haya asignado el usuario
inherited;
//como llamamos a la versión de la superclase, ésta ya se encarga de activar el
//manejador del evento si se ha asignado alguno
end;
end.

__cadetill
27-05-2004, 12:58:41
mmmm, Marto, perdona, pero..... de esta manera creo que no saltará el evento si no lo tiene asociado en el componente, no?

PD: lo digo con la voca xica, que no lo he probado :p

marto
27-05-2004, 12:59:55
mmmm, Marto, perdona, pero..... de esta manera creo que no saltará el evento si no lo tiene asociado en el componente, no?
Copia y pega el código, lo pruebas y luego me cuentas ;)

marto
27-05-2004, 13:08:46
Una pista...


procedure TCustomRichEdit.SelectionChange;
begin
if Assigned(OnSelectionChange) then OnSelectionChange(Self);
end;

Esa es la implementación del método en TCustomEdit.
El método se llama al capturar el mensaje correspondiente de windows:

procedure TCustomRichEdit.CNNotify(var Message: TWMNotify);
begin
with Message do
case NMHdr^.code of
EN_SELCHANGE: SelectionChange;
EN_REQUESTRESIZE: RequestSize(PReqSize(NMHdr)^.rc);
EN_SAVECLIPBOARD:
with PENSaveClipboard(NMHdr)^ do
if not SaveClipboard(cObjectCount, cch) then Result := 1;
EN_PROTECTED:
with PENProtected(NMHdr)^.chrg do
if not ProtectChange(cpMin, cpMax) then Result := 1;
end;
end;

__cadetill
27-05-2004, 13:20:12
Copia y pega el código, lo pruebas y luego me cuentas ;)
pues sí, pues sí, funciona, y yo complicándome la vida!!!! :o :o

Sonic
27-05-2004, 13:41:45
Estimado Cadetill:

He respasado el código Delphi aunque no estoy muy ducho en la sintaxis de Delphi creo que es exáctamente lo que yo hago. Pero me alegra ver que ya más o menos se sabe por donde van los tiros.

Pego a continuación mi código:

//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TSRichEdit *)
{
new TSRichEdit(NULL);
}
//---------------------------------------------------------------------------
__fastcall TSRichEdit::TSRichEdit(TComponent* Owner)
: TRichEdit(Owner)
{
ExOnSelectionChange=false;
Primer_evento=false;
}
//---------------------------------------------------------------------------
namespace Srichedit
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TSRichEdit)};
RegisterComponents("Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TSRichEdit::WndProc (Messages::TMessage &Message)
{
if (!Primer_evento)
{
{
Primer_evento=true;
if (OnSelectionChange!=NULL)
{
ExOnSelectionChange=true;
FExOnSelectionChange=OnSelectionChange;
}

OnSelectionChange=FInOnSelectionChange;
ShowMessage("Hola quillo 0");
OnSelectionChange=FExOnSelectionChange;
}
}

TWinControl::WndProc(Message);
}
//---------------------------------------------------------------------------
void __fastcall TSRichEdit::FInOnSelectionChange (TObject *Sender)
{
ShowMessage("Hola Quillo 1");
if (ExOnSelectionChange)
FExOnSelectionChange(Owner);
}
//---------------------------------------------------------------------------


Según entiendo yo, es lo mismo, salvo que el puntero a la funcion FExOnSelectionChange no lo he declarado como una propiedad. El problema sigue siendo el mismo, mientras estoy en modo de diseño de la aplicación. El componente se ejecuta y en la linea en la que se suplanta el MAnejador del evento, se porvoca el borrado de la citada casilla en el Inspector de objetos

Te dejo el código por si puedes darme alguna pista
Gracias

Sonic
27-05-2004, 13:46:05
Guau! He ido a desayunar, no me esperaba que respondiérais tan rápido, muchísimas gracias. Respondo a Marto, diciendo que no se me había ocurrido esa forma de implemetar mi función, entre otras cosas porque desconocía el siginificado de Inherit;.

Voy a intentar hacer una traducción a Borland y a ver que pasa, No creo que tarde más de 15 minutos.

Por cierto aun no se si lo que hago es un VCL o un template, por favor si puedes aclararmelo o direccionarme a alguna página te lo agradecería.

marto
27-05-2004, 14:05:32
Por cierto aun no se si lo que hago es un VCL o un template, por favor si puedes aclararmelo o direccionarme a alguna página te lo agradecería.Bueno... si lo que haces es Component -> Create Component Template, no estás creando un componente nuevo verdaderamente. En realidad estás duplicando una insatancia, es como si copiases y pegases el componente de un form a otro juntamente con los eventos asociados. Cada vez que dejas caer tu template en un form nuevo, todo ese codigo se crea en la unit correspondiente.
Inconvenientes: Si quieres cambiar algo de ese código, vas a tener que hacerlo en todos los sitios donde dejaste el componente. Además, el código está "visible" en todos lados y puede ser modificado involuntariamente. No nos olvidemos del estilo, es mucho más cómodo que el código no se vea y trabajemos de contra una "caja negra".
Para evitar todos esos inconvenientes, se crea un componente nuevo, es decir una nueva clase. Si no me quivoco esto es lo que intentas y tambien a lo que te refieres por "crear un VCL", si no es así corrígeme ;)
Ah! por cierto, por favor encierra tu código entre tags "code"..."/code" para que se vea bien... ¿de verdad crees que muchos se van a poner a intentar un código de tantas líneas que no está siquiera indentado?

Sonic
27-05-2004, 14:15:23
Vale Marto:

Muchas gracias ya veo la diferencia, y sí, tienes razón es precisamente lo que quiero hacer.

Por lo de mi código, pido perdón os aseguro que está indentado, que yo soy muy ordenado con el código que escribo, pero es la primera vez que pego código en este foro y no se hacer lo de los tags que me dices.

Bueno estoy probando lo del inherited pero no me sale, me da una serie de errores precisamente en esa isntrucción. A mi me gusta investigar un poco por mi cuenta antes de pedir ayuda así que voy a intentarlo un rato más y si no me sale postearé de nuevo.

Otra vez muchas gracias me estais siendo de mucha ayuda!

" asd"

marto
27-05-2004, 14:25:16
Por lo de mi código, pido perdón os aseguro que está indentado, que yo soy muy ordenado con el código que escribo, pero es la primera vez que pego código en este foro y no se hacer lo de los tags que me dices.

Bueno, por esta vez ya te lo he hecho yo, pulsa tu mismo en "editar" y verás como lo he hecho

Sonic
27-05-2004, 15:01:09
Muchas gracias por explicarme cómo pegar código.

Lo siento pero no consigo que el código funcione.
A continuación pego lo que he escrito:



// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TSRichEdit *)
{
new TSRichEdit(NULL);
}
//---------------------------------------------------------------------------
__fastcall TSRichEdit::TSRichEdit(TComponent* Owner)
: TRichEdit(Owner)
{
}
//---------------------------------------------------------------------------
namespace Srichedit
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TSRichEdit)};
RegisterComponents("Samples", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TSRichEdit::SelectionChange (TObject *Sender)
{
ShowMessage("Hola Quillo 1aaaaa");
inherited SelectionChange(TObject *Sender);
//TCustomRichEdit::SelectionChange(); // Esto tampoco funciona
}



Defino la función SelectionChange y recibo el warning de que estoy tapando a la virtual de TCustomRichEdit.

Pero cuando ejecuto el código y ocurre un evento OnSelectionChange solo se ejecuta el código de usuario y no el interno de mi componente.

Tras ver ese post de pista que ofreciste, se me ocurrio sencillamente suplantar al WndProc y capturar el mensaje EN_SELCHANGE, y tras esto ejecutar mi código y luego llamar al WndProc del TWinControl. Esto último ya lo he hecho con otro tipo de mensajes y funciona pero el mensaje EN_SELCHANGE no consigo capturarlo.

Así que de nuevo estoy estancado. Como puedes ver en el código e intentado usar lo de Inherited y esa parece ser la única forma en que compila y la linea que hay más abajo comentada es (según creo yo) otra forma de hacer lo mismo pero que tampoco funciona.

Ah otra cosa, viendo que no funcionaba miré esto:

begin
if Assigned(OnSelectionChange) then OnSelectionChange(Self);
E intenté implantarlo en el constructor de mi objeto de la siguiente manera:

if (OnSelectionChange==NULL)
OnSelectrionChange=SelectrionChange;


y también lo intenté con el Self que parece no reconocerlo de ninguna manera.

Tal y como lo veo ahora tengo dos opciones: intentar seguir por el camino que me marcó Marto, o instentar capturar el mensaje EN_SELCHANGE. Cualquiera de las dos soluciones me serviría. Aunque preferiría poder usar la de Marto ya que me parece la más sencilla de las dos (en cuanto a la estructura del programa).

Muchas Gracias

marto
27-05-2004, 15:09:02
void __fastcall TSRichEdit::SelectionChange (TObject *Sender)
{
ShowMessage("Hola Quillo 1aaaaa");
inherited SelectionChange(TObject *Sender);
//TCustomRichEdit::SelectionChange(); // Esto tampoco funciona
}


¿Eso te compila?
No tengo el c++ y no lo puedo probar, pero a mi me parece que tendría que ser así:

void __fastcall TSRichEdit::SelectionChange (TObject *Sender)
{
ShowMessage("Hola Quillo 1aaaaa");
inherited SelectionChange(Sender);
}




Pero cuando ejecuto el código y ocurre un evento OnSelectionChange solo se ejecuta el código de usuario y no el interno de mi componente.
¿quieres decir que que no se ejecuta el showmessage? eso es porque no estás sobrecargando el método. Ahora no recuerdo cómo se hace en c++, pero tienes que encontrar el equivalente al override de Delphi


P.D: Ojalá todos los usuarios tubiesen tu actitud. Espero que tengamos la suerte de tenerte a menudo por aquí ;)

Sonic
27-05-2004, 15:48:33
Me voy a poner colorao, muchas gracias!

Seguro que me veis por aqui a menudo, es la primera vez que participo en un foro, pero me gusta, además aprendí a manejar el Builder, este Septiembre para mi proyecto fin de carrera, y le cogí el gustillo así que seguro que andaré bastante por aquí.

Bueno al tema:

Si coloco el Sender como argumento Builder me da este error:

[C++ Error] SRichEdit.cpp(86): E2459 VCL style classes must be constructed using operator new

Que la verdad no se a qué viene. Así que lo puse sin argumento y así si compila.

Con respecto a la sobrecarga, el Builder me da el siguiente Warning:

[C++ Warning] SRichEdit.h(31): W8022 '_fastcall TSRichEdit::SelectionChange(TObject *)' hides virtual function '_fastcall TCustomRichEdit::SelectionChange()'

Sin mas que haber definido la funcion con el mismo nombre, por lo que yo entiendo que no necesito ninguna directiva del tipo de override;

Perdón acabo de probarlo, he quitado la función de usuario que responde al evento y ahora no se ejecuta nada, por lo que definitivamente no estoy sobrecargando la función. Pero bueno, ya es la hora de comer así que lo miraré luego, muchas gracias por todo espero poder tener una solución en breve.

marto
27-05-2004, 17:48:01
Despues de buscar un poco por ahí (http://community.borland.com/article/0,1410,20124,00.html), creo que el método debería quedar así:


void __fastcall TSRichEdit::SelectionChange (TObject *Sender)
{
ShowMessage("Hola Quillo 1aaaaa");
TCustomRichEdit::SelectionChange(Sender);
}


El warining te seguirá dando, pero eso es secundario, vamos a ver si consigues que funcione y luego nos pegamos con él ;)

Sonic
27-05-2004, 17:54:16
Acabo de caer, el mensaje que me da Builder no indica que haya sobrescrito la función del manejador del evento sino que he realizado una sobrecarga de operadores:


fastcall TSRichEdit::SelectionChange(TObject *)' hides virtual function '_fastcall TCustomRichEdit::SelectionChange()'

La función del TCustomRichEdit no tiene argumentos y yo le había puesto TObject *Sender.

Aún después de descubrir eso no consigo sobreescribir dicho método por que si quito este párametro recibo otro mensaje de error que dice:


[C++ Error] SRichEdit.h(22): E2113 Virtual function '_fastcall TSRichEdit::SelectionChange()' conflicts with base class 'TCustomRichEdit'

En la ayuda me dice que aunque los parámetros son los mismos puede que algo más no sea igual que en la clase predecesora. Pero no encuentro qué puede ser.

Bueno ya mañana, seguiré con esto.

Lo dicho, cualquier sugerencia siempre será bien recibida. Muchas Gracias

marto
27-05-2004, 17:58:45
Pues la verdad es que ya estoy yo intrigado con el tema... y no lo puedo probar :(

En Delphi no es así, pero ¿puede ser que si el método de TCustomRichEdit está declarado como dinámico tengas que hacer lo mismo en tu clase?

Sonic
28-05-2004, 11:35:27
OLE OLE OLE y OLE!

Ya lo he conseguido, bueno lo hemos conseguido!

Muchas gracias Marto! y también Cadetill y Lepe!

Tenías toda la razón, me estaba complicando demasiado intentando gestionar los mensajes de Windows. Ha sido tan sencillo como sobreponer mi método al del antecesor y luego dentro de mi método hacer una llamada al del éste!

Funciona a las mil maravillas, es más sencillo de hacer, entender y gestionar y ya no tengo el problema que tenía con el modo en que lo estaba haciendo antes.

La verdad es que me alegro mucho de haber encontrado este foro y de haber participado en él. De modo que este hilo, según parece acaba de llegar a su fin, a su buen fin.

Pero como me ha gustado esto de los foros y de bien nacidos es ser agradecidos, continuaré pendiente al foro para ver si puedo ayudar a alguién. De nuevo muchas gracias a todos los que habeis querido ayudarme.

Explico cuál ha sido la solución al final.

Para empezar la función en el .h la he declarado así:


DYNAMIC void __fastcall SelectionChange(void);


Pero luego en la implementación de la función no puedo poner DYNAMIC (por eso ayer aunque intenté poner DYNAMIC no me salía, solo se puede poner en la declaración) si no que lo hago así:


void __fastcall TSRichEdit::SelectionChange()
{
ShowMessage ("Hola quillo 1");
TRichEdit::SelectionChange();

}


He tenido que usar el operador de ámbito porque el inherited aunque se lo traga sin dar warnings ni errores, luego no funciona como yo entiendo que debería hacerlo, de todos modos creo que teóricamente poner el inherited y el TRichEdit::SelectionChange es lo mismo así que como funciona así se queda.

Bueno lo dicho que Muchas Gracias a todos y que espero que nos encontremos y discutamos mucho por este foro de aqui en adelante.

Sonic
28-05-2004, 15:57:22
Bueno mi programa va sobre ruedas, pero me ha surgido una duda:

Esta vez he tenido suerte porque para el evento OnSelectionChange existía una función predeterminada a la que se le puede hacer override.

Pero, ¿cómo tendría que hacerlo si el evento que quisiera manejar fuera OnChange u OnKeyPress o algún otro?

En la ayuda no aparece que estos eventos tengan asociados ninguna función. Y el método que yo usaba inicialmente me daría los mismos problemas ¿Tendría que gestionar yo los mensajes? OnKeyPress tiene su propio mensaje pero OnChange no ¿Cómo podría hacerse esto?

Alguién tiene alguna idea?

Gracias.

marto
28-05-2004, 22:50:04
Wop!

Para lo que comentas y para muchas otras cosas la mejor solución es aprender de los maestros, es decir, de los programadores de Borland. Si navegas por el código de la VCL descubrirás las técnicas que ellos usan para implementar este y otro tipo de cosas.

En concreto, el tema de los eventos acostumbra a seguir siempre el mismo patrón. Se declara una propiedad del tipo del evento que es dónde se asigna el manejador a éste. Por otro lado, se programa un método protegido y virtual / dynamic que es el encargado de llamar al manejador en caso de estar asignado. Bien, este método es el que tenemos que sobreescribir en nuestra clase.

Sonic
29-05-2004, 03:06:09
Como siempre brillante, muchas gracias Marto!

Seguiré tu consejo e investigaré el código de las VCL para aprender más. Aunque ya has resuelto mi duda.

Muchas gracias de nuevo!