Componente de la escritura, parte 1

Componente de la escritura, parte 1


en Primer lugar en una serie de tres partes que abarcan componente escrito en Delphi.




Este artículo apareció originalmente en Desarrolladores de Delphi



derechos de Autor Pinnacle Publishing, Inc. Todos los derechos reservados.







Esta primera parte se muestra algunos de los mejores enfoques para la construcción de los componentes, y al mismo tiempo proporciona consejos para decidir sobre el mejor de la clase base desde la que heredar, el uso de virtual declaraciones, el proceso de sustitución, y así sucesivamente.



Las dos primeras cosas que preguntarte a ti mismo, son la razón por la que usted debe hacer uso de un componente de la escritura, y cuando usted debe necesitar para escribir un componente. La primera pregunta es fácil de responder, de hecho, tiene muchas respuestas.


  • Facilidad de uso: Encapsulado código significa que usted puede colocar simplemente el mismo componente en diversas formas una y otra vez sin necesidad de escribir una sola línea de código.

  • Depuración Centralizada código facilita la reparación de toda la aplicación (o aplicaciones) mediante la fijación de un error en un solo componente, y volver a compilar.

  • Dinero: Hay un montón de empresas que están muy contentos de pagar por el privilegio de no tener que reinventar la rueda.



La segunda pregunta no es demasiado difícil de contestar. Siempre que usted se encuentra el tener que escribir el mismo código más de una vez es una buena idea para escribir un componente, especialmente si el código se realiza de forma diferente en función de los parámetros dados.



¿Cómo los componentes se crean

El primer paso es decidir que clase base tiene que derivar el componente de. Al derivar de otra clase que hereda de la propiedad / método y en caso de que componente posee. A continuación es un ejemplo de cómo decidir qué clase debe heredar de la hora de escribir su propio componente.



(haga Clic para una vista completa)



haga Clic para ver a tamaño completo



En el caso del método a y el método B, suponer que el componente en cuestión es TMemo.





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp


MétodoSolución



& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp;
se Derivan de TMemo






& nbsp & nbsp & nbsp & nbsp;
B



& nbsp & nbsp & nbsp & nbsp;
se Derivan de TCustomMemo






& nbsp & nbsp & nbsp & nbsp;
C



& nbsp & nbsp & nbsp & nbsp
se Derivan de TCustomControl






& nbsp & nbsp & nbsp & nbsp;
D



& nbsp & nbsp & nbsp & nbsp;
se Derivan de TGraphicControl






& nbsp & nbsp & nbsp & nbsp;
E



& nbsp & nbsp & nbsp & nbsp;
se Derivan de TComponent









Esto puede parecer un poco complicado, así que permítanme explicar el proceso.



a: Cuando usted necesita simplemente para añadir funcionalidad extra a un componente existente que se derivan de ese componente. Esto le dará automáticamente el nuevo componente de todos los existentes funcionalidad y propiedades de la componente existente.



B: a Veces, usted no sólo tiene que añadir la funcionalidad, pero usted tiene que quitar al mismo tiempo. La práctica estándar cuando la escritura de un componente es el primero para escribir una TCustomXXXXX componente donde todas las propiedades / eventos y métodos se declaran dentro de la sección Protegida del componente. El componente real se deriva de esta clase base. El truco, por tanto, no es para ocultar la funcionalidad, pero para derivar el componente de la 'costumbre' de la versión del componente y sólo publicar las propiedades que desea guardar (la eliminación eficaz de las propiedades no deseadas / eventos).



C: Cualquier componente que necesite recibir atención necesita un identificador de ventana. TWinControl es donde esta la manija se introdujo por primera vez. TCustomControl es simplemente un TWinControl con su propio Lienzo de la propiedad.



D: TGraphicControl no tiene un identificador de ventana y por lo tanto no pueden recibir el foco. Componentes tales como TLabel se derivan de esta clase base.



E: Algunos componentes no se creó para mejorar la GUI de interactividad pero para hacer su vida más fácil. Nada derivados de TComponent sólo es visible en tiempo de diseño. Un uso típico de este tipo de componente es para conexiones de base de datos, temporizadores, etc.



una Vez que hemos decidido qué nuestra clase base debe ser, el siguiente paso es crear el componente. Desde el menú Componentes, seleccione Nuevo Componente y verá el siguiente cuadro de diálogo.



Nuevo componente






& nbsp & nbsp & nbsp & nbsp;
Antepasado tipo



& nbsp & nbsp & nbsp & nbsp;
Este es el tipo de base que necesitamos para descender de






& nbsp & nbsp & nbsp & nbsp;
nombre de la Clase



& nbsp & nbsp & nbsp & nbsp;
Este es el nombre de la clase de nuestro nuevo componente

(señaladas con la letra 'T')






& nbsp & nbsp & nbsp & nbsp;
Paleta de la página



& nbsp & nbsp & nbsp & nbsp;
Esto es que en la ficha de la paleta de componentes que le gustaría que su

componente a aparecer en, entrar a una inexistente ficha dirá

Delphi que le gustaría una nueva pestaña crear.







Escribir algo de código

Ya es hora de escribir algo. Este primer ejemplo se tiene ningún uso en todos, excepto para demostrar algunos conceptos básicos de los componentes de la escritura.



lo Primero de todo, seleccionar el Componente de la parte principal de Delphi menú y, a continuación, seleccione Nuevo Componente. Introduzca TComponent como el 'Antepasado tipo' y TFirstComponent como el nombre del componente. Luego, haga clic en el botón 'Instalar'.



En este punto usted puede instalar su nuevo componente dentro de un paquete existente (un paquete que contiene una colección de componentes) o instalar un nuevo paquete. Haga clic en 'nuevo de paquete' y haga clic en el botón 'Examinar'.



Instalar el componente



una Vez que haya seleccionado una ruta de acceso y nombre de archivo para el nuevo paquete y entró en una descripción haga clic en 'ACEPTAR'. En el siguiente cuadro de diálogo que le preguntará si desea volver a compilar el paquete) haga clic en 'Sí'. Una vez que el paquete se compila y se instala, guardar el paquete y la unidad.



En este punto hemos especificado nuestra clase base, y también nuestro nuevo nombre de la clase. Hemos creado un nuevo paquete de medidas para contener nuestro componente y se han presentado con un esqueleto de la estructura de clases por Delphi.



Si usted mira el código fuente proporcionado por Delphi ahora verá el Private, Protected, Public, y Publicó artículos.



la Encapsulación

la Encapsulación es un concepto sencillo de comprender, pero extremadamente importante componente de la escritura. La encapsulación se lleva a cabo con el uso de cuatro palabras reservadas: Privado, Protegido, Las, y Publicado, aparecerá el Delphi ha incluido estas secciones automáticamente en el código fuente para el nuevo componente.





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp







& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp











Comenzar a escribir nuestro componente

Delphi ahora necesita saber todo acerca de nuestro nuevo componente. Escriba el código siguiente en el componente de código fuente.

SecciónAccesibilidad
Privadolos Métodos, Propiedades y Eventos declarados dentro de esta sección sólo se

accesible a la unidad de la componente de contenidos

dentro. Componentes en la misma unidad puede acceder a cada uno

Privados de otros elementos.
ProtegidoMétodos, Propiedades y Eventos declarados dentro de esta sección también

accesible para cualquier clase de descendientes de esta clase.
PúblicoMétodos, Propiedades y Eventos declarados aquí accesible desde cualquier lugar.
PublicadoEsta sección permite declarar propiedades y eventos que aparecerán en la

inspector de objetos. Estos valores son de diseño los valores de tiempo de

que se guardan con el proyecto. (No todos los tipos son:

compatible, matrices, por ejemplo, no lo son).




& nbsp & nbsp & nbsp & nbsp







Lo que hemos hecho aquí se agregan dos variables FStartTime y FStopTime (que es el estándar para preceder a los nombres de variables con la letra F). Hay dos métodos para el control de estas variables, de Inicio y de Parada. Hemos añadido una función GetElapsedTime que volverá FStopTime - FStartTime como una cadena. Por último, hemos agregado tres propiedades de sólo lectura.



Presione SHIFT-CTRL-C y Delphi se complete automáticamente el código de la clase (o haga clic en el botón derecho del ratón y seleccione 'clase Completa en el cursor'). A continuación escriba el siguiente código para cada método.





privada

& nbsp & nbsp { Private declarations }

& nbsp & nbsp FStartTime,

& nbsp & nbsp FStopTime :DWord

protegido

& nbsp & nbsp { declaraciones Protegidos }

& nbsp & nbsp función GetElapsedTime: cadena de virtual

público

& nbsp & nbsp { Public declarations }

& nbsp & nbsp procedimiento Inicio virtual

& nbsp & nbsp procedimiento Dejar virtual



& nbsp & nbsp propiedad StartTime:DWord leer FStartTime

& nbsp & nbsp propiedad StopTime:DWord leer FStopTime

& nbsp & nbsp propiedad ElapsedTime: cadena de leer GetElapsedTime

publicado

& nbsp & nbsp { Publicado declaraciones }

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Prueba de la unidad

Guardar su unidad y vuelva a abrir el paquete (Archivo, Abrir Proyecto en el menú, y seleccione 'Delphi' Paquete para el tipo de archivo), una vez que el paquete está abierto haga clic en el botón 'Compilar'. También puede abrir el paquete de la elección de Componente en el menú principal y, a continuación, Instalar los Paquetes. Seleccione su paquete y, a continuación, haga clic en el botón 'Editar'.



ahora puede soltar un TFirstComponent en un formulario, de hecho, usted puede colocar tantos como desee. Agregue dos botones (btnStart y btnStop) y agregue el siguiente código al formulario y, a continuación, ejecutar la aplicación de prueba'.





{ TFirstComponent }

función TFirstComponent.GetElapsedTime: string

begin

& nbsp & nbsp Resultado := IntToStr(FStopTime - FStartTime)

fin



procedimiento TFirstComponent.Inicio

begin

& nbsp & nbsp FStartTime := GetTickCount

fin



procedimiento TFirstComponent.Stop

begin

& nbsp & nbsp FStopTime := GetTickCount

fin



fin.

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp







procedimiento TForm1.btnStartClick(Sender: TObject)

begin

& nbsp & nbsp FirstComponent1.Inicio

fin



procedimiento TForm1.btnStopClick(Sender: TObject)

begin

& nbsp & nbsp FirstComponent1.Stop

& nbsp & nbsp Caption := FirstComponent1.ElapsedTime

fin

& nbsp & nbsp & nbsp & nbsp





Clic en el botón 'Inicio' va a marcar la hora de inicio (GetTickCount es un WinAPI comando que devuelve el número de milisegundos desde el inicio de Windows).



Clic en el botón 'Stop' marca de la hora de parada, y cambiar el título del formulario.



Virtual, Dinámico, Abstracto y Reemplazar

Usted puede haber notado la virtual de la declaración después de Iniciar, Detener y GetElapsedTime. El siguiente ejercicio te explica sus usos.



Crear un nuevo componente, se derivan de este componente de TFirstComponent (nombre TSecondComponent) e instalarlo.



El Virtual y Dinámica de los identificadores son un componente del escritor manera de decirle a Delphi que el método puede ser reemplazado en un descendiente de la clase. Si queremos sobreescribir un método en una clase, nuestro nuevo código se ejecutará en lugar de la original del código.







& nbsp & nbsp & nbsp & nbsp









Nosotros, a continuación, implementar el código anterior de la siguiente manera.





protegido

& nbsp & nbsp { Declaraciones protegidos }

& nbsp & nbsp función GetElapsedTime: cadena de reemplazar

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Nuestro código nuevo es que ahora se llama en sustitución de la original GetElapsedTime, incluso las llamadas implementado en TFirstComponent a GetElapsed tiempo de llamar a nuestro nuevo código (si hemos creado una instancia de TSecondComponent que es). El código original se invoca a través de la utilización de los Heredado de comandos.



Nota : Si no 'anular' una base de método (ya que la base no fue declarado como virtual o porque se le olvidó). TSecondComponent llamará el nuevo código, mientras que el código implementado en TFirstComponent todavía siguen pidiendo el código original de TFirstComponent.



El Resumen identificador dice Delphi no esperar ningún código para el método con nombre. Usted no debe crear una instancia de un objeto con métodos abstractos (como el TStrings). La práctica estándar es crear un descendiente de una clase y reemplazar todos los métodos abstractos (como TStringList).



Dinámica Vs Virtual es simplemente una cuestión de velocidad Vs tamaño. Un método Dinámico se traducirá en cada instancia de una clase que requiere menos memoria, mientras que un método Virtual se ejecutará más rápido en el costo de un poco más de memoria.



Hay algunos pasos simples para agregar eventos a su componente. Los eventos permiten que el componente para comunicarse con su aplicación, para notificar cuando algo importante ha sucedido. Un evento es simplemente una propiedad de lectura y escritura, en lugar de ser un simple tipo de variable (como string, integer, etc) es un procedimiento o función.



Crear un nuevo componente, descender de TSecondComponent y el nombre de TThirdComponent. Guardar la unidad, instalar el componente, y agregue el siguiente código.



función TSecondComponent.GetElapsedTime: string

var

& nbsp & nbsp S: string

begin

& nbsp & nbsp S := heredado GetElapsedTime

& nbsp & nbsp Resultado := S ' milisegundos o '

& nbsp & nbsp & nbsp & nbsp Formato('%.2f segundos',

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp [(StopTime - StartTime) / 1000])

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Eventos son simplemente los procedimientos o funciones (rara vez) que pertenecen a una clase (de ahí el 'objeto' de la cláusula puede ver en la TStateChangeEvent). Por ejemplo, TNotifyEvent es un estándar tipo de evento implementado en Delphi que sólo pasa el objeto que desencadenó el evento, siempre es bueno enviar 'Auto' (Sender : TObject) como el primer parámetro de cualquier evento como el mismo código de evento puede ser utilizado para varios componentes.



TNotifyEvent se define como



tipo

& nbsp & nbsp TState = (stStarted, stStopped)

& nbsp & nbsp TStateChangeEvent = procedimiento Sender : TObject Estado : TState) de objeto



& nbsp & nbsp TThirdComponent = clase(TSecondComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp { Private declarations }

& nbsp & nbsp & nbsp & nbsp FState: TState

& nbsp & nbsp & nbsp & nbsp FOnStart,

& nbsp & nbsp & nbsp & nbsp FOnStop: TNotifyEvent

& nbsp & nbsp & nbsp & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protegido

& nbsp & nbsp & nbsp & nbsp { declaraciones Protegidos }

& nbsp & nbsp público

& nbsp & nbsp & nbsp & nbsp { Public declarations }

& nbsp & nbsp & nbsp & nbsp constructor Create(AOwner : TComponent) reemplazar

& nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar

& nbsp & nbsp & nbsp & nbsp procedimiento Inicio reemplazar

& nbsp & nbsp & nbsp & nbsp procedimiento Dejar reemplazar

& nbsp & nbsp & nbsp & nbsp propiedad Estado: TState leer FState

& nbsp & nbsp publicado

& nbsp & nbsp & nbsp & nbsp { Publicado declaraciones }

& nbsp & nbsp & nbsp & nbsp propiedad OnStart: TNotifyEvent leer FOnStart escribe FOnStart

& nbsp & nbsp & nbsp & nbsp propiedad OnStateChange: TStateChangeEvent leer FOnStateChange

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp escribe FOnStateChange

& nbsp & nbsp & nbsp & nbsp propiedad OnStop: TNotifyEvent leer FOnStop escribe FOnStop

& nbsp & nbsp fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









para llamar A un evento desde dentro de un componente es sólo un caso de la comprobación de si el evento ha sido asignado y, si es así, llama. He reemplazado los métodos Start y Stop de TSecondComponent para desencadenar estos eventos, como tal.





tipo

& nbsp & nbsp TNotifyEvent = procedimiento (Sender: TObject) del objeto

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Recompilar el paquete (no olvides guardar tu paquete en cualquier momento de agregar un nuevo componente). Después de dejar a su nuevo componente en el formulario que usted va a notar que hay tres eventos. OnStart, OnStop, y OnStateChange. Si usted mira Demo3 verá cómo he utilizado estos eventos.



OnStart se establece el título de 'Iniciado'

OnStop muestra el tiempo transcurrido

OnStateChange activa / desactiva el correspondiente botón Start / Stop





procedimiento TThirdComponent.Inicio

begin

& nbsp & nbsp heredado //Esto exige TSecondComponent.Inicio

& nbsp & nbsp FState := stStarted

& nbsp & nbsp si Asignado(OnStart) entonces OnStart(Auto)

& nbsp & nbsp si Asignado(OnStateChange) entonces OnStateChange(Self, Estado)

fin



procedimiento TThirdComponent.Stop

begin

& nbsp & nbsp heredado //Esto exige TSecondComponent.Stop

& nbsp & nbsp FState := stStopped

& nbsp & nbsp si Asignado(OnStop) entonces OnStop(Auto)

& nbsp & nbsp si Asignado(OnStateChange) entonces OnStateChange(Self, Estado)

fin



constructor TThirdComponent.Create(AOwner: TComponent)

begin

& nbsp & nbsp heredado

& nbsp & nbsp //es inicializar las propiedades, y crear

& nbsp & nbsp //y los objetos de su componente puede utilizar internamente

& nbsp & nbsp FState := stStopped

fin



destructor TThirdComponent.Destruir

begin

& nbsp & nbsp //aquí es donde se podría destruir

& nbsp & nbsp //creación de objetos


& nbsp & nbsp heredado

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp







procedimiento TForm1.ThirdComponent1Start(Sender: TObject)

begin

& nbsp & nbsp Caption := 'Inicio'

fin



procedimiento TForm1.ThirdComponent1Stop(Sender: TObject)

begin

& nbsp & nbsp Caption := ThirdComponent1.ElapsedTime

fin



procedimiento TForm1.ThirdComponent1StateChange(Sender: TObject Estado: TState)

begin

& nbsp & nbsp btnStart.Enabled := ThirdComponent1.Estado = stStopped

& nbsp & nbsp btnStop.Enabled := ThirdComponent1.Estado = stStarted

fin

& nbsp & nbsp & nbsp & nbsp





Estándares en el componente de escritura

por último vamos a cubrir un par de puntos más sobre la componente de la escritura, incluyendo algunos de los métodos existentes de componentes de base, y las normas para la escritura.



de la Creación y la destrucción de su componente:

los Objetos se crean a través de un constructor y destruido a través de un destructor. El propósito primordial de un constructor es triple


  1. crear objetos que contiene dentro de sí mismo (sub objetos)

  2. Para inicializar los valores de la clase (propiedades, etc)

  3. Para elevar una excepción y dejar la clase que se va a crear.



Que es el estándar para llamar al constructor heredado desde dentro de su propio constructor, para que los padres de clase puede realizar sus inicializaciones, aunque no es necesario hacerlo con el fin de crear el componente. (Su componente se crea tan pronto como el constructor está terminado, no se crea llamando al constructor heredado)



El propósito de reemplazar un destructor es simplemente para liberar todos los recursos que fueron asignados durante la vida útil del componente. Llame heredado sólo después de haber liberado a estos recursos.



Estándar componentes:

Pintura:

puede invalidar este método para proporcionar su propio dibujo de su componente.



Carga:

Este es llamado por Delphi tan pronto como todas sus propiedades se han terminado de establecer, cuando su padre se crea el formulario. Puede invalidar este método para realizar las acciones que dependen de un grupo de propiedades.



Invalidar: Cuando una propiedad cambia que afecta a la apariencia visual de un componente debe llamar a este método.



ComponentState: Esta propiedad es muy útil cuando usted necesita para comprobar si el componente que existe actualmente en la fase de diseño/tiempo de ejecución, o si sus propiedades están siendo leídas por un proceso de transmisión.



la Encapsulación de su componente correctamente

es un estándar para escribir su componente como TCustomMyClass y luego derivar el componente de la clase base. La 'costumbre' de componentes que se escribe tiene la mayoría (si no todos) de sus propiedades / métodos declarados dentro de su sección Protegida.



Cuando se desciende de su 'costumbre' de la clase simplemente se sus propiedades dentro de la Pública o Publicada secciones.







& nbsp & nbsp & nbsp & nbsp









Esta es una buena práctica ya que permite que otras personas obtienen sus propios componentes basados en la suya, mientras que les permite extraer ciertas propiedades.



Nota cómo SetSomeString ha sido declarado como virtual dentro del área protegida. Este es también el buen comportamiento ya que permite a los descendientes de las clases para responder a los cambios en los valores de la propiedad mediante la sustitución del procedimiento que establece ellos. Esto también se aplica a los eventos, donde se ve un OnStateChange caso de que usted encontrará a menudo un DoStateChange método, por ejemplo:





tipo

& nbsp & nbsp TCustomMyClass = clase(TComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp FSomeString: cadena

& nbsp & nbsp protegido

& nbsp & nbsp & nbsp & nbsp procedimiento SetSomeString(const Valor : string) virtual

& nbsp & nbsp & nbsp & nbsp propiedad SomeString: cadena de leer FSomeString escribe SetSomeString

& nbsp & nbsp fin



& nbsp & nbsp TMyClass = clase(TCustomMyClass)

& nbsp & nbsp publicado

& nbsp & nbsp & nbsp & nbsp propiedad SomeString

& nbsp & nbsp fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp;






& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp;






& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp






& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp;






& nbsp & nbsp & nbsp & nbsp;



& nbsp & nbsp & nbsp & nbsp;









Esto puede parecer un poco complicado, asi que permitanme explicar el proceso.



a: Cuando usted necesita simplemente para añadir funcionalidad extra a un componente existente que se derivan de ese componente. Esto le dara automaticamente el nuevo componente de todos los existentes funcionalidad y propiedades de la componente existente.



B: a Veces, usted no solo tiene que añadir la funcionalidad, pero usted tiene que quitar al mismo tiempo. La practica estandar cuando la escritura de un componente es el primero para escribir una TCustomXXXXX componente donde todas las propiedades / eventos y metodos se declaran dentro de la seccion Protegida del componente. El componente real se deriva de esta clase base. El truco, por tanto, no es para ocultar la funcionalidad, pero para derivar el componente de la 'costumbre' de la version del componente y solo publicar las propiedades que desea guardar (la eliminacion eficaz de las propiedades no deseadas / eventos).



C: Cualquier componente que necesite recibir atencion necesita un identificador de ventana. TWinControl es donde esta la manija se introdujo por primera vez. TCustomControl es simplemente un TWinControl con su propio Lienzo de la propiedad.



D: TGraphicControl no tiene un identificador de ventana y por lo tanto no pueden recibir el foco. Componentes tales como TLabel se derivan de esta clase base.



E: Algunos componentes no se creo para mejorar la GUI de interactividad pero para hacer su vida mas facil. Nada derivados de TComponent solo es visible en tiempo de diseño. Un uso tipico de este tipo de componente es para conexiones de base de datos, temporizadores, etc.



una Vez que hemos decidido que nuestra clase base debe ser, el siguiente paso es crear el componente. Desde el menu Componentes, seleccione Nuevo Componente y vera el siguiente cuadro de dialogo.



Nuevo componente





tipo

& nbsp & nbsp TCustomMyClass = clase(TComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protegido








Componente de la escritura, parte 1


Componente de la escritura, parte 1 : Multi-millones de consejos para hacer su vida mas facil.


en Primer lugar en una serie de tres partes que abarcan componente escrito en Delphi.




Este articulo aparecio originalmente en Desarrolladores de Delphi



derechos de Autor Pinnacle Publishing, Inc. Todos los derechos reservados.







Esta primera parte se muestra algunos de los mejores enfoques para la construccion de los componentes, y al mismo tiempo proporciona consejos para decidir sobre el mejor de la clase base desde la que heredar, el uso de virtual declaraciones, el proceso de sustitucion, y asi sucesivamente.



Las dos primeras cosas que preguntarte a ti mismo, son la razon por la que usted debe hacer uso de un componente de la escritura, y cuando usted debe necesitar para escribir un componente. La primera pregunta es facil de responder, de hecho, tiene muchas respuestas.


  • Facilidad de uso: Encapsulado codigo significa que usted puede colocar simplemente el mismo componente en diversas formas una y otra vez sin necesidad de escribir una sola linea de codigo.

  • Depuracion Centralizada codigo facilita la reparacion de toda la aplicacion (o aplicaciones) mediante la fijacion de un error en un solo componente, y volver a compilar.

  • Dinero: Hay un monton de empresas que estan muy contentos de pagar por el privilegio de no tener que reinventar la rueda.



La segunda pregunta no es demasiado dificil de contestar. Siempre que usted se encuentra el tener que escribir el mismo codigo mas de una vez es una buena idea para escribir un componente, especialmente si el codigo se realiza de forma diferente en funcion de los parametros dados.



¿Como los componentes se crean

El primer paso es decidir que clase base tiene que derivar el componente de. Al derivar de otra clase que hereda de la propiedad / metodo y en caso de que componente posee. A continuacion es un ejemplo de como decidir que clase debe heredar de la hora de escribir su propio componente.



(haga Clic para una vista completa)



haga Clic para ver a tamaño completo



En el caso del metodo a y el metodo B, suponer que el componente en cuestion es TMemo.





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp


MetodoSolucion

se Derivan de TMemo
Bse Derivan de TCustomMemo
Cse Derivan de TCustomControl
Dse Derivan de TGraphicControl
Ese Derivan de TComponent



& nbsp & nbsp & nbsp & nbsp;
Antepasado tipo



& nbsp & nbsp & nbsp & nbsp;
Este es el tipo de base que necesitamos para descender de






& nbsp & nbsp & nbsp & nbsp;
nombre de la Clase



& nbsp & nbsp & nbsp & nbsp;
Este es el nombre de la clase de nuestro nuevo componente

(señaladas con la letra 'T')






& nbsp & nbsp & nbsp & nbsp;
Paleta de la pagina



& nbsp & nbsp & nbsp & nbsp;
Esto es que en la ficha de la paleta de componentes que le gustaria que su

componente a aparecer en, entrar a una inexistente ficha dira

Delphi que le gustaria una nueva pestaña crear.







Escribir algo de codigo

Ya es hora de escribir algo. Este primer ejemplo se tiene ningun uso en todos, excepto para demostrar algunos conceptos basicos de los componentes de la escritura.



lo Primero de todo, seleccionar el Componente de la parte principal de Delphi menu y, a continuacion, seleccione Nuevo Componente. Introduzca TComponent como el 'Antepasado tipo' y TFirstComponent como el nombre del componente. Luego, haga clic en el boton 'Instalar'.



En este punto usted puede instalar su nuevo componente dentro de un paquete existente (un paquete que contiene una coleccion de componentes) o instalar un nuevo paquete. Haga clic en 'nuevo de paquete' y haga clic en el boton 'Examinar'.



Instalar el componente



una Vez que haya seleccionado una ruta de acceso y nombre de archivo para el nuevo paquete y entro en una descripcion haga clic en 'ACEPTAR'. En el siguiente cuadro de dialogo que le preguntara si desea volver a compilar el paquete) haga clic en 'Si'. Una vez que el paquete se compila y se instala, guardar el paquete y la unidad.



En este punto hemos especificado nuestra clase base, y tambien nuestro nuevo nombre de la clase. Hemos creado un nuevo paquete de medidas para contener nuestro componente y se han presentado con un esqueleto de la estructura de clases por Delphi.



Si usted mira el codigo fuente proporcionado por Delphi ahora vera el Private, Protected, Public, y Publico articulos.



la Encapsulacion

la Encapsulacion es un concepto sencillo de comprender, pero extremadamente importante componente de la escritura. La encapsulacion se lleva a cabo con el uso de cuatro palabras reservadas: Privado, Protegido, Las, y Publicado, aparecera el Delphi ha incluido estas secciones automaticamente en el codigo fuente para el nuevo componente.





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp





& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp







& nbsp & nbsp & nbsp & nbsp

& nbsp & nbsp & nbsp & nbsp











Comenzar a escribir nuestro componente

Delphi ahora necesita saber todo acerca de nuestro nuevo componente. Escriba el codigo siguiente en el componente de codigo fuente.

SeccionAccesibilidad
Privadolos Metodos, Propiedades y Eventos declarados dentro de esta seccion solo se

accesible a la unidad de la componente de contenidos

dentro. Componentes en la misma unidad puede acceder a cada uno

Privados de otros elementos.
ProtegidoMetodos, Propiedades y Eventos declarados dentro de esta seccion tambien

accesible para cualquier clase de descendientes de esta clase.
PublicoMetodos, Propiedades y Eventos declarados aqui accesible desde cualquier lugar.
PublicadoEsta seccion permite declarar propiedades y eventos que apareceran en la

inspector de objetos. Estos valores son de diseño los valores de tiempo de

que se guardan con el proyecto. (No todos los tipos son:

compatible, matrices, por ejemplo, no lo son).




& nbsp & nbsp & nbsp & nbsp







Lo que hemos hecho aqui se agregan dos variables FStartTime y FStopTime (que es el estandar para preceder a los nombres de variables con la letra F). Hay dos metodos para el control de estas variables, de Inicio y de Parada. Hemos añadido una funcion GetElapsedTime que volvera FStopTime - FStartTime como una cadena. Por ultimo, hemos agregado tres propiedades de solo lectura.



Presione SHIFT-CTRL-C y Delphi se complete automaticamente el codigo de la clase (o haga clic en el boton derecho del raton y seleccione 'clase Completa en el cursor'). A continuacion escriba el siguiente codigo para cada metodo.





privada

& nbsp & nbsp { Private declarations }

& nbsp & nbsp FStartTime,

& nbsp & nbsp FStopTime :DWord

protegido

& nbsp & nbsp { declaraciones Protegidos }

& nbsp & nbsp funcion GetElapsedTime: cadena de virtual

publico

& nbsp & nbsp { Public declarations }

& nbsp & nbsp procedimiento Inicio virtual

& nbsp & nbsp procedimiento Dejar virtual



& nbsp & nbsp propiedad StartTime:DWord leer FStartTime

& nbsp & nbsp propiedad StopTime:DWord leer FStopTime

& nbsp & nbsp propiedad ElapsedTime: cadena de leer GetElapsedTime

publicado

& nbsp & nbsp { Publicado declaraciones }

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Prueba de la unidad

Guardar su unidad y vuelva a abrir el paquete (Archivo, Abrir Proyecto en el menu, y seleccione 'Delphi' Paquete para el tipo de archivo), una vez que el paquete esta abierto haga clic en el boton 'Compilar'. Tambien puede abrir el paquete de la eleccion de Componente en el menu principal y, a continuacion, Instalar los Paquetes. Seleccione su paquete y, a continuacion, haga clic en el boton 'Editar'.



ahora puede soltar un TFirstComponent en un formulario, de hecho, usted puede colocar tantos como desee. Agregue dos botones (btnStart y btnStop) y agregue el siguiente codigo al formulario y, a continuacion, ejecutar la aplicacion de prueba'.





{ TFirstComponent }

funcion TFirstComponent.GetElapsedTime: string

begin

& nbsp & nbsp Resultado := IntToStr(FStopTime - FStartTime)

fin



procedimiento TFirstComponent.Inicio

begin

& nbsp & nbsp FStartTime := GetTickCount

fin



procedimiento TFirstComponent.Stop

begin

& nbsp & nbsp FStopTime := GetTickCount

fin



fin.

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp







procedimiento TForm1.btnStartClick(Sender: TObject)

begin

& nbsp & nbsp FirstComponent1.Inicio

fin



procedimiento TForm1.btnStopClick(Sender: TObject)

begin

& nbsp & nbsp FirstComponent1.Stop

& nbsp & nbsp Caption := FirstComponent1.ElapsedTime

fin

& nbsp & nbsp & nbsp & nbsp





Clic en el boton 'Inicio' va a marcar la hora de inicio (GetTickCount es un WinAPI comando que devuelve el numero de milisegundos desde el inicio de Windows).



Clic en el boton 'Stop' marca de la hora de parada, y cambiar el titulo del formulario.



Virtual, Dinamico, Abstracto y Reemplazar

Usted puede haber notado la virtual de la declaracion despues de Iniciar, Detener y GetElapsedTime. El siguiente ejercicio te explica sus usos.



Crear un nuevo componente, se derivan de este componente de TFirstComponent (nombre TSecondComponent) e instalarlo.



El Virtual y Dinamica de los identificadores son un componente del escritor manera de decirle a Delphi que el metodo puede ser reemplazado en un descendiente de la clase. Si queremos sobreescribir un metodo en una clase, nuestro nuevo codigo se ejecutara en lugar de la original del codigo.







& nbsp & nbsp & nbsp & nbsp









Nosotros, a continuacion, implementar el codigo anterior de la siguiente manera.





protegido

& nbsp & nbsp { Declaraciones protegidos }

& nbsp & nbsp funcion GetElapsedTime: cadena de reemplazar

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Nuestro codigo nuevo es que ahora se llama en sustitucion de la original GetElapsedTime, incluso las llamadas implementado en TFirstComponent a GetElapsed tiempo de llamar a nuestro nuevo codigo (si hemos creado una instancia de TSecondComponent que es). El codigo original se invoca a traves de la utilizacion de los Heredado de comandos.



Nota : Si no 'anular' una base de metodo (ya que la base no fue declarado como virtual o porque se le olvido). TSecondComponent llamara el nuevo codigo, mientras que el codigo implementado en TFirstComponent todavia siguen pidiendo el codigo original de TFirstComponent.



El Resumen identificador dice Delphi no esperar ningun codigo para el metodo con nombre. Usted no debe crear una instancia de un objeto con metodos abstractos (como el TStrings). La practica estandar es crear un descendiente de una clase y reemplazar todos los metodos abstractos (como TStringList).



Dinamica Vs Virtual es simplemente una cuestion de velocidad Vs tamaño. Un metodo Dinamico se traducira en cada instancia de una clase que requiere menos memoria, mientras que un metodo Virtual se ejecutara mas rapido en el costo de un poco mas de memoria.



Hay algunos pasos simples para agregar eventos a su componente. Los eventos permiten que el componente para comunicarse con su aplicacion, para notificar cuando algo importante ha sucedido. Un evento es simplemente una propiedad de lectura y escritura, en lugar de ser un simple tipo de variable (como string, integer, etc) es un procedimiento o funcion.



Crear un nuevo componente, descender de TSecondComponent y el nombre de TThirdComponent. Guardar la unidad, instalar el componente, y agregue el siguiente codigo.



funcion TSecondComponent.GetElapsedTime: string

var

& nbsp & nbsp S: string

begin

& nbsp & nbsp S := heredado GetElapsedTime

& nbsp & nbsp Resultado := S ' milisegundos o '

& nbsp & nbsp & nbsp & nbsp Formato('%.2f segundos',

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp [(StopTime - StartTime) / 1000])

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Eventos son simplemente los procedimientos o funciones (rara vez) que pertenecen a una clase (de ahi el 'objeto' de la clausula puede ver en la TStateChangeEvent). Por ejemplo, TNotifyEvent es un estandar tipo de evento implementado en Delphi que solo pasa el objeto que desencadeno el evento, siempre es bueno enviar 'Auto' (Sender : TObject) como el primer parametro de cualquier evento como el mismo codigo de evento puede ser utilizado para varios componentes.



TNotifyEvent se define como



tipo

& nbsp & nbsp TState = (stStarted, stStopped)

& nbsp & nbsp TStateChangeEvent = procedimiento Sender : TObject Estado : TState) de objeto



& nbsp & nbsp TThirdComponent = clase(TSecondComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp { Private declarations }

& nbsp & nbsp & nbsp & nbsp FState: TState

& nbsp & nbsp & nbsp & nbsp FOnStart,

& nbsp & nbsp & nbsp & nbsp FOnStop: TNotifyEvent

& nbsp & nbsp & nbsp & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protegido

& nbsp & nbsp & nbsp & nbsp { declaraciones Protegidos }

& nbsp & nbsp publico

& nbsp & nbsp & nbsp & nbsp { Public declarations }

& nbsp & nbsp & nbsp & nbsp constructor Create(AOwner : TComponent) reemplazar

& nbsp & nbsp & nbsp & nbsp destructor Destruir reemplazar

& nbsp & nbsp & nbsp & nbsp procedimiento Inicio reemplazar

& nbsp & nbsp & nbsp & nbsp procedimiento Dejar reemplazar

& nbsp & nbsp & nbsp & nbsp propiedad Estado: TState leer FState

& nbsp & nbsp publicado

& nbsp & nbsp & nbsp & nbsp { Publicado declaraciones }

& nbsp & nbsp & nbsp & nbsp propiedad OnStart: TNotifyEvent leer FOnStart escribe FOnStart

& nbsp & nbsp & nbsp & nbsp propiedad OnStateChange: TStateChangeEvent leer FOnStateChange

& nbsp & nbsp & nbsp & nbsp & nbsp & nbsp escribe FOnStateChange

& nbsp & nbsp & nbsp & nbsp propiedad OnStop: TNotifyEvent leer FOnStop escribe FOnStop

& nbsp & nbsp fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









para llamar A un evento desde dentro de un componente es solo un caso de la comprobacion de si el evento ha sido asignado y, si es asi, llama. He reemplazado los metodos Start y Stop de TSecondComponent para desencadenar estos eventos, como tal.





tipo

& nbsp & nbsp TNotifyEvent = procedimiento (Sender: TObject) del objeto

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp









Recompilar el paquete (no olvides guardar tu paquete en cualquier momento de agregar un nuevo componente). Despues de dejar a su nuevo componente en el formulario que usted va a notar que hay tres eventos. OnStart, OnStop, y OnStateChange. Si usted mira Demo3 vera como he utilizado estos eventos.



OnStart se establece el titulo de 'Iniciado'

OnStop muestra el tiempo transcurrido

OnStateChange activa / desactiva el correspondiente boton Start / Stop





procedimiento TThirdComponent.Inicio

begin

& nbsp & nbsp heredado //Esto exige TSecondComponent.Inicio

& nbsp & nbsp FState := stStarted

& nbsp & nbsp si Asignado(OnStart) entonces OnStart(Auto)

& nbsp & nbsp si Asignado(OnStateChange) entonces OnStateChange(Self, Estado)

fin



procedimiento TThirdComponent.Stop

begin

& nbsp & nbsp heredado //Esto exige TSecondComponent.Stop

& nbsp & nbsp FState := stStopped

& nbsp & nbsp si Asignado(OnStop) entonces OnStop(Auto)

& nbsp & nbsp si Asignado(OnStateChange) entonces OnStateChange(Self, Estado)

fin



constructor TThirdComponent.Create(AOwner: TComponent)

begin

& nbsp & nbsp heredado

& nbsp & nbsp //es inicializar las propiedades, y crear

& nbsp & nbsp //y los objetos de su componente puede utilizar internamente

& nbsp & nbsp FState := stStopped

fin



destructor TThirdComponent.Destruir

begin

& nbsp & nbsp //aqui es donde se podria destruir

& nbsp & nbsp //creacion de objetos


& nbsp & nbsp heredado

fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp & nbsp & nbsp







procedimiento TForm1.ThirdComponent1Start(Sender: TObject)

begin

& nbsp & nbsp Caption := 'Inicio'

fin



procedimiento TForm1.ThirdComponent1Stop(Sender: TObject)

begin

& nbsp & nbsp Caption := ThirdComponent1.ElapsedTime

fin



procedimiento TForm1.ThirdComponent1StateChange(Sender: TObject Estado: TState)

begin

& nbsp & nbsp btnStart.Enabled := ThirdComponent1.Estado = stStopped

& nbsp & nbsp btnStop.Enabled := ThirdComponent1.Estado = stStarted

fin

& nbsp & nbsp & nbsp & nbsp





Estandares en el componente de escritura

por ultimo vamos a cubrir un par de puntos mas sobre la componente de la escritura, incluyendo algunos de los metodos existentes de componentes de base, y las normas para la escritura.



de la Creacion y la destruccion de su componente:

los Objetos se crean a traves de un constructor y destruido a traves de un destructor. El proposito primordial de un constructor es triple


  1. crear objetos que contiene dentro de si mismo (sub objetos)

  2. Para inicializar los valores de la clase (propiedades, etc)

  3. Para elevar una excepcion y dejar la clase que se va a crear.



Que es el estandar para llamar al constructor heredado desde dentro de su propio constructor, para que los padres de clase puede realizar sus inicializaciones, aunque no es necesario hacerlo con el fin de crear el componente. (Su componente se crea tan pronto como el constructor esta terminado, no se crea llamando al constructor heredado)



El proposito de reemplazar un destructor es simplemente para liberar todos los recursos que fueron asignados durante la vida util del componente. Llame heredado solo despues de haber liberado a estos recursos.



Estandar componentes:

Pintura:

puede invalidar este metodo para proporcionar su propio dibujo de su componente.



Carga:

Este es llamado por Delphi tan pronto como todas sus propiedades se han terminado de establecer, cuando su padre se crea el formulario. Puede invalidar este metodo para realizar las acciones que dependen de un grupo de propiedades.



Invalidar: Cuando una propiedad cambia que afecta a la apariencia visual de un componente debe llamar a este metodo.



ComponentState: Esta propiedad es muy util cuando usted necesita para comprobar si el componente que existe actualmente en la fase de diseño/tiempo de ejecucion, o si sus propiedades estan siendo leidas por un proceso de transmision.



la Encapsulacion de su componente correctamente

es un estandar para escribir su componente como TCustomMyClass y luego derivar el componente de la clase base. La 'costumbre' de componentes que se escribe tiene la mayoria (si no todos) de sus propiedades / metodos declarados dentro de su seccion Protegida.



Cuando se desciende de su 'costumbre' de la clase simplemente se sus propiedades dentro de la Publica o Publicada secciones.







& nbsp & nbsp & nbsp & nbsp









Esta es una buena practica ya que permite que otras personas obtienen sus propios componentes basados en la suya, mientras que les permite extraer ciertas propiedades.



Nota como SetSomeString ha sido declarado como virtual dentro del area protegida. Este es tambien el buen comportamiento ya que permite a los descendientes de las clases para responder a los cambios en los valores de la propiedad mediante la sustitucion del procedimiento que establece ellos. Esto tambien se aplica a los eventos, donde se ve un OnStateChange caso de que usted encontrara a menudo un DoStateChange metodo, por ejemplo:





tipo

& nbsp & nbsp TCustomMyClass = clase(TComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp FSomeString: cadena

& nbsp & nbsp protegido

& nbsp & nbsp & nbsp & nbsp procedimiento SetSomeString(const Valor : string) virtual

& nbsp & nbsp & nbsp & nbsp propiedad SomeString: cadena de leer FSomeString escribe SetSomeString

& nbsp & nbsp fin



& nbsp & nbsp TMyClass = clase(TCustomMyClass)

& nbsp & nbsp publicado

& nbsp & nbsp & nbsp & nbsp propiedad SomeString

& nbsp & nbsp fin

& nbsp & nbsp & nbsp & nbsp




& nbsp & nbsp


tipo

& nbsp & nbsp TCustomMyClass = clase(TComponent)

& nbsp & nbsp privada

& nbsp & nbsp & nbsp & nbsp FOnStateChange: TStateChangeEvent

& nbsp & nbsp protegido

Componente de la escritura, parte 1

Componente de la escritura, parte 1 : Multi-millones de consejos para hacer su vida más fácil.
Recommander aux amis
  • gplus
  • pinterest

Comentario

Dejar un comentario

Clasificación

Consejos Y Trucos www.consejosytrucos.net Ciempozuelos, Madrid Extramuros 82 ES-M 28350 Spain 674 192 969