El componente visual es en realidad una clase. Para escribir una clase, puede escribirla directamente en el archivo *.pas. Pero para escribir controles, debes usar paquetes. Seleccione Nuevo en el menú Archivo para crear un nuevo paquete. Este es el paquete utilizado para almacenar e instalar el control. Luego haga clic en el botón Agregar en la ventana Paquete para agregar un componente (Unidad).
Seleccione Nuevo componente en la parte superior del cuadro de diálogo emergente. Debido a que es imposible programar todas las propiedades, métodos y eventos de un control usted mismo, debe seleccionar la clase antecesora (o "clase principal" o "clase base") y luego agregar sus propias propiedades, métodos y eventos a ello. Seleccione la clase de ancestro requerida en el cuadro desplegable después del tipo de ancestro. Dado que escribir controles visuales requiere dibujar, se selecciona TGraphicControl como clase antecesora. Luego ingrese el nombre del nuevo control (clase) en el cuadro Nombre de clase, que generalmente comienza con "T". La página de paleta se utiliza para seleccionar el nombre de la página de control del nuevo control en la ventana de Delphi, como "Estándar". Puede elegirlo usted mismo. Agregue la ruta y el nombre del archivo del nuevo archivo de control en Nombre de archivo de unidad y haga clic en el botón Aceptar. Se agregan nuevos controles. Ahora es el momento de escribir código para el control.
A continuación se toma como ejemplo la escritura de una barra de desplazamiento que puede personalizar imágenes para ilustrar el método de escritura de controles visuales.
Siga el método anterior, seleccione TGraphicControl como clase ancestral y el nombre del nuevo control es TPigHorizontalScroller. Después de seleccionar la ruta del archivo y el nombre del archivo, haga clic en el botón Aceptar para comenzar a escribir código.
Cada control será creado (Crear) y eliminado (Destruir), por lo que estos dos procesos deben escribirse primero. Para cada procedimiento en el control, se debe definir primero y luego escribirlo. Hay tres tipos de procesos o propiedades definidas: 1. Los definidos después de PRIvate son usados internamente por el control y no pueden ser vistos por las personas que usan el control 2. Los definidos después de protected son generalmente invisibles y solo pueden ser utilizados por otros cuando; otros usan el control. El control solo es visible cuando se escriben otros controles como una clase ancestral; 3. Los definidos después de público solo pueden ser llamados por otros en el programa. 4. Los definidos después de publicados se pueden ver en la ventana de propiedades (Objeto); Inspector). Dado que el proceso de creación y eliminación no solo se ejecuta automáticamente cuando se crea el control durante el proceso de programación, sino que también se puede llamar cuando el control se crea dinámicamente durante la ejecución del programa, se define después de público (1). (El número de serie indica la posición del código del subpaso en el programa fuente adjunto, el mismo a continuación) Quizás aún no sepas qué se debe compilar en estos dos procesos y cómo compilarlo. Hablaremos de ello a continuación.
Primero agreguemos algunas propiedades a este control. Definimos una propiedad Max para establecer o leer el valor máximo de la barra de desplazamiento. Debido a que los atributos generalmente no se usan directamente en los programas, se debe definir una variable que corresponda al atributo y su valor se puede modificar o leer. Debido a que solo se usa dentro del control, lo definimos después de privado (2). (Generalmente, las variables asociadas con atributos comienzan con "F", como FMax) Después de definir las variables, defina los atributos. Esta propiedad debe estar visible en la ventana del Inspector de objetos, así que defínala y publíquela (3). La sintaxis definida es:
propiedad <nombre de propiedad>:<tipo> leer <variable correspondiente al leer esta propiedad> escribir <variable o procedimiento correspondiente al escribir esta propiedad>
Otras variables y atributos también se definen de manera similar (como el valor mínimo mínimo, el valor actual, etc.). A continuación, definimos varias propiedades y variables para configurar la imagen de la barra de desplazamiento (debido a que la variable de imagen es especial, hablaremos de ella por separado). Definimos LeftButtonUpPicture (imagen del botón izquierdo), LeftButtonDownPicture (imagen al presionar el botón izquierdo), etc. como tipos TBitmap (se deben definir las variables correspondientes).
Debes haber notado que en el programa fuente adjunto, al definir estos atributos, la variable correspondiente al atributo leído después de la lectura es F..., pero la variable correspondiente al atributo especificado después de la escritura no es una Variable, sino algo así como Set ... Este es un proceso personalizado. El proceso como función se define como:
procedimiento <nombre del procedimiento>(Valor: <tipo de valor del atributo que se establece>)
Debido a que es necesario hacer otras cosas al escribir este tipo de atributo, no puede simplemente usar una variable para manejarlo, debe usar un proceso para manejarlo. Este proceso generalmente se define después de protegido. En este tipo de procedimiento, se utiliza una declaración como ⑷ para asignar un valor a una variable del tipo TBitmap. Esto se adopta porque a las variables de este tipo no se les puede asignar un valor directamente.
Después de definir las propiedades de estas variables de tipo TBitmap, debe escribir código en el proceso de creación y destrucción mencionado anteriormente. Debido a que TBitmap también es una clase, debe crearse durante el proceso de creación (5) y debe liberarse (liberarse) durante el proceso de destrucción (6). La declaración heredada a la que se hace referencia en ⑺ aquí se utiliza para indicar que el proceso se hereda de la clase ancestral. (Esto no se debe dejar caer).
Debido a que estamos escribiendo un control visual, debemos hacer dibujos en el control. La clase ancestral de nuestro control, TGraphicControl, encapsula un objeto Canvas (lienzo) y podemos usarlo directamente para hacer dibujos. Si aún no estás familiarizado con el uso del lienzo, es una buena idea buscar un libro y leerlo.
Lo siguiente que debe hacer es hacer el dibujo. ¿Cómo hacer dibujos en el control? Hay un evento Paint en la clase ancestral TGraphicControl, que se activa automáticamente cuando es necesario volver a dibujar el control. Lo que tenemos que hacer ahora es escribir un programa para este evento. Primero defina un objeto Canvas después de protegerlo. Como ya existe en la clase ancestral, no es necesario agregar ninguna explicación⑻. Usaremos este objeto para dibujar la imagen. A continuación, debe definir un proceso de Paint y escribir el código para dibujar el control. Defina el proceso de pintura primero después del público. Dado que lo activa la clase ancestral en lugar de ser llamado por el usuario, se debe agregar la anulación después. De lo contrario, el control no se convertirá en un control visual porque nunca se llamará al proceso Paint. A continuación escribiremos el código para el proceso Paint⑽.
T_Height y otras variables en el proceso Paint del programa fuente adjunto a este artículo se utilizan para guardar el tamaño de los botones, controles deslizantes, etc. en la barra de desplazamiento. Esta parte del programa no es muy diferente del programa en aplicaciones normales. La mayoría de ellos son para operar en el lienzo, creo que todos lo entenderán de un vistazo. Vale la pena señalar el siguiente juicio sobre la variable FAutoSize. FAutoSize es una variable booleana asociada con el atributo AutoSize del control. Se utiliza para establecer si el tamaño del control cambia con el tamaño de la imagen. Tenga en cuenta que en el código del control, las propiedades generalmente no se llaman directamente, sino que se utilizan las variables correspondientes.
En este punto del programa, finalmente ha aparecido su nuevo control, pero aún no puede desplazarse. Ahora escribamos eventos del mouse que nos permitirán manipularlo. La definición del proceso de eventos del mouse es muy similar al proceso Paint, excepto que las descripciones de los parámetros deben agregarse al final. Los eventos del mouse se dividen en tres tipos: MouseDown, MouseMove y MouseUp deben agregarse después de la definición. Luego escriba su código detrás. Nota: El evento del mouse aquí es Mouse..., no el habitual OnMouse.... Pero, ¿para qué se utiliza la definición en ⒀? Las definiciones de eventos aquí son todas para usuarios, es decir, cuando se usa el control, se mostrará en la página Evento en el Inspector de objetos.
El código para estos eventos del mouse también es muy simple: determina las coordenadas del mouse, dibuja la imagen correspondiente en el lienzo, etc., y activa el evento correspondiente al mismo tiempo. Vale la pena señalar que al llamar a un evento personalizado, primero debe usar una declaración como ⒁ para determinar si el usuario ha escrito código para el evento. Esto es muy importante, de lo contrario se producirá un error.
Todos han notado que los eventos que acabamos de llamar están todos personalizados y el método definido también es muy simple. Es similar a definir propiedades, excepto que el tipo es TNotifyEvent.
TNotifyEvent es el evento predeterminado, que se define como:
TNotifyEvent = procedimiento (Remitente: TObject)
Si deseas definir otra forma de evento, debes hacer esto: escríbelo primero y luego escribe
<nombre del tipo de evento> = procedimiento(<parámetro>:<tipo>)
Por ejemplo:
TCustomEvent = procedimiento(a: Entero; b:Cadena);
Luego defínelo después de público:
<nombre del evento>:<nombre del tipo de evento>
Por ejemplo:
UnEvento: TCustomEvent;
Después de leer esto, debería comprender todo el procedimiento. Si se producen errores de compilación o ejecución, verifique los siguientes puntos:
1. ¿Existen declaraciones heredadas en los procesos de creación y destrucción?
2. ¿Se han creado y liberado las variables de tipo TBitmap?
3. ¿Hay un nombre de control antes del proceso, por ejemplo: TPigHorizontalScroller.MoseMove?
Cómo determinar si el mouse entra o sale del control:
Defina el siguiente proceso:
procedimiento MouseEnter(var Msg: TMessage); mensaje CM_MOUSEENTER;
procedimiento MouseLeave(var Msg: TMessage); mensaje CM_MOUSELEAVE;