Академический Документы
Профессиональный Документы
Культура Документы
• by Zarko Gajic
Si lee entre líneas, encontrará que los métodos de clase son accesibles incluso
cuando no haya creado una instancia de la clase (el objeto).
myCheckbox.Repaint;
Los métodos de clase se pueden invocar sin una instancia de la clase (p. Ej.,
"TCheckbox.Create"). Los métodos de clase también se pueden invocar
directamente desde un objeto (p. Ej., "MyCheckbox.ClassName"). Sin embargo,
los métodos de objeto solo pueden invocarse mediante una instancia de una clase
(por ejemplo, "myCheckbox.Repaint").
~~~~~~~~~~~~~~~~~~~~~~~~~
procedimiento TfrMain.mnuInfoClick (Sender: TObject);
empezar
AboutBox: = TAboutBox.Create (nil);
tratar
AboutBox.ShowModal;
finalmente
AboutBox.Release;
fin;
fin;
~~~~~~~~~~~~~~~~~~~~~~~~~
Esto, por supuesto, es una muy buena forma de hacer el trabajo, pero solo para
hacer que el código sea más fácil de leer (y administrar), sería mucho más
eficiente cambiarlo a:
~~~~~~~~~~~~~~~~~~~~~~~~~
procedimiento TfrMain.mnuInfoClick (Sender: TObject);
empezar
TAboutBox.ShowYourself;
fin;
~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~
procedimiento de clase TAboutBox.ShowYourself;
empezar
AboutBox: = TAboutBox.Create (nil);
tratar
AboutBox.ShowModal;
finalmente
AboutBox.Release;
fin;
fin;
~~~~~~~~~~~~~~~~~~~~~~~~~
• Errores, Excepciones?
• Una excepción generalmente es una condición de error u otro evento que
interrumpe el flujo normal de ejecución en una aplicación. Cuando se
produce un error al procesar una línea de código, Delphi crea (aumenta) un
descendiente de objeto de TObject llamado objeto de excepción.
• Bloques guardados
• Una aplicación responde a una excepción ejecutando un código de
terminación, manejando la excepción o ambas. La forma de habilitar la
captura de error / excepción dentro de un código dado, la excepción debe
ocurrir dentro de un bloque de instrucciones oculto. El código general se ve
así:
• Ejemplo:
• > ... Cero: = 0; try dummy: = 10 / Zero; excepto en EZeroDivide do MessageDlg ('No
se puede dividir por cero!', mtError, [mbOK], 0); fin; ...
• Protección de recursos
• Cuando una sección de código adquiere un recurso, a menudo es
necesario garantizar que el recurso se libera nuevamente (o puede tener
una fuga de memoria ), independientemente de si el código se completa
normalmente o si se interrumpe con una excepción.
• > {algún código para asignar recursos} intente {bloque de código guardado}
finalmente {bloque de terminación - código para liberar recursos} final;
• Ejemplo:
• Application.OnException
• Si su aplicación no maneja el error que causó la excepción, Delphi usará su
manejador de excepción predeterminado: aparecerá un cuadro de mensaje.
Puede considerar escribir código en el evento OnException para el objeto
TApplication, para atrapar errores en el nivel de la aplicación.
• Break On Exceptions
• Al crear un programa con manejo de excepciones, es posible que no desee
que Delphi incumpla las Excepciones. Esta es una gran característica si
desea que Delphi muestre dónde se ha producido una excepción; sin
embargo, puede ser molesto cuando prueba su propio manejo de
excepciones.
De forma nativa, Delphi admite imágenes BMP, ICO, WMF y JPG, que pueden
cargarse en un componente compatible con gráficos (como TImage) y utilizarse en
una aplicación.
Nota: A partir de Delphi versión 2006, el formato GIF es compatible con el VCL.
Para utilizar imágenes GIF animadas, aún necesitaría un control de terceros.
GIF es el formato de gráficos más compatible (mapa de bits) en la Web, tanto para
imágenes fijas como para animaciones.
Usando en Delphi
▪ TGIFImage [1] - gratis con fuente (una versión de TGIFImage de Anders Melander
portada a Delphi 7). Implementación completa de TGraphic del formato de
gráficos GIF. Lee, escribe y muestra archivos GIF animados y transparentes, y
puede convertir a cualquier formato compatible con TGraphic (por ejemplo,
TBitmap, TJPEGImage, TIcon, TMetaFile, etc.). Implementa las especificaciones
completas GIF87a y GIF89a y las extensiones GIF más comunes. Las
características avanzadas incluyen:
▪ Se integra con TPicture para agregar compatibilidad GIF a los componentes
TImage, TOpenPictureDialog y TSavePictureDialog. También funciona en
tiempo de diseño.
▪ Importa imágenes con más de 256 colores utilizando la cuantización del
color y 6 diferentes métodos de difuminado (por ejemplo, floyd s! Teinberg).
▪ Motor de dibujo multihilo.
▪ El optimizador de GIF reduce el tamaño de tus GIF.
▪ Conversor GIF a AVI y AVI a GIF.
Los juegos y otros tipos de aplicaciones que usan archivos multimedia como
sonidos y animaciones deben distribuir los archivos multimedia adicionales junto
con la aplicación o insertar los archivos dentro del ejecutable.
En lugar de distribuir archivos separados para el uso de su aplicación, puede
agregar los datos sin formato a su aplicación como recurso. A continuación, puede
recuperar los datos de su aplicación cuando sea necesario.
Esta técnica es generalmente más deseable porque puede evitar que otros
manipulen esos archivos de complemento.
1. Cree un archivo de script de recursos (.rc) que describa los recursos utilizados
por su aplicación.
2. Compile el archivo de archivo de script de recursos (.rc) para crear un archivo de
recursos (.res),
3. Enlace el archivo de recursos compilados en el archivo ejecutable de la
aplicación,
4. Use un elemento de recurso individual.
El primer paso debe ser simple, simplemente decida qué tipos de archivos desea
almacenar en su ejecutable.
Por ejemplo, almacenaremos dos canciones .wav, una animación .ani y una
canción .mp3.
Nota: asegúrese de tener todos los recursos que lista en su archivo .rc disponible.
Si los archivos están dentro del directorio de proyectos, no es necesario que
incluya el nombre completo del archivo. En mi archivo .rc, las canciones .wav se
encuentran * en algún lugar * en el disco y tanto la animación como la canción
mp3 se encuentran en el directorio del proyecto.
BRCC32 AboutDelphi.RC
De forma predeterminada, al compilar recursos, BRCC32 nombra el archivo de
recursos compilados (.RES) con el nombre base del archivo .RC y lo coloca en el
mismo directorio que el archivo .RC.
Puede asignarle al archivo de recursos todo lo que desee, siempre que tenga la
extensión ".RES" y el nombre del archivo sin la extensión no sea el mismo que el
de cualquier unidad o proyecto. Esto es importante porque, de forma
predeterminada, cada proyecto Delphi que se compila en una aplicación tiene un
archivo de recursos con el mismo nombre que el archivo del proyecto, pero con la
extensión .RES. Lo mejor es guardar el archivo en el mismo directorio que su
archivo de proyecto.
Jugando WAVs
Como hemos colocado dos archivos WAVE en nuestro archivo ejecutable, ahora
veremos cómo tomar una canción dentro del archivo ejecutable. Coloque un botón
(Button1) en un formulario y asigne el siguiente código al controlador de eventos
OnClick: > usa mmsystem; ... procedimiento TForm1.Button1Click (Sender:
TObject); var hFind, hRes: THandle; Canción: PChar; begin hFind: = FindResource
(HInstance, 'MailBeep', 'WAVE'); si hFind <> 0 entonces comienza hRes: =
LoadResource (HInstance, hFind); si hRes <> 0 entonces comienza Song: =
LockResource (hRes); si se asigna (canción), luego SndPlaySound (canción,
snd_ASync o snd_Memory); UnlockResource (hRes); fin ; FreeResource
(hFind); fin ; fin ; Este enfoque usa varias llamadas API para cargar un recurso de
tipo WAVE llamado MailBeep y reproducirlo. Nota: tu cal utiliza Delphi para
reproducir sonidos predefinidos del sistema.
Reproducción de MP3
El único archivo MP3 en nuestro recurso tiene el nombre Intro. Dado que este
recurso es del tipo RCDATA, utilizaremos otra técnica para obtener y reproducir la
canción mp3. En caso de que no sepa que Delphi puede reproducir canciones MP3,
lea el artículo " Cree su propio WinAmp ". Sí, así es, TMediaPlayer puede reproducir
el archivo mp3.
Ahora, agregue el componente TMediaPlayer a un formulario (nombre:
MediaPlayer1) y agregue un TButton (Button2). Deje que el evento OnClick se vea
así:
Extrayendo *. ???
Por supuesto, cualquier otro tipo de archivo binario se puede almacenar como un
tipo de RCDATA. El TRsourceStream está diseñado especialmente para ayudarnos a
extraer dicho archivo de un ejecutable. Las posibilidades son infinitas: HTML en un
exe, EXE en exe, base de datos vacía en un exe, ....
• Es por esa razón que puede leer acerca de cómo una cadena u objeto es
realmente solo un puntero, o que un controlador de eventos como OnClick,
en realidad es un puntero a un procedimiento.
• Para concretar esta definición, tenga en cuenta que todo lo que usa una
aplicación se almacena en algún lugar de la memoria de la computadora.
Como un puntero contiene la dirección de otra variable, se dice que apunta
a esa variable.
• > var iValue, j: entero ; pIntValue: ^ entero; begin iValue: = 2001; pIntValue: =
@iValue; ... j: = pIntValue ^; fin ;
• Punteros de personaje
• Los tipos fundamentales PAnsiChar y PWideChar representan punteros a
los valores de AnsiChar y WideChar. El PChar genérico representa un
puntero a una variable Char.
• Las funciones de API de Windows usan una cantidad de tipos de datos que
pueden ser desconocidos para el programador Delphi. La mayoría de los
parámetros en las funciones de API de llamada son indicadores de algún
tipo de datos. Como se indicó anteriormente, usamos cadenas terminadas
en nulo en Delphi cuando llamamos a funciones de la API de Windows.
• Errores, Excepciones?
• Una excepción generalmente es una condición de error u otro evento que
interrumpe el flujo normal de ejecución en una aplicación. Cuando se
produce un error al procesar una línea de código, Delphi crea (aumenta) un
descendiente de objeto de TObject llamado objeto de excepción.
• Bloques guardados
• Una aplicación responde a una excepción ejecutando un código de
terminación, manejando la excepción o ambas. La forma de habilitar la
captura de error / excepción dentro de un código dado, la excepción debe
ocurrir dentro de un bloque de instrucciones oculto. El código general se ve
así:
• Ejemplo:
• > ... Cero: = 0; try dummy: = 10 / Zero; excepto en EZeroDivide do MessageDlg ('No
se puede dividir por cero!', mtError, [mbOK], 0); fin; ...
• Protección de recursos
• Cuando una sección de código adquiere un recurso, a menudo es
necesario garantizar que el recurso se libera nuevamente (o puede tener
una fuga de memoria ), independientemente de si el código se completa
normalmente o si se interrumpe con una excepción.
• En este caso, la sintaxis utiliza finalmente la palabra clave y se ve así:
• > {algún código para asignar recursos} intente {bloque de código guardado}
finalmente {bloque de terminación - código para liberar recursos} final;
• Ejemplo:
• Application.OnException
• Si su aplicación no maneja el error que causó la excepción, Delphi usará su
manejador de excepción predeterminado: aparecerá un cuadro de mensaje.
Puede considerar escribir código en el evento OnException para el objeto
TApplication, para atrapar errores en el nivel de la aplicación.
• Break On Exceptions
• Al crear un programa con manejo de excepciones, es posible que no desee
que Delphi incumpla las Excepciones. Esta es una gran característica si
desea que Delphi muestre dónde se ha producido una excepción; sin
embargo, puede ser molesto cuando prueba su propio manejo de
excepciones.
• 01 de 04
• FastReport
• FastReport es un componente adicional que le da a la aplicación la
capacidad de generar informes de manera rápida y eficiente. FastReport
proporciona todas las herramientas necesarias para desarrollar informes,
incluido un motor de informes, diseñador de informes, vista previa,
diseñador de cuadros de diálogo y macrointerpreta tipo Pascal. Con
FastReport, puede desarrollar informes que satisfagan sus necesidades
multiplataforma para Windows y Linux. Más "
• 02 de 04
• Informes Rave
• Los Informes Rave combinan los requisitos esenciales con el entorno de
diseño visual más fácil pero más potente disponible. El sistema de informes
basado en código contiene 19 componentes con más de 500 métodos,
propiedades y eventos, y se compila en su aplicación sin archivos externos.
Algunas de sus características incluyen memos envueltos en palabras,
gráficos completos, justificación y posicionamiento preciso de la página.
Más "
• 03 de 04
• QuickReport
• QuickReport es un generador de informes con bandas escrito en código
100% Delphi. ¡QuickReport se integra con Delphi y C ++ Builder casi al
extremo! Diseñe informes dentro de Delphi IDE, utilizando el familiar
diseñador de formularios como diseñador de informes. QuickReport es tan
fácil de usar, rápido y potente que Borland elige usarlo como la herramienta
de informes estándar para Delphi y C ++ Builder. Más "
• 04 de 04
IS y AS
Conclusión
Como podemos ver, el parámetro del remitente puede ser muy útil cuando se usa
correctamente. Supongamos que tenemos un montón de cuadros de edición y
etiquetas que comparten el mismo controlador de eventos. Si queremos saber
quién desencadenó el evento y actuar, tendremos que tratar con las variables
Object. Pero, dejemos esto para alguna otra ocasión.
Cómo agregar los principales ceros a un
número (formato Delphi)
• by Zarko Gajic
• Las diferentes aplicaciones requieren valores específicos para ajustarse a
los paradigmas estructurales. Por ejemplo, los números de la Seguridad
Social siempre tienen nueve dígitos de largo. Algunos informes requieren
que los números se muestren con una cantidad fija de caracteres. Los
números de secuencia, por ejemplo, generalmente comienzan con 1 y se
incrementan sin fin, por lo que se muestran con ceros a la izquierda para
presentar un atractivo visual.
• Para rellenar el número 7 con dos ceros a la izquierda, inserte esos valores
en el código:
• > función LeftPad (valor: entero; longitud: entero = 8; pad: char = '0'):
cadena; sobrecarga; begin result: = RightStr (StringOfChar (pad, length) + IntToStr
(value), length); fin;
• i: = 1234;
r: = LeftPad (i);
• 01 de 07
• 02 de 07
• TmySQL
• TmySQL proporciona acceso a servidores MySQL desde Delphi a través de un
componente visual y un componente no visual extensible. TmySQL utiliza una única
DLL de cliente, que es proporcionada por la mayoría de las versiones de MySQL
compiladas en Windows. TmySQL no utiliza los componentes de la base de datos
en Delphi, como TDatabase, TQuery, etc. Open Source. Más "
• 03 de 07
• MySQLDAC
• MySQLDAC es el reemplazo de MySQL BDE. Este conjunto de componentes
permite crear aplicaciones Delphi con acceso directo a MySQL DB sin BDE y ODBC.
Los campos BLOB son compatibles. MySQLDAC fue desarrollado para facilitar la
migración de proyectos existentes desde el esquema BDE / ODBC al nativo. El
componente TDBImageEx para compatibilidad con imágenes JPEG está incluido en
el paquete de forma gratuita (con fuentes). MySQLDAC es un producto libre de
regalías. Más "
• 04 de 07
• 05 de 07
• Componentes MySQL
• El TMySQLComponents consiste en TMySQLServer y TMySQLDataset. El objetivo de
estos componentes es brindarle acceso directo a todas las características del
servidor MySQL utilizando los controles estándar de datos en Delphi o Kylix sin las
limitaciones de BDE o dbExpress. Los componentes son de fuente única y se
compilarán en Delphi 5/6 o Kylix 1/2 utilizando los mismos archivos fuente.
Comercial. Más "
• 06 de 07
• SQL directo
• La idea principal del proyecto es tener componentes nativos delphi multiplataforma
(Windows + Linux) para acceder directamente a los servidores SQL (sin utilizar
ningún dll externall). El primer lanzamiento será para My-sql e Interbase, pero hay
planes para ser extendend. Licencia pública general de GNU. Más "
• 07 de 07
• Biblioteca Zeos
• Componentes para un acceso rápido a MySql, PostgreSql, MicrosoftSQL, Oracle e
Interbase SQL sin usar complementos, como BDE / ODBC / ADO. Además, los
componentes: las fuentes de datos son compatibles con el TDataset estándar y
tienen varias funciones adicionales. Fuente abierta. Más "
Esta guía paso a paso describe cómo conectarse a Microsoft Excel, recuperar
datos de hojas y habilitar la edición de los datos utilizando DBGrid. También
encontrará una lista de los errores más comunes que pueden aparecer en el
proceso, además de cómo tratarlos.
▪ Métodos para transferir datos entre Excel y Delphi . Cómo conectarse a Excel
con ADO (ActiveX Data Objects) y Delphi.
▪ Crear un editor de hoja de cálculo Excel usando Delphi y ADO
▪ Recuperando los datos de Excel. Cómo hacer referencia a una tabla (o rango) en
un libro de Excel.
▪ Una discusión sobre los tipos de campo Excel (columna)
▪ Cómo modificar hojas de Excel: edita, agrega y elimina filas.
▪ Transferencia de datos de una aplicación Delphi a Excel. Cómo crear una hoja
de trabajo y llenarla con datos personalizados de una base de datos de MS
Access.
Para transferir sus datos ay desde Excel sin automatización, puede usar otros
métodos como:
▪ Escriba datos en un archivo de texto delimitado por comas y deje que Excel
analice el archivo en celdas
Como Excel es compatible con JET OLE DB, puede conectarse con Delphi usando
ADO (dbGO o AdoExpress) y luego recuperar los datos de la hoja de cálculo en un
conjunto de datos ADO emitiendo una consulta SQL (del mismo modo que abriría
un conjunto de datos contra cualquier tabla de base de datos) .
De esta forma, todos los métodos y características del objeto ADODataset están
disponibles para procesar los datos de Excel. En otras palabras, el uso de los
componentes de ADO le permite crear una aplicación que puede usar un libro de
Excel como base de datos. Otro hecho importante es que Excel es un servidor
ActiveX fuera de proceso. ADO se ejecuta en proceso y ahorra la sobrecarga de
costosas llamadas fuera de proceso.
Cuando se conecta a Excel utilizando ADO, solo puede intercambiar datos sin
procesar desde y hacia un libro de trabajo. Una conexión ADO no se puede usar
para formatear hojas o implementar fórmulas en celdas. Sin embargo, si transfiere
sus datos a una hoja de trabajo preformateada, se conserva el formato. Después
de insertar los datos desde su aplicación a Excel, puede llevar a cabo cualquier
formateo condicional utilizando una macro (pregrabada) en la hoja de trabajo.
Puede conectarse a Excel utilizando ADO con los dos proveedores OLE DB que
forman parte de MDAC: proveedor Microsoft Jet OLE DB o proveedor Microsoft
OLE DB para controladores ODBC.
Nos centraremos en el proveedor Jet OLE DB, que se puede usar para acceder a
los datos en los libros de Excel a través de los controladores instalados del
Método de acceso secuencial indexado (ISAM).
Consejo: consulte el Curso de principiantes para la Programación de bases de
datos ADO de Delphi si es nuevo en ADO.
Para conectarse a Excel, una cadena de conexión válida solo implica dos piezas
adicionales de información: la ruta completa al libro de trabajo y la versión del
archivo de Excel.
Para un libro de Excel95, este valor es "Excel 5.0" (sin las comillas); utilice "Excel
8.0" para Excel 97, Excel 2000, Excel 2002 y ExcelXP.
Importante: debe usar el proveedor de Jet 4.0 ya que Jet 3.5 no es compatible
con los controladores de ISAM. Si configura el proveedor de Jet en la versión 3.5,
recibirá el error "No se pudo encontrar ISAM instalable".
Otra propiedad extendida de Jet es "HDR =". "HDR = Sí" significa que hay una fila
de encabezado en el rango, por lo que el Jet no incluirá la primera fila de la
selección en el conjunto de datos. Si se especifica "HDR = No", el proveedor
incluirá la primera fila del rango (o rango con nombre) en el conjunto de datos.
La primera fila en un rango se considera la fila del encabezado por defecto ("HDR
= Yes"). Por lo tanto, si tiene un encabezado de columna, no necesita especificar
este valor. Si no tiene encabezados de columna, debe especificar "HDR = No".
Ahora que ya está listo, esta es la parte donde las cosas se vuelven interesantes
ya que ahora estamos listos para algún código. Veamos cómo crear un editor de
hoja de cálculo Excel simple usando Delphi y ADO.
Nota: debe continuar aunque no tenga conocimiento de la programación de ADO
y Jet.
Como verá, editar un libro de Excel es tan simple como editar datos desde
cualquier base de datos estándar.
• El componente TDBGrid Delphi es una de las joyas del VCL. Diseñado para
permitir a un usuario ver y editar datos en una cuadrícula tabular, DBGrid
proporciona varias formas de personalizar la forma en que representa sus
propios datos.
dgMultiSelect Ejemplo
Una buena situación para usar dgMultiSelect podría ser cuando necesite una
opción para seleccionar registros aleatorios o si necesita la suma de los valores de
los campos seleccionados.
El código usa selección múltiple para obtener la suma de los valores en el campo
"Tamaño". Utilice este código de ejemplo si desea seleccionar todo el DBGrid :
• Deje todos los nombres de los componentes tal como están cuando se
colocaron primero en el formulario (DBGrid1, ADOQuery1, AdoTable 1,
etc.). Utilice el Inspector de Objetos para establecer una propiedad
ConnectionString del componente ADOConnection1 (TDOConnection) para
que apunte a la base de datos de muestra QuickiesContest.mdb MS
Access.
• Para el resto de las celdas (no enfocadas) que llevan los campos booleanos
(en la columna "Ganador"), necesitamos proporcionar alguna
representación gráfica del valor booleano (Verdadero / Falso).
• Esto significa que necesita al menos dos imágenes para dibujar: una para el
estado comprobado (valor verdadero) y otra para el estado no verificado
(valor falso).
Implementando el algoritmo de
clasificación QuickSort en Delphi
• by Zarko Gajic
• Uno de los problemas comunes en la programación es ordenar una matriz
de valores en algún orden (ascendente o descendente).
• Si bien hay muchos algoritmos de clasificación "estándar", QuickSort es uno
de los más rápidos. Quicksort ordena empleando una estrategia de divide y
vencerás para dividir una lista en dos sublistas.
• Algoritmo QuickSort
• El concepto básico es elegir uno de los elementos en la matriz,
llamado pivote . Alrededor del pivote, otros elementos serán reorganizados.
• Todo lo que no sea el pivote se mueve hacia la izquierda del pivote, hacia la
partición izquierda. Todo lo que sea mayor que el pivote entra en la
partición correcta. En este punto, cada partición es recursiva "ordenada
rápidamente".
• > procedimiento QuickSort ( var A: array de Integer; iLo, iHi: Integer); var Lo, Hola,
Pivote, T: Entero; comenzar Lo: = iLo; Hola: = iHi; Pivote: = A [(Lo +
Hi) div 2]; repita mientras A [Lo] do Inc (Lo); mientras que A [Hi]> Pivot do Dec
(Hi); si Lo <= Hi entonces comienza T: = A [Lo]; A [Lo]: = A [Hola]; A [Hola]: = T; Inc
(Lo); Dec (Hola); fin ; hasta Lo> Hola; si Hola> iLo entonces QuickSort (A, iLo,
Hola); si Lo entonces QuickSort (A, Lo, iHi); fin ;
• Uso:
• > var intArray: array de entero; comenzar SetLength (intArray, 10); // Agregar
valores a intArray intArray [0]: = 2007; ... intArray [9]: = 1973; // ordenar QuickSort
(intArray, Low (intArray), High (intArray));
Por ejemplo, en una consulta SQL: "SELECT * FROM TBL WHERE DateField =
'10 / 12/2008 '" desea obtener todos los registros de la tabla denominada TBL
donde un campo de fecha general DateField es igual a 10/12/2008.
Al utilizar Access y JET ( controles dbGo - ADO Delphi ), el formato del SQL para
el campo de fecha debe * siempre * ser:
> # YYYY-MM-DD #
Cualquier otra cosa podría funcionar en pruebas limitadas pero a menudo puede
conducir a resultados inesperados o errores en la máquina del usuario.
Aquí hay una función Delphi personalizada que puede usar para formatear un
valor de fecha para la consulta de Access SQL.
Tan pronto como construya una cadena de fecha y hora válida para el SQL
usando el formato general anterior y lo intente usando cualquiera de los
componentes del conjunto de datos de Delphi como TADOQuery, recibirá el
horrible "El objeto del parámetro está definido incorrectamente. Se proporcionó
información incompleta o incoherente" en tiempo de ejecución !
El problema con el formato anterior está en el carácter ":", ya que se usa para
parámetros en consultas Delphi parametrizadas. Como en "... WHERE DateField
=: dateValue" - aquí "dateValue" es un parámetro y ":" se usa para marcarlo.
Una forma de "corregir" el error es usar otro formato para fecha / hora (reemplace
":" por "."):
Aquí hay una versión más corta que usa la rutina FormatDateTime:
procedure TForm1.Button1Click (Sender: TObject); var f: TForm2; begin f: = TForm2.Create ( nil ); intente si f.ShowM
mrOk luego Caption: = 'Yes' else Leyenda: = 'No'; finalmente f. Libera; fin ; fin ;
procedimiento TButton.Click; var Form: TCustomForm; begin Form: = GetParentForm (Self); si es nulo, entonces Fo
ModalResult; Click heredado ; fin ;
• IP? TCP?
• Simplemente técnico: Internet se basa en conexiones TCP / IP. La parte
TCP describe cómo dos computadoras establecen una conexión entre sí y
transfieren datos.
• Obtener IP Delphi.Project.Code
• Inicie Delphi y coloque un botón y dos cuadros de edición en un formulario
recién creado. Agregue la función GetIPFromHost a la parte de
implementación de su unidad y asigne el siguiente código al controlador de
eventos OnClick de un botón (a continuación):
• AsyncCalls en acción
• Si bien solo hay una unidad para incluir en su aplicación, asynccalls.pas proporciona
más formas en que uno puede ejecutar una función en un hilo diferente y
sincronizar el hilo. Eche un vistazo al código fuente y al archivo de ayuda HTML
incluido para familiarizarse con los conceptos básicos de asynccalls.
• Aquí hay una llamada de ejemplo a un método que espera dos parámetros
enteros (devolviendo un IAsyncCall): >
• Mi ayudante de AsnycCalls
• Para ayudarme a implementar el método WaitAll, he codificado una simple clase
TAsyncCallsHelper. TAsyncCallsHelper expone un procedimiento AddTask (const
call: IAsyncCall); y rellena una matriz interna de array de IAsyncCall. Esta es
una matriz bidimensional donde cada elemento contiene 61 elementos de
IAsyncCall.
• También me gustaría tener una forma de "cancelar" las tareas que están en
el grupo, pero estoy esperando su ejecución.
• Confesión
• He alterado el asynccalls.pas de una manera que se adapta a las necesidades
específicas de mi proyecto. Si no necesita implementar "CancelAll" o "WaitAll" de la
manera descrita anteriormente, asegúrese de usar siempre, y solo, la versión
original de asynccalls.pas tal como la lanzó Andreas. Espero, sin embargo, que
Andreas incluya mis cambios como funciones estándar, tal vez no soy el único
desarrollador que intenta usar AsyncCalls, pero me faltan algunos métodos útiles :)
• ¡DARSE CUENTA! :)
• Solo unos días después de escribir este artículo, Andreas lanzó una nueva versión
2.99 de AsyncCalls. La interfaz IAsyncCall ahora incluye tres métodos más: >>>> El
método CancelInvocation evita que se invoque AsyncCall. Si AsyncCall ya está
procesado, una llamada a CancelInvocation no tiene efecto y la función Cancelada
devolverá False ya que AsyncCall no se canceló. El método Cancelado devuelve True
si cancela la AsyncCall mediante CancelInvocation. El método Forget desvincula la
interfaz IAsyncCall de la AsyncCall interna. Esto significa que si la última referencia a
la interfaz IAsyncCall se ha ido, la llamada asincrónica se seguirá ejecutando. Los
métodos de la interfaz arrojarán una excepción si son llamados después de llamar a
Forget. La función asíncrona no debe invocar al hilo principal porque podría
ejecutarse después de que el RTTL.Sincronizar / Mecanismo de cola fuera cerrado por
el RTL, lo que puede causar un bloqueo muerto. Por lo tanto, no es necesario usar
mi versión alterada .
En la mayoría de los escenarios, declara una matriz como una variable, lo que
permite que los elementos de la matriz se modifiquen en tiempo de ejecución.
Sin embargo, algunas veces necesita declarar una matriz constante, una matriz de
solo lectura. No puede cambiar el valor de una constante o una variable de solo
lectura.
▪ Days es una matriz de cadenas de seis elementos. Days [1] devuelve la cadena Mon.
▪ CursorMode es una matriz de dos elementos , por lo cual la declaración CursorMode
[false] = crHourGlass y CursorMode = crSQLWait. Las constantes "cr *" se pueden usar
para cambiar el cursor de la pantalla actual.
▪ Items define una matriz de tres registros de TShopItem.
tipo TShopItem = registro Nombre: cadena; Precio: moneda; fin; const Days: array [0..6] de
string = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); CursorMode: array [boolean] de
TCursor = (crHourGlass, crSQLWait); Items: array [1..3] de TShopItem = ((Nombre: 'Clock';
Price: 20.99), (Nombre: 'Pencil'; Precio: 15.75), (Nombre: 'Board'; Precio: 42.96));
Intentar asignar un valor para un elemento en una matriz constante aumenta el
error de tiempo de compilación "No se puede asignar el lado izquierdo". Por
ejemplo, el siguiente código no se ejecuta correctamente:
• Delphi proporciona varios métodos para analizar una cadena, pero puede
encontrar que ninguno hace exactamente lo que necesita.
• ~~~~~~~~~~~~~~~~~~~~~~~~~
procedimiento ParseDelimited (const sl: TStrings; const value: string; const
delimiter: string);
var
dx: entero;
ns: cadena;
txt: cadena;
delta: entero;
empezar
delta: = Longitud (delimitador);
txt: = valor + delimitador;
sl.BeginUpdate;
sl.Clear;
tratar
mientras que Length (txt)> 0 do
empezar
dx: = Pos (delimitador, txt);
ns: = Copia (txt, 0, dx-1);
sl.Add (ns);
txt: = Copiar (txt, dx + delta, MaxInt);
fin;
finalmente
sl.EndUpdate;
fin;
fin;
~~~~~~~~~~~~~~~~~~~~~~~~~
• Uso (rellena Memo1):
ParseDelimited (Memo1.lines, 'Zarko; Gajic ;; DelphiGuide', ';')
• Declaración:
función CompareText ( const S1, S2: string ): entero ;
• Descripción:
Compara dos cadenas sin mayúsculas y minúsculas.
• Ejemplo:
• var s1, s2: cadena; i: entero; s1: = 'Delphi'; s2: = 'Programación'; i: = CompareTexto
(s1, s2); //yo
• Copiar función
• Devuelve una subcadena de una cadena o un segmento de una matriz
dinámica.
• Declaración:
función Copiar (S; índice, recuento: entero): cadena ;
función Copiar (S; índice, recuento: entero): matriz ;
• Descripción:
Devuelve una subcadena de una cadena o un segmento de una matriz
dinámica.
S es una expresión de una cadena o tipo de matriz dinámica. El índice y el
recuento son expresiones de tipo entero. Copiar devuelve una cadena que
contiene una cantidad específica de caracteres de una cadena o matriz
secundaria que contiene elementos de conteo comenzando en S [Índice].
• Ejemplo:
• Eliminar procedimiento
• Elimina una subcadena de una cadena.
• Declaración:
Procedimiento Delete ( var S: string ; Index, Count: Integer)
• Descripción:
Elimina los caracteres de Conteo de una cadena S, comenzando en Índice.
Delphi no modifica la cadena si el índice no es positivo o mayor que el
número de caracteres después del índice. Si Count es mayor que el resto
de los caracteres después del índice, el resto de la cadena se elimina.
• Ejemplo:
• Función ExtractStrings
• Rellena una lista de cadenas con subcadenas analizadas desde una lista
delimitada.
• Declaración:
tipo TSysCharSet = conjunto de Char;
función ExtractStrings (Separadores, WhiteSpace: TSysCharSet;
Contenido: PChar; Cadenas: TStrings): Entero;
• Descripción:
Rellena una lista de cadenas con subcadenas analizadas desde una lista
delimitada.
• Ejemplo:
• // ejemplo 1 - requiere que TMemo se llame "Memo1" ExtractStrings ([';', ','], [''],
'sobre: delphi; pascal, programming', memo1.Lines); // daría como resultado 3
cadenas añadidas a la nota: // sobre: delphi // pascal // programación // ejemplo 2
ExtractStrings ([DateSeparator], [''], PChar (DateToStr (Now)), memo1.Lines); // daría
como resultado 3 cadenas: día mes y año de la fecha currnet // por ejemplo '06',
'25', '2003'
• Función LeftStr
• Devuelve una cadena que contiene un número específico de caracteres del
lado izquierdo de una cadena.
• Declaración:
función LeftStr ( const AString: AnsiString; const Count: Integer):
AnsiString; sobrecarga ; función LeftStr ( const AString:
WideString; const Count: Integer): WideString; sobrecarga ;
• Descripción:
Devuelve una cadena que contiene un número específico de caracteres del
lado izquierdo de una cadena.
• Ejemplo:
• Función de longitud
• Devuelve un número entero que contiene el número de caracteres en una
cadena o la cantidad de elementos en una matriz.
• Descripción:
longitud de la función (const S: cadena ): entero
longitud de la función (const S: array ): entero
• Declaración:
Devuelve un número entero que contiene el número de caracteres en una
cadena o la cantidad de elementos en una matriz.
Para una matriz, Length (S) siempre devuelve Ord (High (S)) - Ord (Low
(S)) + 1
• Ejemplo:
• Función LowerCase
• Devuelve una cadena que se ha convertido a minúsculas.
• Descripción:
función LowerCase ( const S: string ): cadena ;
• Declaración:
Devuelve una cadena que se ha convertido a minúsculas.
LowerCase solo convierte letras mayúsculas a minúsculas; todas las letras
minúsculas y los caracteres que no son letras permanecen sin cambios.
• Ejemplo:
• Pos función
• Devuelve un entero que especifica la posición de la primera aparición de
una cadena dentro de otra.
• Declaración:
función Pos (Str, Fuente: cadena ): entero ;
• Descripción:
Devuelve un entero que especifica la posición de la primera aparición de
una cadena dentro de otra.
• Ejemplo:
• var s: cadena; i: entero; s: = 'PROGRAMACIÓN DELPHI'; i: = Pos ('HI PR', s); // i = 5;
• Función PosEx
• Devuelve un número entero que especifica la posición de la primera
aparición de una cadena dentro de otra, donde la búsqueda comienza en
una posición específica.
• Declaración:
función PosEx (Str, Fuente: cadena , StartFrom: cardinal = 1): entero ;
• Descripción:
Devuelve un número entero que especifica la posición de la primera
aparición de una cadena dentro de otra, donde la búsqueda comienza en
una posición específica.
• Ejemplo:
• Función QuotedStr
• Devuelve la versión entrecomillada de una cadena.
• Declaración:
función QuotedStr ( const S: cadena ): cadena ;
• Descripción:
Devuelve la versión entrecomillada de una cadena.
• Ejemplo:
var s: cadena; s: = 'Pascal' de Delphi; // ShowMessage devuelve Pascal s de Delphi: = QuotedStr (s); // ShowMessage
de Delphi
• Función ReverseString
• Devuelve una cadena en la que se invierte el orden de los caracteres de
una cadena especificada.
• Declaración:
función ReverseString ( const AString: string ): cadena ;
• Ejemplo:
• Función RightStr
• Devuelve una cadena que contiene un número específico de caracteres del
lado derecho de una cadena.
• Declaración:
función RightStr ( const AString: AnsiString; const Count: Integer):
AnsiString; sobrecarga ;
función RightStr ( const AString: WideString; const Count: Integer):
WideString; sobrecarga ;
• Descripción:
Devuelve una cadena que contiene un número específico de caracteres del
lado derecho de una cadena.
• Ejemplo:
• Función StringReplace
• Devuelve una cadena en la cual una subcadena especificada ha sido
reemplazada por otra subcadena.
• Declaración:
tipo TReplaceFlags = conjunto de (rfReplaceAll, rfIgnoreCase);
• Ejemplo:
• Función de ajuste
• Devuelve una cadena que contiene una copia de una cadena especificada
sin espacios iniciales y finales y caracteres de control.
• Descripción: devuelve una cadena que contiene una copia de una cadena
especificada sin espacios iniciales y finales y caracteres de control que no
son de impresión.
• Ejemplo:
• Función UpperCase
• Devuelve una cadena que se ha convertido a mayúsculas.
• Ejemplo:
• Procedimiento Val
• Convierte una cadena en un valor numérico.
• Ejemplo:
• 11011 - Calcula qué es esto en base diez agregando los valores de cada
posición. En este caso, son 16 + 8 + 0 + 2 + 1. Este es el número 27 en la
base 10.
• ¿Variable o constante?
• Las constantes tipadas se pueden comparar con variables inicializadas: variables
cuyos valores se definen al ingresar a su bloque (generalmente controlador de
eventos). Dicha variable se inicializa solo cuando el programa comienza a
ejecutarse. Después de eso, el valor de una constante tipeada persiste entre
llamadas sucesivas a sus procedimientos.
• > {$ J +} clics const : Entero = 1; {$ J-} Por lo tanto, el primer código de ejemplo se
ve así: > procedure TForm1.Button1Click (Sender: TObject); const {$ J +} clics: Entero
= 1; // no es una constante verdadera {$ J-} begin Form1.Caption: = IntToStr
(clicks); clics: = clics + 1; fin ;
• Conclusión
• Depende de usted decidir si desea que las constantes mecanografiadas sean
asignables o no. Lo importante aquí es que además de ser ideal para contadores,
las constantes tipadas son ideales para hacer que los componentes sean
alternativamente visibles o invisibles, o podemos usarlos para alternar entre
cualquier propiedad booleana. Las constantes tipadas también se pueden usar
dentro del controlador de eventos de TTimer para realizar un seguimiento de
cuántas veces se ha disparado.
Si desea más material para principiantes, consulte el resto de los temas de
programación de Delphi For Beginners.
• En la jerga OOP, puede pensar en una interfaz como una clase sin
implementación .
• Si desea crear una aplicación sólida como una roca para que su código sea
sostenible, reutilizable y flexible, la naturaleza OOP de Delphi lo ayudará a
conducir el primer 70% de su ruta.
• tipo
IConfigChanged = interface ['{0D57624C-CDDE-458B-A36C-436AE465B477}']
procedimiento ApplyConfigChange;
fin ;
• Una interfaz en OOP define una abstracción, una plantilla para una clase
real que implementará la interfaz, que implementará los métodos definidos
por la interfaz.
• Una interfaz en realidad no hace nada, solo tiene una firma para interactuar
con otras clases o interfaces (de implementación).
• tipo
IConfigChangedMore = interfaz (IConfigChanged)
procedimiento ApplyMoreChanges;
fin ;
• tipo
TMainForm = clase (TForm, IConfigChanged)
público
procedimiento ApplyConfigChange;
fin ;
• Advertencia : cuando una clase implementa una interfaz, debe implementar todos
sus métodos y propiedades. Si falla / olvida implementar un método (por ejemplo:
ApplyConfigChange) se producirá un error de tiempo de compilación "E2003
Identificador no declarado: 'ApplyConfigChange'" .
• Tenga en cuenta, por supuesto, que cada formulario puede tener su propia
implementación diferente del procedimiento ApplyConfigChange .
• Una vez que hemos configurado el tipo de registro, podemos declarar que
una variable es del tipo TMember.
• TMember ahora es tan bueno como el tipo de variable para variables como
cualquiera de los tipos integrados de Delphi, como String o Integer. Nota: la
declaración del tipo TMember no asigna ninguna memoria para los campos
Nombre, Correo electrónico y Publicaciones;
• > con DPMembers [5] comenzar Nombre: = 'Nombre Apellido'; Correo electrónico: =
'FirstLast@domain.com' Publicaciones: = 0; fin ;
• Sin embargo, los registros variantes pueden ser bastante útiles, si alguna
vez se encuentra en una situación para usarlos, aquí está la segunda parte
de este artículo: "Sin embargo, los registros variantes pueden ser muy
útiles, si alguna vez se encuentra en una situación para usarlos , aquí está
la segunda parte de este artículo: Registros en Delphi - Parte 2 "
Función LeftStr
• by Zarko Gajic
• Declaración: función LeftStr ( const AString: AnsiString; const Count:
Integer): AnsiString; sobrecarga ; función LeftStr ( const AString:
WideString; const Count: Integer): WideString; sobrecarga ;
• Descripción
• Devuelve una cadena que contiene un número específico de caracteres del
lado izquierdo de una cadena.
• Ejemplo
• var s: cadena; s: = 'SOBRE PROGRAMACIÓN DELPHI'; s: = LeftStr (s, 5); // s =
'ABOUT'
Función RightStr
• by Zarko Gajic
• Declaración: función RightStr ( const AString: AnsiString; const Count:
Integer): AnsiString; sobrecarga ; función RightStr ( const AString:
WideString; const Count: Integer): WideString; sobrecarga ;
• Descripción
• Devuelve una cadena que contiene un número específico de caracteres del
lado derecho de una cadena.
• Ejemplo
• var s: cadena; s: = 'SOBRE PROGRAMACIÓN DELPHI'; s: = RightStr (s, 5); // s =
'MMING'
• Función CompareDateTime
• Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
• Declaración:
tipo TValueRelationship = -1..1
función CompareDateTime ( const ADate, BDate: TDateTime):
TValueRelationship
• Descripción:
Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
• Ejemplo:
• Función CompareTime
• Compara dos valores de TDateTime (devuelve "menos", "igual" o
"mayor"). Ignora la parte Fecha si ambos valores ocurren al mismo tiempo.
• Declaración:
tipo TValueRelationship = -1..1
función CompareDate ( const ADate, BDate: TDateTime):
TValueRelationship
• Descripción:
Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
Ignora la parte Tiempo si ambos valores ocurren al mismo tiempo.
• Ejemplo:
• Función de fecha
• Devuelve la fecha del sistema actual.
• Declaración:
tipo TDateTime = tipo Doble;
• Función DateTimeToStr
• Convierte un valor TDateTime en una cadena (fecha y hora).
• Declaración:
tipo TDateTime = tipo Doble;
• Descripción:
Devuelve el día de la semana para una fecha determinada.
• Ejemplo:
• Función DaysBetween
• Da la cantidad de días enteros entre dos fechas especificadas.
• Declaración:
función DaysBetween (const ANow, AThen: TDateTime): Integer;
• Descripción:
Da la cantidad de días enteros entre dos fechas especificadas.
• Función DateOf
• Devuelve solo la parte Fecha del valor TDateTime, configurando la parte
Tiempo en 0.
• Declaración:
función DateOf (Fecha: TDateTime): TDateTime
• Descripción:
Devuelve solo la parte Fecha del valor TDateTime, configurando la parte
Tiempo en 0.
• Ejemplo:
• Función DecodeDate
• Separa los valores de Año, Mes y Día desde un valor de TDateTime.
• Declaración:
procedimiento DecodeDate (Fecha: TDateTime; var Año, Mes, Día:
Palabra) ;;
• Descripción:
Separa los valores de Año, Mes y Día desde un valor de TDateTime.
• Ejemplo:
var Y, M, D: Word; DecodeDate (Fecha, Y, M, D); si Y = 2000 entonces ShowMessage ('¡Estás en un siglo "equivocado
• Función EncodeDate
Crea un valor de TDateTime a partir de los valores de Año, Mes y Día.
• Declaración:
función EncodeDate (año, mes, día: palabra): TDateTime
• Descripción:
Crea un valor de TDateTime a partir de los valores de Año, Mes y Día.
• El año debe estar entre 1 y 9999. Los valores de mes válidos son de 1 a 12.
Los valores de día válidos son de 1 a 28, 29, 30 o 31, según el valor del
mes.
Si la función falla, EncodeDate genera una excepción EConvertError.
• Ejemplo:
• Función FormatDateTime
Formatea un valor TDateTime para una cadena.
• Declaración:
función FormatDateTime ( const Fmt: cadena; Valor:
TDateTime): cadena ;
• Descripción:
Formatea un valor TDateTime para una cadena.
• Ejemplo:
• Función IncDay
• Agrega o sustrae un número determinado de días desde un valor de fecha.
• Declaración:
función IncDay (ADate: TDateTime; Days: Integer = 1): TDateTime;
• Descripción:
Agrega o sustrae un número determinado de días desde un valor de fecha.
• Ejemplo:
• var Fecha: TDateTime; EncodeDate (Fecha, 2003, 1, 29) // 29 de enero de 2003
IncDay (Fecha, -1) // 28 de enero de 2003
• Ahora funciona
• Devuelve la fecha y hora actual del sistema.
• Declaración:
tipo TDateTime = tipo Doble;
• Descripción:
Devuelve la fecha y hora actual del sistema.
• Declaración:
función YearsBetween ( const SomeDate, AnotherDate: TDateTime):
Integer;
• Descripción:
Da la cantidad de años enteros entre dos fechas especificadas.
• Ejemplo:
Portapapeles en General
Como probablemente sepa, el Portapapeles solo puede contener una pieza de
datos para cortar, copiar y pegar al mismo tiempo. En general, puede contener
solo una parte del mismo tipo de datos a la vez.
TClipboard
Para utilizar el Portapapeles de Windows en nuestras aplicaciones, debemos
agregar la unidad ClipBrd a la cláusula uses del proyecto, excepto cuando
restringimos cortar, copiar y pegar a los componentes que tienen soporte
incorporado para los métodos del Portapapeles. Esos componentes son TEdit,
TMemo, TOLEContainer, TDDEServerItem, TDBEdit, TDBImage y TDBMemo.
La unidad ClipBrd crea automáticamente una instancia de un objeto TClipboard
llamado Portapapeles. Utilizaremos los métodos
CutToClipboard , CopyToClipboard , PasteFromClipboard , Clear y HasFormat par
a manejar las operaciones del portapapeles y la manipulación de texto / gráficos.
▪ CF_TEXT - Texto con cada línea que termina con una combinación CR-LF .
▪ CF_BITMAP : un gráfico de mapa de bits de Windows.
▪ CF_METAFILEPICT : un metarchivo de Windows gráfico.
▪ CF_PICTURE - Un objeto de tipo TPicture.
▪ CF_OBJECT - Cualquier objeto persistente.
El método HasFormat devuelve True si la imagen en el Portapapeles tiene el
formato correcto:
Para enviar (asignar) una imagen al Portapapeles, usamos el método Asignar. Por
ejemplo, el siguiente código copia el mapa de bits de un objeto de mapa de bits
llamado MyBitmap en el Portapapeles:
Para recuperar una imagen del Portapapeles debemos: verificar el formato de los
contenidos actuales del portapapeles y usar el método Asignar del objeto de
destino:
> {coloque un botón y un control de imagen en form1} {Antes de ejecutar este código,
presione Alt-PrintScreen key
combination} usa clipbrd; ... procedimiento TForm1.Button1Click (Sender:
TObject); comenzar si Clipboard.HasFormat
(CF_BITMAP) luego Image1.Picture.Bitmap.Assign (Portapapeles); fin;
Más control del portapapeles
El portapapeles almacena información en múltiples formatos para que podamos
transferir datos entre aplicaciones que usan formatos diferentes.
• Dado que es bastante común que las aplicaciones Delphi compartan código
o formularios previamente personalizados, Delphi organiza las aplicaciones
en estos archivos de proyecto.
• DPROJ es otro formato de archivo para los archivos del Proyecto Delphi,
pero almacena la configuración del proyecto en formato XML.
• Aunque puede leer y editar el archivo del proyecto como lo haría con
cualquier código fuente, en la mayoría de los casos, permitirá que Delphi
mantenga el archivo DPR. La razón principal para ver el archivo del
proyecto es ver las unidades y formularios que componen el proyecto, así
como para ver qué formulario se especifica como el formulario "principal" de
la aplicación.
• Otra razón para trabajar con el archivo de proyecto es cuando está creando
un archivo DLL en lugar de una aplicación independiente. O bien, si
necesita algún código de inicio, como una pantalla de bienvenida antes de
que Delphi cree el formulario principal.
• Esta palabra clave identifica a esta unidad como la unidad fuente principal
del programa. Puede ver que el nombre de la unidad, "Proyecto1", sigue la
palabra clave del programa. Delphi le da al proyecto un nombre
predeterminado hasta que lo guarde como algo diferente.
¿Alguna vez te has encontrado escribiendo el mismo código una y otra vez para
realizar alguna tarea común dentro de los manejadores de eventos? ¡Sí! Es hora
de que aprenda sobre los programas dentro de un programa. Llamemos a esos
mini programas subrutinas.
Introducción a subrutinas
Funciones y procedimientos
Como podemos ver, tanto las funciones como los procedimientos actúan como
mini programas. En particular, pueden tener su propio tipo, constantes y
declaraciones de variables dentro de ellos.
Eche un vistazo más de cerca a una función SomeCalc (miscelánea):
> función SomeCalc ( const sStr: string ; const iYear, iMonth: integer; var iDay:
integer): boolean; comenzar ... finalizar ; Cada procedimiento o función comienza
con un encabezado que identifica el procedimiento o función y enumera
los parámetros que utiliza la rutina, si corresponde. Los parámetros se enumeran
entre paréntesis. Cada parámetro tiene un nombre de identificación y
generalmente tiene un tipo. Un punto y coma separa los parámetros en una lista
de parámetros entre sí.
sStr, iYear e iMonth se llaman parámetros constantes . La función (o
procedimiento) no puede cambiar los parámetros constantes. El iDay se pasa
como un parámetro var , y podemos hacer cambios en él, dentro de la subrutina.
▪ Por supuesto, usted decide sobre la firma del "Parámetro TFunction": si se trata
de un procedimiento o una función, cuántos parámetros se necesitan, etc.
▪ Si "TFunctionParameter" es un método (de un objeto de instancia), debe
agregar las palabras de objeto al nombre de tipo de procedimiento, como en:
TFunctionParameter = function (const value: integer): cadena de objetos;
▪ Si espera que se especifique "nil" como el parámetro "f", debe probarlo con la
función Asignada .
▪ Reparar el puntero del método "Tipo incompatible: 'y el procedimiento regular'"
Una secuencia es lo que su nombre sugiere: un "río de datos" que fluye. Una
secuencia tiene un principio, un final, y siempre estás en algún punto intermedio
de estos dos puntos.
Con los objetos TStream de Delphi puede leer o escribir en varios tipos de medios
de almacenamiento, como archivos de disco, memoria dinámica, etc.
Una transmisión puede contener todo lo que desee, en el orden que desee.
En el proyecto de ejemplo que acompaña este artículo, los registros de tamaño fijo
se utilizan con fines de simplicidad, pero puede escribir cualquier combinación de
datos de tamaño variable en una secuencia. Recuerde, sin embargo, que _usted_
es responsable de la casa. ¡No hay forma de que Delphi "recuerde" qué tipo de
datos hay en una transmisión o en qué orden!
Las matrices tienen la desventaja de tener un tamaño fijo que debe conocerse en
tiempo de compilación. Ok, puedes usar matrices dinámicas.
Por otro lado, una transmisión puede crecer hasta el tamaño de la memoria
disponible, que es considerablemente más grande en los sistemas actuales, sin
tareas domésticas.
Una secuencia no puede ser indexada, como una matriz puede. Pero como verá a
continuación, "caminar" arriba y abajo de un arroyo es muy fácil.
TStream es el tipo de clase base (abstracta) para los objetos de transmisión. Ser
abstracto significa que TStream nunca se debe usar como tal, sino solo en sus
formas descendientes.
Para transmitir cualquier tipo de información, elija una clase descendiente según
los datos específicos y las necesidades de almacenamiento. Por ejemplo:
• Este archivo de formato binario es el único (en la mayoría de los casos) que
debe distribuir a sus usuarios. Borre de forma segura su archivo .exe de
proyectos porque Delphi lo recrea cuando compila la aplicación.
• .DCP
Este archivo de imagen binaria consiste en el paquete compilado real. La
información del símbolo y la información del encabezado adicional
requerida por el IDE están todas contenidas dentro del archivo .DCP. El IDE
debe tener acceso a este archivo para construir un proyecto. No elimine
archivos .DCP.
• .BPL o .DPL
Este es el paquete de tiempo de diseño o tiempo de ejecución real. Este
archivo es una DLL de Windows con características específicas de Delphi
integradas. Este archivo es esencial para la implementación de una
aplicación que usa un paquete. En la versión 4 y superior, esta es la
"biblioteca de paquetes de Borland" en la versión 3, es la "biblioteca de
paquetes de Delphi". Consulte BPL vs. DLL para obtener más información
sobre la programación con paquetes.
• IDE específico
.BPG, .BDSGROUP - Borland Project Group ( Borland Developer Studio
Project Group )
BPG debe almacenarse en Source Control
Cree grupos de proyectos para manejar proyectos relacionados a la vez.
Por ejemplo, puede crear un grupo de proyectos que contenga varios
archivos ejecutables, como .DLL y .EXE.
• .DCR
DCR debe almacenarse en Source Control
Los archivos de recursos del componente Delphi contienen el ícono de un
componente tal como aparece en la paleta de VCL. Podemos usar archivos
.dcr cuando construyamos nuestros propios componentes personalizados .
No elimine archivos .dpr.
• .DOF
DOF debe ser almacenado en Source Control
Este archivo de texto contiene la configuración actual para las opciones del
proyecto, como la configuración del compilador y el enlazador, directorios,
directivas condicionales y parámetros de línea de comandos . La única
razón para eliminar el archivo .dof es volver a las opciones estándar para
un proyecto.
• .DSK
Este archivo de texto almacena información sobre el estado de su proyecto,
como qué ventanas están abiertas y en qué posición se encuentran. Esto le
permite restaurar el espacio de trabajo de su proyecto cada vez que vuelva
a abrir el proyecto Delphi.
• .DRO
Este archivo de texto contiene información sobre el repositorio de objetos.
Cada entrada en este archivo contiene información específica sobre cada
elemento disponible en el repositorio de objetos.
• .DMT
Este archivo binario patentado contiene la información de plantillas de menú
enviada y definida por el usuario.
• .TLB
El archivo es un archivo de biblioteca de tipo binario patentado. Este
archivo proporciona una forma de identificar qué tipos de objetos e
interfaces están disponibles en un servidor ActiveX. Al igual que una unidad
o un archivo de encabezado, .TLB sirve como un repositorio de información
de símbolos necesaria para una aplicación.
• .DEM
Este archivo de texto contiene algunos formatos estándar específicos del
país para un componente TMaskEdit.
• .TAXI
Este es el formato de archivo que Delphi ofrece a sus usuarios para la
implementación web. El formato de gabinete es una forma eficiente de
empaquetar varios archivos.
• .DB
Los archivos con esta extensión son archivos estándar de Paradox.
• .DBF
Los archivos con esta extensión son archivos dBASE estándar.
• .GDB
Los archivos con esta extensión son archivos estándar de Interbase.
• .DBI
Este archivo de texto contiene información de inicialización para el
Explorador de la base de datos.
• Precaución
Nunca elimine archivos con nombres que terminen en .dfm, .dpr o .pas, a
menos que desee descartar su proyecto. Estos archivos contienen las
propiedades y el código fuente de la aplicación. Al hacer una copia de
seguridad de una aplicación, estos son los archivos críticos para guardar.
• Proyectos Delphi
• Cuando creamos una aplicación Delphi, podemos comenzar con un
proyecto en blanco, un proyecto existente o una de las aplicaciones o
plantillas de formularios de Delphi.
• Unidades Delphi
• Como sabemos hasta ahora, las formas son parte visible de la mayoría de
los proyectos de Delphi. Cada formulario en un proyecto Delphi también
tiene una unidad asociada. La unidad contiene el código fuente para
cualquier manejador de eventos adjunto a los eventos del formulario o los
componentes que contiene.
• Cada vez que creamos un nuevo formulario (archivo .dfm), Delphi crea
automáticamente su unidad asociada (archivo .pas), vamos a llamarlo
una Unidad de Formulario . Sin embargo, las unidades no tienen que estar
asociadas con formularios.
• Una Unidad de código contiene código que se llama desde otras unidades
en el proyecto. Cuando empiece a construir bibliotecas de rutinas útiles,
probablemente las almacene en una unidad de código. Para agregar una
nueva unidad de código a la aplicación Delphi, seleccione Archivo-Nuevo ...
Unidad.
• Anatomía
• Cada vez que creamos una unidad (formulario o unidad de código) Delphi
agrega automáticamente las siguientes secciones de código: encabezado
de la unidad, sección de interfaz , sección de implementación . También
hay dos secciones opcionales: inicialización y finalización .
• Como verá, las unidades deben estar en un formato predefinido para que el
compilador pueda leerlas y compilar el código de la unidad.
• Sección de interfaz
• Esta sección contiene la cláusula uses que enumera las otras unidades
(código o unidades de formulario) que utilizará la unidad. En el caso de las
unidades de formulario, Delphi agrega automáticamente las unidades
estándar como Windows, Mensajes, etc. A medida que agrega nuevos
componentes a un formulario, Delphi agrega los nombres apropiados a la
lista de usos. Sin embargo, Delphi no agrega una cláusula de uso a la
sección de interfaz de las unidades de código, tenemos que hacerlo
manualmente.
• Tenga en cuenta que Delphi crea una unidad de formulario para usted a
medida que diseña un formulario. El tipo de datos de formulario, la variable
de formulario que crea una instancia del formulario y los controladores de
eventos se declaran en la parte de interfaz.
Debido a que no es necesario sincronizar el código en unidades de código
con una forma asociada, Delphi no mantiene la unidad de código para
usted.
• Sección de implementación
• La sección de implementación de una unidad es la sección que contiene el
código real de la unidad. La implementación puede tener declaraciones
adicionales propias, aunque estas declaraciones no son accesibles a
ninguna otra aplicación o unidad.
• Cualquier objeto Delphi declarado aquí estaría disponible solo para codificar
dentro de la unidad (global a la unidad). Una cláusula de uso opcional
puede aparecer en la parte de implementación e inmediatamente debe
seguir la palabra clave de implementación.
Tanto el "bloque verdadero" como el "bloque falso" pueden ser una declaración
simple o una declaración estructurada (rodeada con un par de inicio-final).
> j: = 50; si j> = 0, entonces comienza si j = 100, entonces Subtítulo: = '¡El número es
100!' else Leyenda: = '¡El número es NEGATIVO!'; fin ;
La mejor solución es: siempre use pares de inicio y final con declaraciones if
anidadas:
> j: = 50; si j> = 0, entonces comienza si j = 100, entonces Subtítulo: = '¡El número es
100!'; end else begin Caption: = '¡El número es NEGATIVO!'; fin ;
¿Demasiados pares de inicio y fin para ti? ¡Más vale prevenir que curar! De todos
modos, las plantillas de código están diseñadas para agregar estructuras de
esqueleto comúnmente utilizadas a su código fuente y luego completarlas.
• 02 de 06
• delphi
program DPR file auto-create formularios de listado.
• Lea "Cómo hacer que los formularios funcionen: un manual" para obtener
una explicación más detallada y cómo especificar qué formularios se crean.
• Lea el " TForm.Create (AOwner) ... AOwner?!? " Para saber quién debe ser
el propietario del formulario (más: qué es el "propietario").
• Ahora, cuando sepa cuándo se deben crear formularios y quién debería ser
el Propietario, pasemos a cómo vigilar el consumo de memoria ...
• 03 de 06
• 04 de 06
• Esta API está diseñada para permitir la configuración de bajo nivel de los
límites mínimos y máximos de memoria para el espacio de uso de memoria
del proceso. Sin embargo, tiene un pequeño capricho incorporado que es
muy afortunado.
• 05 de 06
• Recortar el uso de memoria en la fuerza
06 de 06
Cree una variable global para contener la última cuenta de marca registrada EN
EL FORMULARIO PRINCIPAL. En cualquier momento que haya actividad en el
teclado o el mouse, registre el conteo de ticks.
Adaptar este método para largos tiempos de procesamiento o procesos por lotes
es bastante simple. Normalmente tendrá una buena idea de dónde comenzará un
proceso largo (por ejemplo, el comienzo de una lectura de bucle a través de
millones de registros de la base de datos) y dónde finalizará (final del bucle de
lectura de la base de datos).
Por Jens: Hooks, he visto a mucha gente tratando de hacer una solución limpia
para enganchar mensajes en una aplicación. Así que decidí hace algún tiempo
implementar ganchos como clase, con buenos eventos y cosas :)
En Windows Hooks
Esto es lo que la guía API de Windows tiene que decir en los ganchos:
En pocas palabras, un gancho es una función que puede crear como parte de un
dll o su aplicación para controlar los 'sucesos' dentro del sistema operativo
Windows.
La idea es escribir una función que se llame cada vez que ocurra un determinado
evento en Windows, por ejemplo, cuando un usuario presiona una tecla en el
teclado o mueve el mouse.
Para una introducción más profunda a los ganchos, eche un vistazo a Qué son los
ganchos de Windows y cómo usarlos dentro de una aplicación Delphi .
Tipos de ganchos
Diferentes tipos de ganchos permiten que una aplicación monitoree un aspecto diferente
del mecanismo de manejo de mensajes del sistema.
Por ejemplo:
Puede usar el gancho WH_KEYBOARD para supervisar la entrada del teclado
publicada en una cola de mensajes;
Puede usar el gancho WH_MOUSE para monitorear la entrada del mouse
publicada en una cola de mensajes;
Puede realizar un procedimiento de enlace WH_SHELL cuando la aplicación de
shell está a punto de activarse y cuando se crea o destruye una ventana de nivel
superior.
Hooks.pas
La unidad hooks.pas define varios tipos de gancho:
> usa ganchos, .... var KeyboardHook: TKeyboardHook; .... // Procedimiento del controlador
de eventos OnCreate de MainForm TMainForm.FormCreate (Sender:
TObject); begin KeyboardHook: = TKeyboardHook.Create; KeyboardHook.OnPreExecute: =
KeyboardHookPREExecute; KeyboardHook.Active: = True; fin ; // maneja
el procedimiento OnPREExecute de KeyboardHook TMainForm.KeyboardHookPREExecute
(Hook: THook; var Hookmsg: THookMsg); var clave: Word; begin // Aquí puede elegir si
desea devolver // el trazo de tecla a la aplicación o no Hookmsg.Result: = IfThen
(cbEatKeyStrokes.Checked, 1, 0); Clave: = Hookmsg.WPARAM; Leyenda: = Char
(clave); fin ; Listo, listo, gancho :)
Enganche el mouse para capturar eventos
fuera de una aplicación
• by Zarko Gajic
• Aprenda a seguir la actividad del mouse incluso cuando su aplicación no
esté activa, se encuentre en la bandeja o no tenga ninguna UI .
•
Hay 2 tipos de ganchos: global y local. Un gancho local monitorea cosas
que suceden solo para un programa específico (o hilo). Un gancho global
supervisa todo el sistema (todos los hilos).
• Enganchar el mouse
• Por diseño, el movimiento del mouse está restringido por el tamaño de la
pantalla de su escritorio (incluida la barra de tareas de Windows). Cuando
mueva el mouse hacia el borde izquierdo / derecho / superior / inferior, el
mouse se "detendrá", como se espera (si no tiene más de un monitor).
• Esta es una idea para el gancho del mouse en todo el sistema: si, por
ejemplo, desea mover el mouse hacia el lado derecho de la pantalla cuando
se mueve hacia el borde izquierdo (y lo "toca"), puede escribir un gancho de
ratón global para reposicionar el puntero del mouse.
• Nota 1: Lea los archivos de Ayuda de Win32 SDK para obtener información
sobre el registro PMouseHookStruct y la firma de la función HookProc.
El artículo sobre cómo almacenar una DLL dentro de un archivo exe del programa
Delphi como recurso explica cómo enviar una DLL con su archivo ejecutable de la
aplicación Delphi como recurso.
De acuerdo con el artículo Cargando una DLL de memoria por Joachim Bauch,
esto es posible.
var
ms: TMemoryStream;
rs: TResourceStream;
empezar
si 0 <> FindResource (hInstance, 'DemoDLL', RT_RCDATA), entonces
empezar
rs: = TResourceStream.Create (hInstance, 'DemoDLL', RT_RCDATA);
ms: = TMemoryStream.Create;
tratar
ms.LoadFromStream (rs);
ms.Position: = 0;
m_DllDataSize: = ms.Size;
mp_DllData: = GetMemory (m_DllDataSize);
Luego, cuando tenga la DLL cargada desde un recurso en la memoria, puede llamar a sus
procedimientos:
var
btMM: PBTMemoryModule;
empezar
btMM: = BTMemoryLoadLibary (mp_DllData, m_DllDataSize);
tratar
si btMM = nil luego Abort;
@m_TestCallstd: = BTMemoryGetProcAddress (btMM, 'TestCallstd');
si @m_TestCallstd = nil luego Abort;
m_TestCallstd ('Esta es una llamada de memoria Dll!');
excepto
Showmessage ('Se ha producido un error al cargar el dll:' + BTMemoryGetLastError);
fin ;
si está asignado (btMM), entonces BTMemoryFreeLibrary (btMM);
fin;
• WM_CopyData y TCopyDataStruct
• El mensaje WM_COPYDATA le permite enviar datos de una aplicación a
otra. La aplicación receptora recibe los datos en
un registro TCopyDataStruct. TCopyDataStruct se define en la unidad
Windows.pas y envuelve la estructura COPYDATASTRUCT que contiene
los datos que se pasarán.
El Registro es simplemente una base de datos que una aplicación puede usar
para almacenar y recuperar información de configuración (el último tamaño y
posición de la ventana, las opciones e información del usuario o cualquier otra
información de configuración). El registro también contiene información sobre
Windows (95/98 / NT) y sobre su configuración de Windows.
Probablemente es muy conocido que en los días de Windows 3.xx los archivos INI
eran una forma popular de almacenar información de aplicaciones y otras
configuraciones configurables por el usuario. El aspecto más aterrador de los
archivos INI es que son solo archivos de texto que el usuario puede editar
fácilmente (cambiarlos o incluso eliminarlos).
En Windows de 32 bits, Microsoft recomienda usar Registry para almacenar el tipo
de información que normalmente colocaría en los archivos INI (es menos probable
que los usuarios alteren las entradas de registro).
Delphi brinda soporte completo para cambiar entradas en el Registro del sistema
de Windows: a través de la clase TRegIniFile (la misma interfaz básica que la
clase TIniFile para usuarios de archivos INI con Delphi 1.0) y la clase TRegistry
(contenedor de bajo nivel para el registro de Windows y funciones que operan en
el registro).
Antes de que podamos usar TRegistry, tenemos que agregar la unidad de registro
a la cláusula uses en la parte superior del código fuente.
~~~~~~~~~~~~~~~~~~~~~~~~~
usa registro;
procedure TForm1.FormCreate (Sender: TObject);
var
reg: TRegistry;
empezar
reg: = TRegistry.Create;
con reg comenzar
tratar
si OpenKey ('\ Control Panel \ desktop', False) entonces comienza
// cambiar el fondo de pantalla y colocarlo en mosaico
reg.WriteString ('Fondo de pantalla', 'c: \ windows \ CIRCLES.bmp');
reg.WriteString ('TileWallpaper', '1');
// desactivar el protector de pantalla // ('0' = desactivar, '1' = habilitar)
reg.WriteString ('ScreenSaveActive', '0');
// actualiza los cambios inmediatamente
SystemParametersInfo (SPI_SETDESKWALLPAPER, 0, nil,
SPIF_SENDWININICHANGE);
SystemParametersInfo (SPI_SETSCREENSAVEACTIVE, 0, nil,
SPIF_SENDWININICHANGE);
fin
finalmente
reg.Free;
fin;
fin;
fin;
~~~~~~~~~~~~~~~~~~~~~~~~~
Esas dos líneas de código que comienzan con SystemParametersInfo ... obligan a
Windows a actualizar inmediatamente el fondo de pantalla y la información del
protector de pantalla. Cuando ejecuta su aplicación, verá que el mapa de bits del
fondo de pantalla de Windows cambia a la imagen Circles.bmp (esto es, si tiene
una imagen de circles.bmp en su directorio de Windows).
Nota: su protector de pantalla ahora está desactivado.
• Los archivos INI son archivos de texto utilizados para almacenar los datos
de configuración de una aplicación.
• > [Nombre de sección] nombre clave1 = valor; comentario nombre clave2 = valor
• Los nombres de las secciones están entre corchetes y deben comenzar
al principio de una línea. La sección y los nombres de las teclas no
distinguen entre mayúsculas y minúsculas (el caso no importa) y no pueden
contener caracteres espaciados. El nombre de la tecla es seguido por un
signo igual ("="), opcionalmente rodeado por espacios de caracteres, que
son ignorados.
• Delphi IDE usa el formato de archivo INI en muchos casos. Por ejemplo,
los archivos .DSK (configuración de escritorio) utilizan el formato INI.
• Clase TIniFile
• Delphi proporciona la clase TIniFile , declarada en la unidad inifiles.pas ,
con métodos para almacenar y recuperar valores de archivos INI.
• Antes de trabajar con los métodos TIniFile, debe crear una instancia de la
clase:
• > usa inifiles; ... var IniFile: TIniFile; begin IniFile: = TIniFile.Create ('myapp.ini');
• Lectura de INI
• La clase TIniFile tiene varios métodos de "lectura". ReadString lee un valor
de cadena de una clave, ReadInteger. ReadFloat y similares se usan para
leer un número de una clave. Todos los métodos de "lectura" tienen un
valor predeterminado que se puede usar si la entrada no existe.
• > function ReadString ( const Section, Ident, Default: String): String; anular ;
• Escribir a INI
• El TIniFile tiene un método de "escritura" correspondiente para cada
método de "lectura". Son WriteString, WriteBool, WriteInteger, etc.
• > project1.ini [User] Last = Zarko Gajic Fecha = 29/01/2009 [Placement] Top = 20
Left = 35 Width = 500 Height = 340
• Otro problema puede surgir si tiene una sección con más de 8 K de valor.
Una forma de resolver el problema es escribir su propia versión del método
ReadSection.
• Puedes arrastrar y soltar desde / hacia donde quieras, como de una forma a
otra, o desde Windows Explorer a tu aplicación.
• DragMode
• Los componentes permiten dos tipos de arrastre: automático y manual.
Delphi usa la propiedad DragMode para controlar cuándo el usuario puede
arrastrar el control.
• OnDragDrop
• El evento que reconoce arrastrar y soltar se llama evento OnDragDrop. Lo
usamos para especificar lo que queremos que suceda cuando el usuario
suelta un objeto. Por lo tanto, si queremos mover un componente (imagen)
a una nueva ubicación en un formulario, tenemos que escribir el código
para el controlador de eventos OnDragDrop del formulario.
• Aceptar
• Tenemos que usar el evento OnDragOver del formulario para indicar que el
formulario puede aceptar el control de TImage que queremos colocar sobre
él. Aunque el parámetro Aceptar se establece de forma predeterminada en
Verdadero, si no se proporciona un controlador de eventos OnDragOver, el
control rechaza el objeto arrastrado (como si el parámetro Aceptar se
hubiera cambiado a Falso).
• Drag Cursor
• Si desea cambiar la imagen del cursor presentada cuando se arrastra el
control, use la propiedad DragCursor. Los valores posibles para la
propiedad DragCursor son los mismos que para la propiedad Cursor.
Nunca debe usar rutas codificadas a ubicaciones específicas, como "c: \ Archivos
de programa", ya que puede no funcionar en otras versiones de Windows porque
la ubicación de las carpetas y directorios puede cambiar con diferentes versiones
de Windows.
• Archivos mecanografiados
• Mientras que los archivos de texto consisten en líneas terminadas con una
combinación CR / LF ( # 13 # 10 ), los archivos tipeados consisten en
datos tomados de un tipo particular de estructura de datos .
• Escribir en un archivo
• Supongamos que hemos llenado un conjunto de miembros de Delphi con
sus nombres, correos electrónicos y número de publicaciones, y queremos
almacenar esta información en un archivo en el disco. La siguiente pieza de
código hará el trabajo:
• Leer de un archivo
• Para recuperar toda la información del archivo 'members.dat', usaríamos el
siguiente código :
• > var Miembro: TMember F: archivo de TMember; comenzar AssignFile (F,
'members.dat'); Restablecer (F); intente mientras no Eof (F) comiencen a leer (F,
miembro); {DoSomethingWithMember;} end ; finalmente CloseFile (F); fin ; fin ;
• Buscando y posicionando
• Normalmente, se accede a los archivos secuencialmente. Cuando se lee un
archivo usando el procedimiento estándar Leído o escrito usando el
procedimiento estándar Escribir, la posición actual del archivo se mueve al
siguiente componente de archivo ordenado numéricamente (próximo
registro). También se puede acceder aleatoriamente a los archivos tipeados
a través del procedimiento estándar Buscar, que mueve la posición actual
del archivo a un componente específico. Las
funciones FilePos y FileSize se pueden usar para determinar la posición
actual del archivo y el tamaño actual del archivo.
• > {volver al principio - el primer registro} Buscar (F, 0); {ir al registro 5 °} Buscar (F,
5); {Saltar al final - "después" del último registro} Buscar (F, FileSize (F));
• Cambiar y actualizar
• Acaba de aprender a escribir y leer todo el conjunto de miembros, pero
¿qué sucede si lo único que desea hacer es buscar al 10º miembro y
cambiar el correo electrónico? El siguiente procedimiento hace
exactamente eso:
• Completando la tarea
• Eso es todo, ahora tienes todo lo que necesitas para llevar a cabo tu tarea.
Puede escribir la información de los miembros en el disco, puede leerla e
incluso puede cambiar algunos de los datos (correo electrónico, por
ejemplo) en el "medio" del archivo.
La razón es que una aplicación Delpi tiene un solo subproceso. El código que está
escribiendo representa solo un grupo de procedimientos que son llamados por el
hilo principal de Delphi cada vez que ocurre un evento. El resto del tiempo, el hilo
principal es el manejo de los mensajes del sistema y otras cosas como funciones
de manejo de formularios y componentes.
¿Qué es ProcessMessages?
PprocessMessages maneja todos los mensajes del sistema en espera en la cola
de mensajes de las aplicaciones. Windows usa mensajes para "hablar" a todas las
aplicaciones en ejecución. La interacción del usuario se lleva a cabo a través de
mensajes y "ProcessMessages" los maneja.
Tal vez su aplicación recuperará algunos errores, como liberar los búferes.
La mejor manera:
Para hacerlo más fácil, puede configurar todo el Formulario "enabled: = false", que
bloquea todas las entradas de los usuarios, pero NO lo muestra al usuario (todos
los botones no están atenuados).
Una forma mejor sería configurar todos los botones en "deshabilitado", pero esto
podría ser complejo si desea mantener un botón "Cancelar" por ejemplo. También
necesita revisar todos los componentes para deshabilitarlos y, cuando vuelvan a
habilitarse, debe verificar si quedan algunos en estado deshabilitado.
• Como ejemplo, en lugar de utilizar el tipo TObjectList para tener una lista de
cualquier tipo de objeto, desde Delphi 2009, la
unidad Generics.Collections define TObjectList con más caracteres.
• Aquí hay una lista de artículos que explican los tipos genéricos en Delphi
con ejemplos de uso:
• Para mí, los genéricos fueron la razón para pasar de Delphi 7/2007 a Delphi
2009 (y más reciente).
• Esto sería útil para programas que se dejan funcionando durante largos
periodos de tiempo sin interacción del usuario (tareas en segundo plano
que normalmente se ejecutan en su PC todo el día).
• Vamos a la bandeja
• Afortunadamente, crear una aplicación que se ejecute en la bandeja del
sistema es bastante fácil: solo se necesita una función (API),
Shell_NotifyIcon, para realizar la tarea.
• Tomar uno...
• Si ejecuta su proyecto ahora, verá un ícono cerca del reloj en la bandeja.
Tenga en cuenta tres cosas.
• 1) Primero, no ocurre nada cuando hace clic (o hace cualquier otra cosa
con el mouse) en el ícono colocado en la Bandeja; aún no hemos creado un
procedimiento (manejador de mensajes).
2) Segundo, hay un botón en la barra de tareas (obviamente no lo
queremos allí).
3) En tercer lugar, cuando cierra su aplicación, el icono permanece en la
Bandeja.
• Toma dos...
• Vamos a resolver esto al revés. Para que el icono se elimine de la Bandeja
cuando salga de la aplicación, debe llamar a Shell_NotifyIcon nuevamente,
pero con NIM_DELETE como primer parámetro.
• Nota: una variable global DebugHook se usa arriba para asegurarse de que
las pérdidas de memoria se muestren cuando la aplicación se ejecuta en
modo de depuración, cuando ajusta F9 desde Delphi IDE.
• > var sl: TStringList; begin sl: = TStringList.Create; sl.Add ('¡Fuga de memoria!'); fin ;
• Cuando necesite crear una consulta SQL en una base de datos de Access
donde se usa un valor de fecha (o fecha y hora), debe asegurarse de
utilizar el formato correcto.
• > # YYYY-MM-DD #
• Aquí hay una función Delphi personalizada que puede usar para formatear
un valor de fecha para la consulta de Access SQL.
• > función DateForSQL ( const date: TDate): cadena ; var y, m, d:
palabra; comenzar DecodeDate (date, y, m, d); resultado: = Formato ('#%. * d -%. * d
-%. * d #', [4, y, 2, m, 2, d]); fin ;
• Tan pronto como construya una cadena de fecha y hora válida para el SQL
usando el formato general anterior y lo intente usando cualquiera de los
componentes del conjunto de datos de Delphi como TADOQuery, recibirá el
horrible "El objeto del parámetro está definido incorrectamente. Se
proporcionó información incompleta o incoherente" en tiempo de ejecución !
• Una forma de "corregir" el error es usar otro formato para fecha / hora
(reemplace ":" por "."):
• Y aquí está una función Delphi personalizada para devolver una cadena de
un valor de fecha y hora que puede usar al construir consultas SQL para
Access donde necesita buscar un valor de fecha y hora:
• Aquí hay una versión más corta que usa la rutina FormatDateTime:
Dado que Word (Microsoft) determina cuál es el contenido "en bruto" de un archivo
.DOC, sabe cómo imprimir archivos .DOC. Lo mismo se aplica a cualquier tipo de
archivo "conocido" que contenga cierta información imprimible.
Imprima cualquier tipo de documento (PDF, DOC, XLS, HTML, RTF, DOCX)
usando Delphi
Entonces, ¿cómo se imprime cualquier tipo de documento, utilizando programáticamente
el código Delphi?
• Función CompareDateTime
• Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
• Declaración:
tipo TValueRelationship = -1..1
función CompareDateTime ( const ADate, BDate: TDateTime):
TValueRelationship
• Descripción:
Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
• Ejemplo:
• Función CompareTime
• Compara dos valores de TDateTime (devuelve "menos", "igual" o
"mayor"). Ignora la parte Fecha si ambos valores ocurren al mismo tiempo.
• Declaración:
tipo TValueRelationship = -1..1
función CompareDate ( const ADate, BDate: TDateTime):
TValueRelationship
• Descripción:
Compara dos valores de TDateTime (devuelve "menos", "igual" o "mayor").
Ignora la parte Tiempo si ambos valores ocurren al mismo tiempo.
• Función de fecha
• Devuelve la fecha del sistema actual.
• Declaración:
tipo TDateTime = tipo Doble;
• Descripción:
Devuelve la fecha del sistema actual.
• Función DateTimeToStr
• Convierte un valor TDateTime en una cadena (fecha y hora).
• Declaración:
tipo TDateTime = tipo Doble;
• Descripción:
Devuelve el día de la semana para una fecha determinada.
• Ejemplo:
• const Days: array [1..7] de string = ('Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday') ShowMessage ('Today is' + Days [DayOfWeek
(Date)]); //Hoy es Lunes
• Función DaysBetween
• Da la cantidad de días enteros entre dos fechas especificadas.
• Declaración:
función DaysBetween (const ANow, AThen: TDateTime): Integer;
• Descripción:
Da la cantidad de días enteros entre dos fechas especificadas.
• Ejemplo:
• Función DateOf
• Devuelve solo la parte Fecha del valor TDateTime, configurando la parte
Tiempo en 0.
• Declaración:
función DateOf (Fecha: TDateTime): TDateTime
• Descripción:
Devuelve solo la parte Fecha del valor TDateTime, configurando la parte
Tiempo en 0.
• Ejemplo:
• Función DecodeDate
• Separa los valores de Año, Mes y Día desde un valor de TDateTime.
• Declaración:
procedimiento DecodeDate (Fecha: TDateTime; var Año, Mes, Día:
Palabra) ;;
• Descripción:
Separa los valores de Año, Mes y Día desde un valor de TDateTime.
• Ejemplo:
var Y, M, D: Word; DecodeDate (Fecha, Y, M, D); si Y = 2000 entonces ShowMessage ('¡Estás en un siglo "equivocado
• Función EncodeDate
Crea un valor de TDateTime a partir de los valores de Año, Mes y Día.
• Declaración:
función EncodeDate (año, mes, día: palabra): TDateTime
• Descripción:
Crea un valor de TDateTime a partir de los valores de Año, Mes y Día.
• El año debe estar entre 1 y 9999. Los valores de mes válidos son de 1 a 12.
Los valores de día válidos son de 1 a 28, 29, 30 o 31, según el valor del
mes.
Si la función falla, EncodeDate genera una excepción EConvertError.
• Ejemplo:
• Función FormatDateTime
Formatea un valor TDateTime para una cadena.
• Declaración:
función FormatDateTime ( const Fmt: cadena; Valor:
TDateTime): cadena ;
• Descripción:
Formatea un valor TDateTime para una cadena.
• Función IncDay
• Agrega o sustrae un número determinado de días desde un valor de fecha.
• Declaración:
función IncDay (ADate: TDateTime; Days: Integer = 1): TDateTime;
• Descripción:
Agrega o sustrae un número determinado de días desde un valor de fecha.
• Ejemplo:
• Ahora funciona
• Devuelve la fecha y hora actual del sistema.
• Declaración:
tipo TDateTime = tipo Doble;
• Descripción:
Devuelve la fecha y hora actual del sistema.
• Descripción:
Da la cantidad de años enteros entre dos fechas especificadas.
• Ejemplo:
Para crear un formulario Delphi capaz de recuperar los datos de una base de
datos de Access con el componente ADOQuery, simplemente suelte todos los
componentes de acceso a los datos y datos relacionados y haga un enlace como
se describe en los capítulos anteriores de este curso.
DBGrid1.DataSource = DataSource1
DataSource1.DataSet = ADOQuery1
ADOQuery1.Connection = ADOConnection1
// construimos ConnectionString
ADOConnection1.ConnectionString = ...
ADOConnection1.LoginPrompt = False
con ADOQuery1 do begin Close; SQL.Clear; SQL.Add: = 'SELECT * FROM Authors' SQL.Add: = 'ORDER BY authornam
Tenga en cuenta que obviamente crear una lista persistente de objetos de campo
para un componente ADOQuery no tiene sentido. La próxima vez que llame al
método Open, el SQL puede ser tan diferente que el conjunto completo de
nombres archivados (y tipos) puede cambiar. Por supuesto, este no es el caso si
estamos usando ADOQuery para obtener las filas de una sola tabla con el
conjunto constante de campos, y el conjunto resultante depende de la parte
WHERE de la declaración SQL.
Consultas dinámicas
Cuando cierre la ventana del editor de SQL, abra la ventana Parámetros haciendo
clic en el botón de puntos suspensivos en el Inspector de Objetos.
con ADOQuery1 do begin Close; SQL.Clear; SQL.Add ('SELECT * FROM Aplicaciones WHERE type = : apptype '); Para
('apptype'). Value: = 'multimedia'; Abierto; fin ;
Un ejemplo
Tenga en cuenta que todo esto se puede hacer mediante el uso de ADOTable y su
propiedad TableName.
Sin embargo, verá que inicialmente, tiene que establecer esto en un valor muy
grande que da como resultado que la lista eliminada sea demasiado amplia (en la
mayoría de los casos). Una solución consiste en establecer el ancho de
visualización de un campo en particular que se muestra en una lista desplegable.
Este código, ubicado dentro del evento OnCreate para el formulario, garantiza que
tanto el nombre del autor como su correo electrónico se muestren dentro de la lista
desplegable:
Lo que nos queda por hacer, es hacer que un cuadro combinado pase el mouse
sobre una celda (cuando está en modo de edición), mostrando el campo
AuthorEmail. En primer lugar, debemos asegurarnos de que
DBLookupComboBox1 se mueva y clasifique sobre la celda en la que se muestra
el campo AuthorEmail.
Tenga en cuenta que cuando está en el modo de edición, todas las pulsaciones de
teclado van a la celda de DBGrid, pero debemos asegurarnos de que se envíen a
DBLookupComboBox. En el caso de un DBLookupComboBox, estamos
interesados principalmente en la tecla [Tab]; debería mover el foco de entrada a la
siguiente celda.
• Hilos y GUI
• Cuando se ejecutan varios subprocesos en la aplicación, surge la pregunta
de cómo puede actualizar su interfaz gráfica de usuario (GUI) como
resultado de la ejecución de un subproceso.
• La respuesta está en el método Sincronizar de la clase TThread.
• > unidad MainU; la interfaz usa Windows, Mensajes, SysUtils, Variantes, Clases,
Gráficos, Controles, Formularios, Diálogos, ComCtrls, StdCtrls, ExtCtrls; tipo // clase
de interceptor TButton = clase (StdCtrls.TButton) OwnedThread:
TThread; ProgressBar: TProgressBar; fin ; TMyThread
= clase (TThread) private FCounter: Integer; FCountTo: Integer; FProgressBar:
TProgressBar; FOwnerButton:
TButton; procedimiento DoProgress; procedimiento SetCountTo (const Value:
Integer); procedimiento SetProgressBar (valor de const:
TProgressBar); procedimiento SetOwnerButton (valor de const:
TButton); procedimiento protegido Ejecutar; anular ; public constructor Create
(CreateSuspended: Boolean); propiedad CountTo:
Integer read FCountTo write SetCountTo; propiedad ProgressBar:
TProgressBar leer FProgressBar escribir SetProgressBar; property OwnerButton:
TButton read FOwnerButton escribe SetOwnerButton; fin; TMainForm
= class (TForm) Button1: TButton; ProgressBar1: TProgressBar; Button2:
TButton; ProgressBar2: TProgressBar; Button3: TButton; ProgressBar3:
TProgressBar; Button4: TButton; ProgressBar4: TProgressBar; Button5:
TButton; ProgressBar5: TProgressBar; procedimiento Button1Click (Sender:
TObject); fin ; var MainForm: TMainForm; implementación {$ R *
.dfm} {TMyThread} constructor TMyThread.Create (CreateSuspended:
Boolean); comenzar heredado; FCounter: = 0; FCountTo: =
MAXINT; fin ; procedimiento TMyThread.DoProgress; var PctDone:
Extended; begin PctDone: = (FCounter / FCountTo); FProgressBar.Position: = Round
(FProgressBar.Step * PctDone); FOwnerButton.Caption: = FormatFloat ('0.00%',
PctDone * 100); fin ; procedimiento TMyThread.Execute; const Interval =
1000000; comenzar FreeOnTerminate: = Verdadero; FProgressBar.Max: =
FCountTo div Interval; FProgressBar.Step: =
FProgressBar.Max; mientras FCounter do comienza si FCounter mod Interval =
0 entonces Synchronize (DoProgress); Inc (FCounter); fin ; FOwnerButton.Caption:
= 'Inicio'; FOwnerButton.OwnedThread: = nil ; FProgressBar.Position: =
FProgressBar.Max; fin ; procedimiento TMyThread.SetCountTo (valor de const :
entero); begin FCountTo: = Value; fin ; procedimiento TMyThread.SetOwnerButton
(valor de const : TButton); begin FOwnerButton: =
Valor; fin ; procedimiento TMyThread.SetProgressBar (valor de const :
TProgressBar); comenzar FProgressBar: =
Value; fin ; procedimiento TMainForm.Button1Click (Sender: TObject); var aButton:
TButton; aThread: TMyThread; aProgressBar: TProgressBar; begin aButton: = TButton
(emisor); si no está asignado (aButton.OwnedThread), entonces comienza aThread:
= TMyThread.Create (True); aButton.OwnedThread: = aThread; aProgressBar: =
TProgressBar (FindComponent (StringReplace (aButton.Name, 'Button', 'ProgressBar',
[]))); aThread.ProgressBar: = aProgressBar; aThread.OwnerButton: =
aButton; aThread.Resume; aButton.Caption: = 'Pausa'; end else
begin si aButton.OwnedThread.Suspended then aButton.OwnedThread.Resume else
aButton.OwnedThread.Suspend; aButton.Caption: = 'Ejecutar'; fin ; fin ; fin
Si necesita crear una interfaz de usuario similar a un asistente donde tenga los
botones "Siguiente" y "Anterior" "moviendo" un usuario hacia adelante y hacia
atrás a través de un conjunto de páginas (cuadros de diálogo), es posible que
desee ocultar las pestañas de PageControl y por lo tanto, no se permite
seleccionar una página en particular por medio del mouse del usuario.
El truco está en establecer la propiedad TabVisible en falso para cada una de las
hojas (objeto TTabSheet) del control de página.
Activar la página utilizando las propiedades
ActivePage o ActivePageIndex PageControl no generará
los eventos OnChange y OnChanging .
> // Ocultar las pestañas de PageControl var page: integer; begin for page: =
0 a PageControl1.PageCount - 1 comenzar con PageControl1.Pages [página]
.TabVisible: = false; fin ; // seleccione la primera
pestaña PageControl1.ActivePageIndex: = 0; (* O configure la página activa
directamente PageControl1.ActivePage: = TabSheet1; Nota: las dos anteriores NO
generan los eventos OnChanging y OnChange
*) end ; procedure TForm1.PageControl1Changing (Sender:
TObject; var AllowChange: Boolean); begin // no change if en la última
página AllowChange: = PageControl1.ActivePageIndex <-1 +
PageControl1.PageCount; fin ; // Seleccione el procedimiento de la pestaña
"Anterior" TForm1.PreviousPageButtonClick (Sender:
TObject); comience PageControl1.SelectNextPage (falso, falso); fin ; // Seleccione
el procedimiento de la pestaña "Siguiente" TForm1.NextPageButtonClick (Sender:
TObject); comience PageControl1.SelectNextPage (verdadero, falso); fin ;
El uso de esta técnica desordene el formulario, lo que lleva a una interfaz más
optimizada, pero asegúrese de que la disposición de los controles en cada
pestaña no obligue al usuario a moverse con frecuencia entre pestañas.
Si planea escribir el código Delphi que debería funcionar con varias versiones del
compilador Delphi, necesita saber en qué versiones se compila su código.
La sintaxis se ve así:
Un uso común para la directiva $ IfDef es probar la versión del compilador Delphi.
Nota: el símbolo VER185, por ejemplo, se usa para indicar el compilador de Delphi
2007 o una versión anterior.
Una forma de resolver este problema es crear su propia versión de esta rutina: la
función AddLastBackSlash.
Delphi 2008?
Delphi 2007 usa VER180 para mantener la compatibilidad sin interrupciones con
Delphi 2006 y luego agrega VER185 para el desarrollo que específicamente
necesita apuntar a Delphi 2007 por cualquier razón.
Nota: cada vez que la interfaz de una unidad cambia, el código que usa esa
unidad debe volver a compilarse.
Delphi 2007 es un lanzamiento sin interrupciones, lo que significa que los
archivos DCU de Delphi 2006 funcionarán tal como están.
• Lo que debe hacer es declarar una clase ficticia simple que amplíe
TCheckBox en la misma unidad donde utilizará la propiedad
ClickSDisabled.
Por diseño, una aplicación Delphi se ejecuta en un hilo. Para acelerar algunas
partes de la aplicación, quizás desee agregar varias rutas de ejecución
simultáneas en su aplicación Delphi .
> var s, sg: widestring; c1, c2, c3: entero; begin s: = 'SELECT O.SaleDate, MAX
(I.ItemNo) AS ItemCount' + 'FROM Customer C, Orders O, Items I' + 'WHERE
C.CustNo = O.CustNo AND I.OderNo = O.OrderNo' ; sg: = 'GROUP BY
O.SaleDate'; c1: = Integer (ComboBox1.Items.Objects [ComboBox1.ItemIndex]); c2: =
Integer (ComboBox2.Items.Objects [ComboBox2.ItemIndex]); c3: = Entero
(ComboBox3.Items.Objects [ComboBox3.ItemIndex]); Leyenda: = ''; ct1: = RunThread
(Formato ('% s Y C.CustNo =% d% s', [s, c1, sg]), lbCustomer1, tpTimeCritical,
lblCustomer1); ct2: = RunThread (Formato ('% s Y C.CustNo =% d% s', [s, c2, sg]),
lbCliente2, tpNormal, lblCliente2); ct3: = RunThread (Formato ('% s Y C.CustNo =%
d% s', [s, c3, sg]), lbCustomer3, tpLowest, lblCustomer3); fin ;
• Padre
• Parent se refiere al componente en el que está contenido otro componente,
como TForm, TGroupBox o TPanel. Si un control (principal) contiene otros,
los controles contenidos son controles secundarios del padre.
• Para que un componente sea visible, debe tener un padre para mostrarse
dentro de él .
• ParentThis y ParentThat
• Si selecciona un botón en el momento del diseño y mira el Inspector de
Objetos, notará varias propiedades "para padres". El ParentFont , por
ejemplo, indica si la Fuente utilizada para el título del Botón es la misma
que la utilizada para el elemento primario del Botón (en el ejemplo anterior:
Panel1). Si ParentFont es Verdadero para todos los Botones en un Panel,
al cambiar la propiedad de Fuente del panel a Negrita, todos los leyendas
del Botón en el Panel usarán esa fuente (negrita).
• Propiedad de controles
• Todos los componentes que comparten el mismo Parent están disponibles
como parte de la propiedad Controls de ese Parent. Por ejemplo, los
controles se pueden usar para iterar sobre todos los elementos secundarios
del control de ventana .
• Trucos de engaño
• Los controles con ventana tienen tres características básicas: pueden
recibir el foco de entrada, usan recursos del sistema y pueden ser padres
de otros controles.
• Propiedad
• En primer lugar, tenga en cuenta que un Formulario es el propietario
general de cualquier componente que resida en él (ubicado en el formulario
en el momento del diseño). Esto significa que cuando se destruye un
formulario, también se destruyen todos los componentes del formulario. Por
ejemplo, si tenemos una aplicación con más de un formulario cuando
llamamos al método Free o Release para un objeto de formulario, no
tenemos que preocuparnos de liberar explícitamente todos los objetos en
ese formulario, porque el formulario es el propietario de todos sus
componentes
• Si, por otro lado, hacemos que otro componente (no el formulario) sea el
propietario del componente, entonces hacemos que ese componente sea
responsable de deshacerse del objeto cuando se destruye.
• > usa FindFile; ... var FFile: TFindFile; procedimiento TForm1.InitializeData; begin //
form ("Self") es el propietario del componente // no hay Parent porque this // es un
componente invisible. FFile: = TFindFile.Create (Self); ... fin
• Propiedad de componentes
• Todos los componentes que comparten el mismo Propietario están
disponibles como parte de la propiedad Componentes de ese Propietario.
El siguiente procedimiento se utiliza para borrar todos los componentes de
edición que están en el formulario:
• > procedimiento ClearEdits (AForm: TForm); var ii: Integer; begin for ii: =
0 a AForm.ComponentCount-1 do if (AForm.Components [ii] es TEdit) luego TEdit
(AForm.Components [ii]). Text: = ''; fin ;
• "Huérfanos"
• Algunos controles (como los controles ActiveX) están contenidos en
ventanas que no son de VCL en lugar de en un control principal. Para estos
controles, el valor de Parent es nulo y la
propiedad ParentWindow especifica la ventana padre que no es VCL. El
establecimiento de ParentWindow mueve el control para que esté contenido
en la ventana especificada. ParentWindow se establece automáticamente
cuando se crea un control utilizando el método CreateParented .
• TeeChart
• El componente DBChart es una poderosa herramienta para crear tablas y
gráficos de bases de datos. No solo es poderoso, sino también complejo.
No exploraremos todas sus propiedades y métodos, por lo que deberá
experimentar con él para descubrir todo lo que es capaz de hacer y cómo
puede satisfacer mejor sus necesidades. Al utilizar DBChart con el motor de
gráficos TeeChart, puede hacer gráficos rápidamente para los datos en
conjuntos de datos sin necesidad de ningún código. TDBChart se conecta a
cualquier Delphi DataSource. Los conjuntos de registros ADO son
compatibles de forma nativa. No se requiere código adicional, o solo un
poco como verá. El editor de gráficos lo guiará a través de los pasos para
conectarse a sus datos; ni siquiera necesita ir al Inspector de Objetos.
•
Las bibliotecas de Runtime TeeChart se incluyen como parte de las
versiones Delphi Professional y Enterprise. TChart también está integrado
con QuickReport con un componente TChart personalizado en la paleta
QuickReport. Delphi Enterprise incluye un control DecisionChart en la
página Decision Cube de la paleta de componentes.
• Let's Chart! Preparar
• Nuestra tarea será crear un formulario Delphi simple con un gráfico lleno de
valores de una consulta de base de datos. Para seguir, crea una forma
Delphi de la siguiente manera:
• Tenga en cuenta que esas dos tablas están vinculadas en una relación
maestro-detalle.
• Comando RegSvr32.exe
• Manualmente, el uso de regsvr32.exe (Windows.Start - Run) registrará y
anulará el registro de DLL autoregistro y controles ActiveX en un sistema.
TQuery encapsula una o más sentencias SQL, las ejecuta y proporciona métodos
mediante los cuales podemos manipular los resultados. Las consultas se pueden
dividir en dos categorías: las que producen conjuntos de resultados (como una
instrucción SELECT ) y las que no (como una instrucción UPDATE o INSERT ).
Todas las sentencias SQL ejecutables deben prepararse antes de que puedan
ejecutarse. El resultado de la preparación es la forma ejecutable u operacional de
la declaración. El método de preparación de una declaración SQL y la persistencia
de su forma operacional distinguen SQL estático de SQL dinámico. En el momento
del diseño, una consulta se prepara y ejecuta automáticamente cuando establece
la propiedad Activo del componente de consulta en True. En tiempo de ejecución,
se prepara una consulta con una llamada a Preparar, y se ejecuta cuando la
aplicación llama a los métodos Open o ExecSQL del componente.
Un TQuery puede devolver dos tipos de conjuntos de resultados: "en vivo " como
con el componente TTable (los usuarios pueden editar datos con controles de
datos, y cuando se envía una llamada a los cambios se envían a la base de
datos), " solo lectura " para fines de visualización solamente. Para solicitar un
conjunto de resultados en vivo, establezca la propiedad RequestLive de un
componente de consulta en True y tenga en cuenta que la declaración SQL debe
cumplir con algunos requisitos específicos (sin ORDER BY, SUM, AVG, etc.)
Ejemplo simple
8. Ejecute su aplicación. Cuando hace clic en el botón (siempre que Edit 1 tenga
un valor de moneda válido en él), la grilla mostrará los campos EmpNo, FirstName
y LastName para todos los registros donde Salario sea mayor que el valor de
moneda especificado.
En este ejemplo creamos una declaración SQL estática simple con un conjunto de
resultados en vivo (no hemos cambiado ninguno de los registros visualizados) solo
para propósitos de visualización.
Una vez que coloca un control (componente visual) en el formulario, puede ajustar
su posición, tamaño y otras propiedades de tiempo de diseño. Sin embargo, hay
situaciones en las que tiene que permitir que un usuario de su aplicación cambie la
posición de los controles de formulario y cambie su tamaño, en tiempo de
ejecución.
tipo TForm1 = clase (TForm) ... procedimiento ControlMouseDown (Sender: TObject; Botón: TMouseButton; Shift: T
Integer); procedimiento ControlMouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); procedimiento Contr
(Sender: TObject; Botón: TMouseButton; Shift: TShiftState; X, Y: Integer); private inReposition: boolean; oldPos: TPoin
procedure TForm1.ControlMouseMove (Sender: TObject; Shift: TShiftState; X, Y: Integer); const minWidth = 20; minH
20; var newPos: TPoint; frmPoint: TPoint; comience si inReposition luego comience con TWinControl
(Sender) comience GetCursorPos (newPos); si ssShift en Shift entonces comienza // redimensiona Screen.Cursor: =
frmPoint: = ScreenToClient (Mouse.CursorPos); si frmPoint.X> minWidth then Ancho: = frmPoint.X; si frmPoint.Y>
minHeight, entonces Height: = frmPoint.Y; end else // move begin Screen.Cursor: = crSize; Izquierda: = Izquierda - o
newPos.X; Arriba: = Superior - viejoPos.Y + nuevoPos.Y; oldPos: = newPos; fin ; fin ; fin ; fin ; (* ControlMouseMove *
procedure TForm1.ControlMouseUp (Sender: TObject; Botón: TMouseButton; Shift: TShiftState; X, Y: Integer); comien
en Reposición luego comience Screen.Cursor: = crDefault; ReleaseCapture; inReposition: = False; fin ; fin ; (* Contro
Nota: Otra forma de mover controles en tiempo de ejecución es utilizar las propiedades y métodos relacionados de
de Delphi (Modo Drag, OnDragDrop, DragOver, BeginDrag, etc.). Arrastrar y soltar se puede usar para permitir a los
elementos de un control, como un cuadro de lista o una vista de árbol, a otro.
Cuando este sea el caso, usará el tipo de datos BLOB (Objeto grande binario)
("memo", "ntext", "image", etc. - el nombre del tipo de datos depende de la base de
datos con la que trabaja).
> TUser = registro lleno Nombre: cadena [50]; CanAsk: booleano; NumberOfQuestions:
entero; fin ;
"Record.SaveAsBlob"
Para insertar una nueva fila (registro de base de datos) en una tabla de base de
datos con un campo BLOB llamado "datos", use el siguiente código:
> var Usuario: TUser; blobF: TBlobField; bs: TStream; begin User.Name: =
edName.Text; User.NumberOfQuestions: = StrToInt (edNOQ.Text); User.CanAsk: =
chkCanAsk.Checked; myTable.Insert; blobF: = myTable.FieldByName
('datos') como TBlobField; bs: = myTable.CreateBlobStream (blobF, bmWrite); try bs.Write
(Usuario, SizeOf (Usuario)); finalmente bs.Free; fin ; fin ;
En el código de arriba:
▪ "myTable" es el nombre del componente TDataSet que está utilizando (TTable, TQuery,
ADOTable, TClientDataSet, etc.).
▪ El nombre del campo blob es "datos".
▪ La variable "Usuario" (TUser registro) se completa utilizando 2 cuadros de edición
("edName" y "edNOQ") y una casilla de verificación ("chkCanAsk")
▪ El método CreateBlobStream crea un objeto TStream para escribir en el campo blob.
"Record.ReadFromBlob"
Una vez que haya guardado los datos del registro (TUser) en un campo de tipo de
blob, aquí se explica cómo "transformar" los datos binarios en un valor de TUser:
> var Usuario: TUser; blobF: TBlobField; bs: TStream; comience si myTable.FieldByName
('data'). IsBlob luego comienza blobF: = DataSet.FieldByName ('data') como TBlobField; bs:
= myTable.CreateBlobStream (blobF, bmRead); intente bs.Read (usuario, tamaño de
(TUser)); finalmente bs.Free; fin ; fin ; edName.Text: = User.Name; edNOQ.Text: = IntToStr
(User.NumberOfQuestions); chkCanAsk.Checked: = User.CanAsk; fin ;
• ConnectionString On-The-Fly
• Si estaba utilizando componentes dbGo (ADO), la
propiedad ConnectionString de TADOConnection especifica la información
de conexión para el almacén de datos.
• Obviamente, al crear aplicaciones de bases de datos que se ejecutarán en
varias máquinas, la conexión a la fuente de datos no debe estar codificada
en el ejecutable.
función TDM.DBConnect: boolean; var conStr: cadena; ServerName, DBName: cadena; begin ServerName: = ReadRe
('DataSource'); DBName: = ReadRegistry ('DataCatalog'); conStr: = 'Proveedor = sqloledb;' + 'Data Source =' + Serve
'Initial Catalog =' + DBName + ';' + 'User Id = myUser; Password = myPasword'; Resultado: = falso AdoConn.Close;
AdoConn.ConnectionString: = conStr; AdoConn.LoginPrompt: = Falso; if ( NO AdoConn.Connected) entonces prueb
Resultado: = Verdadero; excepto en E: Excepción do begin MessageDlg ('Hubo un error al conectarse a la base de d
# 10 + e.Message, mtError, [mbOk], 0); if NOT TDatabasePromptForm.Execute (ServerName, DBName) then Result: =
false else begin WriteRegistry ('DataSource', ServerName); WriteRegistry ('DataCatalog', DBName); // recuperar esta
= DBConnect; fin ; fin ; fin ; fin ; // DBConnect
•
Para resolver este problema, debe cambiar manualmente el orden de
creación del módulo de datos y configurarlo para que sea el primer
formulario que la aplicación cree (ya sea utilizando el cuadro de diálogo
Proyecto-Propiedades o editando el archivo fuente de Proyectos ).
• > // richEdit1 de tipo TRichEdit con richEdit1 do begin // move caret to end SelStart:
= GetTextLen; // agrega una línea sin formato SelText: = 'Esta es la primera línea' +
# 13 # 10; // agrega texto de fuente normal SelText: = 'Líneas formateadas en
RichEdit' + # 13 # 10; // texto más grande SelAttributes.Size: = 13; // agrega negrita
+ rojo SelAttributes.Style: = [fsBold]; SelAttributes.Color: = clRed; SelText: = 'Acerca
de'; // solo negrita SelAttributes.Color: = clWindowText; SelText: = 'Delphi'; // agregar
cursiva + azul SelAttributes.Style: = [fsItalic]; SelAttributes.Color: = clBlue; SelText: =
'Programación'; // nueva línea SelText: = # 13 # 10; // agrega normal otra
vez SelAttributes.Size: = 8; SelAttributes.Color: = clGreen; SelText: = 'pensar en el
procedimiento personalizado AddFormattedLine ...'; fin ;
• Para comenzar, mueva el cursor al final del texto en Rich Edit. Luego,
aplique el formateo antes de agregar el nuevo texto.
ListView.OnItemClick / OnItemDblClick
El evento OnClick (OnDblClick) para TListView se activa cada vez que el usuario
hace clic en el control, es decir, cada vez que el "clic" ocurre en algún lugar dentro
del área del cliente del control .
El usuario puede hacer clic dentro de la vista de lista, PERO "perder" alguno de
los elementos. Además, dado que la vista de lista puede cambiar su visualización
dependiendo de la propiedad ViewStyle, el usuario podría haber hecho clic en un
elemento, en un título de elemento, en un icono de elemento, "en ninguna parte",
en un icono de estado de elemento, etc.
Para asegurarse de que se hizo clic en el elemento (o se hizo doble clic), debe
llamar al GetHitTestInfoAt y reaccionar solo si el evento click se produjo en un
elemento real.
Dificultad: Fácil
Tiempo requerido: 5 minutos
Así es cómo:
Un truco para agregar más líneas de texto para una propiedad Caption de TLabel,
en tiempo de diseño, es editar el archivo .DFM del Formulario directamente. Así es
cómo:
Las cadenas crípticas como "# 13 # 10" aparecen regularmente dentro del código
fuente de Delphi. Sin embargo, estas cadenas no son un galimatías al azar; sirven
un propósito esencial para el diseño del texto.
Una cadena de control es una secuencia de uno o más caracteres de control, cada
uno de los cuales consiste en el símbolo # seguido de una constante entera sin
signo de 0 a 255 (decimal o hexadecimal) y denota el
carácter ASCII correspondiente.
Cuando desee, por ejemplo, asignar una cadena de dos líneas a una propiedad
Caption (de un control TLabel), puede usar el siguiente pseudocódigo:
▪ # 0 - personaje NULL
▪ # 9 - TAB (horizontal)
Nota: así es cómo traducir una clave virtual al código ASCII.
• Para un control de TI llamado Foto , utilice uno de los dos métodos para
borrar el gráfico asignado:
• {code: delphi}
Photo.Picture: = nil;
{código}
• o:
• {code: delphi}
Photo.Picture.Assign (nil);
{código}
• Ahora, para saber qué son los campos de búsqueda y cuáles son las
opciones de mostrar un campo de búsqueda en DBGrid de Delphi , es hora
de ver cómo usar la propiedad PickList de una columna DGBrid para
permitir que un usuario elija un valor para un campo de búsqueda de un
cuadro de lista desplegable.
• Llenar el PickList
• Lo que aprenderá aquí es cómo llenar esa lista de cadenas con valores de
otro conjunto de datos en tiempo de ejecución.
Recuerde, estamos editando la tabla Artículos, y que un campo Asunto solo
puede aceptar valores de la tabla Temas: ¡situación ideal para la Lista de
Selección!
• Eso es. Ahora, cuando hace clic en la columna Asunto (para ingresar al
modo de edición).
• Tenga en cuenta que cuando desee editar el campo que muestra una lista
desplegable, deberá hacer clic en la celda 4 veces para seleccionar un
valor de una lista. El siguiente fragmento de código, agregado al controlador
de eventos OnCellClick de DBGrid, imita un golpe en la tecla F2 seguido de
Alt + Flecha descendente.
El enfoque que debe descubrir en este artículo es mucho más flexible: puede tener
casillas de verificación y botones de radio mezclados con otros nodos de la forma
que desee sin cambiar el TTreeview o crear una nueva clase a partir de él para
que esto funcione. Además, usted mismo decide qué imágenes usar para las
casillas de verificación / botones de radio simplemente agregando las imágenes
adecuadas a la lista de imágenes de StateImages.
Aquí se explica cómo hacer que el código sea aún más profesional: en el evento
OnClick de TreeView, escriba el siguiente código para alternar las casillas de
verificación solo si se hizo clic en el estado (las constantes cFlatUnCheck,
cFlatChecked, etc. se definen en otros lugares como índices en la lista de
imágenes de StateImages) :
• > var SomeTxtFile: TextFile; buffer: cadena ; comenzar AssignFile (SomeTxtFile, 'c: \
autoexec.bat'); Restablecer (SomeTxtFile); ReadLn (SomeTxtFile,
buffer); Memo1.Lines.Add (buffer); CloseFile (SomeTxtFile); fin ;
• > var SomeTxtFile: TextFile; buf1, buf2: cadena [5]; comenzar AssignFile
(SomeTxtFile, 'c: \ autoexec.bat'); Restablecer (SomeTxtFile); ReadLn (SomeTxtFile,
buf1, buf2); ShowMessage (buf1 + '' + buf2); CloseFile (SomeTxtFile); fin ;
• > var SomeTxtFile: TextFile; buffer: cadena ; comenzar AssignFile (SomeTxtFile, 'c: \
autoexec.bat'); Restablecer (SomeTxtFile); mientras que no EOF
(SomeTxtFile) comienzan ReadLn (SomeTxtFile, buffer); ShowMessage
(buffer); fin ; CloseFile (SomeTxtFile); fin ;
• Nota: es mejor utilizar el ciclo While que el ciclo Until para tener en cuenta
la posibilidad (poco probable) de que el archivo exista pero no contenga
ningún dato.
• > var SomeTxtFile: TextFile; buffer: cadena; comenzar AssignFile (SomeTxtFile, 'c: \
MyTextFile.txt'); intente restablecer (SomeTxtFile); ReadLn (SomeTxtFile,
buffer); finalmente CloseFile (SomeTxtFile); fin ; fin ;
• Archivos mecanografiados
• Mientras que los archivos de texto consisten en líneas terminadas con una
combinación CR / LF ( # 13 # 10 ), los archivos tipeados consisten en
datos tomados de un tipo particular de estructura de datos .
• Escribir en un archivo
• Supongamos que hemos llenado un conjunto de miembros de Delphi con
sus nombres, correos electrónicos y número de publicaciones, y queremos
almacenar esta información en un archivo en el disco. La siguiente pieza de
código hará el trabajo:
• Leer de un archivo
• Para recuperar toda la información del archivo 'members.dat', usaríamos el
siguiente código :
• > {volver al principio - el primer registro} Buscar (F, 0); {ir al registro 5 °} Buscar (F,
5); {Saltar al final - "después" del último registro} Buscar (F, FileSize (F));
• Cambiar y actualizar
• Acaba de aprender a escribir y leer todo el conjunto de miembros, pero
¿qué sucede si lo único que desea hacer es buscar al 10º miembro y
cambiar el correo electrónico? El siguiente procedimiento hace
exactamente eso:
• Completando la tarea
• Eso es todo, ahora tienes todo lo que necesitas para llevar a cabo tu tarea.
Puede escribir la información de los miembros en el disco, puede leerla e
incluso puede cambiar algunos de los datos (correo electrónico, por
ejemplo) en el "medio" del archivo.
Hay situaciones en las que desea mostrar una lista de cadenas para el usuario, por
ejemplo, en el control de cuadro de lista, pero también tiene una forma
de almacenar una cadena adicional más a lo largo de la que se muestra al
usuario .
Además, es posible que desee almacenar / adjuntar más que solo una cadena
"simple" a la cadena, es posible que desee adjuntar un objeto al elemento
(cadena) .
Tenga en cuenta que el cuadro de lista expone el método AddItem que hace lo
mismo que Items.AddObject.
Para asignar una segunda cadena al elemento del cuadro de lista, debe
"transformar" una variable de cadena en un objeto; necesita un objeto TString
personalizado.
¿Por qué parar aquí? Asignar cadenas y enteros a una cadena en un cuadro de lista
es, como acaba de experimentar, un pedazo de pastel.
Como los controles Delphi son en realidad objetos, puede adjuntar un control a
cada cadena mostrada en el cuadro de lista.
El siguiente código agrega los títulos de ListBox1 (cuadro de lista) de todos los
controles de TButton en un formulario (coloque esto en el controlador de eventos
OnCreate del formulario) junto con la referencia a cada botón.
En una situación más genérica, debería agregar instancias (objetos) de sus propias
clases personalizadas: > escriba TStudent = class private fName: string; fYear:
entero; propiedad pública Nombre: string read fName; propiedad Año:
entero leído fYear; constructor Create (nombre de const : cadena ; const year:
integer); fin ; ........ constructor TStudent.Create (nombre
de const : cadena ; const year: integer); begin fName: = nombre; fYear: =
año; fin ; -------- begin // agrega dos cadenas / objetos -> students a la
lista ListBox1.AddItem ('John', TStudent.Create ('John', 1970)); ListBox1.AddItem
('Jack', TStudent.Create ('Jack', 1982)); // tomar el primer alumno - John student: =
ListBox1.Items.Objects [0] como TStudent; // muestra el año de John ShowMessage
(IntToStr (student.Year)); fin ;
Esto es lo que la Ayuda tiene que decir sobre los objetos en los descendientes de
TStrings: el objeto TStrings no posee los objetos que agrega de esta manera. Los
objetos añadidos al objeto TStrings aún existen aunque se destruya la instancia de
TStrings. Deben ser explícitamente destruidos por la aplicación.
Cuando agrega objetos a cadenas - objetos que crea - debe asegurarse de liberar
la memoria ocupada, o tendrá una pérdida de memoria
> FreeObjects (ListBox1.Items); Nota: SÓLO llama a este procedimiento cuando los
objetos asignados a los elementos de cadena fueron creados por usted.
Tamaño del ancho desplegable del
ComboBox: sin corte para las ubicaciones
del borde derecho
• by Zarko Gajic
• Asegura que la lista desplegable sea visible cuando se muestra la lista
desplegable
• La lista desplegable
• Cuando un cuadro combinado está en estado desplegable, Windows dibuja un tipo
de cuadro de control para mostrar los elementos del cuadro combinado para su
selección.
• Una prueba
Para una prueba, tengo 3 cuadros combinados en un formulario. Todos
tienen elementos con su texto más ancho que el ancho real del cuadro
combinado.
• El tercer cuadro combinado se coloca cerca del borde derecho del borde
del formulario.
• Solución: WM_CTLCOLORLISTBOX
• Justo cuando se va a mostrar la lista desplegable, Windows envía el mensaje
WM_CTLCOLORLISTBOX a la ventana principal de un cuadro de lista: a nuestro
cuadro combinado.
• Aquí está nuestro WindowProc modificado para Combobox3 (el que está
cerca del borde derecho): >
TTreeNode.Data Y / O TTreeView.OnCreateNodeClass
> var tn: TTreeNode; cnt: entero; comenzar TreeView1.Items.Clear; para cnt: =
0 a 9 do begin tn: = TreeView1.Items.AddChild ( nil , IntToStr (cnt)); fin ; fin ;
AddChild devuelve el TTreeNode recién agregado. En el ejemplo de
código anterior, los 10 nodos se agregan como nodos raíz (no tienen nodo
principal).
Supongamos que desea mostrar los datos del pedido de cliente de su base de
datos. Cada cliente puede tener más pedidos y cada orden se compone de más
artículos. Esta es una relación jerárquica que se puede mostrar en una vista de
árbol:
Cuando el usuario selecciona el nodo "Order_1_1", desea que los detalles del
pedido (suma total, fecha, etc.) se muestren al usuario.
Puede, en ese momento, obtener los datos requeridos de la base de datos, PERO
debe conocer el identificador único (digamos un valor entero) del orden
seleccionado para obtener los datos correctos.
Si no desea utilizar la propiedad Data del TTreeNode, sino que desea que su
TreeNode se amplíe con algunas propiedades, Delphi también tiene una solución.
Finalmente, si está listo para usar vistas de árbol en sus aplicaciones, eche un
vistazo a VirtualTreeView.
• FindFirst
• > función FindFirst ( const Path: string; Attr: Integer; var Rec: TSearchRec): Integer;
• EncontrarSiguiente
• > función FindNext ( var Rec: TSearchRec): entero;
• EncontrarCerrar
• > procedimiento FindClose ( var Rec: TSearchRec);
IS y AS
Conclusión
Como podemos ver, el parámetro del remitente puede ser muy útil cuando se usa
correctamente. Supongamos que tenemos un montón de cuadros de edición y
etiquetas que comparten el mismo controlador de eventos. Si queremos saber
quién desencadenó el evento y actuar, tendremos que tratar con las variables
Object. Pero, dejemos esto para alguna otra ocasión.
• Tipos Ordinales
• Las características definitorias de los tipos de datos ordinales son: deben
consistir en un número finito de elementos y deben ordenarse de alguna
manera.
• Los ejemplos más comunes de tipos de datos ordinales son todos los tipos
enteros, así como los tipos Char y Boolean. Más precisamente, Object
Pascal tiene doce tipos ordinales predefinidos: Integer, Shortint, Smallint,
Entero largo, Byte, Word, Cardinal, Boolean, ByteBool, WordBool, LongBool
y Char. También hay otras dos clases de tipos ordinales definidos por el
usuario: tipos enumerados y tipos de subrango.
• En cualquier tipo ordinal, debe tener sentido moverse hacia atrás o hacia
adelante al siguiente elemento. Por ejemplo, los tipos reales no son
ordinales porque moverse hacia atrás o hacia adelante no tiene sentido: la
pregunta "¿Cuál es el siguiente real después de 2.5?" no tiene sentido.
Función Efecto
Dec (X; n) Mueve n elementos hacia atrás (si se omite n mueve 1 elemento hacia atrás)
Inc (X; n) Mueve n elementos hacia adelante (si se omite n mueve 1 elemento hacia adelante)
Bajo (X) Devuelve el valor más bajo en el rango del tipo de datos ordinales X.
Alto (X) Devuelve el valor más alto en el rango del tipo de datos ordinales X.
•
Por ejemplo, High (Byte) devuelve 255 porque el valor más alto de tipo Byte
es 255 y Succ (2) devuelve 3 porque 3 es el sucesor de 2.
• Tipos de subrango
• En pocas palabras, un tipo de subrango representa un subconjunto de los
valores en otro tipo ordinal. En general, podemos definir cualquier subrango
comenzando con cualquier tipo ordinal (incluido un tipo enumerado
previamente definido) y usando un punto doble:
• René sugiere un enfoque más sencillo que solo necesite dos controladores
pares: OnCellClick y OnCustomDrawCell para su control DBGrid:
• Deje todos los nombres de los componentes tal como están cuando se
colocaron primero en el formulario (DBGrid1, ADOQuery1, AdoTable 1,
etc.). Utilice el Inspector de Objetos para establecer una propiedad
ConnectionString del componente ADOConnection1 (TDOConnection) para
que apunte a la base de datos de muestra QuickiesContest.mdb MS
Access.
• Conecte DBGrid1 a DataSource1, DataSource1 a ADOTable1, y finalmente
a ADOTable1 a ADOConnection1. La propiedad ADOTable1 TableName
debe señalar a la tabla Artículos (para hacer que DBGrid muestre los
registros de la tabla Artículos).
• Esto significa que necesita al menos dos imágenes para dibujar: una para el
estado comprobado (valor verdadero) y otra para el estado no verificado
(valor falso).
TMemoField
Para mostrar realmente algo de texto (del campo MEMO) en la celda DBGrid
apropiada, solo necesitará agregar una línea simple de código ...
Para el propósito de la próxima discusión, digamos que tiene una tabla de base de
datos llamada "TestTable" con al menos un campo MEMO llamado "Datos".
OnGetText
procedure TForm1.DBGrid1KeyDown (Sender: TObject; var Clave: Word; Shift: TShiftState); comience si Key =
VK_RETURN luego comience si DBGrid1.SelectedField = DBTableData y luego con TMemoEditorForm.Create
( nil ) intente DBMemoEditor.Text: = DBTableData.AsString; ShowModal; DBTable.Edit; DBTableData.AsString: =
DBMemoEditor.Text; finalmente gratis; fin ; fin ; fin ;
Simbólico Valor
Teclado (o mouse) equivalente
nombre constante (hexadecimal)
30 0 tecla
31 1 llave
32 2 llaves
33 3 llaves
34 4 teclas
35 5 teclas
36 6 teclas
37 7 teclas
38 8 teclas
39 Tecla 9
41 Una llave
42 Tecla B
43 Tecla C
44 Tecla D
45 Tecla E
46 Tecla F
47 Tecla G
48 Tecla H
49 Yo clave
4A J clave
4B Tecla K
4C L tecla
4D M clave
4E Tecla N
4F O clave
50 Tecla P
51 Tecla Q
52 Tecla R
53 Tecla S
54 Tecla T
55 Tecla U
56 Tecla V
57 Tecla W
58 Tecla X
59 Tecla Y
5A Tecla Z
VK_F1 70 Tecla F1
VK_F2 71 Tecla F2
VK_F3 72 Tecla F3
VK_F4 73 Tecla F4
VK_F5 74 Tecla F5
VK_F6 75 Tecla F6
VK_F7 76 Tecla F7
VK_F8 77 Tecla F8
VK_F9 78 Tecla F9
Cada nodo en TTreeView consiste en una etiqueta y una imagen de mapa de bits
opcional, y el objeto TTreeNode describe un nodo individual en un control
TTreeView.
TreeView virtual
Virtual TreeView, que inicialmente estaba siendo desarrollado por Mike Lischke y
ahora se mantiene como un proyecto de código abierto en Google Code, es un
control de uso obligatorio si está dispuesto a trabajar con lo que pueda llamar
"nodos".
No importa la versión de Delphi que esté utilizando, desde Delphi 7 hasta la última
versión (XE3 en este momento), podrá usar y aprovechar la potencia
de TVirtualStringTree y TVirtualDrawTree (los nombres reales de los controles)
en sus aplicaciones.
Estas son solo algunas de las características de "por qué usar" del control
TreeView virtual:
02 de 03
Virtual TreeView - Cómo instalar
Descargue un archivo ZIP que contiene el código fuente, paquetes para instalar el
componente en Delphi, algunas demostraciones y más.
Correr.
Vea qué tan rápido es agregar cientos (incluso miles) de nodos como nodos
secundarios a uno seleccionado. Finalmente, aquí está el código fuente
(implementación importante) de este ejemplo de "mundo hello": >
• Antes de crear realmente una función tan clara para su próxima aplicación
Delphi, debe saber cómo obtener la imagen del formulario ("captura de
pantalla de formulario") y cómo cambiar el tamaño proporcionalmente a la
imagen en miniatura deseada.
• > const maxWidth = 200; maxHeight = 150; var thumbnail: TBitmap; thumbRect:
TRect; comenzar miniatura: = Form1.GetFormImage; prueba thumbRect.Left: =
0; thumbRect.Top: = 0; // cambio de tamaño proporcional si thumbnail.Width>
thumbnail.Height luego comienza con thumbRect.Right: =
maxWidth; thumbRect.Bottom: = (maxWidth *
thumbnail.Height) div thumbnail.Width; end else begin thumbRect.Bottom: =
maxHeight; thumbRect.Right: = (maxHeight *
thumbnail.Width) div thumbnail.Height; fin ; thumbnail.Canvas.StretchDraw
(thumbRect, miniatura); // cambiar el tamaño de la miniatura de la imagen . Ancho:
= thumbRect.Right; thumbnail.Height: = thumbRect.Bottom; // mostrar en un control
de TImage Image1.Picture.Assign (thumbnail); finalmente miniatura. Libre; fin ; fin ;
ListView.OnItemClick / OnItemDblClick
El control TListView de Delphi muestra una lista de elementos en columnas con
encabezados de columnas y subtemas, o vertical u horizontalmente, con iconos
pequeños o grandes.
El evento OnClick (OnDblClick) para TListView se activa cada vez que el usuario
hace clic en el control, es decir, cada vez que el "clic" ocurre en algún lugar dentro
del área del cliente del control .
El usuario puede hacer clic dentro de la vista de lista, PERO "perder" alguno de
los elementos. Además, dado que la vista de lista puede cambiar su visualización
dependiendo de la propiedad ViewStyle, el usuario podría haber hecho clic en un
elemento, en un título de elemento, en un icono de elemento, "en ninguna parte",
en un icono de estado de elemento, etc.
Para asegurarse de que se hizo clic en el elemento (o se hizo doble clic), debe
llamar al GetHitTestInfoAt y reaccionar solo si el evento click se produjo en un
elemento real.
Hay varios tipos de pantallas de presentación. Las más comunes son las pantallas
de inicio, las que ves cuando una aplicación se está cargando. Por lo general,
muestran el nombre, autor, versión, derechos de autor e imagen de la aplicación, o
algún tipo de ícono, que lo identifica de manera única.
Veamos cómo crear una pantalla de bienvenida de inicio simple en unos pocos
pasos:
Para obtener más información sobre cómo hacer que la pantalla de bienvenida
permanezca un poco más, lea el código en este subproceso de desbordamiento
de pila.
Formar
Los objetos de formulario son los componentes básicos de una aplicación Delphi,
las ventanas reales con las que un usuario interactúa cuando ejecuta la aplicación.
Los formularios tienen sus propias propiedades, eventos y métodos con los que
puede controlar su apariencia y comportamiento.
Nacimiento
OnCreate
El evento OnCreate se activa cuando se crea un TForm por primera vez, es decir,
solo una vez. La declaración responsable de crear el formulario está en el origen
del proyecto (si el proyecto lo configura automáticamente). Cuando se está
creando un formulario y su propiedad Visible es Verdadero, los siguientes eventos
ocurren en el orden indicado: OnCreate, OnShow, OnActivate, OnPaint.
Debe usar el controlador de eventos OnCreate para hacer, por ejemplo, tareas de
inicialización como la asignación de listas de cadenas.
Cualquier objeto creado en el evento OnCreate debe ser liberado por el evento
OnDestroy.
> OnCreate -> OnShow -> OnActivate -> OnPaint -> OnResize -> OnPaint ...
En el programa
Este evento indica que se está mostrando el formulario. Se llama a OnShow justo
antes de que un formulario sea visible. Además de las formas principales, este
evento ocurre cuando establecemos la propiedad Visible de los formularios en
True, o llamamos al método Show o ShowModal.
Activado
Se llama a este evento cuando el programa activa el formulario, es decir, cuando
el formulario recibe el foco de entrada. Use este evento para cambiar qué control
realmente obtiene el foco si no es el deseado.
OnPaint, OnResize
Eventos como OnPaint y OnResize siempre se llaman después de que se crea el
formulario inicialmente, pero también se llaman repetidamente. OnPaint ocurre
antes de que se pinten los controles del formulario (úselo para una pintura
especial en el formulario).
Vida
Como hemos visto, el nacimiento de una forma no es tan interesante como
pueden ser la vida y la muerte. Cuando se crea su formulario y todos los controles
están esperando que los eventos lo manejen, ¡el programa se ejecuta hasta que
alguien intente cerrar el formulario!
Muerte
Una aplicación controlada por eventos deja de ejecutarse cuando todas sus
formas están cerradas y no se está ejecutando ningún código. Si aún existe un
formulario oculto cuando se cierra el último formulario visible, parecerá que su
aplicación ha finalizado (porque no hay formularios visibles), pero de hecho
continuará ejecutándose hasta que se cierren todos los formularios ocultos. Solo
piense en una situación donde la forma principal se oculta temprano y todas las
otras formas están cerradas.
> ... OnCloseQuery -> OnClose -> OnDeactivate -> OnHide -> OnDestroy
OnCloseQuery
Cuando tratamos de cerrar el formulario usando el método Close o por otros
medios (Alt + F4), se llama al evento OnCloseQuery.
Por lo tanto, el controlador de eventos para este evento es el lugar para interceptar
el cierre de un formulario y evitarlo. Usamos OnCloseQuery para preguntar a los
usuarios si están seguros de que realmente desean que el formulario se cierre.
El evento OnClose nos da una última oportunidad para evitar que se cierre el
formulario.
• Lo único que queda por hacer es especificar el color de fondo de las celdas
para cualquier columna en particular. Para el color de primer plano de texto,
vea la propiedad de la fuente.
• ¡Faltando a OnCreate!
• Una vez que comience a usar marcos, notará que no hay ningún
evento OnCreate que pueda usar para inicializar sus marcos.
• Aquí está el código fuente de un marco simple que expone una propiedad
pública y anula el constructor Crear:
01 de 03
Algunos más recientes (para ser correctos: a partir de Delphi 2007 ) Las versiones
de Delphi tienen dos (tres) configuraciones predeterminadas de compilación:
DEPURACIÓN y LIBERACIÓN.
El artículo de Compilación condicional 101 menciona configuraciones de
compilación, pero no explica la diferencia en los detalles.
Configuraciones de compilación
Construir es una extensión para compilar donde se compilan todas las unidades
(incluso aquellas que no están alteradas). Cuando cambias las opciones del
proyecto, ¡debes construir!
02 de 03
Opciones de depuración
03 de 03
Opciones de lanzamiento
Para Release (la versión que usarán los usuarios de su aplicación, no para la
depuración), las opciones específicas son:
Portapapeles en General
Como probablemente sepa, el Portapapeles solo puede contener una pieza de
datos para cortar, copiar y pegar al mismo tiempo. En general, puede contener
solo una parte del mismo tipo de datos a la vez.
TClipboard
Para utilizar el Portapapeles de Windows en nuestras aplicaciones, debemos
agregar la unidad ClipBrd a la cláusula uses del proyecto, excepto cuando
restringimos cortar, copiar y pegar a los componentes que tienen soporte
incorporado para los métodos del Portapapeles. Esos componentes son TEdit,
TMemo, TOLEContainer, TDDEServerItem, TDBEdit, TDBImage y TDBMemo.
La unidad ClipBrd crea automáticamente una instancia de un objeto TClipboard
llamado Portapapeles. Utilizaremos los métodos
CutToClipboard , CopyToClipboard , PasteFromClipboard , Clear y HasFormat par
a manejar las operaciones del portapapeles y la manipulación de texto / gráficos.
▪ CF_TEXT - Texto con cada línea que termina con una combinación CR-LF .
▪ CF_BITMAP : un gráfico de mapa de bits de Windows.
▪ CF_METAFILEPICT : un metarchivo de Windows gráfico.
▪ CF_PICTURE - Un objeto de tipo TPicture.
▪ CF_OBJECT - Cualquier objeto persistente.
El método HasFormat devuelve True si la imagen en el Portapapeles tiene el
formato correcto:
> si Clipboard.HasFormat (CF_METAFILEPICT) a continuación, ShowMessage ('Portapapeles
tiene metarchivo');
Para enviar (asignar) una imagen al Portapapeles, usamos el método Asignar. Por
ejemplo, el siguiente código copia el mapa de bits de un objeto de mapa de bits
llamado MyBitmap en el Portapapeles:
Para recuperar una imagen del Portapapeles debemos: verificar el formato de los
contenidos actuales del portapapeles y usar el método Asignar del objeto de
destino:
> {coloque un botón y un control de imagen en form1} {Antes de ejecutar este código,
presione Alt-PrintScreen key
combination} usa clipbrd; ... procedimiento TForm1.Button1Click (Sender:
TObject); comenzar si Clipboard.HasFormat
(CF_BITMAP) luego Image1.Picture.Bitmap.Assign (Portapapeles); fin;
• ParamCount y ParamStr ()
• La función ParamCount devuelve el número de parámetros pasados al
programa en la línea de comando, y ParamStr devuelve un parámetro
especificado de la línea de comando.
• Solicitud de muestra
• Dado que es bastante común que las aplicaciones Delphi compartan código
o formularios previamente personalizados, Delphi organiza las aplicaciones
en estos archivos de proyecto.
• DPROJ es otro formato de archivo para los archivos del Proyecto Delphi,
pero almacena la configuración del proyecto en formato XML.
• Aunque puede leer y editar el archivo del proyecto como lo haría con
cualquier código fuente, en la mayoría de los casos, permitirá que Delphi
mantenga el archivo DPR. La razón principal para ver el archivo del
proyecto es ver las unidades y formularios que componen el proyecto, así
como para ver qué formulario se especifica como el formulario "principal" de
la aplicación.
• Otra razón para trabajar con el archivo de proyecto es cuando está creando
un archivo DLL en lugar de una aplicación independiente. O bien, si
necesita algún código de inicio, como una pantalla de bienvenida antes de
que Delphi cree el formulario principal.
• Esta palabra clave identifica a esta unidad como la unidad fuente principal
del programa. Puede ver que el nombre de la unidad, "Proyecto1", sigue la
palabra clave del programa. Delphi le da al proyecto un nombre
predeterminado hasta que lo guarde como algo diferente.
• ¿Variable o constante?
• Las constantes tipadas se pueden comparar con variables inicializadas: variables
cuyos valores se definen al ingresar a su bloque (generalmente controlador de
eventos). Dicha variable se inicializa solo cuando el programa comienza a
ejecutarse. Después de eso, el valor de una constante tipeada persiste entre
llamadas sucesivas a sus procedimientos.
• > {$ J +} clics const : Entero = 1; {$ J-} Por lo tanto, el primer código de ejemplo se
ve así: > procedure TForm1.Button1Click (Sender: TObject); const {$ J +} clics: Entero
= 1; // no es una constante verdadera {$ J-} begin Form1.Caption: = IntToStr
(clicks); clics: = clics + 1; fin ;
• Conclusión
• Depende de usted decidir si desea que las constantes mecanografiadas sean
asignables o no. Lo importante aquí es que además de ser ideal para contadores,
las constantes tipadas son ideales para hacer que los componentes sean
alternativamente visibles o invisibles, o podemos usarlos para alternar entre
cualquier propiedad booleana. Las constantes tipadas también se pueden usar
dentro del controlador de eventos de TTimer para realizar un seguimiento de
cuántas veces se ha disparado.
Si desea más material para principiantes, consulte el resto de los temas de
programación de Delphi For Beginners.
Puede haber instancias en las que no conozca el tipo de clase exacto de un objeto
de formulario . Solo puede tener la variable de cadena que lleva el nombre de la
clase del formulario, como "TMyForm".
Un ejercicio de muestra
El tipo de conjunto de Delphi es una colección de valores del mismo tipo ordinal .
Los valores posibles del tipo de conjunto son todos los subconjuntos del tipo base,
incluido el conjunto vacío.
Una limitación de los conjuntos es que pueden contener hasta 255 elementos.
Para asignar un valor a una variable de tipo de conjunto, utilice los corchetes y
enumere todos los elementos del conjunto. Como en:
La palabra clave IN
Para probar si un elemento está incluido en el conjunto (variable) use la palabra
clave IN :
Para evitar que los usuarios escriban teclas alfabéticas, agregue esta línea
en OnKeyPress de un control de edición:
> escriba TWorkDay = (lunes, martes, miércoles, jueves, viernes); TDaySet = conjunto
de TWorkDay; var días: TDaySet; comenzar días: = [lunes, viernes]; días: = días + [martes,
jueves] - [viernes]; si miércoles EN días, luego ShowMessage ('Me encanta el miércoles!');
¡La propiedad Style de Font es una propiedad de tipo set! Así es como se define:
Por lo tanto, un tipo enumerado TFontStyle se utiliza como el tipo base para el tipo
de conjunto TFontStyles. La propiedad Style de la clase TFont es de tipo
TFontStyles, por lo tanto, una propiedad de tipo set.
Si muestra un mensaje para el usuario que contiene los botones Sí, Aceptar y
Cancelar y desea ejecutar algún código si se hizo clic en los botones Sí o Aceptar,
puede usar el siguiente código:
Palabra final: los conjuntos son geniales. Los conjuntos pueden parecer confusos
para un principiante de Delphi, pero tan pronto como empiece a usar variables de
tipo de conjunto descubrirá que proporcionan mucho más de lo que sonaba al
principio. Al menos tengo :))
Historia de Delphi - de Pascal a
Embarcadero Delphi XE 2
• by Zarko Gajic
• Historia de Delphi: las raíces
• Que es Delphi?
Delphi es un lenguaje de alto nivel, compilado y fuertemente tipado que
admite el diseño estructurado y orientado a objetos . El lenguaje Delphi se
basa en Object Pascal. Hoy, Delphi es mucho más que simplemente el
"lenguaje Object Pascal".
• Ahora que sabemos qué es Delphi y dónde están sus raíces, es hora de
hacer un viaje al pasado ...
• Delphi 1 (1995)
Delphi, la poderosa herramienta de desarrollo de programación de Windows
de Borland apareció por primera vez en 1995. Delphi 1 extendió el lenguaje
de Borland Pascal al proporcionar un enfoque orientado a objetos y
formularios, compilador de código nativo extremadamente rápido,
herramientas visuales de dos vías y excelente soporte de base de datos,
integración cercana con Windows y la tecnología de componentes.
• Lema de Delphi 1 * :
Delphi y Delphi Client / Server son las únicas herramientas de desarrollo
que ofrecen los beneficios del desarrollo de aplicaciones rápidas (RAD) del
diseño basado en componentes visuales, el poder de un compilador de
código nativo optimizado y una solución cliente / servidor escalable.
• Estas son las "7 principales razones para comprar Borland Delphi 1.0 Client
/ Server * "
• Delphi 2 (1996)
Delphi 2 * es la única herramienta de desarrollo rápido de aplicaciones que
combina el rendimiento del compilador de código nativo de 32 bits más
rápido del mundo, la productividad del diseño basado en componentes
visuales y la flexibilidad de la arquitectura de base de datos escalable en un
entorno robusto orientado a objetos .
• Delphi 3 (1997)
El conjunto más completo de herramientas de desarrollo visual, de alto
rendimiento para clientes y servidores para crear aplicaciones
empresariales y web distribuidas.
• Delphi 5 (1999)
Desarrollo de alta productividad para Internet
• Delphi 6 (2000)
Borland Delphi es el primer entorno de desarrollo rápido de aplicaciones
para Windows que es totalmente compatible con los servicios web nuevos y
emergentes. Con Delphi, los desarrolladores corporativos o individuales
pueden crear aplicaciones de e-business de próxima generación rápida y
fácilmente.
•
Además, Delphi 6 agregó el soporte para el desarrollo multiplataforma, lo
que permite compilar el mismo código con Delphi (en Windows) y Kylix
(bajo Linux). Más mejoras incluidas: soporte para servicios web, el motor
DBExpress , nuevos componentes y clases ...
• Delphi 7 (2001)
Borland Delphi 7 Studio proporciona la ruta de migración a Microsoft .NET
que los desarrolladores han estado esperando. Con Delphi, las opciones
son siempre tuyas: tienes el control de un estudio de desarrollo de e-
business completo, con la libertad de llevar fácilmente tus soluciones
multiplataforma a Linux.
• Delphi 8
Para el octavo aniversario de Delphi, Borland preparó el lanzamiento más
importante de Delphi: Delphi 8 continúa proporcionando Visual Component
Library (VCL) y Component Library para desarrollo multiplataforma
(CLX) para Win32 (y Linux), así como nuevas características y continúa
mejoras en el marco, compilador, IDE y tiempo de diseño.
• Embarcadero Delphi XE
Embarcadero Delphi XE lanzado en 2010. Delphi 2011, trae muchas
características y mejoras nuevas: gestión integrada de código fuente,
desarrollo de nube incorporado (Windows Azure, Amazon EC2), innovador
cofre de herramientas expandido para desarrollo optimizado, DataSnap
desarrollo de múltiples niveles , mucho más...
• Embarcadero Delphi XE 2
Embarcadero Delphi XE 2 lanzado en 2011. Delphi XE2 le permitirá: crear
aplicaciones Delphi de 64 bits, usar el mismo código fuente para apuntar a
Windows y OS X, crear aplicaciones FireMonkey (HD y 3D de negocios),
ampliar múltiples aplicaciones DataSnap de nivel con nueva conectividad
móvil y en la nube en RAD Cloud, use estilos VCL para modernizar el
aspecto de sus aplicaciones ...
• Buscando un ClientDataSet
ClientDataSets proporciona varios mecanismos diferentes para buscar
datos en sus columnas.
• Filtrado de ClientDataSets
Cuando se aplica a un conjunto de datos, un filtro limita los registros a los
que se puede acceder. Este artículo explora las entradas y salidas del
filtrado de ClientDataSets.
• Los basicos
• Puede hacer que la tecla Intro funcione como la tecla Tab en un DBGrid,
que también permite que Shift + Enter funcione como lo haría si se
usara Tab + Enter .
• Siga este tutorial para ver cómo mostrar los contenidos de un campo
MEMO (BLOB textual) en un TDBGrid, además de cómo habilitar la edición
de los MEMO.
• Una de las maneras más naturales y fáciles de dejar que los usuarios
clasifiquen una columna es hacer que hagan clic en el título de la columna.
Siga nuestra guía sobre cómo ordenar registros en Delphi DBGrid para
obtener toda la información que necesita para que esto suceda.
• También encontrará una lista de los errores más comunes que pueden
aparecer durante el proceso, además de cómo tratarlos.
• Guías avanzadas
• ¿Necesitas resaltar la fila detrás del cursor del mouse en un DBGrid? Te
tenemos cubierto . Hace que la lectura de los datos sea mucho más fácil
cuando se ilumina toda la fila. Averigüe cómo seleccionar (hacer activo) y
resaltar (cambiar el color, fuente, etc.) una fila en un DBGrid a medida que
el mouse se mueve alrededor de la grilla.
• VCLSkin
• VCLSkin es un componente fácil de usar para crear una GUI para una
aplicación Delphi. VCLSkin tematizará o despellejará toda la aplicación sin
ninguna modificación del código fuente. Más "
• DynamicSkinForm
• La biblioteca DynamicSkinForm VCL brinda soporte para formularios,
menús, sugerencias y muchos controles originales estándar y no estándar.
Las máscaras tienen muchos objetos y efectos para aplicaciones geniales
estándar y no estándar como WinAmp e iTunes. Un editor especial permite
al usuario crear máscaras personalizadas. SkinAdapter es un componente
de DynamicSkinForm que permite desvelar las aplicaciones sin modificar el
código fuente. Más "
• SUISkin
• SUISkin ofrece una aplicación automática compatible con la piel. Con
SUISkin, no se requieren modificaciones para los proyectos existentes.
Simplemente suelte el componente del motor de la piel en el formulario
principal y establezca algunas propiedades. Piel todas las formas y cuadros
de diálogo automáticamente. Los archivos de máscara se pueden compilar
en el archivo EXE. En tiempo de ejecución, puede cambiar o desactivar las
máscaras fácilmente. Más »
• AppFace
• El Kit de desarrollo de la interfaz de usuario de AppFace es una solución de
desarrollo de interfaz gráfica de usuario de aplicación visual que se puede
usar en VC, C #, VB.Net, Delphi, Visual Basic, C ++ Builder y Win32 SDK.
Incluye control de skinning, creador visual de skin, código fuente de
muestra en VC, C #, VB.Net, Delphi, Visual Basic, C ++ Builder y Win32
SDK, así como un manual técnico. La biblioteca de skinning, appface.dll, es
el componente kernel; puede cubrir todas las ventanas creadas
automáticamente en la aplicación de destino. Más "
• SkinFeature
• skinfeature usa efectos especiales creativos para un desarrollo de GUI
totalmente interactivo. skinfeature es compatible con una amplia gama de
lenguajes de desarrollo, herramientas y frameworks, incluyendo Visual
Basic, Visual C ++, Delphi, Borland C ++ Builder, Microsoft DotNet y Win32
SDK. Más "
• Un diccionario es, en cierto modo, similar a una matriz. En una matriz, usted
trabaja con una serie (colección) de valores indexados por un valor entero,
que puede ser cualquier valor de tipo ordinal .
• En Delphi, el TDictionary se define como una tabla hash. Las tablas hash
representan una colección de pares clave-valor que se organizan en
función del código hash de la clave. Las tablas Hash están optimizadas
para búsquedas (velocidad). Cuando se agrega un par clave-valor a una
tabla hash, el hash de la clave se calcula y se almacena junto con el par
agregado.
• El TKey y TValue, porque son genéricos, pueden ser de cualquier tipo. Por
ejemplo, si la información que debe almacenar en el diccionario proviene de
alguna base de datos, su clave puede ser un valor GUID (u otro valor que
presente el índice exclusivo), mientras que el valor puede ser un objeto
asignado a una fila de datos en sus tablas de base de datos.
• Usando TDictionary
• En aras de la simplicidad, el siguiente ejemplo utiliza enteros para TKeys y
caracteres para TValues.
• Para eliminar un par del diccionario, use el método Eliminar. Este método
no causará problemas si un par con una clave especificada no es parte del
diccionario.
• Para recorrer todos los pares haciendo un bucle a través de las teclas,
puede hacer un bucle for in .
• Ordenar el diccionario
• Como un diccionario es una tabla hash, no almacena elementos en un
orden de clasificación definido. Para iterar a través de las claves que se
ordenan para satisfacer sus necesidades específicas, aproveche el TList,
un tipo de colección genérica que admite la ordenación.
• Puede tener diccionarios complejos donde tanto la clave como el valor sean
tipos "complejos" como registros u objetos.
• El valor de clave no puede ser nulo, mientras que el valor de valor puede.
• Sobrecarga
• En pocas palabras, la sobrecarga es declarar más de una rutina con el
mismo nombre.
• Nota: Solo hay una regla al escribir rutinas sobrecargadas, y es que una
rutina sobrecargada debe diferir en al menos un tipo de parámetro. El tipo
de devolución, en cambio, no se puede usar para distinguir entre dos
rutinas.
El enfoque que debe descubrir en este artículo es mucho más flexible: puede tener
casillas de verificación y botones de radio mezclados con otros nodos de la forma
que desee sin cambiar el TTreeview o crear una nueva clase a partir de él para
que esto funcione. Además, usted mismo decide qué imágenes usar para las
casillas de verificación / botones de radio simplemente agregando las imágenes
adecuadas a la lista de imágenes de StateImages.
Aquí se explica cómo hacer que el código sea aún más profesional: en el evento
OnClick de TreeView, escriba el siguiente código para alternar las casillas de
verificación solo si se hizo clic en el estado (las constantes cFlatUnCheck,
cFlatChecked, etc. se definen en otros lugares como índices en la lista de
imágenes de StateImages) :
Puede pasar "solicitud", pero el retraso causado por el método de notificación que
se envía a cada componente y forma propiedad de la Aplicación o indirectamente
puede ser perjudicial. Si su aplicación consta de muchos formularios con muchos
componentes (en miles) y el formulario que está creando tiene muchos controles
(en cientos), el retraso en la notificación puede ser significativo.
¡La línea de código más libre de errores es la que no tiene que escribir!
Errores, Excepciones?
Bloques guardados
Ejemplo:
> ... Cero: = 0; try dummy: = 10 / Zero; excepto en EZeroDivide do MessageDlg ('No
se puede dividir por cero!', mtError, [mbOK], 0); fin; ...
Protección de recursos
> {algún código para asignar recursos} intente {bloque de código guardado}
finalmente {bloque de terminación - código para liberar recursos} final;
Ejemplo:
> ... AboutBox: = TAboutBox.Create (nil); prueba AboutBox.ShowModal; finalmente
AboutBox.Release; fin; ...
Application.OnException
Break On Exceptions
La idea de este artículo es darle una rápida mirada a las excepciones. Para una
discusión más detallada sobre el manejo de excepciones, considere el Manejo de
excepciones en el manejo de excepciones de Delphi , usando una herramienta
como Delphi Crash / Exception Handling con Bug Reporting y algunos de los
siguientes artículos relacionados:
• Los glifos e íconos (y los gráficos en general) hacen que los elementos de
la interfaz de usuario de la aplicación se vean profesionales y únicos.
Formar
Los objetos de formulario son los componentes básicos de una aplicación Delphi,
las ventanas reales con las que un usuario interactúa cuando ejecuta la aplicación.
Los formularios tienen sus propias propiedades, eventos y métodos con los que
puede controlar su apariencia y comportamiento.
Debe usar el controlador de eventos OnCreate para hacer, por ejemplo, tareas de
inicialización como la asignación de listas de cadenas.
Cualquier objeto creado en el evento OnCreate debe ser liberado por el evento
OnDestroy.
> OnCreate -> OnShow -> OnActivate -> OnPaint -> OnResize -> OnPaint ...
En el programa
Este evento indica que se está mostrando el formulario. Se llama a OnShow justo
antes de que un formulario sea visible. Además de las formas principales, este
evento ocurre cuando establecemos la propiedad Visible de los formularios en
True, o llamamos al método Show o ShowModal.
Activado
Se llama a este evento cuando el programa activa el formulario, es decir, cuando
el formulario recibe el foco de entrada. Use este evento para cambiar qué control
realmente obtiene el foco si no es el deseado.
OnPaint, OnResize
Eventos como OnPaint y OnResize siempre se llaman después de que se crea el
formulario inicialmente, pero también se llaman repetidamente. OnPaint ocurre
antes de que se pinten los controles del formulario (úselo para una pintura
especial en el formulario).
Vida
Como hemos visto, el nacimiento de una forma no es tan interesante como
pueden ser la vida y la muerte. Cuando se crea su formulario y todos los controles
están esperando que los eventos lo manejen, ¡el programa se ejecuta hasta que
alguien intente cerrar el formulario!
Muerte
Una aplicación controlada por eventos deja de ejecutarse cuando todas sus
formas están cerradas y no se está ejecutando ningún código. Si aún existe un
formulario oculto cuando se cierra el último formulario visible, parecerá que su
aplicación ha finalizado (porque no hay formularios visibles), pero de hecho
continuará ejecutándose hasta que se cierren todos los formularios ocultos. Solo
piense en una situación donde la forma principal se oculta temprano y todas las
otras formas están cerradas.
> ... OnCloseQuery -> OnClose -> OnDeactivate -> OnHide -> OnDestroy
OnCloseQuery
Cuando tratamos de cerrar el formulario usando el método Close o por otros
medios (Alt + F4), se llama al evento OnCloseQuery.
Por lo tanto, el controlador de eventos para este evento es el lugar para interceptar
el cierre de un formulario y evitarlo. Usamos OnCloseQuery para preguntar a los
usuarios si están seguros de que realmente desean que el formulario se cierre.
OnClose
Si OnCloseQuery indica que el formulario debe cerrarse, se llama al evento
OnClose.
El evento OnClose nos da una última oportunidad para evitar que se cierre el
formulario.
Por ejemplo, considere el caso de una aplicación de Windows que no tiene una
barra de título, ¿cómo podemos mover dicha ventana? De hecho, es posible crear
ventanas con una barra de título no estándar e incluso formas no rectangulares.
En este caso, ¿cómo podría Windows saber dónde están los bordes y las
esquinas de la ventana?
Del mismo modo, Windows envía un mensaje wm_NCHitTest cada vez que
se produce un evento de mouse , es decir, cuando se mueve el cursor, o cuando
se presiona o se suelta un botón del mouse.
Si podemos hacer que Windows piense que el usuario está arrastrando (ha hecho
clic) en la barra de título en lugar de en el área del cliente, entonces el usuario
puede arrastrar la ventana haciendo clic en el área del cliente. La forma más fácil
de hacerlo es "engañar" a Windows para que piense que realmente está haciendo
clic en la barra de título de un formulario.
El siguiente fragmento de código evitará que los usuarios cierren sus formularios
haciendo clic en el botón Cerrar.
Esto evita que el usuario mueva la ventana con el mouse (al contrario de lo que
estábamos haciendo al principio del artículo).
Nota: este código no funcionará con controles que no sean de ventana, como
los componentes de TLabel .
• Con Delphi, puede escribir y usar sus propias DLL e incluso llamar
funciones independientemente de si fueron desarrolladas o no con otros
sistemas o desarrolladores, como Visual Basic o C / C ++.
• Crear una biblioteca de enlace dinámico
• Las siguientes líneas demostrarán cómo crear una DLL simple usando
Delphi.
• Para comenzar, inicie Delphi y vaya a Archivo> Nuevo> DLL para compilar
una nueva plantilla DLL. Seleccione el texto predeterminado y reemplácelo
con esto:
• Al final del código fuente hay una declaración de exportación que enumera
las rutinas que en realidad se exportan de la DLL de forma que otra
aplicación pueda llamarlas.
• Lo que esto significa es que puede tener, por ejemplo, cinco procedimientos
en un archivo DLL y solo dos de ellos (enumerados en la sección
de exportaciones ) se pueden llamar desde un programa externo (los tres
restantes son "procedimientos secundarios").
• > DllMessage;
• Hemos aprendido cómo manejar algunos eventos básicos del mouse como
MouseUp / MouseDown y MouseMove. Sin embargo, hay momentos en los
que desea que su mouse haga lo que le dice.
• > procedimiento SetMousePos (x, y: longint); var pt: TPoint; begin pt: =
ClientToScreen (point (x, y)); SetCursorPos (pt.x, pt.y); fin ;
• Simulaciones
• En la mayoría de las ocasiones, queremos que el mouse se mueva a una
posición determinada en la pantalla. Sabemos que algunos componentes
no responden a un cambio de cursor hasta que el usuario mueva el mouse,
tenemos que proporcionar una pequeña técnica para mover desde el
código.
• ¿Y qué ocurre con los clics del mouse de simulación sin llamar al
controlador de eventos OnClick?
• > procedure TForm1.FormCreate (Sender: TObject); var r: TRect; begin // sería una
buena idea mover el // mouse dentro del formulario antes de la restricción r: =
BoundsRect; ClipCursor (@R); fin ; procedure TForm1.FormClick (Sender:
TObject); begin // siempre asegúrese de liberar el cursor ClipCursor (nil); fin ;
Desde mapas de bits hasta iconos, pasando por cursores hasta tablas de
cadenas, cada programa de Windows usa recursos. Los recursos son aquellos
elementos de un programa que admiten el programa pero que no son código
ejecutable. En este artículo, veremos algunos ejemplos del uso de bitmaps, iconos
y cursores de los recursos.
▪ Se puede acceder a los recursos más rápidamente porque lleva menos tiempo
localizar un recurso en el archivo ejecutable que cargarlo desde un archivo de
disco.
El editor de imágenes
Primero que nada, necesitamos crear un archivo de recursos. La extensión
predeterminada para los archivos de recursos es .RES . Los archivos de recursos
se pueden crear con Delphi's Image Editor .
Puede asignarle al archivo de recursos todo lo que desee, siempre que tenga la
extensión ".RES" y el nombre del archivo sin la extensión no sea el mismo que el
de cualquier unidad o proyecto. Esto es importante porque, de forma
predeterminada, cada proyecto Delphi que se compila en una aplicación tiene un
archivo de recursos con el mismo nombre que el archivo del proyecto, pero con la
extensión ".RES". Lo mejor es guardar el archivo en el mismo directorio que su
archivo de proyecto.
Para acceder a nuestro propio archivo de recursos, debemos decirle a Delphi que
vincule nuestro archivo de recursos con nuestra aplicación. Esto se logra
agregando una directiva de compilación al código fuente.
{$ R * .DFM} {$ R DPABOUT.RES}
No borre accidentalmente la parte {$ R * .DFM}, ya que esta es la línea de código
que le dice a Delphi que se vincule en la parte visual del formulario. Cuando elige
bitmaps para botones de velocidad, componentes de imagen o componentes de
botón, Delphi incluye el archivo de mapa de bits que eligió como parte del recurso
del formulario.
Fotos en Recursos
Otra forma que podemos usar para mostrar un mapa de bits desde un recurso es
la siguiente:
Cursores en recursos
Iconos en Recursos
Si queremos, por ejemplo, animar el ícono del programa cuando el programa está
minimizado, entonces el siguiente código hará el trabajo.
Ultimas palabras
•
El showTimer se utiliza para garantizar que la HintPause (de la Aplicación)
transcurra antes de que se muestre la pista. El hideTimer usa
Application.HintHidePause para ocultar la ventana de sugerencia después
de un intervalo especificado.
interfaz
usos
Windows, Mensajes, SysUtils, Variantes, Clases, Gráficos,
Controles, Formularios, Diálogos, Menús, AppEvnts,
StdCtrls, ExtCtrls, ComCtrls;
tipo
TMenuItemHint = clase (THintWindow)
privado
activeMenuItem: TMenuItem;
showTimer: TTimer;
hideTimer: TTimer;
procedimiento HideTime (Sender: TObject);
procedimiento ShowTime (Sender: TObject);
público
constructor Create (AOwner: TComponent); anular ;
procedimiento DoActivateHint (menuItem: TMenuItem);
destructor Destroy; anular ;
fin ;
var
Form1: TForm1;
implementación
{$ R * .dfm}
menuItem: = nil ;
if (Msg.MenuFlag <> $ FFFF) o (Msg.IDItem <> 0) luego
empezar
si Msg.MenuFlag y MF_POPUP = MF_POPUP, entonces
empezar
hSubMenu: = GetSubMenu (Msg.Menu, Msg.IDItem);
menuItem: = Self.Menu.FindItem (hSubMenu, fkHandle);
fin
más
empezar
menuItem: = Self.Menu.FindItem (Msg.IDItem, fkCommand);
fin ;
fin ;
{TMenuItemHint}
constructor TMenuItemHint.Create (AOwner: TComponent);
empezar
heredado ;
destructor TMenuItemHint.Destroy;
empezar
hideTimer.OnTimer: = nil ;
showTimer.OnTimer: = nil ;
self.ReleaseHandle;
heredado ;
fin ; (*Destruir*)
showTimer.OnTimer: = ShowTime;
hideTimer.OnTimer: = HideTime;
fin ; (* DoActivateHint *)
showTimer.OnTimer: = nil ;
fin ; (*Tiempo de la funcion*)
fin
dgMultiSelect Ejemplo
Una buena situación para usar dgMultiSelect podría ser cuando necesite una
opción para seleccionar registros aleatorios o si necesita la suma de los valores de
los campos seleccionados.
El código usa selección múltiple para obtener la suma de los valores en el campo
"Tamaño". Utilice este código de ejemplo si desea seleccionar todo el DBGrid :
• Bloques guardados
• Una aplicación responde a una excepción ejecutando un código de
terminación, manejando la excepción o ambas. La forma de habilitar la
captura de error / excepción dentro de un código dado, la excepción debe
ocurrir dentro de un bloque de instrucciones oculto. El código general se ve
así:
• Ejemplo:
• > ... Cero: = 0; try dummy: = 10 / Zero; excepto en EZeroDivide do MessageDlg ('No
se puede dividir por cero!', mtError, [mbOK], 0); fin; ...
• Protección de recursos
• Cuando una sección de código adquiere un recurso, a menudo es
necesario garantizar que el recurso se libera nuevamente (o puede tener
una fuga de memoria ), independientemente de si el código se completa
normalmente o si se interrumpe con una excepción.
• > {algún código para asignar recursos} intente {bloque de código guardado}
finalmente {bloque de terminación - código para liberar recursos} final;
• Ejemplo:
• Application.OnException
• Si su aplicación no maneja el error que causó la excepción, Delphi usará su
manejador de excepción predeterminado: aparecerá un cuadro de mensaje.
Puede considerar escribir código en el evento OnException para el objeto
TApplication, para atrapar errores en el nivel de la aplicación.
• Break On Exceptions
• Al crear un programa con manejo de excepciones, es posible que no desee
que Delphi incumpla las Excepciones. Esta es una gran característica si
desea que Delphi muestre dónde se ha producido una excepción; sin
embargo, puede ser molesto cuando prueba su propio manejo de
excepciones.