SlideShare una empresa de Scribd logo
1 de 914
Descargar para leer sin conexión
La cara
oculta de
DELPHI 4
...Mientras intentaba inútilmente atrapar un rayo de luz
                    en los confines de una oscura galaxia,
                     Ella escuchaba a los tres guardianes
                                del secreto de la Pirámide,
                        y con el Resplandor de sus manos
                me indicaba el camino de regreso a casa...

                  A Naroa, porque sigo creyendo en ella.
INDICE

PRÓLOGO DEL AUTOR                                   19
CONVENIOS SINTÁCTICOS                               21
ACERCA DE LA TERMINOLOGÍA EMPLEADA                  21
AGRADECIMIENTOS                                     21

PRÓLOGO A LA SEGUNDA EDICIÓN                        23
PARA MÁS EJEMPLOS Y ACTUALIZACIONES...              23

ENTORNO Y HERRAMIENTAS                              27

1. ¿ES DELPHI SU LENGUAJE?                          29
BREVE HISTORIA DE UN LENGUAJE LLAMADO DELPHI        29
¿ES DELPHI UN LENGUAJE “SENCILLO”?                  31
PROGRAMACIÓN ORIENTADA A OBJETOS VERDADERA          32
ARQUITECTURA INTEGRADA DE COMPONENTES               33
DELPHI GENERA CONTROLES ACTIVEX                     34
TRATAMIENTO DE EXCEPCIONES                          34
VELOCIDAD DE EJECUCIÓN                              35
VELOCIDAD DE COMPILACIÓN Y ENLACE                   35
RETROALIMENTACIÓN INMEDIATA                         36
EL DEPÓSITO DE OBJETOS Y LA HERENCIA VISUAL         36
APLICACIONES DISTRIBUIDAS                           37
COMPONENTES DE DELPHI                               38

2. HERRAMIENTAS Y UTILIDADES                        41
DELPHI Y EL TECLADO                                 41
CODE INSIGHT: AYUDA DURANTE LA EDICIÓN              44
CLASS COMPLETION                                    48
HERRAMIENTAS DE DEPURACIÓN                          49
OBJECT BROWSER                                      51
BDE ADMINISTRATOR                                   51
DATABASE EXPLORER                                   52
DATABASE DESKTOP                                    53
DATA MIGRATION WIZARD                               54
SQL MONITOR                                         55
IMAGE EDITOR                                        55
4 La Cara Oculta de Delphi

   3. UNIDADES, PROYECTOS Y PAQUETES                     57
   LA ESTRUCTURA DE UN PROYECTO DE APLICACIÓN            58
   ¿QUÉ SE PUEDE DECLARAR?                               60
   SINTAXIS DE LAS UNIDADES                              62
   LA CLÁUSULA USES Y LAS REFERENCIAS CIRCULARES         64
   LA INCLUSIÓN AUTOMÁTICA DE UNIDADES                   65
   LOS FICHEROS DFM                                      66
   BIBLIOTECAS DE ENLACE DINÁMICO                        68
   PAQUETES                                              69
   EL ABC DEL USO DE PAQUETES                            72
   PAQUETES DE TIEMPO DE DISEÑO Y DE EJECUCIÓN           73
   LOS GRUPOS DE PROYECTOS                               74

   4. SISTEMAS DE BASES DE DATOS                         77
   ACERCA DEL ACCESO TRANSPARENTE A BASES DE DATOS        77
   BASES DE DATOS RELACIONALES                            78
   INFORMACIÓN SEMÁNTICA = RESTRICCIONES                  80
   RESTRICCIONES DE UNICIDAD Y CLAVES PRIMARIAS           81
   INTEGRIDAD REFERENCIAL                                 82
   ¿QUÉ TIENE DE MALO EL MODELO RELACIONAL?               83
   BASES DE DATOS LOCALES Y SERVIDORES SQL                85
   CARACTERÍSTICAS GENERALES DE LOS SISTEMAS SQL          87
   EL FORMATO PARADOX                                     88
   EL FORMATO DBF7                                        91
   CRITERIOS PARA EVALUAR UN SERVIDOR SQL                 92
   INTERBASE                                              95
   MICROSOFT SQL SERVER                                   97
   ORACLE                                                 99
   OTROS SISTEMAS DE USO FRECUENTE                       100

   5. EL MOTOR DE DATOS DE BORLAND                       103
   QUÉ ES, Y CÓMO FUNCIONA                               104
   CONTROLADORES LOCALES Y SQL LINKS                     105
   ACCESO A FUENTES DE DATOS ODBC                        106
   ¿DÓNDE SE INSTALA EL BDE?                             106
   EL ADMINISTRADOR DEL MOTOR DE DATOS                   108
   CONFIGURACIÓN DEL REGISTRO E INFORMACIÓN DE VERSIÓN   108
   EL CONCEPTO DE ALIAS                                  110
   PARÁMETROS DEL SISTEMA                                110
   PARÁMETROS DE LOS CONTROLADORES PARA BD LOCALES       112
   BLOQUEOS OPORTUNISTAS                                 114
   PARÁMETROS COMUNES A LOS CONTROLADORES SQL            114
   CONFIGURACIÓN DE INTERBASE                            117
Indice 5

CONFIGURACIÓN DE MS SQL SERVER                             118
CONFIGURACIÓN DE ORACLE                                    120
CONFIGURACIÓN DE OTROS SISTEMAS                            121
CREACIÓN DE ALIAS PARA BASES DE DATOS LOCALES Y SQL        121
ALTERNATIVAS AL MOTOR DE DATOS                             122

FUNDAMENTOS DEL LENGUAJE                                   125

6. PROGRAMACIÓN ORIENTADA A OBJETOS: ENCAPSULAMIENTO       127
EL PROBLEMA DE LA DIVISIÓN EN MÓDULOS                      127
LOS MÓDULOS EN LA PROGRAMACIÓN ESTRUCTURADA                128
REUSABILIDAD Y EL PRINCIPIO “ABIERTO/CERRADO”              129
LLEGAN LOS OBJETOS                                         130
OPERACIONES SOBRE UN TIPO DE DATOS: FUNCIONES              132
OPERACIONES SOBRE UN TIPO DE DATOS: MÉTODOS                134
LA PRIMERA VENTAJA: NOMBRES MÁS CORTOS                     135
LA IMPLEMENTACIÓN DE UN MÉTODO                             136
EL ESTADO INTERNO DE UN OBJETO                             138
PARÁMETROS POR OMISIÓN                                     140
PÚBLICO Y PRIVADO                                          140
LAS VARIABLES DE OBJETOS SON PUNTEROS                      142
CONSTRUCCIÓN Y DESTRUCCIÓN: EL CICLO DE LA VIDA            143
DEFINIENDO CONSTRUCTORES Y DESTRUCTORES                    144

7. HERENCIA Y POLIMORFISMO                                 147
HERENCIA = EXTENSIÓN + ESPECIALIZACIÓN                     147
UN GATO CON BOTAS SIGUE SIENDO UN GATO                     149
LA CLASE TOBJECT                                           152
JERARQUÍAS DE HERENCIA                                     153
HERENCIA MÚLTIPLE, ¿SÍ O NO?                               154
REDEFINICIÓN DE MÉTODOS                                    155
LA TABLA DE MÉTODOS VIRTUALES                              158
UTILIZANDO EL COMPORTAMIENTO HEREDADO                      160
SOBRECARGA: HAY MUY POCOS NOMBRE BUENOS                    161
PÚBLICO, PROTEGIDO, PRIVADO...                             163
MÉTODOS ABSTRACTOS                                         164
REFERENCIAS DE CLASE                                       165
CONSTRUCTORES VIRTUALES                                    167
INFORMACIÓN DE TIPOS EN TIEMPO DE EJECUCIÓN                168
MÉTODOS DE CLASE                                           170
6 La Cara Oculta de Delphi

   8. ELEMENTOS DE PROGRAMACIÓN CON WINDOWS           173
   SI ME NECESITAS, ¡LLÁMAME!                         173
   ¿QUÉ ES UNA VENTANA?                               174
   CLASES DE VENTANA                                  175
   EVENTOS O, MÁS BIEN, MENSAJES                      176
   EL CICLO DE MENSAJES Y LA COLA DE MENSAJES         177
   EJECUCIÓN MODAL Y NO MODAL                         180
   EL PROCEDIMIENTO DE VENTANA                        180
   INTERCEPTANDO MENSAJES EN DELPHI                   181
   TAMBIÉN PODEMOS ENVIAR MENSAJES                    184
   APLICACIONES EN LA BANDEJA DE ICONOS               184
   CICLO DE MENSAJES Y CONCURRENCIA                   187
   CUANDO NO HAY NADA MEJOR QUE HACER…                188
   EJECUTAR Y ESPERAR                                 189

   9. PROPIEDADES                                     191
   LOS PROBLEMAS DE LA POO CLÁSICA                    191
   PROPIEDADES                                        194
   IMPLEMENTACIÓN DE PROPIEDADES MEDIANTE ATRIBUTOS   195
   SI NO CREEMOS EN LA ALQUIMIA…                      197
   LA SEMÁNTICA DE LA ASIGNACIÓN A PROPIEDADES        198
   PROPIEDADES VECTORIALES                            200
   PROPIEDADES VECTORIALES POR OMISIÓN                202
   ESPECIFICACIONES DE ALMACENAMIENTO                 202
   ACCESO A PROPIEDADES POR SU NOMBRE                 205

   10. EVENTOS                                        207
   PUNTEROS A FUNCIONES                               207
   PUNTEROS A MÉTODOS                                 208
   OBJETOS ACTIVOS: ¡ABAJO LA VIGILANCIA!             210
   EVENTOS VS REDEFINICIÓN DE MÉTODOS VIRTUALES       212
   EL EMISOR Y EL RECEPTOR DEL EVENTO                 214
   RECEPTORES COMPARTIDOS                             215
   TIPOS DE EVENTOS                                   216
   NOS PIDEN NUESTRA OPINIÓN...                       218
   LOS EVENTOS EXPRESAN CONTRATOS SIN OBLIGACIONES    218
   ACTIVACIÓN RECURSIVA                               219

   11. EXCEPCIONES                                    223
   SISTEMAS DE CONTROL DE ERRORES                     223
   CONTRATOS INCUMPLIDOS                              224
   CÓMO SE INDICA UN ERROR                            225
Indice 7

LA EJECUCIÓN DEL PROGRAMA FLUYE EN DOS DIMENSIONES        226
EL ESTADO DE PÁNICO                                       227
PAGAMOS NUESTRAS DEUDAS                                   227
EL CONCEPTO DE "RECURSO DE PROGRAMACIÓN"                  228
CÓMO TRANQUILIZAR A UN PROGRAMA ASUSTADO                  229
EJEMPLOS DE CAPTURA DE EXCEPCIONES                        230
CAPTURANDO EL OBJETO DE EXCEPCIÓN                         231
DISTINGUIR EL TIPO DE EXCEPCIÓN                           231
LAS TRES REGLAS DE MARTEENS                               233
CICLO DE MENSAJES Y MANEJO DE EXCEPCIONES                 234
EXCEPCIONES A LA TERCERA REGLA DE MARTEENS                235
EL EVENTO ONEXCEPTION                                     236
LA EXCEPCIÓN SILENCIOSA                                   239
CONSTRUCTORES Y EXCEPCIONES                               240
ASERCIONES                                                243

12. TIPOS DE DATOS DE DELPHI                              247
TIPOS NUMÉRICOS                                           247
FECHAS Y HORAS                                            249
CADENAS DE CARACTERES CORTAS                              251
PUNTEROS A CARACTERES, AL ESTILO C                        253
CADENAS DE CARACTERES LARGAS                              254
VECTORES ABIERTOS                                         256
VECTORES DINÁMICOS                                        258
VECTORES ABIERTOS VARIANTES                               259
VARIANTES                                                 260
CLASES PARA LA REPRESENTACIÓN DE LISTAS                   261
STREAMS: FICHEROS CON INTERFAZ DE OBJETOS                 264

13. TÉCNICAS DE GESTIÓN DE VENTANAS                       267
¿QUÉ HACE DELPHI CUANDO LO DEJAMOS SOLO?                  267
CREACIÓN INMEDIATA DE VENTANAS MODALES                    269
CREACIÓN INMEDIATA DE VENTANAS NO MODALES                 271
MÉTODOS DE CLASE PARA LA CREACIÓN DINÁMICA                273
CÓMO TRANSFORMAR INTROS EN TABS                           276
CÓMO LIMITAR EL TAMAÑO DE UNA VENTANA                     277
CÓMO DISTRIBUIR EL ÁREA INTERIOR ENTRE DOS REJILLAS       279
VENTANAS DE PRESENTACIÓN                                  281

14. LOS MÓDULOS DE DATOS Y EL DEPÓSITO DE OBJETOS         283
LA GALERÍA DE PLANTILLAS DE DELPHI 1                      283
EL DEPÓSITO DE OBJETOS                                    284
LAS PROPIEDADES DEL DEPÓSITO                              286
8 La Cara Oculta de Delphi

   LA UBICACIÓN DEL DEPÓSITO DE OBJETOS            287
   ¿USAR, COPIAR O HEREDAR?                        289
   HERENCIA VISUAL DENTRO DEL PROYECTO             292
   HERENCIA DE EVENTOS                             292
   LAS PLANTILLAS DE COMPONENTES                   293
   LOS MÓDULOS DE DATOS                            294

   COMPONENTES PARA BASES DE DATOS                 297

   15. CONJUNTOS DE DATOS: TABLAS                  299
   LA JERARQUÍA DE LOS CONJUNTOS DE DATOS          299
   LA ARQUITECTURA DE OBJETOS DEL MOTOR DE DATOS   301
   TABLAS                                          303
   CONEXIÓN CON COMPONENTES VISUALES               306
   NAVEGANDO POR LAS FILAS                         308
   MARCAS DE POSICIÓN                              310
   ENCAPSULAMIENTO DE LA ITERACIÓN                 311
   LA RELACIÓN MASTER/DETAIL                       313
   NAVEGACIÓN Y RELACIONES MASTER/DETAIL           316
   EL ESTADO DE UN CONJUNTO DE DATOS               321

   16. ACCESO A CAMPOS                             323
   CREACIÓN DE COMPONENTES DE CAMPOS               323
   CLASES DE CAMPOS                                325
   NOMBRE DEL CAMPO Y ETIQUETA DE VISUALIZACIÓN    327
   ACCESO A LOS CAMPOS POR MEDIO DE LA TABLA       328
   EXTRAYENDO INFORMACIÓN DE LOS CAMPOS            328
   LAS MÁSCARAS DE FORMATO Y EDICIÓN               330
   LOS EVENTOS DE FORMATO DE CAMPOS                331
   VALIDACIÓN A NIVEL DE CAMPOS                    333
   PROPIEDADES DE VALIDACIÓN                       334
   CAMPOS CALCULADOS                               335
   CAMPOS DE BÚSQUEDA                              336
   LA CACHÉ DE BÚSQUEDA                            338
   EL ORDEN DE EVALUACIÓN DE LOS CAMPOS            339
   EL DICCIONARIO DE DATOS                         340
   CONJUNTOS DE ATRIBUTOS                          341
   IMPORTANDO BASES DE DATOS                       342
   EVALUANDO RESTRICCIONES EN EL CLIENTE           343
   INFORMACIÓN SOBRE CAMPOS                        346
   CREACIÓN DE TABLAS                              347
Indice 9

17. CONTROLES DE DATOS Y FUENTES DE DATOS              351
CONTROLES DATA-AWARE                                   351
LOS ENLACES DE DATOS                                   353
CREACIÓN DE CONTROLES DE DATOS                         354
LOS CUADROS DE EDICIÓN                                 355
EDITORES DE TEXTO                                      356
TEXTOS NO EDITABLES                                    357
COMBOS Y LISTAS CON CONTENIDO FIJO                     357
COMBOS Y LISTAS DE BÚSQUEDA                            360
CASILLAS DE VERIFICACIÓN Y GRUPOS DE BOTONES           362
IMÁGENES EXTRAÍDAS DE BASES DE DATOS                   363
LA TÉCNICA DEL COMPONENTE DEL POBRE                    363
PERMITIENDO LAS MODIFICACIONES                         365
BLOB, BLOB, BLOB…                                      367
LA CLASE TBLOBSTREAM                                   368

18. REJILLAS Y BARRAS DE NAVEGACIÓN                    371
EL FUNCIONAMIENTO BÁSICO DE UNA REJILLA DE DATOS       371
OPCIONES DE REJILLAS                                   372
COLUMNAS A LA MEDIDA                                   373
GUARDAR Y RESTAURAR LOS ANCHOS DE COLUMNAS             376
LISTAS DESPLEGABLES Y BOTONES DE EDICIÓN               377
NÚMEROS VERDES Y NÚMEROS ROJOS                         379
MÁS EVENTOS DE REJILLAS                                381
LA BARRA DE DESPLAZAMIENTO DE LA REJILLA               382
REJILLAS DE SELECCIÓN MÚLTIPLE                         383
BARRAS DE NAVEGACIÓN                                   384
HABÍA UNA VEZ UN USUARIO TORPE, MUY TORPE…             385
AYUDAS PARA NAVEGAR                                    385
EL COMPORTAMIENTO DE LA BARRA DE NAVEGACIÓN            386
REJILLAS DE CONTROLES                                  388

19. INDICES                                            391
INDICES EN PARADOX                                     391
INDICES EN DBASE                                       392
INDICES EN INTERBASE                                   394
INDICES EN MS SQL SERVER                               394
INDICES EN ORACLE                                      395
CON QUÉ ÍNDICES PODEMOS CONTAR                         396
ESPECIFICANDO EL ÍNDICE ACTIVO                         398
ESPECIFICANDO UN ORDEN EN TABLAS SQL                   399
BÚSQUEDA BASADA EN ÍNDICES                             401
IMPLEMENTACIÓN DE REFERENCIAS MEDIANTE FINDKEY         403
10 La Cara Oculta de Delphi

   BÚSQUEDAS UTILIZANDO SETKEY                     403
   EXPERIMENTANDO CON SETKEY                       404
   ¿POR QUÉ EXISTE SETKEY?                         405
   RANGOS: DESDE EL ALFA A LA OMEGA                406
   EL EJEMPLO DE RANGOS DE CASI TODOS LOS LIBROS   408
   MÁS PROBLEMAS CON LOS ÍNDICES DE DBASE          410
   CÓMO CREAR UN ÍNDICE TEMPORAL                   411

   20. MÉTODOS DE BÚSQUEDA                         413
   FILTROS                                         413
   ESTO NO LO DICE LA DOCUMENTACIÓN…               414
   UN EJEMPLO CON FILTROS RÁPIDOS                  415
   EL EVENTO ONFILTERRECORD                        418
   LOCALIZACIÓN Y BÚSQUEDA                         419
   UN DIÁLOGO GENÉRICO DE LOCALIZACIÓN             422
   FILTROS LATENTES                                424
   FILTER BY EXAMPLE                               426
   BÚSQUEDA EN UNA TABLA DE DETALLES               430

   PROGRAMACIÓN CON SQL                            433

   21. BREVE INTRODUCCIÓN A SQL                    435
   LA ESTRUCTURA DE SQL                            435
   PARA SEGUIR LOS EJEMPLOS DE ESTE LIBRO…         436
   LA CREACIÓN Y CONEXIÓN A LA BASE DE DATOS       438
   TIPOS DE DATOS EN SQL                           439
   CREACIÓN DE TABLAS                              440
   COLUMNAS CALCULADAS                             441
   VALORES POR OMISIÓN                             442
   RESTRICCIONES DE INTEGRIDAD                     442
   CLAVES PRIMARIAS Y ALTERNATIVAS                 444
   INTEGRIDAD REFERENCIAL                          445
   ACCIONES REFERENCIALES                          446
   NOMBRES PARA LAS RESTRICCIONES                  447
   DEFINICIÓN Y USO DE DOMINIOS                    448
   CREACIÓN DE ÍNDICES                             449
   MODIFICACIÓN DE TABLAS E ÍNDICES                450
   CREACIÓN DE VISTAS                              451
   CREACIÓN DE USUARIOS                            451
   ASIGNACIÓN DE PRIVILEGIOS                       453
   ROLES                                           454
   UN EJEMPLO COMPLETO DE SCRIPT SQL               455
Indice 11

22. CONSULTAS Y MODIFICACIONES EN SQL                    457
LA INSTRUCCIÓN SELECT: EL LENGUAJE DE CONSULTAS          457
LA CONDICIÓN DE SELECCIÓN                                459
OPERADORES DE CADENAS                                    459
EL VALOR NULO: ENFRENTÁNDONOS A LO DESCONOCIDO           460
ELIMINACIÓN DE DUPLICADOS                                461
PRODUCTOS CARTESIANOS Y ENCUENTROS                       462
ORDENANDO LOS RESULTADOS                                 464
EL USO DE GRUPOS                                         465
FUNCIONES DE CONJUNTOS                                   466
LA CLÁUSULA HAVING                                       467
EL USO DE SINÓNIMOS PARA TABLAS                          467
SUBCONSULTAS: SELECCIÓN ÚNICA                            468
SUBCONSULTAS: LOS OPERADORES IN Y EXISTS                 469
SUBCONSULTAS CORRELACIONADAS                             471
EQUIVALENCIAS DE SUBCONSULTAS                            472
ENCUENTROS EXTERNOS                                      473
LAS INSTRUCCIONES DE ACTUALIZACIÓN                       475
VISTAS                                                   476

23. PROCEDIMIENTOS ALMACENADOS Y TRIGGERS                479
¿PARA QUÉ USAR PROCEDIMIENTOS ALMACENADOS?               479
CÓMO SE UTILIZA UN PROCEDIMIENTO ALMACENADO              481
EL CARÁCTER DE TERMINACIÓN                               482
PROCEDIMIENTOS ALMACENADOS EN INTERBASE                  483
PROCEDIMIENTOS QUE DEVUELVEN UN CONJUNTO DE DATOS        486
RECORRIENDO UN CONJUNTO DE DATOS                         488
TRIGGERS, O DISPARADORES                                 489
LAS VARIABLES NEW Y OLD                                  491
MÁS EJEMPLOS DE TRIGGERS                                 491
GENERADORES                                              493
SIMULANDO LA INTEGRIDAD REFERENCIAL                      495
EXCEPCIONES                                              497
ALERTADORES DE EVENTOS                                   498

24. MICROSOFT SQL SERVER                                 501
HERRAMIENTAS DE DESARROLLO EN EL CLIENTE                 501
CREACIÓN DE BASES DE DATOS CON MS SQL SERVER             502
TIPOS DE DATOS PREDEFINIDOS                              504
TIPOS DE DATOS DEFINIDOS POR EL PROGRAMADOR              505
CREACIÓN DE TABLAS Y ATRIBUTOS DE COLUMNAS               506
INTEGRIDAD REFERENCIAL                                   507
INDICES                                                  508
12 La Cara Oculta de Delphi

   SEGURIDAD EN MS SQL SERVER                        508
   PROCEDIMIENTOS ALMACENADOS                        509
   CURSORES                                          510
   TRIGGERS EN TRANSACT-SQL                          512
   INTEGRIDAD REFERENCIAL MEDIANTE TRIGGERS          514

   25. ORACLE                                        517
   SOBREVIVIENDO A SQL*PLUS                          517
   INSTANCIAS, BASES DE DATOS, USUARIOS              519
   TIPOS DE DATOS                                    520
   CREACIÓN DE TABLAS                                521
   PROCEDIMIENTOS ALMACENADOS EN PL/SQL              522
   CURSORES                                          524
   TRIGGERS EN PL/SQL                                525
   SECUENCIAS                                        526
   TIPOS DE OBJETOS                                  528
   EXTENSIONES DE DELPHI PARA LOS TIPOS DE OBJETOS   532

   26. USANDO SQL CON DELPHI                         537
   EL COMPONENTE TQUERY COMO CONJUNTO DE DATOS       537
   ¿QUIÉN EJECUTA LAS INSTRUCCIONES?                 538
   CONSULTAS ACTUALIZABLES                           539
   SIEMPRE HACIA ADELANTE                            540
   CONSULTAS PARAMÉTRICAS                            543
   CONSULTAS DEPENDIENTES                            545
   LA PREPARACIÓN DE LA CONSULTA                     546
   ACTUALIZACIÓN DE DATOS CON SQL                    548
   ALMACENAR EL RESULTADO DE UNA CONSULTA            549
   ¿EJECUTAR O ACTIVAR?                              550
   UTILIZANDO PROCEDIMIENTOS ALMACENADOS             553
   VISUAL QUERY BUILDER                              555

   27. COMUNICACIÓN CLIENTE/SERVIDOR                 559
   NUESTRA ARMA LETAL: SQL MONITOR                   559
   ¿TABLA O CONSULTA?                                560
   LA CACHÉ DE ESQUEMAS                              562
   OPERACIONES DE NAVEGACIÓN SIMPLE                  563
   BÚSQUEDAS EXACTAS CON LOCATE                      564
   BÚSQUEDAS PARCIALES                               564
   UNA SOLUCIÓN PARA BÚSQUEDAS PARCIALES RÁPIDAS     565
   BÚSQUEDAS CON FILTROS LATENTES                    567
Indice 13

ACTUALIZACIONES Y CONCURRENCIA                             569

28. ACTUALIZACIONES                                        571
LOS ESTADOS DE EDICIÓN Y LOS MÉTODOS DE TRANSICIÓN         571
ASIGNACIONES A CAMPOS                                      572
CONFIRMANDO LAS ACTUALIZACIONES                            574
DIFERENCIAS ENTRE INSERT Y APPEND                          575
COMO POR AZAR…                                             576
MÉTODOS ABREVIADOS DE INSERCIÓN                            577
ACTUALIZACIÓN DIRECTA VS VARIABLES EN MEMORIA              577
AUTOMATIZANDO LA ENTRADA DE DATOS                          579
ENTRADA DE DATOS CONTINUA                                  581
ELIMINANDO REGISTROS                                       582
COMPRESIÓN DE TABLAS LOCALES                               583

29. EVENTOS DE TRANSICIÓN DE ESTADOS                       585
CUANDO EL ESTADO CAMBIA…                                   585
REGLAS DE EMPRESA: ¿EN EL SERVIDOR O EN EL CLIENTE?        586
INICIALIZACIÓN DE REGISTROS: EL EVENTO ONNEWRECORD         587
VALIDACIONES A NIVEL DE REGISTROS                          588
ANTES Y DESPUÉS DE UNA MODIFICACIÓN                        589
PROPAGACIÓN DE CAMBIOS EN CASCADA                          591
ACTUALIZACIONES COORDINADAS MASTER/DETAIL                  592
ANTES Y DESPUÉS DE LA APERTURA DE UNA TABLA                593
VACIANDO LOS BUFFERS                                       594
LOS EVENTOS DE DETECCIÓN DE ERRORES                        595
LA ESTRUCTURA DE LA EXCEPCIÓN EDBENGINEERROR               597
APLICACIONES DE LOS EVENTOS DE ERRORES                     600
UNA VEZ MÁS, LA ORIENTACIÓN A OBJETOS…                     602

30. BASES DE DATOS Y SESIONES                              603
EL COMPONENTE TDATABASE                                    603
OBJETOS DE BASES DE DATOS PERSISTENTES                     604
CAMBIANDO UN ALIAS DINÁMICAMENTE                           605
BASES DE DATOS Y CONJUNTOS DE DATOS                        607
PARÁMETROS DE CONEXIÓN                                     609
LA PETICIÓN DE CONTRASEÑAS                                 609
EL DIRECTORIO TEMPORAL DE WINDOWS                          611
PROBLEMAS CON LA HERENCIA VISUAL                           611
SESIONES                                                   613
CADA SESIÓN ES UN USUARIO                                  613
SESIONES E HILOS PARALELOS                                 614
14 La Cara Oculta de Delphi

   INFORMACIÓN SOBRE ESQUEMAS                       617
   EL MINIEXPLORADOR DE BASES DE DATOS              618
   GESTIÓN DE ALIAS A TRAVÉS DE TSESSION            620
   DIRECTORIOS PRIVADOS, DE RED Y CONTRASEÑAS       622

   31. TRANSACCIONES Y CONTROL DE CONCURRENCIA      625
   EL GRAN EXPERIMENTO                              625
   EL GRAN EXPERIMENTO: TABLAS LOCALES              626
   EL GRAN EXPERIMENTO: TABLAS SQL                  628
   PESIMISTAS Y OPTIMISTAS                          628
   EL MODO DE ACTUALIZACIÓN                         630
   LA RELECTURA DEL REGISTRO ACTUAL                 632
   LAS PROPIEDADES “ÁCIDAS” DE UNA TRANSACCIÓN      633
   TRANSACCIONES SQL Y EN BASES DE DATOS LOCALES    635
   TRANSACCIONES IMPLÍCITAS Y EXPLÍCITAS            636
   ENTRADA DE DATOS Y TRANSACCIONES                 638
   AISLAMIENTO DE TRANSACCIONES                     639
   AISLAMIENTO DE TRANSACCIONES MEDIANTE BLOQUEOS   641
   EL JARDÍN DE LOS SENDEROS QUE SE BIFURCAN        643
   DE NUEVO LOS OPTIMISTAS                          644

   32. ACTUALIZACIONES EN CACHÉ                     649
   ¿CACHÉ PARA QUÉ?                                 649
   ACTIVACIÓN DE LAS ACTUALIZACIONES EN CACHÉ       650
   CONFIRMACIÓN DE LAS ACTUALIZACIONES              651
   MARCHA ATRÁS                                     653
   EL ESTADO DE ACTUALIZACIÓN                       653
   EL FILTRO DE TIPOS DE REGISTROS                  655
   UN EJEMPLO INTEGRAL                              656
   EL GRAN FINAL: EDICIÓN Y ENTRADA DE DATOS        658
   COMBINANDO LA CACHÉ CON GRABACIONES DIRECTAS     660
   PROTOTIPOS Y MÉTODOS VIRTUALES                   663
   CÓMO ACTUALIZAR CONSULTAS “NO” ACTUALIZABLES     665
   EL EVENTO ONUPDATERECORD                         668
   DETECCIÓN DE ERRORES DURANTE LA GRABACIÓN        669

   33. LIBRETAS DE BANCOS                           673
   DESCRIPCIÓN DEL MODELO DE DATOS                  673
   CREACIÓN DE VISTAS                               675
   MANTENIENDO ACTUALIZADOS LOS SALDOS              675
   LIBRETAS DE BANCO Y MS SQL SERVER                677
   AHORA, EN ORACLE                                 679
   EL MÓDULO DE DATOS                               681
Indice 15

GESTIÓN DE LIBRETAS                                       684
CÓDIGOS DE OPERACIONES                                    686
LA VENTANA PRINCIPAL                                      688
ENTRADA DE APUNTES                                        690
CORRIGIENDO EL IMPORTE DE UN APUNTE                       692

LOS DETALLES FINALES                                      695

34. IMPRESIÓN DE INFORMES CON QUICKREPORT                 697
LA HISTORIA DEL PRODUCTO                                  697
LA FILOSOFÍA DEL PRODUCTO                                 699
PLANTILLAS Y EXPERTOS PARA QUICKREPORT                    700
EL CORAZÓN DE UN INFORME                                  701
LAS BANDAS                                                703
EL EVENTO BEFOREPRINT                                     704
COMPONENTES DE IMPRESIÓN                                  705
EL EVALUADOR DE EXPRESIONES                               706
DEFINIENDO NUEVAS FUNCIONES                               708
UTILIZANDO GRUPOS                                         709
ELIMINANDO DUPLICADOS                                     711
INFORMES MASTER/DETAIL                                    712
INFORMES COMPUESTOS                                       714
PREVISUALIZACIÓN A LA MEDIDA                              715
LISTADOS AL VUELO                                         716
ENVIANDO CÓDIGOS BINARIOS A UNA IMPRESORA                 718

35. GRÁFICOS DE DECISIÓN                                  721
GRÁFICOS Y BIORRITMOS                                     721
EL COMPONENTE TDBCHART                                    725
COMPONENTES NO VISUALES DE DECISION CUBE                  727
REJILLAS Y GRÁFICOS DE DECISIÓN                           729
MODIFICANDO EL MAPA DE DIMENSIONES                        731

36. BIBLIOTECAS DE ENLACE DINÁMICO                        733
ARQUITECTURA BÁSICA                                       733
PROYECTOS DLL                                             735
EXPORTACIÓN DE FUNCIONES                                  736
IMPORTACIÓN DE FUNCIONES Y UNIDADES DE IMPORTACIÓN        739
TIPOS DE DATOS EN FUNCIONES EXPORTADAS                    740
CÓDIGO DE INICIALIZACIÓN Y FINALIZACIÓN                   742
EXCEPCIONES EN BIBLIOTECAS DINÁMICAS                      744
CARGA DINÁMICA DE BIBLIOTECAS                             745
16 La Cara Oculta de Delphi

   DEPURACIÓN DE BIBLIOTECAS DINÁMICAS                  746
   FUNCIONES DE USUARIO EN INTERBASE                    746
   BIBLIOTECAS DE RECURSOS E INTERNACIONALIZACIÓN       749
   FICHEROS ASIGNADOS EN MEMORIA                        752

   37. SERVIDORES DE INTERNET                           757
   EL MODELO DE INTERACCIÓN EN LA WEB                   757
   APRENDA HTML EN 14 MINUTOS                           758
   EXTENSIONES DEL SERVIDOR Y PÁGINAS DINÁMICAS         761
   ¿QUÉ NECESITO PARA ESTE SEGUIR LOS EJEMPLOS?         762
   MÓDULOS WEB                                          763
   ACCIONES                                             765
   RECUPERACIÓN DE PARÁMETROS                           767
   GENERADORES DE CONTENIDO                             768
   GENERADORES DE TABLAS                                770
   MANTENIMIENTO DE LA INFORMACIÓN DE ESTADO            771
   UN EJEMPLO: BÚSQUEDA DE PRODUCTOS                    773
   EL MOTOR DE BÚSQUEDAS                                775
   CREANDO LA EXTENSIÓN WEB                             778
   GENERANDO LA TABLA DE RESULTADOS                     780
   DOCUMENTOS HTML Y SUSTITUCIÓN DE ETIQUETAS           781
   RESPONDIENDO A LAS ACCIONES                          783

   38. CONJUNTOS DE DATOS CLIENTES                      785
   CREACIÓN DE CONJUNTOS DE DATOS                       785
   CÓMO EL TCLIENTDATASET CONSIGUIÓ SUS DATOS...        787
   NAVEGACIÓN, BÚSQUEDA Y SELECCIÓN                     788
   FILTROS                                              789
   EDICIÓN DE DATOS                                     790
   CONJUNTOS DE DATOS ANIDADOS                          791
   CAMPOS CALCULADOS INTERNOS                           794
   INDICES, GRUPOS Y VALORES AGREGADOS                  795

   39. EL MODELO DE OBJETOS COMPONENTES: LA TEORÍA      799
   COM, DCOM, OLE...                                    800
   INTERFACES                                           801
   LA INTERFAZ IUNKNOWN                                 803
   IMPLEMENTACIÓN DE INTERFACES EN DELPHI               805
   CÓMO OBTENER UN OBJETO COM                           807
   DENTRO DEL PROCESO, EN LA MISMA MÁQUINA, REMOTO...   808
   EL HUEVO, LA GALLINA Y LAS FÁBRICAS DE CLASES        809
   OLE Y EL REGISTRO DE WINDOWS                         810
   ¿CÓMO SE REGISTRA UN SERVIDOR?                       812
Indice 17

AUTOMATIZACIÓN OLE                                      812
CONTROLADORES DE AUTOMATIZACIÓN EN DELPHI               814
INTERFACES DUALES                                       815
EVENTOS Y CONTROLES ACTIVEX                             816
BIBLIOTECAS DE TIPOS                                    817
ACTIVEFORMS: FORMULARIOS EN LA WEB                      819

40. EL MODELO DE OBJETOS COMPONENTES: EJEMPLOS          823
CREACIÓN DE OBJETOS Y MANEJO DE INTERFACES              823
INTERCEPTANDO OPERACIONES EN DIRECTORIOS                824
INFORMES AUTOMATIZADOS                                  828
CONTROLADORES DE AUTOMATIZACIÓN                         833
DECLARANDO UNA INTERFAZ COMÚN                           835
UN SERVIDOR DE BLOQUEOS                                 836
LA IMPLEMENTACIÓN DE LA LISTA DE BLOQUEOS               838
CONTROL DE CONCURRENCIA                                 840
PONIENDO A PRUEBA EL SERVIDOR                           843

41. MIDAS                                               845
¿QUÉ ES MIDAS?                                          845
CUÁNDO UTILIZAR Y CUÁNDO NO UTILIZAR MIDAS              847
MIDAS Y LAS BASES DE DATOS DE ESCRITORIO                849
MÓDULOS DE DATOS REMOTOS                                850
PROVEEDORES                                             853
SERVIDORES REMOTOS Y CONJUNTOS DE DATOS CLIENTES        854
GRABACIÓN DE DATOS                                      856
RESOLUCIÓN                                              859
CONTROL DE ERRORES DURANTE LA RESOLUCIÓN                862
RECONCILIACIÓN                                          864
RELACIONES MASTER/DETAIL Y TABLAS ANIDADAS              866
ENVÍO DE PARÁMETROS                                     866
EXTENDIENDO LA INTERFAZ DEL SERVIDOR                    867
LA METÁFORA DEL MALETÍN                                 870
TIPOS DE CONEXIÓN                                       871
BALANCE DE CARGA SIMPLE                                 874
INTERFACES DUALES EN MIDAS                              875

42. CREACIÓN DE INSTALACIONES                           877
LOS PROYECTOS DE INSTALLSHIELD EXPRESS                  877
LA PRESENTACIÓN DE LA INSTALACIÓN                       879
LAS MACROS DE DIRECTORIOS                               881
GRUPOS Y COMPONENTES                                    881
INSTALANDO EL BDE Y LOS SQL LINKS                       884
18 La Cara Oculta de Delphi

   CONFIGURACIÓN ADICIONAL DEL BDE                885
   INSTALACIÓN DE PAQUETES                        887
   INTERACCIÓN CON EL USUARIO                     888
   LAS CLAVES DEL REGISTRO DE WINDOWS             890
   CÓMO SE REGISTRAN LOS COMPONENTES ACTIVEX      891
   ICONOS Y CARPETAS                              892
   GENERANDO Y PROBANDO LA INSTALACIÓN            894
   LA VERSIÓN COMPLETA DE INSTALLSHIELD EXPRESS   894
   LAS EXTENSIONES DE INSTALLSHIELD EXPRESS       895
Prólogo del Autor
                                            And if the band you’re in start playing different tunes
                                                         I’ll see you on the dark side of the moon
                                                                                        Pink Floyd

      …those dark and hideous mysteries which lie in the outer regions of the moon, regions which,
              owing to the almost miraculous accordance of the satellite’s rotation on its own axis
                               with its sidereal revolution about the earth, have never yet turned,
              and, by God’s mercy, never shall be turned, to the scrutiny of the telescopes of man.
                                        Edgar Allan Poe, The Adventure Of One Hans Pfaall




E       N LA PRIMAVERA DEL 95 APARECIÓ DELPHI.            En aquel momento, el autor
         trabajaba para una empresa de cartografía, programando en C/C++ para el
         entorno Windows, y estaba metido en un proyecto bastante complicado. La
aplicación en cuestión debía trabajar con grandes cantidades de datos, con relaciones
complejas entre los mismos, y tenía que realizar cálculos algebraicos a diestra y si-
niestra; todo esto aprovechando la interfaz gráfica de Windows 3.11. De entrada
descarté a Visual Basic, pues aunque simplificaba la programación de la interfaz de
usuario, era demasiado lento para las operaciones de cálculo y, al no ser un lenguaje
orientado a objetos, no me permitía modelar elegantemente las clases que manipu-
laba mi proyecto. En cuanto al acceso a datos, ya había trabajado con CodeBase, una
biblioteca de funciones para manipular tablas en formato dbf. En un principio, podía
utilizar algo así, aunque la versión 5.1, que era la que estaba utilizando, fallaba cuando
los ficheros de datos pasaban de cierto volumen.

Necesitaba una herramienta de programación que cumpliera con estos requerimien-
tos, y escribí a Borland, pensando en comprar un C++ con las Database Tools. En
cambio, Borland me envió información sobre un nuevo producto llamado Delphi,
cuyo lenguaje de programación parecía ser Pascal, ofrecía un entorno de desarrollo
visual parecido al de Visual Basic, y que permitía el acceso a bases de datos en di-
versos formatos. No lo pensé mucho y compré el producto; tengo que reconocer que
el precio, relativamente barato, también influyó en mi decisión. La historia tuvo, por
supuesto, un final feliz como los de los anuncios de detergentes: el proyecto se ter-
minó a tiempo, la aplicación se ejecutaba de maravillas y todos quedaron contentos,
excepto yo, que tardé más de seis meses en cobrar lo que me correspondía.

Mi primera experiencia con Delphi fue similar a la de miles de programadores, y la
conclusión que extraje de este primer encuentro con el lenguaje debe haber sido
semejante a la de ellos: Delphi es un sistema muy fácil de aprender y utilizar, y ofrece
una potencia de programación similar a la de los lenguajes tradicionales como
C/C++.
20 La Cara Oculta de Delphi

   No obstante, tras esta aparente sencillez se oculta una trampa. La programación con
   Delphi es, efectivamente, muy sencilla si nos limitamos a las tareas básicas. Pero do-
   minar el lenguaje requiere tiempo y dedicación. Los tres problemas básicos a los que
   se enfrenta el programador en Delphi son:

       •   La Programación Orientada a Objetos.
       •   La arquitectura basada en mensajes o eventos.
       •   El control de errores mediante excepciones.

   Además, el programador que quiere desarrollar aplicaciones serias de bases de datos
   tiene que afrontar las dificultades de la programación concurrente: mecanismos de
   control de acceso, transacciones, integridad y consistencia, el dominio del lenguaje
   SQL... Si el entorno del cual procede es la programación para bases de datos locales,
   todos estos conceptos son nuevos o se abordan desde enfoques diferentes en su
   sistema de programación original.

   Por todas estas razones, decidí escribir un libro dedicado especialmente a la pro-
   gramación para bases de datos con Delphi, que entrara en profundidad en los con-
   ceptos específicos de este área. Un libro de carácter “tutorial”, que además conside-
   rase todos los temas anteriores con la profundidad necesaria, hubiera tenido el ta-
   maño de una enciclopedia, y su redacción necesitaría mucho más tiempo. En vez de
   llevar una línea de desarrollo, conducida quizás por una aplicación única de ejemplo,
   he preferido utilizar ejemplos pequeños para cada tema. De este modo, cada capítulo
   puede leerse de forma independiente a los demás, y el libro puede utilizarse como
   referencia.

   El mayor problema de un libro escrito en ese estilo es el de las referencias circulares:
   necesito explicarle qué es un campo antes de poder hacer ejemplos sencillos con las
   tablas, pero también necesito presentar las tablas antes de poder explicar los campos.
   Y la única solución que se me ocurre es ofrecer adelantos: escribir un poco sobre el
   recurso necesario, prometiendo más información sobre éste más adelante.

    “La Cara Oculta de Delphi” está destinada a personas que ya han estado sentadas
   frente a Delphi. No es necesario que hayan programado en Delphi, pero no es mi in-
   tención enseñar cómo se inicia Delphi, qué comandos ofrece, qué es un menú... Hay
   bastante literatura por ahí que se ocupa de estos temas. En particular, me permito
   recomendar el “Manual Fundamental de Borland Delphi 2.0”, de un tal Ian Mar-
   teens; no será el mejor, pero conozco al autor y no es mala persona.
Prólogo del Autor 21


Convenios sintácticos
 A lo largo de este libro tendré que explicar la sintaxis de algunas construcciones de
 Delphi, especialmente en el área de objetos y clases, y de las instrucciones del len-
 guaje SQL. Utilizaré en estos casos la notación habitual, que explico a continuación
 para los lectores no familiarizados:

  Cursivas              Nombres o constantes que el programador debe
                        suministrar.
  [Corchetes]           Lo que se pone entre corchetes es opcional.
  Puntos suspensivos... Los puntos suspensivos indican la repetición de la cláusula
                        anterior.
  Verdadero|Falso       La barra vertical se utiliza para indicar una alternativa.


Acerca de la terminología empleada
 La mayor parte de este libro ha sido redactada directamente en mi (pobre) castellano.
 He tratado, en lo posible, de mantener los nombres originales de los objetos y con-
 ceptos utilizados. En los casos en que he traducido el término, incluyo también su
 nombre en inglés. No tiene sentido traducir términos nuevos o que se utilizan con
 poca frecuencia; el próximo autor posiblemente utilizará una traducción diferente,
 aunque sea por ansias de originalidad.

 Durante la corrección del libro, he insistido en dos traducciones que pueden resultar
 extrañas para el lector español. Una de ellas es traducir library como biblioteca, cuando
 el término más extendido es librería. La otra “singularidad” es utilizar el género feme-
 nino para la palabra interfaz. El castellano moderno tiende a masculinizar las palabras
 importadas de otro idioma, así que casi todos dicen en España: “el interfaz”. Pero
 esta palabra no es realmente una importación; se deriva de faz, que es de género fe-
 menino.


Agradecimientos
 En primer lugar, quiero agradecer la acogida que tuvo el “Manual Fundamental”. Sin
 el apoyo del público, no me hubiera decidido a escribir un segundo libro acerca de
 Delphi. Por otra parte, gracias a los que compraron el libro, Christine (mi ordenador
 personal) pasó de ser un 486 a 100MHz con 12MB, a convertirse en un Pentium
 potente de mente fría y corazón caliente; vamos, que le habéis financiado el lifting.
 Quiero decir, no obstante, que antes de la actualización Delphi 3 podía ejecutarse en
 mi máquina; no muy felizmente, pero podía.
22 La Cara Oculta de Delphi

   Durante la redacción de “La Cara Oculta…” tuve el placer de impartir unos cuantos
   cursos de programación con Delphi. En cada curso aprendí algo, por lo que es de
   justicia mencionar a todos los profesionales y estudiantes que asistieron a los mis-
   mos.

   Dos personas han resultado ser imprescindibles en la revisión del libro. Nuevamente,
   Octavio Hernández ha tenido que soportar largas charlas cada vez que se me ocurría
   “una idea genial”. Muchos de los ejemplos que utilizo son fruto de su imaginación;
   además, le debo el título del libro. Octavio, desgraciadamente, no comparte mi aver-
   sión a C++: nadie es perfecto. Y Marta Fernández ha tenido el mérito de hacerme
   comprender que el sentido del humor no es mi punto fuerte. Si este libro resulta al
   final “legible” e “inteligible” es gracias a ella. A propósito, Marta tampoco es per-
   fecta: le he dicho que si acertaba con la lotería le daría la mitad, y no se lo ha creído.

   Finalmente, de no ser por Danysoft International, este libro no hubiera visto la luz,
   literalmente. Estuvieron las copias de evaluación, las horas de prácticas en red con
   los más diversos sistemas de bases de datos ... y el apoyo personal de Martha y José
   Luis Castaño al autor, todas las veces que éste pensó que hacer libros de Informática
   en España era como escribir frases en la arena de una playa.

   A todos, gracias.


                                                                            Ian Marteens
                                                                Pamplona, Agosto de 1997
Prólogo a la Segunda Edición

 Uno escribe un libro cuando siente que tiene algo interesante que contar ... y claro,
 cuando hay alguien dispuesto a leerlo, y tienes el tiempo disponible, y alguien te
 ofrece dinero por hacerlo ... Uno escribe una segunda edición cuando se da cuenta de
 todo lo que faltaba en la primera. Así que quiero dar las gracias en primer lugar a
 todos los lectores de la primera edición, por la cálida acogida que le dieron a este
 libro, y por hacerme llegar todos sus consejos, sugerencias y comentarios.

 Un libro de este tamaño no puede ser obra exclusiva de la experiencia de una sola
 persona. Aquí está reflejado el trabajo de muchos programadores que tuvieron a bien
 compartir sus conocimientos conmigo. Me gustaría mencionarlos a todos, pero la
 lista es larga y temo dejarme a alguien en el tintero. Gracias de todos modos.

 Agradecimientos especiales a Octavio Hernández, que ha sufrido la revisión de estas
 páginas sin saltarse un capítulo. Después de ver todos los errores que ha encontrado,
 he decidido matricularme en clases nocturnas de Expresión Escrita. Como único
 podré pagárselo es revisando sus tres próximos libros.


Para más ejemplos y actualizaciones...
 Es inevitable que se quede algo en el tintero al terminar un libro. Por este motivo, he
 decidido mantener una página Web en la dirección www.marteens.com. Consulte
 periódicamente esta página para nuevos ejemplos y ampliaciones del material cu-
 bierto en este libro.


                                                                         Ian Marteens
                                                               Madrid, Agosto de 1998
Who is the third who walks always beside you?
When I count, there are only you and I together
     But when I look ahead up the white road
There is always another one walking beside you
     Gliding wrapt in a brown mantle, hooded
   I do not know whether a man or a woman,
 — But who is that on the other side of you?

                 T.S. Eliot, The Waste Land
Œ
Entorno y Herramientas
    • ¿Es Delphi su lenguaje?
    • Herramientas y utilidades
    • Unidades, proyectos y paquetes
    • Sistemas de bases de datos
    • El Motor de Datos de Borland




       Parte
Capítulo




                                                                            1
                         ¿Es Delphi su lenguaje?


 E       STIMADO LECTOR:     si está leyendo estas líneas, es muy probable que haya
        comprado el libro y tenga claro que la mejor forma de abordar su próximo
        proyecto de programación es utilizar Delphi. Puede también que hayan im-
 puesto Delphi en su departamento y no le quede otro remedio que aprenderlo lo
 mejor posible. Pero cabe la posibilidad de que esté hojeando este libro en la tienda, y
 que todavía tenga dudas acerca de cuál es el lenguaje de programación que más le
 conviene para sus aplicaciones de bases de datos.

 Si está usted convencido de que Delphi es el lenguaje que necesita, adelante: sáltese
 esta introducción y entre en materia en el siguiente capítulo. Para los que decidan
 seguir leyendo, describiré en este capítulo las principales características de Delphi
 como herramienta de desarrollo, comparándolo con otros lenguajes y entornos
 cuando sea necesario. Espero entonces que este breve resumen le sea de utilidad.


Breve historia de un lenguaje llamado Delphi
 Delphi 1 salió al mercado en la primavera del 95. Estaba diseñado para ejecutarse en
 Windows 3.1, aunque era compatible con las versiones beta de Windows 95, que aún
 no se había comercializado. Fue el primer entorno de desarrollo RAD que ofrecía un
 compilador de código nativo. El lenguaje en que se basaba, como todos sabemos, era
 Pascal; de hecho, internamente el compilador definía directivas de compilación como
 VER80, para indicar que se consideraba la versión 8 de Turbo Pascal. Se comerciali-
 zaron dos versiones: la Desktop y la Client/Server. Ambas incluían un producto de
 Borland que ya se distribuía con ciertas versiones del Borland C++: el Motor de
 Bases de Datos de Borland, o Borland Database Engine (BDE). Este era un conjunto
 de DLLs que permitían el acceso funcional a dBase, Paradox, fuentes de datos
 ODBC y diversos sistemas SQL: Oracle, InterBase, Informix y Sybase. En la versión
 Desktop, sin embargo, no se incluían los controladores necesarios para acceder a
 bases de datos en un servidor, conformándose con las bases de datos locales y
 ODBC.
30 La Cara Oculta de Delphi

   Aunque en el momento de la aparición de Delphi 1 Visual Basic llevaba unos cuan-
   tos años en el mercado, la nueva herramienta tuvo una clamorosa acogida en la co-
   munidad de programadores. Por primera vez se alcanzaban velocidades de ejecución
   profesionales en programas desarrollados con el paradigma RAD. Por primera vez,
   un lenguaje RAD era totalmente extensible, permitiendo sin ningún tipo de manio-
   bras de distracción el acceso al temido API de Windows. Por primera vez, un len-
   guaje basado en componentes permitía crear también esos componentes, sin necesi-
   dad de recurrir a otro entorno de programación

   La siguiente versión de Delphi apareció también en la primavera (¡qué romántico!)
   del 96. El principal avance fue la conversión del compilador para generar aplicacio-
   nes de 32 bits, para Windows 95 (que todos pensábamos que iba a ser Windows 96) y
   para Windows NT. Además, se incluyó una fase de optimización de código, todo un
   lujo para un lenguaje compilado, mientras Visual Basic 4 seguía generando código
   interpretado. La metodología de programación experimentó mejoras importantes: la
   inclusión de módulos de datos, el Depósito de Objetos, el Diccionario de Datos, la
   herencia visual, etc. Y, gracias a la retroalimentación por parte de los programadores,
   los componentes existentes se hicieron más potentes y manejables. Se incluyó tam-
   bién la posibilidad de crear controladores y servidores de automatización, para apro-
   vechar las nuevas características de OLE de Windows 95 y NT. El Motor de Datos
   se aumentó con un controlador para DB2. Posteriormente, en ese mismo año, se
   realizó una actualización de Delphi con el número de versión 2.01 que, además de
   corregir errores, incluyó el Internet Solutions Pack, un conjunto de controles Acti-
   veX para aplicaciones de Internet.




   En mayo del 97 (¡también primavera!), después de una tensa espera, apareció la ver-
   sión 3. Las novedades se centraron en tres campos: la tecnología de paquetes (pack-
   ages), el aprovechamiento de la tecnología OLE (ActiveX, automatización, bases de
   datos en múltiples capas) y la programación para servidores Web. El objetivo global
¿Es Delphi su lenguaje? 31

 de todas estas incorporaciones fue convertir a Delphi en un verdadero entorno de
 desarrollo cliente/servidor, permitiendo la programación de aplicaciones que se
 ejecutan en el servidor. El Motor de Datos siguió añadiendo formatos: en aquel
 momento le tocó a Access y a FoxPro. Por otra parte, la arquitectura de acceso a
 datos fue modificada para facilitar el desarrollo de componentes de acceso a datos
 que dejaran a un lado el BDE. En esta línea, Borland lanzó Delphi/400, para acceder
 a bases de datos de AS/400, que utilizaba la técnica de saltarse el BDE.

 Al poco tiempo, Borland lanzó una versión de actualización de Delphi, con el nú-
 mero de serie 3.01. Además de la corrección de bugs, incorporaba un nuevo compo-
 nente, TMIDASConnection, para permitir el desarrollo de aplicaciones en múltiples
 capas en redes TCP/IP. Con este componente, se podía evitar la instalación y confi-
 guración de DCOM en redes mayoritariamente formadas por terminales Windows
 95. También hubo un parche, el 3.02, que corrigió algunos problemas relacionados
 con la tecnología Midas y con los dichosos controles del Internet Explorer, que iban
 cambiando de versión mes tras mes. Una versión intermedia del BDE, la 4.51 que
 apareció con Visual dBase 7, añadió el soporte nativo para Access 97, pues la versión
 incluida en Delphi solamente soportaba Access 95.

 Finalmente, en julio del 98, Delphi 4 vio la luz. ¡En verano, no en primavera, por
 primera vez! Delphi 4 ha mejorado ostensiblemente el entorno de programación y
 desarrollo, al añadir el Explorador de Código, las facilidades de completamiento de
 clases, etc. Hay mejoras en el lenguaje, pero usted no las notará en su programación
 cotidiana. Hay novedades en los controles visuales, como el soporte de dockable win-
 dows (ponga aquí su traducción preferida) y las listas de acciones. En el apartado de
 bases de datos, se ha añadido soporte para las extensiones de objetos de Oracle 8 (¡la
 única herramienta RAD que ofrece este soporte, por el momento!) y se ha oficiali-
 zado el soporte de Access 97. La tecnología Midas se ha beneficiado de adelantos
 impresionantes, tanto en estabilidad como en posibilidades de conexión: ahora es
 posible utilizar CORBA como mecanismo de enlace en aplicaciones multicapas y hay
 soporte para Microsoft Transaction Server. También se ha mejorado el sistema de
 base de datos en el cliente de Midas, con la posibilidad de utilizar tablas anidadas,
 campos agregados, etc. No estamos, sin embargo, ante cambios revolucionarios: es
 muy difícil mejorar algo que ya era muy bueno.


¿Es Delphi un lenguaje “sencillo”?
 La respuesta al título de la sección depende de lo que usted quiera hacer con él.
 ¿Quiere montar un mantenimiento simple, con objetos que se pueden representar en
 registros independientes? En ese caso, sí, es muy fácil. ¿Quiere trabajar sobre un
 esquema relacional complejo, con referencias complicadas entre tablas, estructuras
 jerárquicas y todo eso? Bueno, con un poco de disciplina, la aplicación se desarrolla
 en poco tiempo; es fácil plantearse una metodología de trabajo, y el resultado será un
32 La Cara Oculta de Delphi

   programa “robusto”, que es algo de agradecer. ¿Quiere que el programa anterior sea
   independiente del formato de bases de datos subyacente, que se acople lo mismo a
   sistemas locales, como Paradox y dBase, que a Oracle, InterBase o MS SQL Server?
   Entonces, amigo mío, necesita leer este libro, para que sepa en qué terreno se ha
   metido.

   El problema no reside en Delphi, pues las mismas dificultades se le presentarán con
   C++ Builder, Visual Basic ó PowerBuilder. La causa de las complicaciones es, a mi
   entender, el modelo de programación y acceso concurrente que es necesario dominar
   para este tipo de aplicaciones. El programador de bases de datos locales (léase Cli-
   pper, Paradox, los distintos COBOL para PCs, etcétera) aborda las cuestiones de
   concurrencia imponiendo bloqueos en cada registro antes de editarlos. En el 95 por
   ciento de los casos, no se plantea la garantía de atomicidad de las actualizaciones
   compuestas, ni la recuperación en transacciones, ni el elevar al máximo la concurren-
   cia de la aplicación (conozco aplicaciones de facturación escritas en Clipper “para
   red” que sólo dejan facturar desde un puesto a la vez). Por supuesto, al programador
   que solamente ha trabajado en este tipo de entorno le cuesta más acostumbrarse a
   distinguir entre bloqueos optimistas, pesimistas y arquitecturas multigeneracionales.
   Este libro tiene el propósito de ayudar en el aprendizaje de estos conceptos.

   En las secciones que vienen a continuación analizaremos en detalle cada una de las
   principales características de Delphi.


Programación orientada a objetos verdadera
   A 28 años de la definición del primer lenguaje de programación orientado a objetos,
   y a casi 10 años de la popularización de sus conceptos con la aparición de C++,
   nadie duda ya de las grandes ventajas aportadas por este estilo de programación y
   pensamiento. A pesar de esto, muchos de los lenguajes populares RAD no soportan
   verdaderamente la programación orientada a objetos. Para que un lenguaje sea
   orientado a objetos debe dar soporte a estas tres características:

       1. Encapsulación
       2. Herencia
       3. Polimorfismo

   En particular, Visual Basic no permite la herencia, en ninguna de sus versiones. VB
   está basado completamente en el modelo COM, propuesto por Microsoft. En este
   modelo, el concepto fundamental es el de interfaz: un conjunto de funciones que
   deben ser implementadas por cada objeto perteneciente a una clase determinada.
   Otros modelos de objetos, como CORBA y JavaBeans, admiten que una clase herede
   las características de otras, lo cual no sucede en COM.
¿Es Delphi su lenguaje? 33

 Delphi incorpora un modelo completo de programación orientada a objetos, inclu-
 yendo encapsulación, herencia simple y polimorfismo. En este sentido Delphi se
 puede comparar con lenguajes que son paradigmas de ese estilo de programación,
 como C++. Por ejemplo, aunque Delphi no implementa la herencia múltiple al estilo
 C++, la versión 3 incluye en compensación el concepto de interfaces, que se encuentra
 en lenguajes modernos como Java, y que puede utilizarse como mecanismo alterna-
 tivo en la gran mayoría de las aplicaciones prácticas de la herencia múltiple. El so-
 porte de interfaces hace posible la programación de objetos COM, controles Acti-
 veX, automatización OLE, etc.

 Por ser un lenguaje desarrollado cuando los conceptos de Programación Orientada a
 Objetos han alcanzado su madurez, Delphi ofrece técnicas de programación que no
 se encuentran en lenguajes más antiguos como C++. Por ejemplo, Delphi imple-
 menta como parte fundamental de su arquitectura los constructores virtuales, mé-
 todos dinámicos, manejadores de mensajes y un estilo mucho más “humano” y fácil
 de trabajar con la Información de Tipos en Tiempo de Ejecución (RTTI). Estas ex-
 tensiones se han incorporado también al nuevo C++ Builder, de Inprise Corpora-
 tion, la compañía antes conocida como Borland International1.


Arquitectura integrada de componentes
 Una de las principales características de Delphi es la arquitectura de sus componen-
 tes, que permite una completa integración de estos dentro del lenguaje. Los compo-
 nentes de Delphi están basados en clases desarrolladas en el propio lenguaje; no hay
 que utilizar otros entornos de programación para crear o extender componentes.
 Otra consecuencia es que el código de estas clases se ejecuta dentro del mismo espa-
 cio de direcciones de la aplicación, con la consiguiente ventaja en necesidades de
 memoria y tiempo de ejecución. Al conjunto de componentes básicos de Delphi se le
 denomina la Biblioteca de Componentes Visuales; en inglés, Visual Component Library, ó
 VCL.

 Visual Basic utiliza como componentes los llamados controles ActiveX, que Delphi
 también admite. Desde el punto de vista de su implementación, los componentes
 ActiveX son objetos COM implementados en bibliotecas de enlace dinámico, o
 DLLs. Un objeto COM (Component Object Model), a su vez, es un objeto con un for-
 mato binario estándar definido por Microsoft, que permite que diferentes lenguajes
 de programación hagan uso de las propiedades, métodos y eventos del mismo. Esta
 es una buena idea, que ahora llega a su madurez al implementarse el llamado DCOM,
 o Distributed COM, que permite la activación y uso de objetos remotos en red.


 1 ¿Os imagináis a Mr. Yocam cantando Purple Rain en la próxima conferencia de Borland ...
 ejem, perdón ... de Inprise?
34 La Cara Oculta de Delphi

   Sin embargo, este modelo tiene sus luces y sus sombras. Anteriormente hemos men-
   cionado uno de sus defectos: no hay soporte directo de herencia, lo cual limita la
   extensibilidad de las clases. Hay otro inconveniente importante de orden práctico: los
   controles ActiveX se implementan como DLLs de Windows. Una DLL es, desde el
   punto de vista del enlazador (linker), un sistema autoconsistente; esto quiere decir que
   si implementamos un control ActiveX en C, el control debe cargar con el runtime de
   C; si lo implementamos en Delphi o VB5/6, la librería básica de estos lenguajes de-
   berá estar presente en tiempo de ejecución. Si nuestra aplicación está basada com-
   pletamente en este tipo de recursos y tenemos que utilizar (como es lo típico) unas
   cuantas decenas de ellos procedentes de las más diversas fuentes, piense en el gasto
   de recursos en que incurriremos.

   Por el contrario, los componentes VCL se integran directamente dentro de los eje-
   cutables producidos por Delphi y por C++ Builder. No tenemos que cargar con
   copias duplicadas de una biblioteca de tiempo de ejecución. Las llamadas a métodos,
   propiedades y eventos transcurren de modo más eficiente, pues no tienen que pasar
   por la capa OLE. Además, son completamente extensibles por medio de la herencia.


Delphi genera controles ActiveX
   A pesar de todo lo comentado en la sección anterior, Delphi ofrece, a partir de la
   versión 3, lo mejor de ambos mundos: los controles VCL pueden ser convertidos,
   mediante un sencillo paso automático, en controles ActiveX. Hasta el momento, el
   mercado de componentes ha estado orientado a la producción de controles ActiveX;
   si tanto Delphi como VB podían utilizar estos controles, y VB no tenía capacidad
   para trabajar con controles VCL, era evidente que los fabricantes de componentes
   producirían controles compatibles con estos dos lenguajes. Normalmente, estos
   controles se programaban en C/C++, y todo el mecanismo de generación de interfa-
   ces y tablas de métodos virtuales era manual y tedioso.

   Al introducir el concepto de interfaces, Delphi da soporte directo a la programación
   de objetos COM. El proceso de implementar una interfaz consiste en declarar una
   clase que incluya en la lista de ancestros la interfaz que se va a implementar, y en
   suministrar cuerpos para los métodos de la interfaz. Delphi tiene clases predefinidas
   que proporcionan la mayoría de los métodos requeridos por los controles ActiveX y
   otras interfaces COM comunes, además de expertos que facilitan el desarrollo.


Tratamiento de excepciones
   El tratamiento de errores mediante excepciones es la alternativa moderna al trata-
   miento tradicional mediante códigos de retorno de errores. Gracias a esa técnica, se
   evita mezclar la lógica de control del algoritmo con las instrucciones de salto de la
¿Es Delphi su lenguaje? 35

 detección de errores por medio de códigos de estado. Tanto Delphi como VB im-
 plementan excepciones, pero solamente Delphi ofrece un conjunto de instrucciones
 estructuradas correctamente desde el punto de vista del diseño de lenguajes. El di-
 seño de las excepciones de VB, por el contrario, está basado en el sistema tradicional
 de Basic (¡que no es un lenguaje estructurado!) y sufre la influencia del carácter inter-
 pretado del código generado, en las versiones anteriores a la actual.


Velocidad de ejecución
 Delphi, con mucho, sigue siendo el más rápido de los lenguajes RAD. En pruebas
 realizadas por una prestigiosa revista de Informática, se constató que Delphi es de 3
 a 6 veces más rápido que Visual Basic 5 a pesar de que, gracias al compilador incor-
 porado en la esa versión, los programas de VB5 pueden ejecutarse hasta 20 veces
 más rápido que antes (según la propia Microsoft). La versión 4 de Delphi es la ter-
 cera versión de este producto que genera código de 32 bits, por lo cual estamos ante
 un compilador más estable y confiable. Según pruebas realizadas con Delphi 4 y
 Visual Basic 6, se sigue manteniendo la proporción 5:1 en las velocidades de ejecu-
 ción de los programas desarrollados con estos sistemas.

 Delphi comparte la misma etapa final de optimización y generación de código nativo
 que la línea de compiladores de C/C++ de Borland. Las optimizaciones implemen-
 tadas por estos compiladores son muy sofisticadas. Se incluye la detección de subex-
 presiones comunes a nivel local y global, la optimización de registros, la detección de
 invariantes de bucles, etc.

 En el área de la Automatización OLE, es de destacar que a partir de la versión 3 se
 puede trabajar con las interfaces de objetos COM utilizando la v-table: la tabla de
 punteros a funciones de la interfaz. Esta mejora a OLE permite alcanzar mayor velo-
 cidad en las llamadas a funciones en objetos con interfaces duales, en contraste con
 la técnica anterior, que pasaba por invocar una función del API de Windows.


Velocidad de compilación y enlace
 Uno de los puntos fuertes de Delphi es la velocidad con que se compilan y enlazan
 las aplicaciones. En este aspecto no tiene parangón con los sistemas competidores. Y
 es que la velocidad de compilación es muy importante, tratándose de sistemas de
 diseño y programación interactivos. El formato de unidades de compilación nativo
 de Delphi, el formato dcu, permite alcanzar mayores velocidades de compilación y
 enlace al estar basado en el formato obj, especificado por Intel hace ya muchos años,
 con la mente puesta en técnicas obsoletas de enlace. No obstante, Delphi acepta y
 genera ficheros obj (a partir de la versión 2), incluso si han sido generados por otros
 lenguajes. Delphi ofrece un enlazador “inteligente”, que es capaz de eliminar todo el
36 La Cara Oculta de Delphi

   código que no va a ser utilizado por la aplicación. ¿Imagina las consecuencias? Apli-
   caciones más compactas, que se cargan más rápido y que ocupan menos espacio en
   memoria RAM y en el disco.

   A partir de la versión 3 de Delphi, los tiempos de enlace disminuyen aún más gracias
   a los packages. Estos packages, o paquetes, se pueden utilizar opcionalmente, y son
   DLLs que contienen el código de componentes. De esta forma, dos aplicaciones
   escritas en Delphi que se ejecutan en paralelo en la misma máquina utilizan una sola
   copia en memoria del código de las librerías de tiempo de ejecución del lenguaje.
   Como consecuencia, el tamaño físico de los ejecutables disminuye dramáticamente,
   junto con el tiempo invertido por el enlazador en generar el fichero.

   De forma adicional, el Entorno de Desarrollo es mucho más rápido y eficiente. Este
   programa está escrito en Delphi (¡hay que predicar con el ejemplo!) y utiliza la VCL.
   Antes, la librería de componentes, la complib.dcl (16 bits) ó complib32.dcl (32 bits), y el
   Entorno de Desarrollo utilizaban copias diferentes de la VCL. Ahora, gracias a los
   paquetes, este código se comparte, de modo que disminuyen las necesidades de me-
   moria. A esto añádale que cuando se depura una aplicación nos ahorramos otra copia
   de la VCL en memoria.


Retroalimentación inmediata
   Se supone que uno de los objetivos fundamentales de un sistema RAD es permitir
   que el programador pueda hacerse una idea, mientras desarrolla su aplicación, del
   aspecto que va a tener la misma, sin necesidad de efectuar el tedioso ciclo de compi-
   lación/enlace/puesta a punto. ¿Ha visto alguna vez la rejilla de datos de Visual Basic
   durante el tiempo de diseño? Este control no es capaz de mostrar la disposición
   visual que tendrá en tiempo de ejecución, por lo que el programador debe trabajar a
   ciegas. Esto, hay que aclarar, no es una consecuencia del lenguaje en sí, sino de un
   mal diseño de la librería. En cambio, todos los controles de bases de datos de Delphi
   ofrecen una retroalimentación inmediata, en tiempo de diseño, de su aspecto final.
   Incluso al establecer relaciones master/detail entre varias tablas, es posible explorar
   todas ellas de forma sincronizada, utilizando el Editor de Campos. Del mismo modo,
   cualquier modificación en el formato de campos se refleja inmediatamente en los
   controles visuales afectados, e incluso los campos de búsqueda (lookup fields), que
   permiten representar referencias entre tablas, se pueden visualizar durante el diseño
   de la aplicación.


El Depósito de Objetos y la herencia visual
   La herencia visual es una potente técnica disponible cuando utilizamos plantillas del
   Depósito de Objetos de Delphi. Es una técnica dirigida tanto a desarrolladores aisla-
¿Es Delphi su lenguaje? 37

 dos como a grupos de trabajo. El comportamiento típico de otros entornos de desa-
 rrollo en relación con el uso de plantillas y expertos, consiste en que la aplicación que
 solicita una plantilla obtenga una copia local del código necesario. Si posteriormente
 se realizan modificaciones en la plantilla, estos datos no se propagan a la copia local,
 por lo cual es necesario repetir los cambios en esta copia, o comenzar nuevamente
 desde cero.

 Delphi implementa un Depósito de Objetos, en el cual pueden colocarse plantillas
 desarrolladas por nosotros mismo e incluso asistentes desarrollados en el propio
 lenguaje. Delphi permite, al traer plantillas desde el Depósito, hacer una copia, utili-
 zar el original o crear un objeto por herencia a partir del objeto plantilla. Incluso
 permite llamadas a eventos heredados con una sintaxis simple y sin demoras en
 tiempo de ejecución.




 Por supuesto, Visual Basic no implementa ningún tipo de herencia, mucho menos la
 herencia visual.


Aplicaciones distribuidas
 Quizás la novedad más importante que introdujo Delphi 3, y que sigue rindiendo
 frutos en la versión 4, es la posibilidad de crear aplicaciones de bases de datos mul-
 ticapas, en las que todas las peticiones de datos se dirigen a un servidor de aplicacio-
 nes remoto. Este servidor se comunica con los clientes utilizando DCOM, OLEn-
 terprise (un producto cuya versión de evaluación se incluye con Delphi), TCP/IP o
 CORBA. El Motor de Datos de Borland reside, en esta configuración, en el ordena-
 dor en que se ejecuta este servidor remoto. Si vamos a utilizar DCOM como proto-
 colo de transporte, por ejemplo, el ordenador que actúa como servidor debe ejecutar
 Windows NT 4 o Windows 95 con los parches DCOM que ofrece Microsoft en su
 Web, o el nuevo Windows 98. Los clientes, o estaciones de trabajo, no necesitan el
 Motor de Datos, ahorrándose el desarrollador la instalación y configuración del
38 La Cara Oculta de Delphi

   mismo. ¡Piense cuanto tiempo se ahorra si se trata de instalar una aplicación de bases
   de datos con decenas de usuarios accediendo a la misma! El conjunto de técnicas que
   hacen posible esta comunicación se conoce como Midas (Multi-tiered Distributed Appli-
   cation Services), y le dedicaremos todo un capítulo en este libro.

   A propósito del Motor de Datos, ahora Delphi puede acceder directamente a bases
   de datos de Access y FoxPro, si existe una copia del JetEngine de Microsoft en el
   ordenador. Se siguen soportando todos los formatos anteriores: Paradox, dBase,
   InterBase, Oracle, Informix, DB2, Sybase y MS SQL Server. El Motor de Datos ha
   sido mejorado para permitir la adición de nuevos controladores SQL-Links, y la ar-
   quitectura de la VCL ha sido modificada para permitir la incorporación incruenta de
   sustitutos del BDE, tales como Titan, Apollo, etc.


Componentes de Delphi
   Por último, se han incorporado en Delphi componentes para dar respuesta a las prin-
   cipales necesidades de las aplicaciones de gestión: gráficos, tablas cruzadas para so-
   porte de decisiones, informes. ¿Gráficos tridimensionales? No hay problema. ¿Los
   quiere en pantalla?, tenemos TChart. ¿Alimentados por una base de datos?, entonces
   necesita TDbChart. ¿En un informe?, para eso está TQrChart. Y no tema, que estos
   controles son componentes VCL, nada de controles ActiveX ni cosas semejantes.

   Una nueva página, Decision Cube, contiene componentes para sofisticados análisis de
   datos dinámicos. Estos componentes serán fundamentales en la programación de
   aplicaciones de negocios, que ofrezcan posibilidades de análisis multi-dimensional, lo
   que comúnmente se clasifica como técnicas de data warehousing.




   QuickReport, la herramienta de creación e impresión de informes, también ha sido
   mejorada y aumentada. Ahora es más fácil el diseño de la página de impresión, con
   un componente más “visual”, y un editor de propiedades más amigable. Se han in-
   cluido componentes para imprimir imágenes de forma más rápida y conveniente,
   texto con formato e incluso gráficos de negocios. También se puede guardar el resul-
   tado en formato HTML, para ser distribuido en la Web.
¿Es Delphi su lenguaje? 39

La versión cliente/servidor de Delphi permite, finalmente, la programación de ex-
tensiones para servidores Web. De este modo, es muy sencillo exportar datos que
pueden ser visualizados en Internet, sin necesidad de comprar herramientas adicio-
nales.




En esta misma línea se incluye un amplio conjunto de componentes para el desarro-
llo de todo tipo de aplicaciones clientes de Internet: correo electrónico, clientes de
FTP, visores para el formato HTML, etc.
Capítulo




                                                                                    2
                      Herramientas y utilidades


  E       L PROPÓSITO DE ESTE BREVE CAPÍTULO        es presentar las herramientas que
          acompañan a Delphi, y las novedades del propio Entorno de Desarrollo
          dignas de mención en la versión 4. No es mi intención entrar en detalles con
  estas herramientas: mejor que leer una larga parrafada, es preferible familiarizarse
  con las mismas mediante la práctica.


Delphi y el teclado
  Nadie discute las ventajas de alcanzar una buena velocidad de edición y diseño con
  cualquier herramienta de programación. Es doloroso, en consecuencia, ver a ciertos
  programadores de Delphi sufrir calladamente mientras realizan determinadas opera-
  ciones que desconocen que se pueden realizar de una forma más sencilla. En esta
  sección menciono algunos trucos para acelerar el trabajo con el Entorno de Desa-
  rrollo.

  Comencemos por la adición de componentes a un formulario. Delphi ofrece, que yo
  conozca, cuatro formas diferentes de traer un componente a un formulario, aunque
  muchos programadores solamente aprovechen una o dos:

  •   Realizar un doble clic sobre el componente en la Paleta: Se añade un nuevo componente
      con el tamaño predeterminado y situado sobre el centro del componente activo
      del formulario. Supongamos que tiene un panel que ocupa todo el formulario
      (Align=alClient), y que quiere añadir una barra de mensajes debajo del panel. Si
      pincha la barra sobre el panel, la barra pertenecerá al panel, no al formulario. La
      solución es seleccionar el formulario (ver truco con la tecla ESC más adelante), ir
      al botón TStatusBar y hacer el doble clic.
  •   Realizar un clic en la Paleta y un clic sobre el futuro padre del componente: El componente
      se crea en el sitio indicado, pero con un tamaño predeterminado. Es la mejor
      forma de colocar botones, cuadros de edición y otros componentes que se bene-
      fician con una apariencia estándar.
  •   Realizar un clic en la Paleta, y arrastrar sobre el padre para definir el tamaño: Este método
      ahorra tiempo cuando se va a utilizar un tamaño diferente del predefinido. Es el
42 La Cara Oculta de Delphi

       método soportado por Visual Basic, y el único que muchos programadores prin-
       cipiantes utilizan.
   •   Pulsar la mayúscula y realizar un clic en la Paleta: Con este método, el botón de la
       Paleta queda seleccionado, aún después de añadir el componente. Así se pueden
       traer varias instancias del mismo componente con menos clics del ratón. Para
       volver al modo de selección, hay que pulsar el botón con la flecha de cursor que
       aparece a la izquierda de la Paleta de Componentes.




   Las siguientes combinaciones de teclas y ratón sirven durante el diseño de formula-
   rios, y se aplican cuando hay algún componente seleccionado, y el formulario de
   diseño está activo, con la barra de títulos en color azul:

        CTRL+FLECHA     Mueve el componente seleccionado, píxel a píxel
        MAY+FLECHA      Cambia el tamaño del componente seleccionado, píxel a píxel
                ESC     Selecciona el “padre” del componente activo
         MAY+RATÓN      Selecciona el formulario, que puede estar oculto bajo varias capas de
                        componentes

   También podemos activar el movimiento o cambio de tamaño de un componente
   píxel a píxel si pulsamos la tecla ALT mientras lo manipulamos con el ratón.

   Para el Editor de Código también existen trucos. Cuando hay un bloque selecciona-
   do en el editor, pueden aplicarse las siguientes operaciones:

           CTRL+K P Imprime el bloque
            CTRL+K I Aumenta el margen del bloque
           CTRL+K U Disminuye el margen del bloque
Herramientas y utilidades 43

Y hablando de bloques, ¿sabía que se pueden definir bloques “rectangulares” en el
Editor de Código? El modo de definición de los bloques se controla mediante los
siguiente comandos:

        CTRL+O+C     Bloques por columnas
        CTRL+O+I     Bloques “inclusivos” (¡pruébelos!)
       CTRL+O+K      Bloques no inclusivos (los de toda la vida)
       CTRL+O+L      Bloques por líneas

¿Tiene una unidad mencionada en la cláusula uses de un formulario, y quiere abrir el
fichero con el código fuente? Si el fichero se encuentra en el directorio activo, pulse
la combinación CTRL+INTRO, estando situado sobre el nombre de la unidad, y Delphi
se encargará del asunto. Pulsando CTRL+K y un número del cero al nueve, creamos
una marca de posición a la cual podemos regresar en cualquier momento pulsando
CTRL+Q, más el número en cuestión.

Pero quizás la mayor sorpresa es descubrir que Delphi ofrece un mecanismo rudi-
mentario para grabar y ejecutar una macro de teclado:

     CTRL+MAY+R Inicia y termina la grabación de una macro
     CTRL+MAY+P Reproduce la última macro grabada

Por último, las siguientes combinaciones de teclas pueden resultar útiles para no
perdernos dentro de la maraña de ventanas y diálogos de una sesión típica de desa-
rrollo con Delphi:

       F11    Trae al Inspector de Objetos al primer plano
       F12    Intercambia representación visual de un formulario con su código
  MAY+F12     Muestra la lista de formularios de un proyecto
  CTRL+F12    Muestra la lista de unidades de código de un proyecto
     ALT+0    Muestra todas las ventanas abiertas del Entorno de Desarrollo

La tecla F12 funciona no sólo con el Editor de Código y los formularios en diseño,
sino también con el editor de paquetes (ver el capítulo 3) y con el editor de Bibliotecas
de Tipos. Finalmente, el nuevo comando Search|Find in files nos permite buscar tex-
tos dentro de ficheros, que pueden ser los del proyecto activo o los de un directorio
determinado.

  He dejado para el final el mejor truco: ¿sabía usted que en el fichero de ayuda
  aparecen estos comandos, y muchos más, perfectamente documentados? Quizás
  merezca la pena que pierda unos minutos aprendiendo trucos de teclado, pues le
  harán ser más productivo.
44 La Cara Oculta de Delphi

Code Insight: ayuda durante la edición
   El Editor de Código ha experimentado mejoras sustanciales a partir de Delphi 3.
   Una de ellas es el uso de plantillas de código, o code templates. Sitúese en el editor y
   pulse la combinación de teclas CTRL+J. En respuesta, aparece una lista de nombres
   de plantillas. Cuando seleccionamos una, se copia el código asociado, y el cursor se
   desplaza a un punto que depende de la definición de la plantilla.




   Otra forma de lograr el mismo efecto es tecleando primero el nombre de la plantilla
   y pulsando entonces CTRL+J; pruebe, por ejemplo, con whileb, que crea el esqueleto
   de un bloque while con una instrucción compuesta begin…end:
           while { Aquí se queda el cursor } do
           begin
           end;


   Aunque existe una gran variedad de plantillas predefinidas, también podemos añadir
   las nuestras. Las plantillas de código se configuran en el diálogo asociado al comando
   de menú Tools|Environment options, en la página Code Insight:




   El texto de las plantillas se guardan en el subdirectorio bin de Delphi, en el fichero
   delphi32.dci. Para definir una plantilla nueva, el programador debe pulsar el botón
Herramientas y utilidades 45

Add. En respuesta aparece un cuadro de diálogo que pide el nombre y la descripción
de la plantilla:




Luego, debe utilizarse el editor para suministrar el texto de la plantilla. La barra verti-
cal | sirve para indicar dónde debe quedar el cursor al ejecutarse la plantilla. Por
ejemplo:
        with T|.Create(Self) do
        try
        finally
           Free;
        end;


  Las definiciones de macros de Code Insight se almacenan en el fichero delphi32.dci,
  en el directorio bin de Delphi.

Pero seguramente el programador utilizará con mayor frecuencia las ayudas interacti-
vas de Delphi acerca de los métodos aplicables a un objeto, y de los parámetros de
los procedimientos y funciones. Cuando tecleamos el nombre de una variable de
objeto, o de un tipo de clase, y añadimos un punto, aparece una ventana emergente
con la lista de métodos y propiedades aplicables. Da lo mismo que el tipo del objeto
sea predefinido o haya sido creado por nosotros, con tal de que esté compilado.




Si quiere que aparezca esta ventana en cualquier otro momento, debe pulsar la com-
binación de teclas CTRL+ESPACIO.

Para los procedimientos, funciones y métodos, la ayuda se presenta cuando teclea-
mos el paréntesis de apertura a continuación del nombre de una rutina. La ventana
46 La Cara Oculta de Delphi

   de ayuda es una ventana de indicaciones (esos recuadros amarillos que se interponen
   en nuestro campo visual cuando dejamos tranquilo al ratón por un tiempo), con el
   nombre y tipo de los parámetros, según aparecen en la declaración de la rutina. Si se
   nos pierde la ventana, tenemos el comando de teclado CTRL+MAY+ESPACIO, para que
   reaparezca la ayuda:




   La misma combinación CTRL+ESPACIO, que nos ofrece ayuda para seleccionar méto-
   dos y propiedades, sirve para ayudarnos con los posibles valores de un parámetro
   cuando nos encontramos dentro de la lista de parámetros de un método, procedi-
   miento o función:




   Hay que utilizar con precaución esta técnica, porque en la lista de posibilidades apa-
   recen todas las constantes, variables y funciones de tipos compatibles, y esto incluye
   a las de tipo Variant, que salen hasta en la sopa.

   Ahora mencionaremos las novedades de Delphi 4. La primera es la presencia del
   nuevo Explorador de Código:
Herramientas y utilidades 47




Esta ventana muestra los símbolos definidos dentro de una unidad. Si está activa,
podemos realizar búsquedas incrementales de símbolos utilizando el teclado. Tam-
bién es útil para cambiar el nombre a un símbolo. Tenga en cuenta, no obstante, que
el cambio solamente se aplicará a la declaración, y que habrá que cambiar manual-
mente el código en los sitios donde se utiliza el símbolo. Ah, y si le molesta mucho
esta ventana, recuerde que puede arrastrarla fuera del Editor, o simplemente cerrarla.

La segunda novedad se conoce como Navegación por el Código. Si colocamos el
ratón (más bien, el puntero del mismo) sobre un símbolo, ya sea una variable, una
clase, un método, un procedimiento, aparece una indicación acerca de dónde está
definido tal símbolo.




Si además pulsamos la tecla CONTROL mientras estamos sobre el símbolo, éste adopta
la apariencia de un enlace HTML (¡ah, la moda!), y nos permite ir inmediatamente al
lugar donde ha sido definido o implementado. La historia de esta navegación se al-
macena en las listas desplegables asociadas al par de botones de la esquina superior
derecha del Editor, que nos permiten movernos hacia delante y hacia atrás por la
misma.

Por último, las combinaciones de teclas CTRL+MAY+ABAJO y CTRL+MAY+ARRIBA,
sirven para alternar rápidamente entre la declaración de un método en la interfaz de
una unidad, y su cuerpo, en la sección de implementación.
48 La Cara Oculta de Delphi

Class completion
   Class completion es otra de las técnicas de mejora de la productividad introducidas por
   Delphi 4. Como el lector conoce, los métodos de una clase deben definir sus cabece-
   ras dentro de la declaración de la misma, pero su cuerpo debe definirse por separado.
   Esto implica, casi siempre, navegar desesperadamente desde la sección de interfaz de
   la unidad a la sección de implementación, y un uso habilidoso de los comandos de
   copiar y pegar. Delphi nos releva de esta tortura cuando crea métodos de respuesta a
   eventos, pero nos deja abandonados cuando tenemos que definir otro tipo de méto-
   dos. Lo mismo sucede cuando queremos definir propiedades para una clase. La decla-
   ración de una propiedad debe ir precedida por la declaración de sus métodos de
   acceso. Estos, a su vez, llevan doble trabajo: la declaración de sus cabeceras y su
   posterior implementación. Es cierto que estas labores son más frecuentes durante la
   escritura de componentes ... pero todos tenemos derecho a una vida mejor.

   Delphi 4 ofrece la combinación CTRL+MAY+C para ayudarnos en estos menesteres.
   Supongamos que tecleamos la siguiente declaración de clase:
           type
              TYoQueSe = class(TCiertaClase)
              public
                 constructor Create(AOwner: TComponent);
                 destructor Destroy; override;
              published
                 property Entero: Integer;
                 property Vector[Index: Integer]: string;
              end;


   Hemos dejado incompletas las dos declaraciones de propiedades. Si ahora tecleamos
   CTRL+MAY+C, Delphi modifica la clase de esta manera:

           type
              TYoQueSe = class(TCiertaClase)
              private
                 FEntero: Integer;
                 function GetVector(Index: Integer): string;
                 procedure SetEntero(const Value: Integer);
                 procedure SetVector(Index: Integer; const Value: string);
              public
                 constructor Create(AOwner: TComponent);
                 destructor Destroy; override;
              published
                 property Entero: Integer read FEntero write SetEntero;
                 property Vector[Index: Integer]: string
                    read GetVector write SetVector;
              end;


   También añade, en la sección de implementación de la clase, un cuerpo para el cons-
   tructor, el destructor y para los tres métodos de acceso que ha generado. Incluso, en
   el caso de los métodos de acceso, se atreve a sugerirnos una posible implementación:
Herramientas y utilidades 49

         procedure TYoQueSe.SetEntero(const Value: Integer);
         begin
            FEntero := Value;
         end;




Herramientas de depuración
 Para desarrollar eficientemente aplicaciones con Delphi, es sumamente conveniente
 dominar las técnicas de depuración. Estas técnicas siguen siendo similares a las del
 depurador integrado en las primeras versiones de Turbo Pascal. Sin embargo, las
 diferencias quedan determinadas por la diferente estructura de los programas escritos
 para MS-DOS y Windows. En un programa para Windows es imposible seguir paso
 a paso la ejecución de todas las instrucciones del mismo. Hay un momento en que
 perdemos de vista el puntero de las instrucciones: cuando nos sumergimos en una
 rutina conocida como el ciclo de mensajes. A partir de este punto, recuperamos periódi-
 camente el control, cuando Delphi, C++ Builder ó Visual Basic ejecutan algunas de
 las respuestas a eventos, o cuando C++ ejecuta alguna función de respuesta o método
 asociado a mensajes.

 Por lo tanto, lo que debe saber el programador de Delphi es cómo interceptar al
 programa cuando pase por los sitios que le interesa, y para esto tiene dos posibi-
 lidades. La primera es establecer un punto de ruptura (ó breakpoint) en una instrucción,
 para lo cual puede pulsar la tecla F5 (CTRL+F8, si se utiliza a configuración de teclado
 tradicional de Borland), o ejecutar el comando de menú Run|Add breakpoint, estando
 seleccionada la línea en la cual nos queremos detener. Cuando el programa se ejecute
 y pase por esa línea, se detendrá, se activará el Entorno de Desarrollo, y podremos
 decidir qué hacer: evaluar el estado actual de las variables, seguir ejecutando paso a
 paso, detener el programa ... La otra posibilidad es utilizar el comando de menú
 Run|Run to cursor, o pulsar la tecla F4, estando situados sobre la línea deseada. El
 efecto es similar a colocar un punto de ruptura temporal, ejecutar el programa y
 liberar el punto una vez llegados al mismo.




 A un punto de ruptura se le puede asociar una condición de parada, que debe cum-
 plirse para que el programa detenga allí su ejecución, y un contador de pasadas, para
 activar el punto a las tantas veces que se pase por él. Los puntos de ruptura pueden
50 La Cara Oculta de Delphi

   controlarse con el comando de menú View|Breakpoints. El margen izquierdo del
   Editor de Código muestra también los puntos de ruptura y el estado de los mismos.

   Una vez que el programa se ha detenido temporalmente en un lugar determinado,
   comenzamos a seguirle la pista a las instrucciones por las que pasa. Tenemos a nues-
   tra disposición los siguientes comandos del menú Run:

                           Trace into (F7) Avanzar una instrucción. Si es una rutina y
                                            tenemos el código fuente, entramos en su
                                            interior.
                             Step over (F8) Igual a la anterior, pero esquivando el interior
                                            de las rutinas.
      Trace to next source line (MAY+F7) Ir hasta la siguiente línea de código disponible.

   También se puede pulsar F9, y dejar que el programa se ejecute hasta terminar o
   encontrar un punto de ruptura.

   La otra técnica importante nos permite conocer el contenido de las variables, atri-
   butos y propiedades del espacio de datos del programa. Los comandos Run|Evaluate
   y Add watch nos permiten evaluar dinámicamente una expresión ó inspeccionar cons-
   tantemente el valor, respectivamente.




   Recuerde también que, si se trata de una variable o propiedad de un objeto, basta con
   situar el cursor sobre una referencia a la misma en el código del programa para obte-
   ner su contenido en una ventana de indicaciones. También podemos utilizar el co-
   mando de menú Run|Inspect, que solamente está disponible en tiempo de ejecución,
   para mostrar una ventana como la siguiente con los datos, métodos y propiedades del
   objeto que deseemos:
Herramientas y utilidades 51

 Por último, Delphi 4 añade una nueva ventana de depuración: el event log, o registro
 de eventos que almacena y muestra opcionalmente los siguientes sucesos: carga y
 descarga de módulos por la aplicación, mensajes de Windows recibidos por nuestra
 aplicación, activación de puntos de rupturas y mensajes generados con el procedi-
 miento de Delphi OutputDebugString. ¿Recuerda que en la época de MS-DOS la téc-
 nica más potente de depuración era con frecuencia escribir en la consola mensajes
 del tipo “Killroy was here”? Ahora podemos retornar nuestra adolescencia gracias al
 registro de eventos.


Object Browser
 Uno de los grandes desconocidos del Entorno de Desarrollo de Delphi es el Explo-
 rador de Objetos; en inglés: Object Browser. Es una herramienta integrada en el entorno,
 que se ejecuta desde el comando de menú View|Browser. La información que se
 muestra con la misma se extrae del ejecutable de la aplicación, por lo que el proyecto
 debe haber sido compilado previamente para poder activar la utilidad.

 La siguiente figura muestra la ventana principal del Explorador. Consta de dos pane-
 les; en el de la izquierda se muestra la jerarquía de las clases incluidas en el proyecto,
 mientras que sus métodos, eventos y propiedades se muestran en el panel derecho.
 La barra de herramientas de la porción superior de la ventana sirve para restringir la
 información visualizada. Una posibilidad interesante es la navegación por referencias.




BDE Administrator
 El Administrador del Motor de Datos (BDE Administrator) es el programa necesario
 para configurar las opciones de acceso a bases de datos de Delphi. Esta aplicación
 también se instala cuando distribuimos el Motor de Datos con nuestras aplicaciones.
 Puede ejecutarse desde el grupo de programas de Delphi. También puede configu-
 rarse el menú Tools del entorno de desarrollo de Delphi para incluir el Administrador,
52 La Cara Oculta de Delphi

   si es que vamos a utilizarlo con frecuencia. Para configurar Tools ejecute el comando
   de menú Tools|Configure tools. En el cuadro de diálogo que aparece, pulse el botón
   Add para añadir la nueva opción. El ejecutable del Administrador, en mi ordenador,
   corresponde al fichero:

           C:Archivos de programaBorlandCommon FilesBDEBdeadmin.exe




   Para más detalles sobre esta herramienta, lea el capítulo sobre el Motor de Bases de
   Datos.


Database Explorer
   Para conocer la estructura de una base de datos, saber qué tablas contiene, qué co-
   lumnas, índices y restricciones se han definido para cada tabla, y para visualizar los
   datos almacenados en las mismas, Delphi ofrece Database Explorer: el Explorador de
   Bases de Datos. Para activar este programa desde Delphi, basta con seleccionar el
   comando de menú Database|Explore, pero también puede ejecutarse como utilidad
   independiente desde el grupo de programas de Delphi. En la versión cliente/servi-
   dor, en la que se incluye, como es lógico, el acceso a bases de datos SQL, la utilidad
   se nombra SQL Explorer.




   La ventana principal de la utilidad contiene dos páginas: Databases y Dictionary. En la
   primera es donde aparecen las distintas bases de datos asociadas a los alias persis-
Herramientas y utilidades 53

 tentes del Motor de Datos. El árbol del panel de la izquierda puede expandirse para
 mostrar jerárquicamente los objetos de la base de datos. Se pueden realizar modifica-
 ciones en todos estos objetos en el panel de la derecha.

 El Explorador de Bases de Datos también sirve para configurar el Diccionario de Datos.
 Esta entidad es utilizada por Delphi en tiempo de diseño; no tiene función alguna en
 tiempo de ejecución. En el Diccionario de Datos pueden almacenarse, en primer
 lugar, definiciones de conjuntos de atributos de campos. Los conjuntos de atributos se
 pueden asociar a los campos de las tablas al ser creados desde Delphi, y permiten
 uniformizar las propiedades de visualización, edición y validación de los mismos.
 También se consultan cuando arrastramos un campo sobre un formulario y Delphi
 crea un control de edición; el tipo del control puede determinarse de acuerdo a los
 atributos asociados.

 La otra operación importante con el Diccionario de Datos es la importación de bases de
 datos al diccionario. Cuando importamos una base de datos, se copian sus definicio-
 nes de tablas, campos e índices al Diccionario. Se pueden entonces asociar conjuntos
 de atributos a los campos, de modo tal que estos atributos se asocian automática-
 mente cuando se crean los campos. Cuando una base de datos ha sido importada,
 pueden también importarse las restricciones de integridad a determinadas propieda-
 des de los campos y tablas de Delphi. Esto es útil en la programación
 cliente/servidor, pues permite evaluar las verificaciones en los ordenadores clientes
 antes de ser enviadas, disminuyendo el tráfico en la red.

 Los datos del Diccionario por omisión se almacenan en formato Paradox, en la tabla
 bdesdd.db. Sin embargo, pueden crearse nuevos diccionarios en diferentes formatos,
 incluso en bases de datos cliente/servidor, y ser compartidos por todos los miem-
 bros de un equipo de desarrollo.


Database Desktop
 Sin embargo, mi herramienta preferida para crear tablas de Paradox y dBase sigue
 siendo Database Desktop, que acompaña a Delphi desde su primera versión. A pesar
 de la apariencia más moderna de Database Explorer, determinadas tareas se ejecutan
 más cómodamente y con mayor eficiencia con la “vieja” interfaz del Database
 Desktop. Por ejemplo, es muy fácil copiar tablas, modificar su estructura y editar su
 contenido. La siguiente figura muestra el diálogo de creación de una tabla en el for-
 mato de Paradox 7:
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi
La cara-oculta-de-delphi

Más contenido relacionado

Similar a La cara-oculta-de-delphi (20)

Manual de c# 3
Manual de c# 3Manual de c# 3
Manual de c# 3
 
Manual de C#
Manual de C#Manual de C#
Manual de C#
 
Libro csharp2
Libro csharp2Libro csharp2
Libro csharp2
 
Manual c#
Manual c#Manual c#
Manual c#
 
Manual c#
Manual c#Manual c#
Manual c#
 
MANUAL DE C#
MANUAL DE C#MANUAL DE C#
MANUAL DE C#
 
Manual2 de c#
Manual2 de c#Manual2 de c#
Manual2 de c#
 
MANUAL 1
MANUAL 1MANUAL 1
MANUAL 1
 
manual C#
manual C#manual C#
manual C#
 
Libro csharp
Libro csharpLibro csharp
Libro csharp
 
Manual C#
Manual C#Manual C#
Manual C#
 
manual 5
manual  5manual  5
manual 5
 
manual de c# (3)
manual de c# (3)manual de c# (3)
manual de c# (3)
 
c sharp
c sharpc sharp
c sharp
 
Manual_C#_3
Manual_C#_3Manual_C#_3
Manual_C#_3
 
El lenguaje de programación c++, apuntesprev
El lenguaje de programación c++, apuntesprevEl lenguaje de programación c++, apuntesprev
El lenguaje de programación c++, apuntesprev
 
Tutorial de Python - Pyar
Tutorial de Python - PyarTutorial de Python - Pyar
Tutorial de Python - Pyar
 
Librocsharp 141006120117-conversion-gate02
Librocsharp 141006120117-conversion-gate02Librocsharp 141006120117-conversion-gate02
Librocsharp 141006120117-conversion-gate02
 
Libro_Csharp.pdf
Libro_Csharp.pdfLibro_Csharp.pdf
Libro_Csharp.pdf
 
LibroCsharp.pdf
LibroCsharp.pdfLibroCsharp.pdf
LibroCsharp.pdf
 

La cara-oculta-de-delphi

  • 2.
  • 3. ...Mientras intentaba inútilmente atrapar un rayo de luz en los confines de una oscura galaxia, Ella escuchaba a los tres guardianes del secreto de la Pirámide, y con el Resplandor de sus manos me indicaba el camino de regreso a casa... A Naroa, porque sigo creyendo en ella.
  • 4.
  • 5. INDICE PRÓLOGO DEL AUTOR 19 CONVENIOS SINTÁCTICOS 21 ACERCA DE LA TERMINOLOGÍA EMPLEADA 21 AGRADECIMIENTOS 21 PRÓLOGO A LA SEGUNDA EDICIÓN 23 PARA MÁS EJEMPLOS Y ACTUALIZACIONES... 23 ENTORNO Y HERRAMIENTAS 27 1. ¿ES DELPHI SU LENGUAJE? 29 BREVE HISTORIA DE UN LENGUAJE LLAMADO DELPHI 29 ¿ES DELPHI UN LENGUAJE “SENCILLO”? 31 PROGRAMACIÓN ORIENTADA A OBJETOS VERDADERA 32 ARQUITECTURA INTEGRADA DE COMPONENTES 33 DELPHI GENERA CONTROLES ACTIVEX 34 TRATAMIENTO DE EXCEPCIONES 34 VELOCIDAD DE EJECUCIÓN 35 VELOCIDAD DE COMPILACIÓN Y ENLACE 35 RETROALIMENTACIÓN INMEDIATA 36 EL DEPÓSITO DE OBJETOS Y LA HERENCIA VISUAL 36 APLICACIONES DISTRIBUIDAS 37 COMPONENTES DE DELPHI 38 2. HERRAMIENTAS Y UTILIDADES 41 DELPHI Y EL TECLADO 41 CODE INSIGHT: AYUDA DURANTE LA EDICIÓN 44 CLASS COMPLETION 48 HERRAMIENTAS DE DEPURACIÓN 49 OBJECT BROWSER 51 BDE ADMINISTRATOR 51 DATABASE EXPLORER 52 DATABASE DESKTOP 53 DATA MIGRATION WIZARD 54 SQL MONITOR 55 IMAGE EDITOR 55
  • 6. 4 La Cara Oculta de Delphi 3. UNIDADES, PROYECTOS Y PAQUETES 57 LA ESTRUCTURA DE UN PROYECTO DE APLICACIÓN 58 ¿QUÉ SE PUEDE DECLARAR? 60 SINTAXIS DE LAS UNIDADES 62 LA CLÁUSULA USES Y LAS REFERENCIAS CIRCULARES 64 LA INCLUSIÓN AUTOMÁTICA DE UNIDADES 65 LOS FICHEROS DFM 66 BIBLIOTECAS DE ENLACE DINÁMICO 68 PAQUETES 69 EL ABC DEL USO DE PAQUETES 72 PAQUETES DE TIEMPO DE DISEÑO Y DE EJECUCIÓN 73 LOS GRUPOS DE PROYECTOS 74 4. SISTEMAS DE BASES DE DATOS 77 ACERCA DEL ACCESO TRANSPARENTE A BASES DE DATOS 77 BASES DE DATOS RELACIONALES 78 INFORMACIÓN SEMÁNTICA = RESTRICCIONES 80 RESTRICCIONES DE UNICIDAD Y CLAVES PRIMARIAS 81 INTEGRIDAD REFERENCIAL 82 ¿QUÉ TIENE DE MALO EL MODELO RELACIONAL? 83 BASES DE DATOS LOCALES Y SERVIDORES SQL 85 CARACTERÍSTICAS GENERALES DE LOS SISTEMAS SQL 87 EL FORMATO PARADOX 88 EL FORMATO DBF7 91 CRITERIOS PARA EVALUAR UN SERVIDOR SQL 92 INTERBASE 95 MICROSOFT SQL SERVER 97 ORACLE 99 OTROS SISTEMAS DE USO FRECUENTE 100 5. EL MOTOR DE DATOS DE BORLAND 103 QUÉ ES, Y CÓMO FUNCIONA 104 CONTROLADORES LOCALES Y SQL LINKS 105 ACCESO A FUENTES DE DATOS ODBC 106 ¿DÓNDE SE INSTALA EL BDE? 106 EL ADMINISTRADOR DEL MOTOR DE DATOS 108 CONFIGURACIÓN DEL REGISTRO E INFORMACIÓN DE VERSIÓN 108 EL CONCEPTO DE ALIAS 110 PARÁMETROS DEL SISTEMA 110 PARÁMETROS DE LOS CONTROLADORES PARA BD LOCALES 112 BLOQUEOS OPORTUNISTAS 114 PARÁMETROS COMUNES A LOS CONTROLADORES SQL 114 CONFIGURACIÓN DE INTERBASE 117
  • 7. Indice 5 CONFIGURACIÓN DE MS SQL SERVER 118 CONFIGURACIÓN DE ORACLE 120 CONFIGURACIÓN DE OTROS SISTEMAS 121 CREACIÓN DE ALIAS PARA BASES DE DATOS LOCALES Y SQL 121 ALTERNATIVAS AL MOTOR DE DATOS 122 FUNDAMENTOS DEL LENGUAJE 125 6. PROGRAMACIÓN ORIENTADA A OBJETOS: ENCAPSULAMIENTO 127 EL PROBLEMA DE LA DIVISIÓN EN MÓDULOS 127 LOS MÓDULOS EN LA PROGRAMACIÓN ESTRUCTURADA 128 REUSABILIDAD Y EL PRINCIPIO “ABIERTO/CERRADO” 129 LLEGAN LOS OBJETOS 130 OPERACIONES SOBRE UN TIPO DE DATOS: FUNCIONES 132 OPERACIONES SOBRE UN TIPO DE DATOS: MÉTODOS 134 LA PRIMERA VENTAJA: NOMBRES MÁS CORTOS 135 LA IMPLEMENTACIÓN DE UN MÉTODO 136 EL ESTADO INTERNO DE UN OBJETO 138 PARÁMETROS POR OMISIÓN 140 PÚBLICO Y PRIVADO 140 LAS VARIABLES DE OBJETOS SON PUNTEROS 142 CONSTRUCCIÓN Y DESTRUCCIÓN: EL CICLO DE LA VIDA 143 DEFINIENDO CONSTRUCTORES Y DESTRUCTORES 144 7. HERENCIA Y POLIMORFISMO 147 HERENCIA = EXTENSIÓN + ESPECIALIZACIÓN 147 UN GATO CON BOTAS SIGUE SIENDO UN GATO 149 LA CLASE TOBJECT 152 JERARQUÍAS DE HERENCIA 153 HERENCIA MÚLTIPLE, ¿SÍ O NO? 154 REDEFINICIÓN DE MÉTODOS 155 LA TABLA DE MÉTODOS VIRTUALES 158 UTILIZANDO EL COMPORTAMIENTO HEREDADO 160 SOBRECARGA: HAY MUY POCOS NOMBRE BUENOS 161 PÚBLICO, PROTEGIDO, PRIVADO... 163 MÉTODOS ABSTRACTOS 164 REFERENCIAS DE CLASE 165 CONSTRUCTORES VIRTUALES 167 INFORMACIÓN DE TIPOS EN TIEMPO DE EJECUCIÓN 168 MÉTODOS DE CLASE 170
  • 8. 6 La Cara Oculta de Delphi 8. ELEMENTOS DE PROGRAMACIÓN CON WINDOWS 173 SI ME NECESITAS, ¡LLÁMAME! 173 ¿QUÉ ES UNA VENTANA? 174 CLASES DE VENTANA 175 EVENTOS O, MÁS BIEN, MENSAJES 176 EL CICLO DE MENSAJES Y LA COLA DE MENSAJES 177 EJECUCIÓN MODAL Y NO MODAL 180 EL PROCEDIMIENTO DE VENTANA 180 INTERCEPTANDO MENSAJES EN DELPHI 181 TAMBIÉN PODEMOS ENVIAR MENSAJES 184 APLICACIONES EN LA BANDEJA DE ICONOS 184 CICLO DE MENSAJES Y CONCURRENCIA 187 CUANDO NO HAY NADA MEJOR QUE HACER… 188 EJECUTAR Y ESPERAR 189 9. PROPIEDADES 191 LOS PROBLEMAS DE LA POO CLÁSICA 191 PROPIEDADES 194 IMPLEMENTACIÓN DE PROPIEDADES MEDIANTE ATRIBUTOS 195 SI NO CREEMOS EN LA ALQUIMIA… 197 LA SEMÁNTICA DE LA ASIGNACIÓN A PROPIEDADES 198 PROPIEDADES VECTORIALES 200 PROPIEDADES VECTORIALES POR OMISIÓN 202 ESPECIFICACIONES DE ALMACENAMIENTO 202 ACCESO A PROPIEDADES POR SU NOMBRE 205 10. EVENTOS 207 PUNTEROS A FUNCIONES 207 PUNTEROS A MÉTODOS 208 OBJETOS ACTIVOS: ¡ABAJO LA VIGILANCIA! 210 EVENTOS VS REDEFINICIÓN DE MÉTODOS VIRTUALES 212 EL EMISOR Y EL RECEPTOR DEL EVENTO 214 RECEPTORES COMPARTIDOS 215 TIPOS DE EVENTOS 216 NOS PIDEN NUESTRA OPINIÓN... 218 LOS EVENTOS EXPRESAN CONTRATOS SIN OBLIGACIONES 218 ACTIVACIÓN RECURSIVA 219 11. EXCEPCIONES 223 SISTEMAS DE CONTROL DE ERRORES 223 CONTRATOS INCUMPLIDOS 224 CÓMO SE INDICA UN ERROR 225
  • 9. Indice 7 LA EJECUCIÓN DEL PROGRAMA FLUYE EN DOS DIMENSIONES 226 EL ESTADO DE PÁNICO 227 PAGAMOS NUESTRAS DEUDAS 227 EL CONCEPTO DE "RECURSO DE PROGRAMACIÓN" 228 CÓMO TRANQUILIZAR A UN PROGRAMA ASUSTADO 229 EJEMPLOS DE CAPTURA DE EXCEPCIONES 230 CAPTURANDO EL OBJETO DE EXCEPCIÓN 231 DISTINGUIR EL TIPO DE EXCEPCIÓN 231 LAS TRES REGLAS DE MARTEENS 233 CICLO DE MENSAJES Y MANEJO DE EXCEPCIONES 234 EXCEPCIONES A LA TERCERA REGLA DE MARTEENS 235 EL EVENTO ONEXCEPTION 236 LA EXCEPCIÓN SILENCIOSA 239 CONSTRUCTORES Y EXCEPCIONES 240 ASERCIONES 243 12. TIPOS DE DATOS DE DELPHI 247 TIPOS NUMÉRICOS 247 FECHAS Y HORAS 249 CADENAS DE CARACTERES CORTAS 251 PUNTEROS A CARACTERES, AL ESTILO C 253 CADENAS DE CARACTERES LARGAS 254 VECTORES ABIERTOS 256 VECTORES DINÁMICOS 258 VECTORES ABIERTOS VARIANTES 259 VARIANTES 260 CLASES PARA LA REPRESENTACIÓN DE LISTAS 261 STREAMS: FICHEROS CON INTERFAZ DE OBJETOS 264 13. TÉCNICAS DE GESTIÓN DE VENTANAS 267 ¿QUÉ HACE DELPHI CUANDO LO DEJAMOS SOLO? 267 CREACIÓN INMEDIATA DE VENTANAS MODALES 269 CREACIÓN INMEDIATA DE VENTANAS NO MODALES 271 MÉTODOS DE CLASE PARA LA CREACIÓN DINÁMICA 273 CÓMO TRANSFORMAR INTROS EN TABS 276 CÓMO LIMITAR EL TAMAÑO DE UNA VENTANA 277 CÓMO DISTRIBUIR EL ÁREA INTERIOR ENTRE DOS REJILLAS 279 VENTANAS DE PRESENTACIÓN 281 14. LOS MÓDULOS DE DATOS Y EL DEPÓSITO DE OBJETOS 283 LA GALERÍA DE PLANTILLAS DE DELPHI 1 283 EL DEPÓSITO DE OBJETOS 284 LAS PROPIEDADES DEL DEPÓSITO 286
  • 10. 8 La Cara Oculta de Delphi LA UBICACIÓN DEL DEPÓSITO DE OBJETOS 287 ¿USAR, COPIAR O HEREDAR? 289 HERENCIA VISUAL DENTRO DEL PROYECTO 292 HERENCIA DE EVENTOS 292 LAS PLANTILLAS DE COMPONENTES 293 LOS MÓDULOS DE DATOS 294 COMPONENTES PARA BASES DE DATOS 297 15. CONJUNTOS DE DATOS: TABLAS 299 LA JERARQUÍA DE LOS CONJUNTOS DE DATOS 299 LA ARQUITECTURA DE OBJETOS DEL MOTOR DE DATOS 301 TABLAS 303 CONEXIÓN CON COMPONENTES VISUALES 306 NAVEGANDO POR LAS FILAS 308 MARCAS DE POSICIÓN 310 ENCAPSULAMIENTO DE LA ITERACIÓN 311 LA RELACIÓN MASTER/DETAIL 313 NAVEGACIÓN Y RELACIONES MASTER/DETAIL 316 EL ESTADO DE UN CONJUNTO DE DATOS 321 16. ACCESO A CAMPOS 323 CREACIÓN DE COMPONENTES DE CAMPOS 323 CLASES DE CAMPOS 325 NOMBRE DEL CAMPO Y ETIQUETA DE VISUALIZACIÓN 327 ACCESO A LOS CAMPOS POR MEDIO DE LA TABLA 328 EXTRAYENDO INFORMACIÓN DE LOS CAMPOS 328 LAS MÁSCARAS DE FORMATO Y EDICIÓN 330 LOS EVENTOS DE FORMATO DE CAMPOS 331 VALIDACIÓN A NIVEL DE CAMPOS 333 PROPIEDADES DE VALIDACIÓN 334 CAMPOS CALCULADOS 335 CAMPOS DE BÚSQUEDA 336 LA CACHÉ DE BÚSQUEDA 338 EL ORDEN DE EVALUACIÓN DE LOS CAMPOS 339 EL DICCIONARIO DE DATOS 340 CONJUNTOS DE ATRIBUTOS 341 IMPORTANDO BASES DE DATOS 342 EVALUANDO RESTRICCIONES EN EL CLIENTE 343 INFORMACIÓN SOBRE CAMPOS 346 CREACIÓN DE TABLAS 347
  • 11. Indice 9 17. CONTROLES DE DATOS Y FUENTES DE DATOS 351 CONTROLES DATA-AWARE 351 LOS ENLACES DE DATOS 353 CREACIÓN DE CONTROLES DE DATOS 354 LOS CUADROS DE EDICIÓN 355 EDITORES DE TEXTO 356 TEXTOS NO EDITABLES 357 COMBOS Y LISTAS CON CONTENIDO FIJO 357 COMBOS Y LISTAS DE BÚSQUEDA 360 CASILLAS DE VERIFICACIÓN Y GRUPOS DE BOTONES 362 IMÁGENES EXTRAÍDAS DE BASES DE DATOS 363 LA TÉCNICA DEL COMPONENTE DEL POBRE 363 PERMITIENDO LAS MODIFICACIONES 365 BLOB, BLOB, BLOB… 367 LA CLASE TBLOBSTREAM 368 18. REJILLAS Y BARRAS DE NAVEGACIÓN 371 EL FUNCIONAMIENTO BÁSICO DE UNA REJILLA DE DATOS 371 OPCIONES DE REJILLAS 372 COLUMNAS A LA MEDIDA 373 GUARDAR Y RESTAURAR LOS ANCHOS DE COLUMNAS 376 LISTAS DESPLEGABLES Y BOTONES DE EDICIÓN 377 NÚMEROS VERDES Y NÚMEROS ROJOS 379 MÁS EVENTOS DE REJILLAS 381 LA BARRA DE DESPLAZAMIENTO DE LA REJILLA 382 REJILLAS DE SELECCIÓN MÚLTIPLE 383 BARRAS DE NAVEGACIÓN 384 HABÍA UNA VEZ UN USUARIO TORPE, MUY TORPE… 385 AYUDAS PARA NAVEGAR 385 EL COMPORTAMIENTO DE LA BARRA DE NAVEGACIÓN 386 REJILLAS DE CONTROLES 388 19. INDICES 391 INDICES EN PARADOX 391 INDICES EN DBASE 392 INDICES EN INTERBASE 394 INDICES EN MS SQL SERVER 394 INDICES EN ORACLE 395 CON QUÉ ÍNDICES PODEMOS CONTAR 396 ESPECIFICANDO EL ÍNDICE ACTIVO 398 ESPECIFICANDO UN ORDEN EN TABLAS SQL 399 BÚSQUEDA BASADA EN ÍNDICES 401 IMPLEMENTACIÓN DE REFERENCIAS MEDIANTE FINDKEY 403
  • 12. 10 La Cara Oculta de Delphi BÚSQUEDAS UTILIZANDO SETKEY 403 EXPERIMENTANDO CON SETKEY 404 ¿POR QUÉ EXISTE SETKEY? 405 RANGOS: DESDE EL ALFA A LA OMEGA 406 EL EJEMPLO DE RANGOS DE CASI TODOS LOS LIBROS 408 MÁS PROBLEMAS CON LOS ÍNDICES DE DBASE 410 CÓMO CREAR UN ÍNDICE TEMPORAL 411 20. MÉTODOS DE BÚSQUEDA 413 FILTROS 413 ESTO NO LO DICE LA DOCUMENTACIÓN… 414 UN EJEMPLO CON FILTROS RÁPIDOS 415 EL EVENTO ONFILTERRECORD 418 LOCALIZACIÓN Y BÚSQUEDA 419 UN DIÁLOGO GENÉRICO DE LOCALIZACIÓN 422 FILTROS LATENTES 424 FILTER BY EXAMPLE 426 BÚSQUEDA EN UNA TABLA DE DETALLES 430 PROGRAMACIÓN CON SQL 433 21. BREVE INTRODUCCIÓN A SQL 435 LA ESTRUCTURA DE SQL 435 PARA SEGUIR LOS EJEMPLOS DE ESTE LIBRO… 436 LA CREACIÓN Y CONEXIÓN A LA BASE DE DATOS 438 TIPOS DE DATOS EN SQL 439 CREACIÓN DE TABLAS 440 COLUMNAS CALCULADAS 441 VALORES POR OMISIÓN 442 RESTRICCIONES DE INTEGRIDAD 442 CLAVES PRIMARIAS Y ALTERNATIVAS 444 INTEGRIDAD REFERENCIAL 445 ACCIONES REFERENCIALES 446 NOMBRES PARA LAS RESTRICCIONES 447 DEFINICIÓN Y USO DE DOMINIOS 448 CREACIÓN DE ÍNDICES 449 MODIFICACIÓN DE TABLAS E ÍNDICES 450 CREACIÓN DE VISTAS 451 CREACIÓN DE USUARIOS 451 ASIGNACIÓN DE PRIVILEGIOS 453 ROLES 454 UN EJEMPLO COMPLETO DE SCRIPT SQL 455
  • 13. Indice 11 22. CONSULTAS Y MODIFICACIONES EN SQL 457 LA INSTRUCCIÓN SELECT: EL LENGUAJE DE CONSULTAS 457 LA CONDICIÓN DE SELECCIÓN 459 OPERADORES DE CADENAS 459 EL VALOR NULO: ENFRENTÁNDONOS A LO DESCONOCIDO 460 ELIMINACIÓN DE DUPLICADOS 461 PRODUCTOS CARTESIANOS Y ENCUENTROS 462 ORDENANDO LOS RESULTADOS 464 EL USO DE GRUPOS 465 FUNCIONES DE CONJUNTOS 466 LA CLÁUSULA HAVING 467 EL USO DE SINÓNIMOS PARA TABLAS 467 SUBCONSULTAS: SELECCIÓN ÚNICA 468 SUBCONSULTAS: LOS OPERADORES IN Y EXISTS 469 SUBCONSULTAS CORRELACIONADAS 471 EQUIVALENCIAS DE SUBCONSULTAS 472 ENCUENTROS EXTERNOS 473 LAS INSTRUCCIONES DE ACTUALIZACIÓN 475 VISTAS 476 23. PROCEDIMIENTOS ALMACENADOS Y TRIGGERS 479 ¿PARA QUÉ USAR PROCEDIMIENTOS ALMACENADOS? 479 CÓMO SE UTILIZA UN PROCEDIMIENTO ALMACENADO 481 EL CARÁCTER DE TERMINACIÓN 482 PROCEDIMIENTOS ALMACENADOS EN INTERBASE 483 PROCEDIMIENTOS QUE DEVUELVEN UN CONJUNTO DE DATOS 486 RECORRIENDO UN CONJUNTO DE DATOS 488 TRIGGERS, O DISPARADORES 489 LAS VARIABLES NEW Y OLD 491 MÁS EJEMPLOS DE TRIGGERS 491 GENERADORES 493 SIMULANDO LA INTEGRIDAD REFERENCIAL 495 EXCEPCIONES 497 ALERTADORES DE EVENTOS 498 24. MICROSOFT SQL SERVER 501 HERRAMIENTAS DE DESARROLLO EN EL CLIENTE 501 CREACIÓN DE BASES DE DATOS CON MS SQL SERVER 502 TIPOS DE DATOS PREDEFINIDOS 504 TIPOS DE DATOS DEFINIDOS POR EL PROGRAMADOR 505 CREACIÓN DE TABLAS Y ATRIBUTOS DE COLUMNAS 506 INTEGRIDAD REFERENCIAL 507 INDICES 508
  • 14. 12 La Cara Oculta de Delphi SEGURIDAD EN MS SQL SERVER 508 PROCEDIMIENTOS ALMACENADOS 509 CURSORES 510 TRIGGERS EN TRANSACT-SQL 512 INTEGRIDAD REFERENCIAL MEDIANTE TRIGGERS 514 25. ORACLE 517 SOBREVIVIENDO A SQL*PLUS 517 INSTANCIAS, BASES DE DATOS, USUARIOS 519 TIPOS DE DATOS 520 CREACIÓN DE TABLAS 521 PROCEDIMIENTOS ALMACENADOS EN PL/SQL 522 CURSORES 524 TRIGGERS EN PL/SQL 525 SECUENCIAS 526 TIPOS DE OBJETOS 528 EXTENSIONES DE DELPHI PARA LOS TIPOS DE OBJETOS 532 26. USANDO SQL CON DELPHI 537 EL COMPONENTE TQUERY COMO CONJUNTO DE DATOS 537 ¿QUIÉN EJECUTA LAS INSTRUCCIONES? 538 CONSULTAS ACTUALIZABLES 539 SIEMPRE HACIA ADELANTE 540 CONSULTAS PARAMÉTRICAS 543 CONSULTAS DEPENDIENTES 545 LA PREPARACIÓN DE LA CONSULTA 546 ACTUALIZACIÓN DE DATOS CON SQL 548 ALMACENAR EL RESULTADO DE UNA CONSULTA 549 ¿EJECUTAR O ACTIVAR? 550 UTILIZANDO PROCEDIMIENTOS ALMACENADOS 553 VISUAL QUERY BUILDER 555 27. COMUNICACIÓN CLIENTE/SERVIDOR 559 NUESTRA ARMA LETAL: SQL MONITOR 559 ¿TABLA O CONSULTA? 560 LA CACHÉ DE ESQUEMAS 562 OPERACIONES DE NAVEGACIÓN SIMPLE 563 BÚSQUEDAS EXACTAS CON LOCATE 564 BÚSQUEDAS PARCIALES 564 UNA SOLUCIÓN PARA BÚSQUEDAS PARCIALES RÁPIDAS 565 BÚSQUEDAS CON FILTROS LATENTES 567
  • 15. Indice 13 ACTUALIZACIONES Y CONCURRENCIA 569 28. ACTUALIZACIONES 571 LOS ESTADOS DE EDICIÓN Y LOS MÉTODOS DE TRANSICIÓN 571 ASIGNACIONES A CAMPOS 572 CONFIRMANDO LAS ACTUALIZACIONES 574 DIFERENCIAS ENTRE INSERT Y APPEND 575 COMO POR AZAR… 576 MÉTODOS ABREVIADOS DE INSERCIÓN 577 ACTUALIZACIÓN DIRECTA VS VARIABLES EN MEMORIA 577 AUTOMATIZANDO LA ENTRADA DE DATOS 579 ENTRADA DE DATOS CONTINUA 581 ELIMINANDO REGISTROS 582 COMPRESIÓN DE TABLAS LOCALES 583 29. EVENTOS DE TRANSICIÓN DE ESTADOS 585 CUANDO EL ESTADO CAMBIA… 585 REGLAS DE EMPRESA: ¿EN EL SERVIDOR O EN EL CLIENTE? 586 INICIALIZACIÓN DE REGISTROS: EL EVENTO ONNEWRECORD 587 VALIDACIONES A NIVEL DE REGISTROS 588 ANTES Y DESPUÉS DE UNA MODIFICACIÓN 589 PROPAGACIÓN DE CAMBIOS EN CASCADA 591 ACTUALIZACIONES COORDINADAS MASTER/DETAIL 592 ANTES Y DESPUÉS DE LA APERTURA DE UNA TABLA 593 VACIANDO LOS BUFFERS 594 LOS EVENTOS DE DETECCIÓN DE ERRORES 595 LA ESTRUCTURA DE LA EXCEPCIÓN EDBENGINEERROR 597 APLICACIONES DE LOS EVENTOS DE ERRORES 600 UNA VEZ MÁS, LA ORIENTACIÓN A OBJETOS… 602 30. BASES DE DATOS Y SESIONES 603 EL COMPONENTE TDATABASE 603 OBJETOS DE BASES DE DATOS PERSISTENTES 604 CAMBIANDO UN ALIAS DINÁMICAMENTE 605 BASES DE DATOS Y CONJUNTOS DE DATOS 607 PARÁMETROS DE CONEXIÓN 609 LA PETICIÓN DE CONTRASEÑAS 609 EL DIRECTORIO TEMPORAL DE WINDOWS 611 PROBLEMAS CON LA HERENCIA VISUAL 611 SESIONES 613 CADA SESIÓN ES UN USUARIO 613 SESIONES E HILOS PARALELOS 614
  • 16. 14 La Cara Oculta de Delphi INFORMACIÓN SOBRE ESQUEMAS 617 EL MINIEXPLORADOR DE BASES DE DATOS 618 GESTIÓN DE ALIAS A TRAVÉS DE TSESSION 620 DIRECTORIOS PRIVADOS, DE RED Y CONTRASEÑAS 622 31. TRANSACCIONES Y CONTROL DE CONCURRENCIA 625 EL GRAN EXPERIMENTO 625 EL GRAN EXPERIMENTO: TABLAS LOCALES 626 EL GRAN EXPERIMENTO: TABLAS SQL 628 PESIMISTAS Y OPTIMISTAS 628 EL MODO DE ACTUALIZACIÓN 630 LA RELECTURA DEL REGISTRO ACTUAL 632 LAS PROPIEDADES “ÁCIDAS” DE UNA TRANSACCIÓN 633 TRANSACCIONES SQL Y EN BASES DE DATOS LOCALES 635 TRANSACCIONES IMPLÍCITAS Y EXPLÍCITAS 636 ENTRADA DE DATOS Y TRANSACCIONES 638 AISLAMIENTO DE TRANSACCIONES 639 AISLAMIENTO DE TRANSACCIONES MEDIANTE BLOQUEOS 641 EL JARDÍN DE LOS SENDEROS QUE SE BIFURCAN 643 DE NUEVO LOS OPTIMISTAS 644 32. ACTUALIZACIONES EN CACHÉ 649 ¿CACHÉ PARA QUÉ? 649 ACTIVACIÓN DE LAS ACTUALIZACIONES EN CACHÉ 650 CONFIRMACIÓN DE LAS ACTUALIZACIONES 651 MARCHA ATRÁS 653 EL ESTADO DE ACTUALIZACIÓN 653 EL FILTRO DE TIPOS DE REGISTROS 655 UN EJEMPLO INTEGRAL 656 EL GRAN FINAL: EDICIÓN Y ENTRADA DE DATOS 658 COMBINANDO LA CACHÉ CON GRABACIONES DIRECTAS 660 PROTOTIPOS Y MÉTODOS VIRTUALES 663 CÓMO ACTUALIZAR CONSULTAS “NO” ACTUALIZABLES 665 EL EVENTO ONUPDATERECORD 668 DETECCIÓN DE ERRORES DURANTE LA GRABACIÓN 669 33. LIBRETAS DE BANCOS 673 DESCRIPCIÓN DEL MODELO DE DATOS 673 CREACIÓN DE VISTAS 675 MANTENIENDO ACTUALIZADOS LOS SALDOS 675 LIBRETAS DE BANCO Y MS SQL SERVER 677 AHORA, EN ORACLE 679 EL MÓDULO DE DATOS 681
  • 17. Indice 15 GESTIÓN DE LIBRETAS 684 CÓDIGOS DE OPERACIONES 686 LA VENTANA PRINCIPAL 688 ENTRADA DE APUNTES 690 CORRIGIENDO EL IMPORTE DE UN APUNTE 692 LOS DETALLES FINALES 695 34. IMPRESIÓN DE INFORMES CON QUICKREPORT 697 LA HISTORIA DEL PRODUCTO 697 LA FILOSOFÍA DEL PRODUCTO 699 PLANTILLAS Y EXPERTOS PARA QUICKREPORT 700 EL CORAZÓN DE UN INFORME 701 LAS BANDAS 703 EL EVENTO BEFOREPRINT 704 COMPONENTES DE IMPRESIÓN 705 EL EVALUADOR DE EXPRESIONES 706 DEFINIENDO NUEVAS FUNCIONES 708 UTILIZANDO GRUPOS 709 ELIMINANDO DUPLICADOS 711 INFORMES MASTER/DETAIL 712 INFORMES COMPUESTOS 714 PREVISUALIZACIÓN A LA MEDIDA 715 LISTADOS AL VUELO 716 ENVIANDO CÓDIGOS BINARIOS A UNA IMPRESORA 718 35. GRÁFICOS DE DECISIÓN 721 GRÁFICOS Y BIORRITMOS 721 EL COMPONENTE TDBCHART 725 COMPONENTES NO VISUALES DE DECISION CUBE 727 REJILLAS Y GRÁFICOS DE DECISIÓN 729 MODIFICANDO EL MAPA DE DIMENSIONES 731 36. BIBLIOTECAS DE ENLACE DINÁMICO 733 ARQUITECTURA BÁSICA 733 PROYECTOS DLL 735 EXPORTACIÓN DE FUNCIONES 736 IMPORTACIÓN DE FUNCIONES Y UNIDADES DE IMPORTACIÓN 739 TIPOS DE DATOS EN FUNCIONES EXPORTADAS 740 CÓDIGO DE INICIALIZACIÓN Y FINALIZACIÓN 742 EXCEPCIONES EN BIBLIOTECAS DINÁMICAS 744 CARGA DINÁMICA DE BIBLIOTECAS 745
  • 18. 16 La Cara Oculta de Delphi DEPURACIÓN DE BIBLIOTECAS DINÁMICAS 746 FUNCIONES DE USUARIO EN INTERBASE 746 BIBLIOTECAS DE RECURSOS E INTERNACIONALIZACIÓN 749 FICHEROS ASIGNADOS EN MEMORIA 752 37. SERVIDORES DE INTERNET 757 EL MODELO DE INTERACCIÓN EN LA WEB 757 APRENDA HTML EN 14 MINUTOS 758 EXTENSIONES DEL SERVIDOR Y PÁGINAS DINÁMICAS 761 ¿QUÉ NECESITO PARA ESTE SEGUIR LOS EJEMPLOS? 762 MÓDULOS WEB 763 ACCIONES 765 RECUPERACIÓN DE PARÁMETROS 767 GENERADORES DE CONTENIDO 768 GENERADORES DE TABLAS 770 MANTENIMIENTO DE LA INFORMACIÓN DE ESTADO 771 UN EJEMPLO: BÚSQUEDA DE PRODUCTOS 773 EL MOTOR DE BÚSQUEDAS 775 CREANDO LA EXTENSIÓN WEB 778 GENERANDO LA TABLA DE RESULTADOS 780 DOCUMENTOS HTML Y SUSTITUCIÓN DE ETIQUETAS 781 RESPONDIENDO A LAS ACCIONES 783 38. CONJUNTOS DE DATOS CLIENTES 785 CREACIÓN DE CONJUNTOS DE DATOS 785 CÓMO EL TCLIENTDATASET CONSIGUIÓ SUS DATOS... 787 NAVEGACIÓN, BÚSQUEDA Y SELECCIÓN 788 FILTROS 789 EDICIÓN DE DATOS 790 CONJUNTOS DE DATOS ANIDADOS 791 CAMPOS CALCULADOS INTERNOS 794 INDICES, GRUPOS Y VALORES AGREGADOS 795 39. EL MODELO DE OBJETOS COMPONENTES: LA TEORÍA 799 COM, DCOM, OLE... 800 INTERFACES 801 LA INTERFAZ IUNKNOWN 803 IMPLEMENTACIÓN DE INTERFACES EN DELPHI 805 CÓMO OBTENER UN OBJETO COM 807 DENTRO DEL PROCESO, EN LA MISMA MÁQUINA, REMOTO... 808 EL HUEVO, LA GALLINA Y LAS FÁBRICAS DE CLASES 809 OLE Y EL REGISTRO DE WINDOWS 810 ¿CÓMO SE REGISTRA UN SERVIDOR? 812
  • 19. Indice 17 AUTOMATIZACIÓN OLE 812 CONTROLADORES DE AUTOMATIZACIÓN EN DELPHI 814 INTERFACES DUALES 815 EVENTOS Y CONTROLES ACTIVEX 816 BIBLIOTECAS DE TIPOS 817 ACTIVEFORMS: FORMULARIOS EN LA WEB 819 40. EL MODELO DE OBJETOS COMPONENTES: EJEMPLOS 823 CREACIÓN DE OBJETOS Y MANEJO DE INTERFACES 823 INTERCEPTANDO OPERACIONES EN DIRECTORIOS 824 INFORMES AUTOMATIZADOS 828 CONTROLADORES DE AUTOMATIZACIÓN 833 DECLARANDO UNA INTERFAZ COMÚN 835 UN SERVIDOR DE BLOQUEOS 836 LA IMPLEMENTACIÓN DE LA LISTA DE BLOQUEOS 838 CONTROL DE CONCURRENCIA 840 PONIENDO A PRUEBA EL SERVIDOR 843 41. MIDAS 845 ¿QUÉ ES MIDAS? 845 CUÁNDO UTILIZAR Y CUÁNDO NO UTILIZAR MIDAS 847 MIDAS Y LAS BASES DE DATOS DE ESCRITORIO 849 MÓDULOS DE DATOS REMOTOS 850 PROVEEDORES 853 SERVIDORES REMOTOS Y CONJUNTOS DE DATOS CLIENTES 854 GRABACIÓN DE DATOS 856 RESOLUCIÓN 859 CONTROL DE ERRORES DURANTE LA RESOLUCIÓN 862 RECONCILIACIÓN 864 RELACIONES MASTER/DETAIL Y TABLAS ANIDADAS 866 ENVÍO DE PARÁMETROS 866 EXTENDIENDO LA INTERFAZ DEL SERVIDOR 867 LA METÁFORA DEL MALETÍN 870 TIPOS DE CONEXIÓN 871 BALANCE DE CARGA SIMPLE 874 INTERFACES DUALES EN MIDAS 875 42. CREACIÓN DE INSTALACIONES 877 LOS PROYECTOS DE INSTALLSHIELD EXPRESS 877 LA PRESENTACIÓN DE LA INSTALACIÓN 879 LAS MACROS DE DIRECTORIOS 881 GRUPOS Y COMPONENTES 881 INSTALANDO EL BDE Y LOS SQL LINKS 884
  • 20. 18 La Cara Oculta de Delphi CONFIGURACIÓN ADICIONAL DEL BDE 885 INSTALACIÓN DE PAQUETES 887 INTERACCIÓN CON EL USUARIO 888 LAS CLAVES DEL REGISTRO DE WINDOWS 890 CÓMO SE REGISTRAN LOS COMPONENTES ACTIVEX 891 ICONOS Y CARPETAS 892 GENERANDO Y PROBANDO LA INSTALACIÓN 894 LA VERSIÓN COMPLETA DE INSTALLSHIELD EXPRESS 894 LAS EXTENSIONES DE INSTALLSHIELD EXPRESS 895
  • 21. Prólogo del Autor And if the band you’re in start playing different tunes I’ll see you on the dark side of the moon Pink Floyd …those dark and hideous mysteries which lie in the outer regions of the moon, regions which, owing to the almost miraculous accordance of the satellite’s rotation on its own axis with its sidereal revolution about the earth, have never yet turned, and, by God’s mercy, never shall be turned, to the scrutiny of the telescopes of man. Edgar Allan Poe, The Adventure Of One Hans Pfaall E N LA PRIMAVERA DEL 95 APARECIÓ DELPHI. En aquel momento, el autor trabajaba para una empresa de cartografía, programando en C/C++ para el entorno Windows, y estaba metido en un proyecto bastante complicado. La aplicación en cuestión debía trabajar con grandes cantidades de datos, con relaciones complejas entre los mismos, y tenía que realizar cálculos algebraicos a diestra y si- niestra; todo esto aprovechando la interfaz gráfica de Windows 3.11. De entrada descarté a Visual Basic, pues aunque simplificaba la programación de la interfaz de usuario, era demasiado lento para las operaciones de cálculo y, al no ser un lenguaje orientado a objetos, no me permitía modelar elegantemente las clases que manipu- laba mi proyecto. En cuanto al acceso a datos, ya había trabajado con CodeBase, una biblioteca de funciones para manipular tablas en formato dbf. En un principio, podía utilizar algo así, aunque la versión 5.1, que era la que estaba utilizando, fallaba cuando los ficheros de datos pasaban de cierto volumen. Necesitaba una herramienta de programación que cumpliera con estos requerimien- tos, y escribí a Borland, pensando en comprar un C++ con las Database Tools. En cambio, Borland me envió información sobre un nuevo producto llamado Delphi, cuyo lenguaje de programación parecía ser Pascal, ofrecía un entorno de desarrollo visual parecido al de Visual Basic, y que permitía el acceso a bases de datos en di- versos formatos. No lo pensé mucho y compré el producto; tengo que reconocer que el precio, relativamente barato, también influyó en mi decisión. La historia tuvo, por supuesto, un final feliz como los de los anuncios de detergentes: el proyecto se ter- minó a tiempo, la aplicación se ejecutaba de maravillas y todos quedaron contentos, excepto yo, que tardé más de seis meses en cobrar lo que me correspondía. Mi primera experiencia con Delphi fue similar a la de miles de programadores, y la conclusión que extraje de este primer encuentro con el lenguaje debe haber sido semejante a la de ellos: Delphi es un sistema muy fácil de aprender y utilizar, y ofrece una potencia de programación similar a la de los lenguajes tradicionales como C/C++.
  • 22. 20 La Cara Oculta de Delphi No obstante, tras esta aparente sencillez se oculta una trampa. La programación con Delphi es, efectivamente, muy sencilla si nos limitamos a las tareas básicas. Pero do- minar el lenguaje requiere tiempo y dedicación. Los tres problemas básicos a los que se enfrenta el programador en Delphi son: • La Programación Orientada a Objetos. • La arquitectura basada en mensajes o eventos. • El control de errores mediante excepciones. Además, el programador que quiere desarrollar aplicaciones serias de bases de datos tiene que afrontar las dificultades de la programación concurrente: mecanismos de control de acceso, transacciones, integridad y consistencia, el dominio del lenguaje SQL... Si el entorno del cual procede es la programación para bases de datos locales, todos estos conceptos son nuevos o se abordan desde enfoques diferentes en su sistema de programación original. Por todas estas razones, decidí escribir un libro dedicado especialmente a la pro- gramación para bases de datos con Delphi, que entrara en profundidad en los con- ceptos específicos de este área. Un libro de carácter “tutorial”, que además conside- rase todos los temas anteriores con la profundidad necesaria, hubiera tenido el ta- maño de una enciclopedia, y su redacción necesitaría mucho más tiempo. En vez de llevar una línea de desarrollo, conducida quizás por una aplicación única de ejemplo, he preferido utilizar ejemplos pequeños para cada tema. De este modo, cada capítulo puede leerse de forma independiente a los demás, y el libro puede utilizarse como referencia. El mayor problema de un libro escrito en ese estilo es el de las referencias circulares: necesito explicarle qué es un campo antes de poder hacer ejemplos sencillos con las tablas, pero también necesito presentar las tablas antes de poder explicar los campos. Y la única solución que se me ocurre es ofrecer adelantos: escribir un poco sobre el recurso necesario, prometiendo más información sobre éste más adelante. “La Cara Oculta de Delphi” está destinada a personas que ya han estado sentadas frente a Delphi. No es necesario que hayan programado en Delphi, pero no es mi in- tención enseñar cómo se inicia Delphi, qué comandos ofrece, qué es un menú... Hay bastante literatura por ahí que se ocupa de estos temas. En particular, me permito recomendar el “Manual Fundamental de Borland Delphi 2.0”, de un tal Ian Mar- teens; no será el mejor, pero conozco al autor y no es mala persona.
  • 23. Prólogo del Autor 21 Convenios sintácticos A lo largo de este libro tendré que explicar la sintaxis de algunas construcciones de Delphi, especialmente en el área de objetos y clases, y de las instrucciones del len- guaje SQL. Utilizaré en estos casos la notación habitual, que explico a continuación para los lectores no familiarizados: Cursivas Nombres o constantes que el programador debe suministrar. [Corchetes] Lo que se pone entre corchetes es opcional. Puntos suspensivos... Los puntos suspensivos indican la repetición de la cláusula anterior. Verdadero|Falso La barra vertical se utiliza para indicar una alternativa. Acerca de la terminología empleada La mayor parte de este libro ha sido redactada directamente en mi (pobre) castellano. He tratado, en lo posible, de mantener los nombres originales de los objetos y con- ceptos utilizados. En los casos en que he traducido el término, incluyo también su nombre en inglés. No tiene sentido traducir términos nuevos o que se utilizan con poca frecuencia; el próximo autor posiblemente utilizará una traducción diferente, aunque sea por ansias de originalidad. Durante la corrección del libro, he insistido en dos traducciones que pueden resultar extrañas para el lector español. Una de ellas es traducir library como biblioteca, cuando el término más extendido es librería. La otra “singularidad” es utilizar el género feme- nino para la palabra interfaz. El castellano moderno tiende a masculinizar las palabras importadas de otro idioma, así que casi todos dicen en España: “el interfaz”. Pero esta palabra no es realmente una importación; se deriva de faz, que es de género fe- menino. Agradecimientos En primer lugar, quiero agradecer la acogida que tuvo el “Manual Fundamental”. Sin el apoyo del público, no me hubiera decidido a escribir un segundo libro acerca de Delphi. Por otra parte, gracias a los que compraron el libro, Christine (mi ordenador personal) pasó de ser un 486 a 100MHz con 12MB, a convertirse en un Pentium potente de mente fría y corazón caliente; vamos, que le habéis financiado el lifting. Quiero decir, no obstante, que antes de la actualización Delphi 3 podía ejecutarse en mi máquina; no muy felizmente, pero podía.
  • 24. 22 La Cara Oculta de Delphi Durante la redacción de “La Cara Oculta…” tuve el placer de impartir unos cuantos cursos de programación con Delphi. En cada curso aprendí algo, por lo que es de justicia mencionar a todos los profesionales y estudiantes que asistieron a los mis- mos. Dos personas han resultado ser imprescindibles en la revisión del libro. Nuevamente, Octavio Hernández ha tenido que soportar largas charlas cada vez que se me ocurría “una idea genial”. Muchos de los ejemplos que utilizo son fruto de su imaginación; además, le debo el título del libro. Octavio, desgraciadamente, no comparte mi aver- sión a C++: nadie es perfecto. Y Marta Fernández ha tenido el mérito de hacerme comprender que el sentido del humor no es mi punto fuerte. Si este libro resulta al final “legible” e “inteligible” es gracias a ella. A propósito, Marta tampoco es per- fecta: le he dicho que si acertaba con la lotería le daría la mitad, y no se lo ha creído. Finalmente, de no ser por Danysoft International, este libro no hubiera visto la luz, literalmente. Estuvieron las copias de evaluación, las horas de prácticas en red con los más diversos sistemas de bases de datos ... y el apoyo personal de Martha y José Luis Castaño al autor, todas las veces que éste pensó que hacer libros de Informática en España era como escribir frases en la arena de una playa. A todos, gracias. Ian Marteens Pamplona, Agosto de 1997
  • 25. Prólogo a la Segunda Edición Uno escribe un libro cuando siente que tiene algo interesante que contar ... y claro, cuando hay alguien dispuesto a leerlo, y tienes el tiempo disponible, y alguien te ofrece dinero por hacerlo ... Uno escribe una segunda edición cuando se da cuenta de todo lo que faltaba en la primera. Así que quiero dar las gracias en primer lugar a todos los lectores de la primera edición, por la cálida acogida que le dieron a este libro, y por hacerme llegar todos sus consejos, sugerencias y comentarios. Un libro de este tamaño no puede ser obra exclusiva de la experiencia de una sola persona. Aquí está reflejado el trabajo de muchos programadores que tuvieron a bien compartir sus conocimientos conmigo. Me gustaría mencionarlos a todos, pero la lista es larga y temo dejarme a alguien en el tintero. Gracias de todos modos. Agradecimientos especiales a Octavio Hernández, que ha sufrido la revisión de estas páginas sin saltarse un capítulo. Después de ver todos los errores que ha encontrado, he decidido matricularme en clases nocturnas de Expresión Escrita. Como único podré pagárselo es revisando sus tres próximos libros. Para más ejemplos y actualizaciones... Es inevitable que se quede algo en el tintero al terminar un libro. Por este motivo, he decidido mantener una página Web en la dirección www.marteens.com. Consulte periódicamente esta página para nuevos ejemplos y ampliaciones del material cu- bierto en este libro. Ian Marteens Madrid, Agosto de 1998
  • 26.
  • 27. Who is the third who walks always beside you? When I count, there are only you and I together But when I look ahead up the white road There is always another one walking beside you Gliding wrapt in a brown mantle, hooded I do not know whether a man or a woman, — But who is that on the other side of you? T.S. Eliot, The Waste Land
  • 28.
  • 29. Œ Entorno y Herramientas • ¿Es Delphi su lenguaje? • Herramientas y utilidades • Unidades, proyectos y paquetes • Sistemas de bases de datos • El Motor de Datos de Borland Parte
  • 30.
  • 31. Capítulo 1 ¿Es Delphi su lenguaje? E STIMADO LECTOR: si está leyendo estas líneas, es muy probable que haya comprado el libro y tenga claro que la mejor forma de abordar su próximo proyecto de programación es utilizar Delphi. Puede también que hayan im- puesto Delphi en su departamento y no le quede otro remedio que aprenderlo lo mejor posible. Pero cabe la posibilidad de que esté hojeando este libro en la tienda, y que todavía tenga dudas acerca de cuál es el lenguaje de programación que más le conviene para sus aplicaciones de bases de datos. Si está usted convencido de que Delphi es el lenguaje que necesita, adelante: sáltese esta introducción y entre en materia en el siguiente capítulo. Para los que decidan seguir leyendo, describiré en este capítulo las principales características de Delphi como herramienta de desarrollo, comparándolo con otros lenguajes y entornos cuando sea necesario. Espero entonces que este breve resumen le sea de utilidad. Breve historia de un lenguaje llamado Delphi Delphi 1 salió al mercado en la primavera del 95. Estaba diseñado para ejecutarse en Windows 3.1, aunque era compatible con las versiones beta de Windows 95, que aún no se había comercializado. Fue el primer entorno de desarrollo RAD que ofrecía un compilador de código nativo. El lenguaje en que se basaba, como todos sabemos, era Pascal; de hecho, internamente el compilador definía directivas de compilación como VER80, para indicar que se consideraba la versión 8 de Turbo Pascal. Se comerciali- zaron dos versiones: la Desktop y la Client/Server. Ambas incluían un producto de Borland que ya se distribuía con ciertas versiones del Borland C++: el Motor de Bases de Datos de Borland, o Borland Database Engine (BDE). Este era un conjunto de DLLs que permitían el acceso funcional a dBase, Paradox, fuentes de datos ODBC y diversos sistemas SQL: Oracle, InterBase, Informix y Sybase. En la versión Desktop, sin embargo, no se incluían los controladores necesarios para acceder a bases de datos en un servidor, conformándose con las bases de datos locales y ODBC.
  • 32. 30 La Cara Oculta de Delphi Aunque en el momento de la aparición de Delphi 1 Visual Basic llevaba unos cuan- tos años en el mercado, la nueva herramienta tuvo una clamorosa acogida en la co- munidad de programadores. Por primera vez se alcanzaban velocidades de ejecución profesionales en programas desarrollados con el paradigma RAD. Por primera vez, un lenguaje RAD era totalmente extensible, permitiendo sin ningún tipo de manio- bras de distracción el acceso al temido API de Windows. Por primera vez, un len- guaje basado en componentes permitía crear también esos componentes, sin necesi- dad de recurrir a otro entorno de programación La siguiente versión de Delphi apareció también en la primavera (¡qué romántico!) del 96. El principal avance fue la conversión del compilador para generar aplicacio- nes de 32 bits, para Windows 95 (que todos pensábamos que iba a ser Windows 96) y para Windows NT. Además, se incluyó una fase de optimización de código, todo un lujo para un lenguaje compilado, mientras Visual Basic 4 seguía generando código interpretado. La metodología de programación experimentó mejoras importantes: la inclusión de módulos de datos, el Depósito de Objetos, el Diccionario de Datos, la herencia visual, etc. Y, gracias a la retroalimentación por parte de los programadores, los componentes existentes se hicieron más potentes y manejables. Se incluyó tam- bién la posibilidad de crear controladores y servidores de automatización, para apro- vechar las nuevas características de OLE de Windows 95 y NT. El Motor de Datos se aumentó con un controlador para DB2. Posteriormente, en ese mismo año, se realizó una actualización de Delphi con el número de versión 2.01 que, además de corregir errores, incluyó el Internet Solutions Pack, un conjunto de controles Acti- veX para aplicaciones de Internet. En mayo del 97 (¡también primavera!), después de una tensa espera, apareció la ver- sión 3. Las novedades se centraron en tres campos: la tecnología de paquetes (pack- ages), el aprovechamiento de la tecnología OLE (ActiveX, automatización, bases de datos en múltiples capas) y la programación para servidores Web. El objetivo global
  • 33. ¿Es Delphi su lenguaje? 31 de todas estas incorporaciones fue convertir a Delphi en un verdadero entorno de desarrollo cliente/servidor, permitiendo la programación de aplicaciones que se ejecutan en el servidor. El Motor de Datos siguió añadiendo formatos: en aquel momento le tocó a Access y a FoxPro. Por otra parte, la arquitectura de acceso a datos fue modificada para facilitar el desarrollo de componentes de acceso a datos que dejaran a un lado el BDE. En esta línea, Borland lanzó Delphi/400, para acceder a bases de datos de AS/400, que utilizaba la técnica de saltarse el BDE. Al poco tiempo, Borland lanzó una versión de actualización de Delphi, con el nú- mero de serie 3.01. Además de la corrección de bugs, incorporaba un nuevo compo- nente, TMIDASConnection, para permitir el desarrollo de aplicaciones en múltiples capas en redes TCP/IP. Con este componente, se podía evitar la instalación y confi- guración de DCOM en redes mayoritariamente formadas por terminales Windows 95. También hubo un parche, el 3.02, que corrigió algunos problemas relacionados con la tecnología Midas y con los dichosos controles del Internet Explorer, que iban cambiando de versión mes tras mes. Una versión intermedia del BDE, la 4.51 que apareció con Visual dBase 7, añadió el soporte nativo para Access 97, pues la versión incluida en Delphi solamente soportaba Access 95. Finalmente, en julio del 98, Delphi 4 vio la luz. ¡En verano, no en primavera, por primera vez! Delphi 4 ha mejorado ostensiblemente el entorno de programación y desarrollo, al añadir el Explorador de Código, las facilidades de completamiento de clases, etc. Hay mejoras en el lenguaje, pero usted no las notará en su programación cotidiana. Hay novedades en los controles visuales, como el soporte de dockable win- dows (ponga aquí su traducción preferida) y las listas de acciones. En el apartado de bases de datos, se ha añadido soporte para las extensiones de objetos de Oracle 8 (¡la única herramienta RAD que ofrece este soporte, por el momento!) y se ha oficiali- zado el soporte de Access 97. La tecnología Midas se ha beneficiado de adelantos impresionantes, tanto en estabilidad como en posibilidades de conexión: ahora es posible utilizar CORBA como mecanismo de enlace en aplicaciones multicapas y hay soporte para Microsoft Transaction Server. También se ha mejorado el sistema de base de datos en el cliente de Midas, con la posibilidad de utilizar tablas anidadas, campos agregados, etc. No estamos, sin embargo, ante cambios revolucionarios: es muy difícil mejorar algo que ya era muy bueno. ¿Es Delphi un lenguaje “sencillo”? La respuesta al título de la sección depende de lo que usted quiera hacer con él. ¿Quiere montar un mantenimiento simple, con objetos que se pueden representar en registros independientes? En ese caso, sí, es muy fácil. ¿Quiere trabajar sobre un esquema relacional complejo, con referencias complicadas entre tablas, estructuras jerárquicas y todo eso? Bueno, con un poco de disciplina, la aplicación se desarrolla en poco tiempo; es fácil plantearse una metodología de trabajo, y el resultado será un
  • 34. 32 La Cara Oculta de Delphi programa “robusto”, que es algo de agradecer. ¿Quiere que el programa anterior sea independiente del formato de bases de datos subyacente, que se acople lo mismo a sistemas locales, como Paradox y dBase, que a Oracle, InterBase o MS SQL Server? Entonces, amigo mío, necesita leer este libro, para que sepa en qué terreno se ha metido. El problema no reside en Delphi, pues las mismas dificultades se le presentarán con C++ Builder, Visual Basic ó PowerBuilder. La causa de las complicaciones es, a mi entender, el modelo de programación y acceso concurrente que es necesario dominar para este tipo de aplicaciones. El programador de bases de datos locales (léase Cli- pper, Paradox, los distintos COBOL para PCs, etcétera) aborda las cuestiones de concurrencia imponiendo bloqueos en cada registro antes de editarlos. En el 95 por ciento de los casos, no se plantea la garantía de atomicidad de las actualizaciones compuestas, ni la recuperación en transacciones, ni el elevar al máximo la concurren- cia de la aplicación (conozco aplicaciones de facturación escritas en Clipper “para red” que sólo dejan facturar desde un puesto a la vez). Por supuesto, al programador que solamente ha trabajado en este tipo de entorno le cuesta más acostumbrarse a distinguir entre bloqueos optimistas, pesimistas y arquitecturas multigeneracionales. Este libro tiene el propósito de ayudar en el aprendizaje de estos conceptos. En las secciones que vienen a continuación analizaremos en detalle cada una de las principales características de Delphi. Programación orientada a objetos verdadera A 28 años de la definición del primer lenguaje de programación orientado a objetos, y a casi 10 años de la popularización de sus conceptos con la aparición de C++, nadie duda ya de las grandes ventajas aportadas por este estilo de programación y pensamiento. A pesar de esto, muchos de los lenguajes populares RAD no soportan verdaderamente la programación orientada a objetos. Para que un lenguaje sea orientado a objetos debe dar soporte a estas tres características: 1. Encapsulación 2. Herencia 3. Polimorfismo En particular, Visual Basic no permite la herencia, en ninguna de sus versiones. VB está basado completamente en el modelo COM, propuesto por Microsoft. En este modelo, el concepto fundamental es el de interfaz: un conjunto de funciones que deben ser implementadas por cada objeto perteneciente a una clase determinada. Otros modelos de objetos, como CORBA y JavaBeans, admiten que una clase herede las características de otras, lo cual no sucede en COM.
  • 35. ¿Es Delphi su lenguaje? 33 Delphi incorpora un modelo completo de programación orientada a objetos, inclu- yendo encapsulación, herencia simple y polimorfismo. En este sentido Delphi se puede comparar con lenguajes que son paradigmas de ese estilo de programación, como C++. Por ejemplo, aunque Delphi no implementa la herencia múltiple al estilo C++, la versión 3 incluye en compensación el concepto de interfaces, que se encuentra en lenguajes modernos como Java, y que puede utilizarse como mecanismo alterna- tivo en la gran mayoría de las aplicaciones prácticas de la herencia múltiple. El so- porte de interfaces hace posible la programación de objetos COM, controles Acti- veX, automatización OLE, etc. Por ser un lenguaje desarrollado cuando los conceptos de Programación Orientada a Objetos han alcanzado su madurez, Delphi ofrece técnicas de programación que no se encuentran en lenguajes más antiguos como C++. Por ejemplo, Delphi imple- menta como parte fundamental de su arquitectura los constructores virtuales, mé- todos dinámicos, manejadores de mensajes y un estilo mucho más “humano” y fácil de trabajar con la Información de Tipos en Tiempo de Ejecución (RTTI). Estas ex- tensiones se han incorporado también al nuevo C++ Builder, de Inprise Corpora- tion, la compañía antes conocida como Borland International1. Arquitectura integrada de componentes Una de las principales características de Delphi es la arquitectura de sus componen- tes, que permite una completa integración de estos dentro del lenguaje. Los compo- nentes de Delphi están basados en clases desarrolladas en el propio lenguaje; no hay que utilizar otros entornos de programación para crear o extender componentes. Otra consecuencia es que el código de estas clases se ejecuta dentro del mismo espa- cio de direcciones de la aplicación, con la consiguiente ventaja en necesidades de memoria y tiempo de ejecución. Al conjunto de componentes básicos de Delphi se le denomina la Biblioteca de Componentes Visuales; en inglés, Visual Component Library, ó VCL. Visual Basic utiliza como componentes los llamados controles ActiveX, que Delphi también admite. Desde el punto de vista de su implementación, los componentes ActiveX son objetos COM implementados en bibliotecas de enlace dinámico, o DLLs. Un objeto COM (Component Object Model), a su vez, es un objeto con un for- mato binario estándar definido por Microsoft, que permite que diferentes lenguajes de programación hagan uso de las propiedades, métodos y eventos del mismo. Esta es una buena idea, que ahora llega a su madurez al implementarse el llamado DCOM, o Distributed COM, que permite la activación y uso de objetos remotos en red. 1 ¿Os imagináis a Mr. Yocam cantando Purple Rain en la próxima conferencia de Borland ... ejem, perdón ... de Inprise?
  • 36. 34 La Cara Oculta de Delphi Sin embargo, este modelo tiene sus luces y sus sombras. Anteriormente hemos men- cionado uno de sus defectos: no hay soporte directo de herencia, lo cual limita la extensibilidad de las clases. Hay otro inconveniente importante de orden práctico: los controles ActiveX se implementan como DLLs de Windows. Una DLL es, desde el punto de vista del enlazador (linker), un sistema autoconsistente; esto quiere decir que si implementamos un control ActiveX en C, el control debe cargar con el runtime de C; si lo implementamos en Delphi o VB5/6, la librería básica de estos lenguajes de- berá estar presente en tiempo de ejecución. Si nuestra aplicación está basada com- pletamente en este tipo de recursos y tenemos que utilizar (como es lo típico) unas cuantas decenas de ellos procedentes de las más diversas fuentes, piense en el gasto de recursos en que incurriremos. Por el contrario, los componentes VCL se integran directamente dentro de los eje- cutables producidos por Delphi y por C++ Builder. No tenemos que cargar con copias duplicadas de una biblioteca de tiempo de ejecución. Las llamadas a métodos, propiedades y eventos transcurren de modo más eficiente, pues no tienen que pasar por la capa OLE. Además, son completamente extensibles por medio de la herencia. Delphi genera controles ActiveX A pesar de todo lo comentado en la sección anterior, Delphi ofrece, a partir de la versión 3, lo mejor de ambos mundos: los controles VCL pueden ser convertidos, mediante un sencillo paso automático, en controles ActiveX. Hasta el momento, el mercado de componentes ha estado orientado a la producción de controles ActiveX; si tanto Delphi como VB podían utilizar estos controles, y VB no tenía capacidad para trabajar con controles VCL, era evidente que los fabricantes de componentes producirían controles compatibles con estos dos lenguajes. Normalmente, estos controles se programaban en C/C++, y todo el mecanismo de generación de interfa- ces y tablas de métodos virtuales era manual y tedioso. Al introducir el concepto de interfaces, Delphi da soporte directo a la programación de objetos COM. El proceso de implementar una interfaz consiste en declarar una clase que incluya en la lista de ancestros la interfaz que se va a implementar, y en suministrar cuerpos para los métodos de la interfaz. Delphi tiene clases predefinidas que proporcionan la mayoría de los métodos requeridos por los controles ActiveX y otras interfaces COM comunes, además de expertos que facilitan el desarrollo. Tratamiento de excepciones El tratamiento de errores mediante excepciones es la alternativa moderna al trata- miento tradicional mediante códigos de retorno de errores. Gracias a esa técnica, se evita mezclar la lógica de control del algoritmo con las instrucciones de salto de la
  • 37. ¿Es Delphi su lenguaje? 35 detección de errores por medio de códigos de estado. Tanto Delphi como VB im- plementan excepciones, pero solamente Delphi ofrece un conjunto de instrucciones estructuradas correctamente desde el punto de vista del diseño de lenguajes. El di- seño de las excepciones de VB, por el contrario, está basado en el sistema tradicional de Basic (¡que no es un lenguaje estructurado!) y sufre la influencia del carácter inter- pretado del código generado, en las versiones anteriores a la actual. Velocidad de ejecución Delphi, con mucho, sigue siendo el más rápido de los lenguajes RAD. En pruebas realizadas por una prestigiosa revista de Informática, se constató que Delphi es de 3 a 6 veces más rápido que Visual Basic 5 a pesar de que, gracias al compilador incor- porado en la esa versión, los programas de VB5 pueden ejecutarse hasta 20 veces más rápido que antes (según la propia Microsoft). La versión 4 de Delphi es la ter- cera versión de este producto que genera código de 32 bits, por lo cual estamos ante un compilador más estable y confiable. Según pruebas realizadas con Delphi 4 y Visual Basic 6, se sigue manteniendo la proporción 5:1 en las velocidades de ejecu- ción de los programas desarrollados con estos sistemas. Delphi comparte la misma etapa final de optimización y generación de código nativo que la línea de compiladores de C/C++ de Borland. Las optimizaciones implemen- tadas por estos compiladores son muy sofisticadas. Se incluye la detección de subex- presiones comunes a nivel local y global, la optimización de registros, la detección de invariantes de bucles, etc. En el área de la Automatización OLE, es de destacar que a partir de la versión 3 se puede trabajar con las interfaces de objetos COM utilizando la v-table: la tabla de punteros a funciones de la interfaz. Esta mejora a OLE permite alcanzar mayor velo- cidad en las llamadas a funciones en objetos con interfaces duales, en contraste con la técnica anterior, que pasaba por invocar una función del API de Windows. Velocidad de compilación y enlace Uno de los puntos fuertes de Delphi es la velocidad con que se compilan y enlazan las aplicaciones. En este aspecto no tiene parangón con los sistemas competidores. Y es que la velocidad de compilación es muy importante, tratándose de sistemas de diseño y programación interactivos. El formato de unidades de compilación nativo de Delphi, el formato dcu, permite alcanzar mayores velocidades de compilación y enlace al estar basado en el formato obj, especificado por Intel hace ya muchos años, con la mente puesta en técnicas obsoletas de enlace. No obstante, Delphi acepta y genera ficheros obj (a partir de la versión 2), incluso si han sido generados por otros lenguajes. Delphi ofrece un enlazador “inteligente”, que es capaz de eliminar todo el
  • 38. 36 La Cara Oculta de Delphi código que no va a ser utilizado por la aplicación. ¿Imagina las consecuencias? Apli- caciones más compactas, que se cargan más rápido y que ocupan menos espacio en memoria RAM y en el disco. A partir de la versión 3 de Delphi, los tiempos de enlace disminuyen aún más gracias a los packages. Estos packages, o paquetes, se pueden utilizar opcionalmente, y son DLLs que contienen el código de componentes. De esta forma, dos aplicaciones escritas en Delphi que se ejecutan en paralelo en la misma máquina utilizan una sola copia en memoria del código de las librerías de tiempo de ejecución del lenguaje. Como consecuencia, el tamaño físico de los ejecutables disminuye dramáticamente, junto con el tiempo invertido por el enlazador en generar el fichero. De forma adicional, el Entorno de Desarrollo es mucho más rápido y eficiente. Este programa está escrito en Delphi (¡hay que predicar con el ejemplo!) y utiliza la VCL. Antes, la librería de componentes, la complib.dcl (16 bits) ó complib32.dcl (32 bits), y el Entorno de Desarrollo utilizaban copias diferentes de la VCL. Ahora, gracias a los paquetes, este código se comparte, de modo que disminuyen las necesidades de me- moria. A esto añádale que cuando se depura una aplicación nos ahorramos otra copia de la VCL en memoria. Retroalimentación inmediata Se supone que uno de los objetivos fundamentales de un sistema RAD es permitir que el programador pueda hacerse una idea, mientras desarrolla su aplicación, del aspecto que va a tener la misma, sin necesidad de efectuar el tedioso ciclo de compi- lación/enlace/puesta a punto. ¿Ha visto alguna vez la rejilla de datos de Visual Basic durante el tiempo de diseño? Este control no es capaz de mostrar la disposición visual que tendrá en tiempo de ejecución, por lo que el programador debe trabajar a ciegas. Esto, hay que aclarar, no es una consecuencia del lenguaje en sí, sino de un mal diseño de la librería. En cambio, todos los controles de bases de datos de Delphi ofrecen una retroalimentación inmediata, en tiempo de diseño, de su aspecto final. Incluso al establecer relaciones master/detail entre varias tablas, es posible explorar todas ellas de forma sincronizada, utilizando el Editor de Campos. Del mismo modo, cualquier modificación en el formato de campos se refleja inmediatamente en los controles visuales afectados, e incluso los campos de búsqueda (lookup fields), que permiten representar referencias entre tablas, se pueden visualizar durante el diseño de la aplicación. El Depósito de Objetos y la herencia visual La herencia visual es una potente técnica disponible cuando utilizamos plantillas del Depósito de Objetos de Delphi. Es una técnica dirigida tanto a desarrolladores aisla-
  • 39. ¿Es Delphi su lenguaje? 37 dos como a grupos de trabajo. El comportamiento típico de otros entornos de desa- rrollo en relación con el uso de plantillas y expertos, consiste en que la aplicación que solicita una plantilla obtenga una copia local del código necesario. Si posteriormente se realizan modificaciones en la plantilla, estos datos no se propagan a la copia local, por lo cual es necesario repetir los cambios en esta copia, o comenzar nuevamente desde cero. Delphi implementa un Depósito de Objetos, en el cual pueden colocarse plantillas desarrolladas por nosotros mismo e incluso asistentes desarrollados en el propio lenguaje. Delphi permite, al traer plantillas desde el Depósito, hacer una copia, utili- zar el original o crear un objeto por herencia a partir del objeto plantilla. Incluso permite llamadas a eventos heredados con una sintaxis simple y sin demoras en tiempo de ejecución. Por supuesto, Visual Basic no implementa ningún tipo de herencia, mucho menos la herencia visual. Aplicaciones distribuidas Quizás la novedad más importante que introdujo Delphi 3, y que sigue rindiendo frutos en la versión 4, es la posibilidad de crear aplicaciones de bases de datos mul- ticapas, en las que todas las peticiones de datos se dirigen a un servidor de aplicacio- nes remoto. Este servidor se comunica con los clientes utilizando DCOM, OLEn- terprise (un producto cuya versión de evaluación se incluye con Delphi), TCP/IP o CORBA. El Motor de Datos de Borland reside, en esta configuración, en el ordena- dor en que se ejecuta este servidor remoto. Si vamos a utilizar DCOM como proto- colo de transporte, por ejemplo, el ordenador que actúa como servidor debe ejecutar Windows NT 4 o Windows 95 con los parches DCOM que ofrece Microsoft en su Web, o el nuevo Windows 98. Los clientes, o estaciones de trabajo, no necesitan el Motor de Datos, ahorrándose el desarrollador la instalación y configuración del
  • 40. 38 La Cara Oculta de Delphi mismo. ¡Piense cuanto tiempo se ahorra si se trata de instalar una aplicación de bases de datos con decenas de usuarios accediendo a la misma! El conjunto de técnicas que hacen posible esta comunicación se conoce como Midas (Multi-tiered Distributed Appli- cation Services), y le dedicaremos todo un capítulo en este libro. A propósito del Motor de Datos, ahora Delphi puede acceder directamente a bases de datos de Access y FoxPro, si existe una copia del JetEngine de Microsoft en el ordenador. Se siguen soportando todos los formatos anteriores: Paradox, dBase, InterBase, Oracle, Informix, DB2, Sybase y MS SQL Server. El Motor de Datos ha sido mejorado para permitir la adición de nuevos controladores SQL-Links, y la ar- quitectura de la VCL ha sido modificada para permitir la incorporación incruenta de sustitutos del BDE, tales como Titan, Apollo, etc. Componentes de Delphi Por último, se han incorporado en Delphi componentes para dar respuesta a las prin- cipales necesidades de las aplicaciones de gestión: gráficos, tablas cruzadas para so- porte de decisiones, informes. ¿Gráficos tridimensionales? No hay problema. ¿Los quiere en pantalla?, tenemos TChart. ¿Alimentados por una base de datos?, entonces necesita TDbChart. ¿En un informe?, para eso está TQrChart. Y no tema, que estos controles son componentes VCL, nada de controles ActiveX ni cosas semejantes. Una nueva página, Decision Cube, contiene componentes para sofisticados análisis de datos dinámicos. Estos componentes serán fundamentales en la programación de aplicaciones de negocios, que ofrezcan posibilidades de análisis multi-dimensional, lo que comúnmente se clasifica como técnicas de data warehousing. QuickReport, la herramienta de creación e impresión de informes, también ha sido mejorada y aumentada. Ahora es más fácil el diseño de la página de impresión, con un componente más “visual”, y un editor de propiedades más amigable. Se han in- cluido componentes para imprimir imágenes de forma más rápida y conveniente, texto con formato e incluso gráficos de negocios. También se puede guardar el resul- tado en formato HTML, para ser distribuido en la Web.
  • 41. ¿Es Delphi su lenguaje? 39 La versión cliente/servidor de Delphi permite, finalmente, la programación de ex- tensiones para servidores Web. De este modo, es muy sencillo exportar datos que pueden ser visualizados en Internet, sin necesidad de comprar herramientas adicio- nales. En esta misma línea se incluye un amplio conjunto de componentes para el desarro- llo de todo tipo de aplicaciones clientes de Internet: correo electrónico, clientes de FTP, visores para el formato HTML, etc.
  • 42.
  • 43. Capítulo 2 Herramientas y utilidades E L PROPÓSITO DE ESTE BREVE CAPÍTULO es presentar las herramientas que acompañan a Delphi, y las novedades del propio Entorno de Desarrollo dignas de mención en la versión 4. No es mi intención entrar en detalles con estas herramientas: mejor que leer una larga parrafada, es preferible familiarizarse con las mismas mediante la práctica. Delphi y el teclado Nadie discute las ventajas de alcanzar una buena velocidad de edición y diseño con cualquier herramienta de programación. Es doloroso, en consecuencia, ver a ciertos programadores de Delphi sufrir calladamente mientras realizan determinadas opera- ciones que desconocen que se pueden realizar de una forma más sencilla. En esta sección menciono algunos trucos para acelerar el trabajo con el Entorno de Desa- rrollo. Comencemos por la adición de componentes a un formulario. Delphi ofrece, que yo conozca, cuatro formas diferentes de traer un componente a un formulario, aunque muchos programadores solamente aprovechen una o dos: • Realizar un doble clic sobre el componente en la Paleta: Se añade un nuevo componente con el tamaño predeterminado y situado sobre el centro del componente activo del formulario. Supongamos que tiene un panel que ocupa todo el formulario (Align=alClient), y que quiere añadir una barra de mensajes debajo del panel. Si pincha la barra sobre el panel, la barra pertenecerá al panel, no al formulario. La solución es seleccionar el formulario (ver truco con la tecla ESC más adelante), ir al botón TStatusBar y hacer el doble clic. • Realizar un clic en la Paleta y un clic sobre el futuro padre del componente: El componente se crea en el sitio indicado, pero con un tamaño predeterminado. Es la mejor forma de colocar botones, cuadros de edición y otros componentes que se bene- fician con una apariencia estándar. • Realizar un clic en la Paleta, y arrastrar sobre el padre para definir el tamaño: Este método ahorra tiempo cuando se va a utilizar un tamaño diferente del predefinido. Es el
  • 44. 42 La Cara Oculta de Delphi método soportado por Visual Basic, y el único que muchos programadores prin- cipiantes utilizan. • Pulsar la mayúscula y realizar un clic en la Paleta: Con este método, el botón de la Paleta queda seleccionado, aún después de añadir el componente. Así se pueden traer varias instancias del mismo componente con menos clics del ratón. Para volver al modo de selección, hay que pulsar el botón con la flecha de cursor que aparece a la izquierda de la Paleta de Componentes. Las siguientes combinaciones de teclas y ratón sirven durante el diseño de formula- rios, y se aplican cuando hay algún componente seleccionado, y el formulario de diseño está activo, con la barra de títulos en color azul: CTRL+FLECHA Mueve el componente seleccionado, píxel a píxel MAY+FLECHA Cambia el tamaño del componente seleccionado, píxel a píxel ESC Selecciona el “padre” del componente activo MAY+RATÓN Selecciona el formulario, que puede estar oculto bajo varias capas de componentes También podemos activar el movimiento o cambio de tamaño de un componente píxel a píxel si pulsamos la tecla ALT mientras lo manipulamos con el ratón. Para el Editor de Código también existen trucos. Cuando hay un bloque selecciona- do en el editor, pueden aplicarse las siguientes operaciones: CTRL+K P Imprime el bloque CTRL+K I Aumenta el margen del bloque CTRL+K U Disminuye el margen del bloque
  • 45. Herramientas y utilidades 43 Y hablando de bloques, ¿sabía que se pueden definir bloques “rectangulares” en el Editor de Código? El modo de definición de los bloques se controla mediante los siguiente comandos: CTRL+O+C Bloques por columnas CTRL+O+I Bloques “inclusivos” (¡pruébelos!) CTRL+O+K Bloques no inclusivos (los de toda la vida) CTRL+O+L Bloques por líneas ¿Tiene una unidad mencionada en la cláusula uses de un formulario, y quiere abrir el fichero con el código fuente? Si el fichero se encuentra en el directorio activo, pulse la combinación CTRL+INTRO, estando situado sobre el nombre de la unidad, y Delphi se encargará del asunto. Pulsando CTRL+K y un número del cero al nueve, creamos una marca de posición a la cual podemos regresar en cualquier momento pulsando CTRL+Q, más el número en cuestión. Pero quizás la mayor sorpresa es descubrir que Delphi ofrece un mecanismo rudi- mentario para grabar y ejecutar una macro de teclado: CTRL+MAY+R Inicia y termina la grabación de una macro CTRL+MAY+P Reproduce la última macro grabada Por último, las siguientes combinaciones de teclas pueden resultar útiles para no perdernos dentro de la maraña de ventanas y diálogos de una sesión típica de desa- rrollo con Delphi: F11 Trae al Inspector de Objetos al primer plano F12 Intercambia representación visual de un formulario con su código MAY+F12 Muestra la lista de formularios de un proyecto CTRL+F12 Muestra la lista de unidades de código de un proyecto ALT+0 Muestra todas las ventanas abiertas del Entorno de Desarrollo La tecla F12 funciona no sólo con el Editor de Código y los formularios en diseño, sino también con el editor de paquetes (ver el capítulo 3) y con el editor de Bibliotecas de Tipos. Finalmente, el nuevo comando Search|Find in files nos permite buscar tex- tos dentro de ficheros, que pueden ser los del proyecto activo o los de un directorio determinado. He dejado para el final el mejor truco: ¿sabía usted que en el fichero de ayuda aparecen estos comandos, y muchos más, perfectamente documentados? Quizás merezca la pena que pierda unos minutos aprendiendo trucos de teclado, pues le harán ser más productivo.
  • 46. 44 La Cara Oculta de Delphi Code Insight: ayuda durante la edición El Editor de Código ha experimentado mejoras sustanciales a partir de Delphi 3. Una de ellas es el uso de plantillas de código, o code templates. Sitúese en el editor y pulse la combinación de teclas CTRL+J. En respuesta, aparece una lista de nombres de plantillas. Cuando seleccionamos una, se copia el código asociado, y el cursor se desplaza a un punto que depende de la definición de la plantilla. Otra forma de lograr el mismo efecto es tecleando primero el nombre de la plantilla y pulsando entonces CTRL+J; pruebe, por ejemplo, con whileb, que crea el esqueleto de un bloque while con una instrucción compuesta begin…end: while { Aquí se queda el cursor } do begin end; Aunque existe una gran variedad de plantillas predefinidas, también podemos añadir las nuestras. Las plantillas de código se configuran en el diálogo asociado al comando de menú Tools|Environment options, en la página Code Insight: El texto de las plantillas se guardan en el subdirectorio bin de Delphi, en el fichero delphi32.dci. Para definir una plantilla nueva, el programador debe pulsar el botón
  • 47. Herramientas y utilidades 45 Add. En respuesta aparece un cuadro de diálogo que pide el nombre y la descripción de la plantilla: Luego, debe utilizarse el editor para suministrar el texto de la plantilla. La barra verti- cal | sirve para indicar dónde debe quedar el cursor al ejecutarse la plantilla. Por ejemplo: with T|.Create(Self) do try finally Free; end; Las definiciones de macros de Code Insight se almacenan en el fichero delphi32.dci, en el directorio bin de Delphi. Pero seguramente el programador utilizará con mayor frecuencia las ayudas interacti- vas de Delphi acerca de los métodos aplicables a un objeto, y de los parámetros de los procedimientos y funciones. Cuando tecleamos el nombre de una variable de objeto, o de un tipo de clase, y añadimos un punto, aparece una ventana emergente con la lista de métodos y propiedades aplicables. Da lo mismo que el tipo del objeto sea predefinido o haya sido creado por nosotros, con tal de que esté compilado. Si quiere que aparezca esta ventana en cualquier otro momento, debe pulsar la com- binación de teclas CTRL+ESPACIO. Para los procedimientos, funciones y métodos, la ayuda se presenta cuando teclea- mos el paréntesis de apertura a continuación del nombre de una rutina. La ventana
  • 48. 46 La Cara Oculta de Delphi de ayuda es una ventana de indicaciones (esos recuadros amarillos que se interponen en nuestro campo visual cuando dejamos tranquilo al ratón por un tiempo), con el nombre y tipo de los parámetros, según aparecen en la declaración de la rutina. Si se nos pierde la ventana, tenemos el comando de teclado CTRL+MAY+ESPACIO, para que reaparezca la ayuda: La misma combinación CTRL+ESPACIO, que nos ofrece ayuda para seleccionar méto- dos y propiedades, sirve para ayudarnos con los posibles valores de un parámetro cuando nos encontramos dentro de la lista de parámetros de un método, procedi- miento o función: Hay que utilizar con precaución esta técnica, porque en la lista de posibilidades apa- recen todas las constantes, variables y funciones de tipos compatibles, y esto incluye a las de tipo Variant, que salen hasta en la sopa. Ahora mencionaremos las novedades de Delphi 4. La primera es la presencia del nuevo Explorador de Código:
  • 49. Herramientas y utilidades 47 Esta ventana muestra los símbolos definidos dentro de una unidad. Si está activa, podemos realizar búsquedas incrementales de símbolos utilizando el teclado. Tam- bién es útil para cambiar el nombre a un símbolo. Tenga en cuenta, no obstante, que el cambio solamente se aplicará a la declaración, y que habrá que cambiar manual- mente el código en los sitios donde se utiliza el símbolo. Ah, y si le molesta mucho esta ventana, recuerde que puede arrastrarla fuera del Editor, o simplemente cerrarla. La segunda novedad se conoce como Navegación por el Código. Si colocamos el ratón (más bien, el puntero del mismo) sobre un símbolo, ya sea una variable, una clase, un método, un procedimiento, aparece una indicación acerca de dónde está definido tal símbolo. Si además pulsamos la tecla CONTROL mientras estamos sobre el símbolo, éste adopta la apariencia de un enlace HTML (¡ah, la moda!), y nos permite ir inmediatamente al lugar donde ha sido definido o implementado. La historia de esta navegación se al- macena en las listas desplegables asociadas al par de botones de la esquina superior derecha del Editor, que nos permiten movernos hacia delante y hacia atrás por la misma. Por último, las combinaciones de teclas CTRL+MAY+ABAJO y CTRL+MAY+ARRIBA, sirven para alternar rápidamente entre la declaración de un método en la interfaz de una unidad, y su cuerpo, en la sección de implementación.
  • 50. 48 La Cara Oculta de Delphi Class completion Class completion es otra de las técnicas de mejora de la productividad introducidas por Delphi 4. Como el lector conoce, los métodos de una clase deben definir sus cabece- ras dentro de la declaración de la misma, pero su cuerpo debe definirse por separado. Esto implica, casi siempre, navegar desesperadamente desde la sección de interfaz de la unidad a la sección de implementación, y un uso habilidoso de los comandos de copiar y pegar. Delphi nos releva de esta tortura cuando crea métodos de respuesta a eventos, pero nos deja abandonados cuando tenemos que definir otro tipo de méto- dos. Lo mismo sucede cuando queremos definir propiedades para una clase. La decla- ración de una propiedad debe ir precedida por la declaración de sus métodos de acceso. Estos, a su vez, llevan doble trabajo: la declaración de sus cabeceras y su posterior implementación. Es cierto que estas labores son más frecuentes durante la escritura de componentes ... pero todos tenemos derecho a una vida mejor. Delphi 4 ofrece la combinación CTRL+MAY+C para ayudarnos en estos menesteres. Supongamos que tecleamos la siguiente declaración de clase: type TYoQueSe = class(TCiertaClase) public constructor Create(AOwner: TComponent); destructor Destroy; override; published property Entero: Integer; property Vector[Index: Integer]: string; end; Hemos dejado incompletas las dos declaraciones de propiedades. Si ahora tecleamos CTRL+MAY+C, Delphi modifica la clase de esta manera: type TYoQueSe = class(TCiertaClase) private FEntero: Integer; function GetVector(Index: Integer): string; procedure SetEntero(const Value: Integer); procedure SetVector(Index: Integer; const Value: string); public constructor Create(AOwner: TComponent); destructor Destroy; override; published property Entero: Integer read FEntero write SetEntero; property Vector[Index: Integer]: string read GetVector write SetVector; end; También añade, en la sección de implementación de la clase, un cuerpo para el cons- tructor, el destructor y para los tres métodos de acceso que ha generado. Incluso, en el caso de los métodos de acceso, se atreve a sugerirnos una posible implementación:
  • 51. Herramientas y utilidades 49 procedure TYoQueSe.SetEntero(const Value: Integer); begin FEntero := Value; end; Herramientas de depuración Para desarrollar eficientemente aplicaciones con Delphi, es sumamente conveniente dominar las técnicas de depuración. Estas técnicas siguen siendo similares a las del depurador integrado en las primeras versiones de Turbo Pascal. Sin embargo, las diferencias quedan determinadas por la diferente estructura de los programas escritos para MS-DOS y Windows. En un programa para Windows es imposible seguir paso a paso la ejecución de todas las instrucciones del mismo. Hay un momento en que perdemos de vista el puntero de las instrucciones: cuando nos sumergimos en una rutina conocida como el ciclo de mensajes. A partir de este punto, recuperamos periódi- camente el control, cuando Delphi, C++ Builder ó Visual Basic ejecutan algunas de las respuestas a eventos, o cuando C++ ejecuta alguna función de respuesta o método asociado a mensajes. Por lo tanto, lo que debe saber el programador de Delphi es cómo interceptar al programa cuando pase por los sitios que le interesa, y para esto tiene dos posibi- lidades. La primera es establecer un punto de ruptura (ó breakpoint) en una instrucción, para lo cual puede pulsar la tecla F5 (CTRL+F8, si se utiliza a configuración de teclado tradicional de Borland), o ejecutar el comando de menú Run|Add breakpoint, estando seleccionada la línea en la cual nos queremos detener. Cuando el programa se ejecute y pase por esa línea, se detendrá, se activará el Entorno de Desarrollo, y podremos decidir qué hacer: evaluar el estado actual de las variables, seguir ejecutando paso a paso, detener el programa ... La otra posibilidad es utilizar el comando de menú Run|Run to cursor, o pulsar la tecla F4, estando situados sobre la línea deseada. El efecto es similar a colocar un punto de ruptura temporal, ejecutar el programa y liberar el punto una vez llegados al mismo. A un punto de ruptura se le puede asociar una condición de parada, que debe cum- plirse para que el programa detenga allí su ejecución, y un contador de pasadas, para activar el punto a las tantas veces que se pase por él. Los puntos de ruptura pueden
  • 52. 50 La Cara Oculta de Delphi controlarse con el comando de menú View|Breakpoints. El margen izquierdo del Editor de Código muestra también los puntos de ruptura y el estado de los mismos. Una vez que el programa se ha detenido temporalmente en un lugar determinado, comenzamos a seguirle la pista a las instrucciones por las que pasa. Tenemos a nues- tra disposición los siguientes comandos del menú Run: Trace into (F7) Avanzar una instrucción. Si es una rutina y tenemos el código fuente, entramos en su interior. Step over (F8) Igual a la anterior, pero esquivando el interior de las rutinas. Trace to next source line (MAY+F7) Ir hasta la siguiente línea de código disponible. También se puede pulsar F9, y dejar que el programa se ejecute hasta terminar o encontrar un punto de ruptura. La otra técnica importante nos permite conocer el contenido de las variables, atri- butos y propiedades del espacio de datos del programa. Los comandos Run|Evaluate y Add watch nos permiten evaluar dinámicamente una expresión ó inspeccionar cons- tantemente el valor, respectivamente. Recuerde también que, si se trata de una variable o propiedad de un objeto, basta con situar el cursor sobre una referencia a la misma en el código del programa para obte- ner su contenido en una ventana de indicaciones. También podemos utilizar el co- mando de menú Run|Inspect, que solamente está disponible en tiempo de ejecución, para mostrar una ventana como la siguiente con los datos, métodos y propiedades del objeto que deseemos:
  • 53. Herramientas y utilidades 51 Por último, Delphi 4 añade una nueva ventana de depuración: el event log, o registro de eventos que almacena y muestra opcionalmente los siguientes sucesos: carga y descarga de módulos por la aplicación, mensajes de Windows recibidos por nuestra aplicación, activación de puntos de rupturas y mensajes generados con el procedi- miento de Delphi OutputDebugString. ¿Recuerda que en la época de MS-DOS la téc- nica más potente de depuración era con frecuencia escribir en la consola mensajes del tipo “Killroy was here”? Ahora podemos retornar nuestra adolescencia gracias al registro de eventos. Object Browser Uno de los grandes desconocidos del Entorno de Desarrollo de Delphi es el Explo- rador de Objetos; en inglés: Object Browser. Es una herramienta integrada en el entorno, que se ejecuta desde el comando de menú View|Browser. La información que se muestra con la misma se extrae del ejecutable de la aplicación, por lo que el proyecto debe haber sido compilado previamente para poder activar la utilidad. La siguiente figura muestra la ventana principal del Explorador. Consta de dos pane- les; en el de la izquierda se muestra la jerarquía de las clases incluidas en el proyecto, mientras que sus métodos, eventos y propiedades se muestran en el panel derecho. La barra de herramientas de la porción superior de la ventana sirve para restringir la información visualizada. Una posibilidad interesante es la navegación por referencias. BDE Administrator El Administrador del Motor de Datos (BDE Administrator) es el programa necesario para configurar las opciones de acceso a bases de datos de Delphi. Esta aplicación también se instala cuando distribuimos el Motor de Datos con nuestras aplicaciones. Puede ejecutarse desde el grupo de programas de Delphi. También puede configu- rarse el menú Tools del entorno de desarrollo de Delphi para incluir el Administrador,
  • 54. 52 La Cara Oculta de Delphi si es que vamos a utilizarlo con frecuencia. Para configurar Tools ejecute el comando de menú Tools|Configure tools. En el cuadro de diálogo que aparece, pulse el botón Add para añadir la nueva opción. El ejecutable del Administrador, en mi ordenador, corresponde al fichero: C:Archivos de programaBorlandCommon FilesBDEBdeadmin.exe Para más detalles sobre esta herramienta, lea el capítulo sobre el Motor de Bases de Datos. Database Explorer Para conocer la estructura de una base de datos, saber qué tablas contiene, qué co- lumnas, índices y restricciones se han definido para cada tabla, y para visualizar los datos almacenados en las mismas, Delphi ofrece Database Explorer: el Explorador de Bases de Datos. Para activar este programa desde Delphi, basta con seleccionar el comando de menú Database|Explore, pero también puede ejecutarse como utilidad independiente desde el grupo de programas de Delphi. En la versión cliente/servi- dor, en la que se incluye, como es lógico, el acceso a bases de datos SQL, la utilidad se nombra SQL Explorer. La ventana principal de la utilidad contiene dos páginas: Databases y Dictionary. En la primera es donde aparecen las distintas bases de datos asociadas a los alias persis-
  • 55. Herramientas y utilidades 53 tentes del Motor de Datos. El árbol del panel de la izquierda puede expandirse para mostrar jerárquicamente los objetos de la base de datos. Se pueden realizar modifica- ciones en todos estos objetos en el panel de la derecha. El Explorador de Bases de Datos también sirve para configurar el Diccionario de Datos. Esta entidad es utilizada por Delphi en tiempo de diseño; no tiene función alguna en tiempo de ejecución. En el Diccionario de Datos pueden almacenarse, en primer lugar, definiciones de conjuntos de atributos de campos. Los conjuntos de atributos se pueden asociar a los campos de las tablas al ser creados desde Delphi, y permiten uniformizar las propiedades de visualización, edición y validación de los mismos. También se consultan cuando arrastramos un campo sobre un formulario y Delphi crea un control de edición; el tipo del control puede determinarse de acuerdo a los atributos asociados. La otra operación importante con el Diccionario de Datos es la importación de bases de datos al diccionario. Cuando importamos una base de datos, se copian sus definicio- nes de tablas, campos e índices al Diccionario. Se pueden entonces asociar conjuntos de atributos a los campos, de modo tal que estos atributos se asocian automática- mente cuando se crean los campos. Cuando una base de datos ha sido importada, pueden también importarse las restricciones de integridad a determinadas propieda- des de los campos y tablas de Delphi. Esto es útil en la programación cliente/servidor, pues permite evaluar las verificaciones en los ordenadores clientes antes de ser enviadas, disminuyendo el tráfico en la red. Los datos del Diccionario por omisión se almacenan en formato Paradox, en la tabla bdesdd.db. Sin embargo, pueden crearse nuevos diccionarios en diferentes formatos, incluso en bases de datos cliente/servidor, y ser compartidos por todos los miem- bros de un equipo de desarrollo. Database Desktop Sin embargo, mi herramienta preferida para crear tablas de Paradox y dBase sigue siendo Database Desktop, que acompaña a Delphi desde su primera versión. A pesar de la apariencia más moderna de Database Explorer, determinadas tareas se ejecutan más cómodamente y con mayor eficiencia con la “vieja” interfaz del Database Desktop. Por ejemplo, es muy fácil copiar tablas, modificar su estructura y editar su contenido. La siguiente figura muestra el diálogo de creación de una tabla en el for- mato de Paradox 7: