Aula Macedonia


Curso de Programación Visual en Delphi


Artículo realizado por
José Antonio Suárez.





Anexo 1


De vez en cuando, serán introducidos anexos de este tipo, que tratarán sobre el tema que se esté exponiendo en ese momento, extraidos de Internet, y que suelen ser de gran ayuda a la hora del aprendizaje de Delphi.

Este FAQ (Frecuently Asqued Question) pertenece a Pablo León, y aquí tan solo se ha incluido su trabajo, por lo que cualquier derecho pertenece exclusivamente a él.

En este caso que tratamos ahora, es un FAQ sobre los componentes de Delphi, su instalación, su anejo, su reutilización, etc.

Tiene un nivel mucho más elevado que el dado hasta ahora, pero estoy seguro de que servirán de referencia para aquellos que profundicen en el tema.


  1. ¿Cómo crear un nuevo componente?

  2. ¿Cómo añado una propiedad a mi nuevo componente?

  3. ¿Cómo añado un evento a mi nuevo componente?

  4. A mi componente le sobran algunas propiedades que ha heredado de su antecesor; ¿Como las elimino?

  5. ¿Cómo pongo un manejador de mensajes estándar de windows?

  6. ¿Cómo puedo modicar el aspecto de un control estándar de windows?

  7. ¿Cómo elijo un antecesor para mi componente?

  8. ¿Cómo creo un control en tiempo de ejecución?

1.- ¿Cómo crear un nuevo componente?

  1. En el menú del delphi, seleccionar Component y luego New.

  2. Como Class Name hay que poner el nombre del componente precedido de una T, p.e. TMiNuevoComponente.

  3. En Ancestor Type hay que seleccionar el componente del que vas a    derivar p.e. TGraphicControl.

  4. En Palette Page pon el nombre de la solapa en la que quieres que vaya tu nuevo componente. Si no existe una solapa con el mismo nombre, esta se creará.

  5. Al pulsar OK se genera el fichero fuente de tu objeto. Guardalo con un nombre apropiado, que debe ser dirente que el del componente, p.e. MisComponentes.pas

  6. En el menú de delphi selecciona Component y luego Install. Con el Botón add, añade el fichero del punto 5.

  7. ¡Ya has creado un componente idéntico al Ancestor!

Volver 

 

2.- ¿Cómo añado una propiedad a mi nuevo componente?

Interface

type TMarcos = class (TPadre_de_Marcos)

private
    fMarcos:string;
    fAcierto:boolean;
    fOnFallo:TNotifyEvent;
    procedure SetMarcos(M:string);

published

    // He aqui la propiedad
    property Marcos:string read fMarcos write SetMarcos;
             ------             -------       ---------
                |                  |              |
                |                  |              +-- Procedimiento donde se pone
                |                  |                   la propiedad
                |                  |                   (también puede ser una varible)
                |                  |
                |                  +-- Variable de donde se lee la propiedad
                |                       (tambien puede ser una función)
                |
                +-- Nombre de la propiedad tal como aparece en el
                      inspector de objetos

    // Esto es un evento
    property OnFallo:TNotifyEvent read fOnFallo write fOnFallo;

end;

implementation

procedure tMarcos.SetMarcos(M:string);
begin
        // Asignamos la propiedad
        fMarcos:=M;
        // Y hacemos algunas otras cosas
        if Upper(fMarcos)='MMMMMMM' then
            fAcierto:=true
        else if fOnFallo<nil then
                fOnFallo(self);
        Repaint;
end;

Volver 

3.- ¿ Cómo añado un evento a mi nuevo componente?

Un evento es muy parecido a una propiedad, solo que el tipo de la misma es TNoSeCuantosEvent, o sea, tipo función. Si no te vale TNotifyEvent a algun otro ya definido,
tienes que definirtelo tú:

Interface

type T_A_Este_Evento_Le_Paso_Un_Entero_Event = procedure (Sender:TComponent;I:integer) of object;

type T_Este_Objeto_Usa_Eventos = Class (T_Padre)
  private
    fOnQuieroPasarUnEntero:T_A_Este_Evento_Le_Paso_Un_Entero_Event;
    fOnMeValeElEventoEstándar:TNotifyEvent;
  public
    constructor Create(AOwner:Tcomponent); override;
  published
    // He aqui los eventos
    OnQuieroPasarUnEntero:T_A_Este_Evento_Le_Paso_Un_Entero_Event
        read fOnQuieroPasarUnEntero write fOnQuieroPasarUnEntero;
    OnMeValeElEventoEstándar:TNotifyEvent
        read fOnMeValeElEventoEstándar write fOnQuieroPasarUnEntero;
  end;

implementation

procedure T_Este_Objeto_Usa_Eventos.Create(AOwner:Tcomponent);
begin
inherited;
    // ***Atencion***: Es imprescindible comprobar que el evento está asignado antes de llamarlo
    if fOnQuieroPasarUnEntero<nil then
        fOnQuieroPasarUnEntero(self,33); //Los años de cristo
end;

Volver 

4.- A mi componente le sobran algunas propiedades que ha heredado de su antecesor; ¿Cómo las elimino?

No puedes eliminaralas. Lo siento. Si te molestan mucho, intenta derivar de objetos más primitivos. Aunque la tentacion sea fuerte NO MODIFIQUES LOS FUENTES QUE VIENEN CON EL DELPHI.

Volver 

 

5.- ¿ Cómo pongo un manejador de mensajes estándar de windows?

Así:

Interface

type MiComponente=Class(TComponent); 
  private
    // Este mensaje indica que se ha soltado el botón izquierdo del ratón
    procedure WMLBUTTONUP(var Msg:TWMLBUTTONUP); message WM_LBUTTONUP;
  end;

Implementation

  procedure MiComponente.WMLBUTTONUP(var Msg:TWMLBUTTONUP);
  begin
          inherited;
  end;

Volver 

 

6.- ¿ Cómo puedo modificar el aspecto de un control estándar de windows?

Derivar la rutina CreateParams suele ser el quid de la cuestión:

Interface

type MiEditor = Class(Tedit);

protected
  procedure CreateParams(var Params:TCreateParams); override;
end;

Implementation

procedure MiEditor.CreateParams(var Params:TCreateParams);
begin
    inherited;
    Style:=Style or ES_RIGHT; //¡Un Edit que se alinea a la derecha!
end;

Volver 

7.- ¿ Cómo elijo un antecesor para mi componente?

  • Si es como otro componente al que le falta alguna carateristica, pues de ese componente.

  • Si es parecido a otro componente, y este deriva de TCustomAlgo, prueba con él.

  • Si es un control de windows entonces de TWinControl puede servir.

  • Si es un componente que puede tener el foco de windows, de TCustomControl.

  • Si es un componente que no necesita el foco de windows, de TGraphicControl.

  • Si es un componente no-visual (no se vé) de TComponent.

Volver 


8.- ¿ Cómo creo un control en tiempo de ejecución?

Pues...

procedure PonEdit;
var
    pEdit:tEdit;
begin
     pEdit:=TEdit.Create;
     pEdit.Left:=10;
     pEdti.Right:=50;
     pEdit.parent:=self;
end;

Fíjate, que al tener el objeto un padre (propiedad parent), no necesitas liberarlo explictamente (con free), debido a que un padre de windows libera a sus hijos antes de liberarse él.

No confundas un padre con un antecesor: Padre se aplica a los controles de windows, mientras que antecesor se aplica a los objetos de delphi.

Volver 

 

(Creado originalmente por Pablo León)




AULA MACEDONIA
a
MACEDONIA Magazine