2010-03-23 15 views
10

¿Alguien sabe el truco, cómo liberar el control dentro de su controlador de eventos? De acuerdo con la ayuda de Delphi no es posible ...¿Cómo liberar el control dentro de su controlador de eventos?

Quiero liberar dinámicamente TEdit creado, cuando Self.Text = ''.

TAmountEdit = class (TEdit) 
. 
. 
public 
    procedure KeyUp(var Key: Word; Shift :TShiftState); 
end; 

procedure TAmountEdit.KeyUp(var Key: Word; Shift :TShiftState); 
begin 
inherited; 
if Text='' then Free; // after calling free, an exception arises 
end; 

¿Cómo se debe hacer para lograr el mismo efecto?

Thanx

+0

¿Ha intentado simplemente iniciar un temporizador que libera la edición y luego se deshabilita? – frogb

+0

Hmm ... buena pregunta. Si se tratara de un formulario, llamaría a Release, pero eso está declarado en TCustomForm, no en TControl o TComponent. –

+0

Buena pregunta. Necesitaba algo así varias veces en el pasado. – Ampere

Respuesta

15

la solución es para enviar un mensaje en cola con el control, que responde a por destruirse a sí mismo. Ny convención usamos CM_RELEASE que es el mensaje privado utilizado por TForm en su implementación del método Release que realiza una tarea análoga.

interface 

type 
    TAmountEdit = class (TEdit) 
    ... 
    procedure KeyUp(var Key: Word; Shift :TShiftState); override; 
    procedure HandleRelease(var Msg: TMessage); message CM_RELEASE; 
    ... 
    end; 

implementation 

procedure TAmountEdit.KeyUp(var Key: Word; Shift :TShiftState); 
begin 
    inherited; 
    if Text = '' then 
    PostMessage(Handle, CM_RELEASE, 0, 0); 
end; 

procedure TAmountEdit.HandleRelease(var Msg: TMessage); 
begin 
    Free; 
end; 

El control se destruye cuando la aplicación enciende su cola de mensajes.

+1

No es necesario declarar un nuevo ID de mensaje. Consulte CM_RELEASE, que está diseñado específicamente para hacer esto para formularios. Pero la idea básica es correcta. +1 –

+0

SÍ. Funciona !!! Muchas gracias .... :-) – lyborko

+0

Llamaría a este método un truco, porque no es 100% seguro. Intente usar Liberar aquí: TForm2 = clase (TForm) S: cadena; procedimiento WndProc (var Msg: TMessage); anulación; public constructor Create (AOwner: TComponent); override; // ... constructor TForm2.Create (AOwner: TComponent); begin S: = 'abc'; heredado final; procedimiento TForm2.WndProc (var Msg: TMessage); begin inherited; S [2]: = 'x' {*} final; – Torbins

6

Antes de implementar este Me parar y preguntar "Lo que tienes es el mejor enfoque?"

Está seguro de querer una clase de control de edición que siempre destruye a sí misma cuando los resultados de entrada clave en el texto propiedad convirtiéndose en una cadena vacía?

¿No es más probable que tenga un formulario/diálogo específico donde se requiere este comportamiento? En ese caso, no hay problema ... puede liberar el control de edición en el evento KeyUp manejado por el formulario sin incurrir en una Infracción de Acceso .

+0

Sí, lo sé. El problema es que tengo un componente (mi propio) basado en TCustomControl, que contiene controles TAmountEdit (no se especifica cuántos). Es por eso que tengo que crearlos dinámicamente y luego liberarlos de acuerdo con mis reglas ... Es similar a las pestañas en el IE o FireFox, donde cierro la pestaña y desaparece ... (¿Frees? No lo sé ... . :-)) – lyborko

+4

Ya veo. Pero si su componente crea los controles, entonces, en mi opinión, también debería ser responsable de liberarlos.Las reglas parecen ser establecidas por el control * que contiene * los controles ** TAmountEdit **, no por el control ** TAmountEdit **. Su control personalizado crearía un ** TAmountEdit ** y luego asignaría un controlador de eventos (que implementa) al evento ** OnKeyUp() ** del ** TAmountEdit ** (tenga en cuenta que técnicamente su pregunta original no se trata de manejar un evento, sino * interceptando * ¡uno!). – Deltics

+0

:-) No me preocupa liberar TAmountEdit, mientras que se agregan a la matriz de componentes del contenedorcontrol (los posee). Por lo tanto, se liberan automáticamente, cuando el contenedor de control está a punto de ser destruido. Yo intercepto el evento OnKeyUp() de TAmountEdit de todos modos para navegar por ellos fácilmente. Para liberar TAmountEdit es su propiedad opcional y quería implementarlo dentro del control mismo. Además, tuve algunas dificultades específicas para liberar el control del padre solo por interceptar el evento OnKeyUp ... – lyborko

Cuestiones relacionadas