2011-01-13 18 views
13

Sé que he visto un ejemplo en algún lugar de un hack para definir una versión personalizada de un componente VCL existente, como TButton o TEdit, con el mismo nombre de clase y hacer algo para que el transmisor de flujo continuo DFM creará una instancia de su versión en lugar del original. Lamentablemente, estoy en una situación en la que necesito poder hacer eso y no puedo encontrar la reseña. ¿Alguien sabe dónde encontrar información sobre cómo lograr esto?Reemplazando una clase de componente en delphi

+1

¿Has mirado en tu bolsa de trucos? http://windwings.wordpress.com/2009/10/07/turbocharging-delphi-2010-2-adding-dynamic-functionality-to-3rd-parties-the-solution/#comment-1066 ;-) –

+0

@ Jørn , eso es lo que muestra esta respuesta: http://stackoverflow.com/questions/4685863/replacing-a-component-class-in-delphi/4686920#4686920 –

+1

@Jeroen, lo sé ... solo necesitaba mostrar @ Mason es "lo ha visto en alguna parte". :-) –

Respuesta

18

En su forma se puede reemplazar el método ReadState así:

type 
    TMyForm = class(TForm) 
    protected 
    procedure ReadState(Reader: TReader); override; 
    end; 

procedure TMyForm.ReadState(Reader: TReader); 
begin 
    Reader.OnFindComponentClass := FindComponentClass; 
    inherited; 
end; 

procedure TMyForm.FindComponentClass(Reader: TReader; const ClassName: string; 
    var ComponentClass: TComponentClass); 
begin 
    if ComponentClass=TButton then begin 
    ComponentClass := TMySuperDuperButton; 
    end else if ComponentClass=TEdit then begin 
    ComponentClass := TMyTotallyAwesomeEdit; 
    end; 
end; 

es probable muchas otras maneras de hacer esto, pero esta es la forma en que lo hago!

EDIT: Inspeccionar TReader.GetFieldClass(Instance: TObject; const ClassName: string) sugiere el truco que Mason recuerda. La primera línea establece ClassType := Instance.ClassType. Así que sospecho que al cambiar la declaración en el archivo pas de Button1: TButton a Button1: MyUnit.TButton, se creará su botón. O tal vez el truco fue agregar MyUnit a la cláusula uses al final para que tu versión de TButton sea la que está en el alcance. Sin embargo, nada de esto suena muy práctico.

+0

Puedo estar equivocado, pero también agregaría el cheque para ClassName y no solo para ComponentClass. En caso de que algo haya cambiado entre Delphi 2 y Delphi XE;) –

+0

Interesante. No he oído hablar de esta versión, pero podría funcionar para lo que tengo que hacer. –

+0

@Eugene Lo siento, no entiendo lo que quieres decir. –

11

Supongo que lo que estás tratando de recordar es un "interposer class": heredando una clase que da el mismo nombre que el antecesor, prefijando el nombre de la unidad del antepasado. Como el nombre de clase no se cambia, el mecanismo de transmisión dfm no se altera. Solo afectaría a la unidad en la que se vuelve a declarar la clase, a menos que se coloque en una unidad separada y esa unidad se incluya en la sección de usos después de la clase base. Obviamente, no puede haber publicado propiedades en una clase interpuesta.

type 
    TButton = class(stdctrls.TButton) 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    end; 

    TForm1 = class(TForm) 
    Button1: TButton; 
    [...] 
    private 
+0

Sí, eso es en lo que estaba pensando. Pero la solución de David resultó ser más efectiva para el problema que estaba tratando de resolver. –

Cuestiones relacionadas