Boletín Pascal #48
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
![]() |
Boletín Pascal #48 - 08-SEP-2003 Índice 1. Unas palabras del editor 2. Cuadros de diálogo HTML Usando la función API ShowHTMLDialog en la MSHTML.dll 3. Reemplazando el InplaceEditor estándar del TStringGrid Cómo modificar el TStringGrid para tener una lista de opciones o un botón con puntos suspensivos en la celda seleccionada 4. Usando los Shell Controls de Delphi 5. Inline Assembler en Delphi (X) - Sonido con el altavoz del PC 6. Foros / listas de correo 7. Delphi en la Red - Componentes, librerías y aplicaciones · Shareware · Freeware · Actualizaciones de Delphi y otros productos Borland - Artículos, trucos y consejos - Tutoriales y capacitación - Otros enlaces - Noticias ________________________________________________________________________ Tecno Soft Solutions. Reseller Autorizado de Symbol Technologies, líder mundial en captura de códigos de barras. >>> http://www.tecno-symbol.com ________________________________________________________________________ 1. Unas palabras del editor Han transcurrido casi cuatro meses desde la última edición, pero ahora me alegra poder anunciar que el boletín ha vuelto! Muchas gracias por las palabras de aprecio y de ánimo que he recibo de los suscriptores. Es agradable saber que el boletín no pasa desapercibido. Hay varios artículos en español que me han enviado en este tiempo y que ya lo iré publicando en subsiguientes ediciones. Como de costumbre, me gustaría comenzar agradeciendo a los autores que contribuyeron artícu- los para esta edición: Wes Turner, Werner Palmer y Dave Murray, y me complace entregar los premios disponibles para esta edición a: * Wes Turner ("Cuadros de diálogo HTML") · SMImport v1.75 - por Scalabium Software ($30 standard, $50 c/fuentes) Conjunto de componentes VCL nativos para importar datos en un dataset sin librerías externas. Soporta Access (usando DAO/MS Jet), Excel (sin OLE/DDE), Lotus 123, QuattroPro, texto, HTML, XML incluyendo formato TClientDataset, Paradox, dBase y cualquier descendiente de TDataSet. Nuevo en la versión 1.75: Creador visual de expresiones; importación desde Word; importación directa desde dBase sin BDE; carga de campos BLOB para XML; estilo extendido para el diálogo del asistente; evento OnCreateStructure que permite la creación dinámica de un dataset antes de realizar el verdadero proceso de importación, y más. http://www.scalabium.com/ * Werner Palmer ("Reemplazando el InplaceEditor estándar ...") · EurekaLog v4.1.1 - por Fabio Dell'Aria (Std $24, Pro $49, Ent $99) EurekaLog le confiere a su aplicación (GUI, consola, Web, etc.) la habilidad de capturar cada excepción que se produzca, generar un registro detallado (con unidad, clase, método y número de línea) y enviarlo por email. Se integra completamente en el IDE, y Ud. sólo tiene tiene que hacer un simple "build" para añadir EurekaLog a sus aplicaciones. No disminuye el rendimiento de las aplicaciones e incrementa el tamaño del archivo compilado en sólo un 0.5% - 4%. Compatible con Delphi 3 - 7 y todas las plataformas de Windows. http://www.eurekalog.com/bannerclick.php?id=15 Para la próxima edición tenemos disponibles los siguientes premios para para dos de los autores que colaboren artículos (en inglés): * NTTools 7 For Delphi - por i-tivity (USD 39.95) ¡Basta de batallar con la API de Seguridad de Windows NT! Obtenga su copia de NTTools 7 para Delphi 4/5/6/7 ahora y ahórrese incontables horas con esta colección de 40 componentes VCL escritos específica- mente para tratar con las funciones de Seguridad de Windows NT. Se incluye código fuente completo. http://www.i-tivity.biz/nttools.htm * LMD SearchPack 2.0 - por LMD Innovative (EUR 39) LMD SearchPack incluye 3 controles para integrar capacidades avanzadas de búsqueda de textos en su proyecto, incluyendo soporte de operadores AND, OR, NEAR y NOT. Viene con código fuente y extensivos ejemplos. http://www.ceberus.com/lmd/products/index.php3#P6 La unidad HighResTimer.pas publicada en la última edición como parte del artículo "Mediciones de tiempo de alta precisión" -por Michael Darling- ha sido modificada para funcionar bajo Delphi 6 y Delphi 7 (y espero que también bajo Delphi 8 eventualmente). Gracias a Francisco Arena por hacernos saber del problema con la compilación condicional. La edición actualizada está en http://www.latiumsoftware.com/download/p0047.zip A propósito, hay una actualización al artículo "Codificar y decodificar Base64 (MIME)" -por Daniel Wischnewski- y su respectivo código fuente, publicado en el Boletín Pascal #40. Gracias al autor por la revisión. La edición actualizada de ese boletín se encuentra disponible para descarga en http://www.latiumsoftware.com/download/p0040.zip Cambiando de tema, quisiera aprovechar este espacio para felicitar a EC Software por su producto Help & Manual (una utilidad de autoría de ayuda), el que ha sido seleccionado como Producto del Año en los Readers Choice Awards 2003 de la revista Delphi Informant Magazine (que mencioné en la edición pasada), aparte de ganar muy ampliamente su categoría (Paquete de Autoría de Ayuda) con un abrumador 51% de los votos! http://www.delphizine.com/opinion/2003/09/di200309jc_o/di200309jc_o.asp Bien, eso es todo por ahora. Espero que disfruten esta edición. Saludos, Ernesto De Spirito eds2004 @ latiumsoftware.com __________________ Colaboraron en esta edición: Dave Murray ________________________________________________________________________ Help & Manual 3, por EC Software · Shareware ($ 279) - Una herramienta visual de autoría de ayuda para generar archivos WinHelp (.HLP), Adobe PDF, páginas HTML y los nuevos archivos HTML HELP (.CHM) introducidos en Windows 98, así como otros formatos de archivo y documentación impresa, todo desde una misma fuente. Una herramienta imprescindible para cualquier desarrollador de software. http://www.helpandmanual.com/ ________________________________________________________________________ 2. Cuadros de diálogo HTML Usando la función API ShowHTMLDialog en la MSHTML.dll Por Wes Turner <splitdfile @ yahoo.com> ¿Dónde está la función ShowHTMLDialog? ¿En una unidad .PAS? =========================================================== No. La función ShowHTMLDialog() está en la biblioteca MSHTML.dll, y necesitará hacer hLib := LoadLibrary('MSHTML.DLL'); para acceder a esta DLL, y luego hacer ShowHTMLDialog := GetProcAddress(hLib, 'ShowHTMLDialog'); para obtener la dirección de la función. Sólo puede usarse esta función si se encuentra instalado el Internet Explorer (o Explorador de Internet) versión 4 o posterior. ¿Cómo es un Cuadro de Diálogo HTML? =================================== Cuando llame a ShowHTMLDialog, Internet Explorer muestra una ventana de navegador tipo diálogo con sólo una barra de título (sin barras de menú, de herramientas, ni de estado). Esta ventana de navegador leerá el HTML en un archivo y lo mostrará en la ventana de navegador. Si necesita entrada de datos del usuario (botones, textos, botones de radio, etc.) necesitará usar JScript o VBScript como lenguaje de codificación para leer o cambiar estas entradas. ¿Qué código se necesita para usar un diálogo HTML? ================================================== Dado que un diálogo HTML es una ventana del navegador Internet Explorer, se usa COM para la comunicación entre su programa y el IE, con variants, y las interfaces IMoniker y IHTMLDialog. La función ShowHTMLDialog implementará estas interfaces por usted. La función ShowHTMLDialog se define a continuación: function ShowHTMLDialog( hwndParent: Cardinal; // Manejador del padre UrlMnk: IMoniker; // IMoniker que tiene el archivo fuente HTML PvarArgIn: PVariantArg; // Dirección variant que contiene el PWChar // enviado al diálogo PWCHOptions: PWChar; // Puntero a cadena con opciones del diálogo PvarArgOut: PVariantArg // Dirección variant que recibe los datos // puestos en IHTMLDialog::returnValue ): HRESULT; // El valor devuelto es un OLE HRESULT (Integer) Parámetros hwndParent - Manejador del padre del cuadro de diálogo; puede ser cero. UrlMnk - Una interfaz IMoniker conteniendo la URL de la que se cargará el archivo HTML para el cuadro de diálogo. El archivo puede ser un recurso de la aplicación. PvarArgIn - Puntero a un registro VariantArg que contiene los datos enviados al cuadro de diálogo. Los datos pasados en este VariantArg se colocan en la propiedad IHTMLDialog::dialogArguments del objeto ventana de diálogo. Se establece principalmente como VT_BSTR, con un PWChar para el texto que el diálogo mostrará. Este parámetro puede establecerse como un VariantArg vacío (VT_EMPTY). PWCHOptions - Opciones de ventana para el cuadro de diálogo. Este parámetro puede ser NIL o la dirección de un PWChar conteniendo una combinación de valores separados por punto y coma (;). POptions := 'dialogHeight:13;dialogWidth:21;resizable:no;help:no;' + 'center:yes' PvarArgOut - Puntero a un registro VariantArg que contendrá los datos enviados desde el cuadro de diálogo cuando se cierre. Este VariantArg obtiene los datos que fueron puestos en la propiedad IHTMLDialog::returnValue del objeto ventana de diálogo. Este pará- metro puede ser un VariantArg vacío. Valor devuelto - Devuelve S_OK si fue exitosa, o un valor de error. El segundo parámetro de ShowHTMLDialog es de tipo IMoniker. Para colocar datos en un IMoniker debe usar la función CreateURLMoniker en la unidad UrlMon.pas, definida a continuación: function CreateURLMoniker( MkCtx: IMoniker; // moniker a usar como contexto de base, // puede ser NIL szURL: PWChar; // contiene el texto de la URL a interpretar out mk: IMoniker // moniker con la nueva URL creada por MkCtx y // szURL. ): HResult; // el resultado es un OLE HRESULT (Integer) Esta cadena URL (szURL) debe ser prefijada con "file://" para significar una ubicación de un archivo en disco, o con "res://" para significar una ubicación de un recurso de programa, y en el caso de un recurso debe ser seguida por un camino y nombre de archivo, y un "/#" precediendo el número de recurso, como ésta para un archivo: UrlStr := 'file://C:\Program Files\HtmlDlg1.htm'; o UrlStr := 'file://' + ExtractFilePath(ParamStr(0)) + 'HtmlDlg1.htm'; y como ésta para un recurso: UrlStr := 'res://MyProgram.exe/#101'; o UrlStr := 'res://' + ExtractFileName(ParamStr(0)) + '/#101'; ====> el #101 se define en su archivo .rc de creación de recursos El tercer y el quinto parámetro de ShowHTMLDialog son de tipo PVariantArg, esto es, un Variant que Delphi no "decodifica" automáti- camente por usted, así que tendrá que leer o escribir este variant usted mismo con el tipo de datos variant .vt (VarArgs.vt) y luego usar ese "tipo" de datos cuando use los datos del Variant. Código de ejemplo para un diálogo HTML ====================================== Aquí va un código de clic de botón que mostrará cun cuadro de diálogo HTML. No comprobé la versión de Internet Explorer puesto que no usé DHTML u objetos COM disponibles en versiones superiores (5, 6, 7 , 8) de IE. El código usa un archivo HTML en disco (HtmlDlg1.htm), en la carpeta de la aplicación. Una cadena de texto (VarArgs.bstrVal) se envía al diálogo con el título del diálogo, una cadena de texto de información, y elementos de texto para colocar en el cuadro combinado. El código para la página web HtmlDlg1.htm se encuentra más abajo en este artículo. uses ActiveX, ComObj, UrlMon; procedure TForm1.button_FileHtmlDlgClick(Sender: TObject); type TShowHTMLDialog = function(hwndParent: Cardinal; UrlMnk: IMoniker; PvarArgIn: PVariantArg; PWCHOptions: PWChar; PvarArgOut: PVariantArg): HRESULT; stdcall; var hLib2: Integer; ShowHTMLDialog: TShowHTMLDialog; URLMoniker: IMoniker; VarArgs, VarReturn: TVariantArg; ArugStr, UrlStr, Return: String; POptions: PWChar; begin Return := 'ERROR, la versión de IE es anterior a la 4 o no soporta ' + 'diálogos HTML'; hLib2 := LoadLibrary('MSHTML.DLL'); if hLib2 <> 0 then try ShowHTMLDialog := GetProcAddress(hLib2, 'ShowHTMLDialog'); if Assigned(ShowHTMLDialog) then begin // Se usa PvarArgIn para pasar datos al diálogo HTML. El variant // VarArgs se usará aquí como un PWChar, usando "^" como deli- // mitador para las siete subcadenas que se envían al diálogo ArugStr := 'Título diálogo HTML^Este es texto de información ' + 'pasado al diálogo<br>Ingrese su nombre abajo^' + 'Pequeña^Mediana^Grande^Mi talla^Talla universal'; // La primer subcadena es el título del diálogo, y la siguiente // subcadena es el texto (y HTML) que será escrito al HTML con // document.write(ArgArray[1]) en JScript. Note que usé tags // HTML en este texto. Esto le permite adaptar el diálogo en // base a datos de su programa. Las restantes subcadenas se // colocan el combo box VarArgs.vt := VT_BSTR; VarArgs.bstrVal := StringToOleStr(ArugStr); // UrlStr se prefija con file:// para significar un archivo en // disco. Use res:// para significar un recurso UrlStr := 'file://'+ExtractFilePath(ParamStr(0))+'HtmlDlg1.htm'; // URLMoniker se establece con la URL del archivo HTML que se // usará como origen del cuadro de diálogo. Puede ser un archivo // un archivo en disco, un recurso de programa, o una dirección // de un archivo en Internet. Si no se encuentra el archivo HTML // se muestra un cuadro de diálogo en blanco OLECheck(CreateURLMoniker(nil, StringToOleStr(UrlStr), URLMoniker)); POptions := 'dialogHeight:17;dialogWidth:23;resizable:no;' + 'help:no;center:yes'; // Se puede omitir POptions (poniéndola en Nil), pero le permite // establecer algunas opciones del diálogo, como ancho y altura VariantInit(OleVariant(VarReturn)); // VariantInit establece el VarReturn.vt a VT_EMPTY if ShowHTMLDialog(Handle, URLMoniker, @VarArgs, POptions, @VarReturn) = S_OK then begin // El método window.returnValue de JScript automáticamente // establecerá VarReturn.vt al tipo de datos que se le asigne. // Yo sólo usé dos tipos de datos para window.returnValue: una // cadena de texto JScript (VT_BSTR - OLE wide string) y un // entero (VT_I4), así que cualquier otro tipo de datos // variant indicará un error. if VarReturn.vt = VT_BSTR then begin Return := VarReturn.bstrVal; // Usé un "^" para delimitar VarReturn.bstrVal, pero el // primer caracter es el número del botón de radio, que // es menor que 9, así que no lo delimité, pues siempre // será un solo caracter (Return[1]) Return := 'Se pulsó Aceptar'#10'Radio es '+Return[1]+#10 + 'Combo es '+Copy(Return,2,Pos('^',Return)-2) + #10'Texto es ' + Copy(Return,Pos('^',Return)+1, 512); end else if VarReturn.vt = VT_I4 then Return := 'No se pulsó Aceptar'#10'VarReturn es ' + IntToStr(VarReturn.lVal) else Return := 'ERROR: El tipo de datos Variant no es entero ' + 'o cadena OLE'; end else Return := 'ShowHTMLDialog FALLÓ'; end; finally FreeLibrary(hLib2); end; ShowMessage(Return); end; Código HTML para el diálogo de arriba ===================================== Abajo se encuentra el código HTML para la página web "HtmlDlg1.htm", a mostrarse en el cuadro de diálogo HTML creado por el código Delphi de arriba. Para obtener funcionalidad de su cuadro de diálogo (presión de botones, ingreso de textos, selección de combos) necesitará usar un lenguaje de HTML script. Si no sabe HTML o algún lenguaje de HTML scripting (JScript, JavaScript, VBscript), entonces los cuadros de diálogo HTML no son para usted. La propiedad window.dialogArguments es su acceso a los datos pasados por el cuadro de diálogo. Habitualmente pasará al cuadro de diálogo una cadena Wide String o un entero en su parámetro VarArgs. Si desea más de un elemento de dato en su variant, puede usar una cadena delimitada y luego el método Split: ArgArray = window.dialogArguments.split("^"); Split usará su único parámetro como el caracter delimitador, para dividir la cadena en un arreglo. Recíprocamente, si necesita devolver más de un dato desde el cuadro de diálogo, nuevamente puede usar una cadena delimitada, como he hecho aquí: <html id=dlg1 style="width: 25.9em; height: 22em"> <!-- Si NO usa PWCHOptions en la llamada a ShowHTMLDialog, puede poner el ancho y altura de la ventana arriba --> <head> <title>Diálogo HTML de prueba</title> <script language="JScript"> var RBnum = 0; var ArgArray = new Array(); // obtener los argumentos del diálogo en un arreglo con .split y el // delimitador ArgArray = window.dialogArguments.split("^"); // La comprobación de ArgArray de abajo no es necesaria, pero le // permite tener un cuadro de diálogo predeterminado en caso de // llamar a ShowHTMLDialog con un PvarArgIn vacío if (ArgArray.length==0) {ArgArray[0]="Título del diálogo";} if (ArgArray.length==1) {ArgArray[1]="No <b>Información </b> Texto";} if (ArgArray.length==2) {ArgArray[2]="Ninguno";} // la primer cadena del arreglo es el título document.title = ArgArray[0]; // establece el valor de retorno predeterminado window.returnValue = 0; function StartUp() { // limpia las opciones en Combo1 Combo1.options.length = 0; // Agrega las cadenas de ArgArray a las opciones del Combo1 var index; index = 2; // Comienza con un índice de 2 porque las primeras dos cadenas // eran el título y la información while(index < ArgArray.length) { var tempOption = new Option(ArgArray[index]); Combo1.options[Combo1.options.length] = tempOption; index++; } // Establece la primera opción del Combo1 como la seleccionada Combo1.options[0].selected = true; } function OkClick() { // Este valor de retorno significa que se presionó el botón Aceptar window.returnValue = RBnum+Combo1.options[Combo1.selectedIndex].text+ "^"+Edit1.value; // Dado que window.returnValue es un variant, no puede obtener texto, // números ni objetos // El entero RBnum se convierte automáticamente a texto // Cierra la ventana de diálogo window.close(); } function CancelClick() { // El valor de retorno -1 significa que se presionó el botón Cancelar window.returnValue = -1; window.close(); } function RadioClick(num) { RBnum = num; // Seleccionar y deseleccionar los botones de radio RB1.checked = (num == 0); RB2.checked = (num == 1); RB3.checked = (num == 2); } </script> </head> <body onload="StartUp()" BGCOLOR="#A0E2F2" TEXT="Black"> <center> <font size="5"><b>Un Cuadro de Diálogo HTML</b></font> <!-- Usé tamaños de fuente fijos porque IE puede tener su fuente predeterminada como grande o pequeña, arruinando su tamaño, pero usted puede usar hojas de estilo para definir fuentes, colores y bordes --> <font size="3"> <br><script language="JScript"> // Una operación útil - document.write( ) // La segunda cadena del arrglo es el texto informativo que se // escribe aquí document.write(ArgArray[1]) </script> <br><input type=text name="Edit1" value="Sin nombre" size="24" title="Escriba su nombre aquí"><p> <table border="2" cellpadding="8" cellspacing="0"> <tr> <td><font size="3"><input type=radio name="RB1" checked=1 onClick="RadioClick(0)">Sr.<br> <input type=radio name="RB2" onClick="RadioClick(1)">Sra.<br> <input type=radio name="RB3" onClick="RadioClick(2)">Srta.</font> </td> <td><font size="3">Elija su talla - <select name="Combo1"></select></font> </td> </tr> </table> <P><input type=button value="Aceptar" id="OkBut" onClick="OkClick()" title="Presione aquí para usar las entradas de arriba"> <input type=button value="Cancel" id="CancelBut" onClick="CancelClick()"> </font> </center> </body> </html> Hay siete subcadenas en el parámetro VarArgs de ShowHTMLDialog. La primera se usa como el título del diálogo, la segunda es el texto informativo escrito en la página HTML con JScript, y las subcadenas restantes se añaden al cuadro combinado (combo box). Para cuadros de diálogo HTML más avanzados también es posible establecer un enlace IDispatch entre el cuadro de diálogo y su programa, de modo que el cuadro de diálogo pueda llamar a código en su programa Delphi a través de IDispatch. Usando un recurso para su archivo HTML ====================================== Puede usarse el mismo código de arriba para un archivo HTML como recurso de un programa, excepto que UrlStr debe cambiarse a UrlStr := 'res://' + ExtractFileName(ParamStr(0)+'/#101'); OLECheck(CreateURLMoniker(nil, StringToOleStr(UrlStr), URLMoniker)); y debe añadirse un recurso a su programa donde se necesitará definir el recurso HTML como número 23 y definir la llamada a ese recurso con un número, como este para HtmDlg.rc: #define RT_HTML 23 #define Dlg1 101 Dlg1 RT_HTML "HtmlDlg1.htm" Necesitará definir el RT_HTML como el número 23 (puede usar cualquier otra designación aparte de RT_HTML, pero ese es el nombre MS), y luego darle a sus archivos HTML un número como 101. Si tiene un navegador o muestra páginas web en su programa, puede considerar usar diálogos HTML. __________________ Visite el sitio web de Wes Turner si desea aprender cómo hacer programas a pura API sin la unidad Forms: http://www.angelfire.com/hi5/delphizeus/ Allí encontrará numerosos ejemplos de programación Windows básica. ________________________________________________________________________ JfControls Lib. Multilenguaje. Multiapariencia. Skins. Privilegios. Más de 40 componentes integrados y personalizables. Múltiples problemas de programación resueltos. Administración centralizada de recursos. Para Delphi 3-7 y C++ Builder 3-6. http://www.jfactivesoft.com/spindex.htm ________________________________________________________________________ 3. Reemplazando el InplaceEditor estándar del TStringGrid Cómo modificar el TStringGrid para tener una lista de opciones o un botón con puntos suspensivos en la celda seleccionada Por Werner Palmer <werner.pamler @ infineon.com> El TStringGrid es un componente Delphi ampliamente utilizado. Se puede ingresar texto directamente en las celdas de la cuadrícula, pero a veces es deseable usar editor "in-situ" alternativos, como un cuadro combinado para elegir entre una lista de valores, o un diálogo de usuario llamado cuando al pulsar el botón "[...]" en la correspondiente celda de la cuadrícula. Mientras que éste es un comportamiento estándar para un TDBGrid, no está disponible para la no enlazada a datos TStringGrid. Se pueden encontrar algunas soluciones por toda la web, pero sin embargo, la funcionalidad básica ya ha sido implementada en el ancestro de cualquier cuadrícula, TCustomGrid. Trabajo con Delphi 6, y esto puede no ser cierto para versiones anteriores. El correspondiente editor in-situ que tiene todas las características mencionadas puede encontrarse en la unidad Grids como TInplaceEditList. Puede ser accedido derivando un nuevo componente desde TStringGrid, el que aquí llamaremos TNewStringGrid. En este nuevo componente, el método "CreateEditor" será reemplazado para usar TInplaceEditList como editor in-situ (en vez del estándar TInplaceEdit). La nueva StringGrid también hereda el método "GetEditStyle" que decide cuáles celdas usarán el nuevo editor in-situ. En la implementación de TNewStringGrid creamos un nuevo evento "OnGetEditStyle" que llama al método GetEditStyle. El manejador del evento recibe las coordenadas de la celda y devuelve el estilo del editor (esSimple, esPickList o esEllipsis, tal como se define en Grids.pas). Adicionalmente para el estilo de editor esPicklist, tenemos que escribir un manejador de evento para el evento "OnGetPickListItems" para pasarle la lista de opciones (un TStringList) a la nueva StringGrid. Para el estilo de editor esEllipsis, necesitaremos un manejador de evento para el evento "OnEditButtonClicked" que se dispara cuando el usuario pulsa el botón "[...]"; este manejador de evento por ejemplo podría abrir un cuadro de diálogo complejo solicitando entrada del usuario y debería llenar la celda con el correspondiente texto ingresado. No se olvide de activar la opción goEditing de la StringGrid, o de otro modo no podrá editar los datos de la cuadrícula. Se adjunta la unidad NewStringGrid y un proyecto de ejemplo. ________________________________________________________________________ ¡Vote por el Boletín Pascal en el DPSC Top 100 Programming web sites! (sólo cliquea "here" donde dice "Click here to vote!", y eso es todo) http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium ________________________________________________________________________ 4. Usando los Shell Controls de Delphi Por Dave Murray <irongut @ vodafone.net> Desde Delphi 6 en adelante, Borland provee Shell Controls, incluyendo TShellTreeView y TShellListView, que imitan la funcionalidad del Explo- rador de Windows, pero están escondidos en la página Samples (muestras) de la Paleta de Componentes, no tienen documentación y hasta su código fuente puede ser difícil de hallar (está en Delphi\Demos\ShellControls). Puede perdonársele si piensa que son una ocurrencia tardía que no se espera que usted use. Recientemente quise construir mi propio cliente FTP porque no me gustan ninguno de los gratuitos que evalué y pensé "tengo Indy, así que ¿cuán difícil puede ser?" Probé la demo de TIdFTP, el componente Indy cliente FTP, y la conexión de red parecía bastante fácil así que comencé a pensar acerca del diseño. Quería algo simple y me decidí por una vista del sistema de archivos local sobre una vista del sistema de archivos remoto, con la barra de herramientas principal entre ambas vistas. Cada vista contendría un TreeView y un ListView con unos pocos botones para una navegación simple al estilo Explorador. También quería arrastrar y soltar (drag and drop) entre los controles y con el Explorador. A esta altura comencé a buscar componentes para implementar el lado local y descubrí los Shell Controls de Borland. Decidí que esa clase de disposición era algo que podía reutilizar, así que comencé a trabajar en un marco genérico. Así que, ¿cómo trabajan? Bien, alguna funcionalidad es fácil de implementar pero en otras formas estos controles pueden ser difíciles de usar y prestarse a confusiones. La mayoría de los métodos que uno esperaría encontrar o no existen o devuelven parámetros de dudoso valor. Frecuentemente son del tipo equivocado para otras llamadas que usted quiera hacer. Lo que deberían haber sido un par de horas de programación fácil rápidamente se transformaron en varias noches de lectura de código fuente, experimentación y tirarse de los pelos. En algún punto de este proceso decidí convertirlo en un artículo, así podría compartir mi dolor con ustedes. ;) Comencemos por lo fácil. Conecté mi TShellTreeView a un TShellListView y comencé con la barra de herramientas. El primer botón que quería era uno que subiera un nivel en el árbol de directorios y después de un poco de mirar me di cuenta que el método TShellListView.Back haría esto por mí. La mayoría de los otros botones que quería eran más difíciles, así que volveré a ellos luego, pero un botón Vistas para el TShellListView fue fácil. Simplemente creé un menú desplegable para mi botón que estableciera TShellListView.ViewStyles. En este punto tenía un simple administrador de archivos que que proveía características básicas de navegación y el menú contextual estándar del Explorador de Windows. Consideré añadir un TShellComboBox sobre la lista de archivos. Quería que ajustara su tamaño con el marco como los otros controles, pero no tiene una propiedad Align. Intenté usando Anchors pero no pude obtener el efecto que quería, así que deseché la idea. Ahora vamos a la parte más complicada. Los shell controls no proveen métodos para ayudarnos a manipular archivos, así que necesitamos usar la API de Windows. La función SHFileOperation() puede realizar las opera- ciones de Copiar, Mover, Eliminar y Renombrar, así que escribí el siguiente envoltorio para hacerla fácil de usar. function TconExplorerFrame.FileOperation(const source, dest : string; op, flags : Integer) : boolean; // Copia, mueve, elimina o renombra archivos y carpetas via WinAPI var Structure : TSHFileOpStruct; src, dst : string; OpResult : integer; begin // Inicializa la estructura de operación de archivo FillChar(Structure, SizeOf (Structure), #0); src := source + #0#0; dst := dest + #0#0; Structure.Wnd := 0; Structure.wFunc := op; Structure.pFrom := PChar(src); Structure.pTo := PChar(dst); Structure.fFlags := flags; case op of // Establece el título de un simple diálogo de progreso FO_COPY : Structure.lpszProgressTitle := 'Copiando...'; FO_DELETE : Structure.lpszProgressTitle := 'Eliminando...'; FO_MOVE : Structure.lpszProgressTitle := 'Moviendo...'; FO_RENAME : Structure.lpszProgressTitle := 'Renombrando...'; end; // case op of.. OpResult := 1; try // realiza la operación OpResult := SHFileOperation(Structure); finally // reporta éxito / fracaso result := (OpResult = 0); end; // try..finally end; // function TconExplorerFrame.FileOperation Esta función devuelve True si la operación fue exitosa, y muestra un diálogo de progreso si es necesario. Fíjese en SHFILEOPSTRUCT en la ayuda de WinAPI para ver los posibles valores y señales. Aún no me decido si necesitaré acceso a esta función desde fuera de mi marco, así que por el momento es un método privado, pero puedo cambiar esto en el futuro. Un botón Eliminar fue simple; todo lo que que tuve que hacer fue determinar qué archivo o carpeta estaba seleccionado y eliminarlo usando FileOperation(). Mientras hacía un botón Refrescar decidí escribir una función genérica que podría ser llamada desde otros métodos y que refrescaría ambos controles. TShellTreeView.Refresh toma un nodo como parámetro, pero ¿qué nodo pasarle? Intenté pasándole la carpeta actual, pero no siempre funcionó (esto también parece ser un problema en el Explorador). Luego probé pasándole el nodo raíz y esto funcionó apropiadamente. El control TShellListView parpadea cuando refrescamos el TShellTreeView al que está conectado, así que primero lo desconecto. Vea el procedimiento TconExplorerFrame.Refresh en el fuente. Al crear una nueva carpeta debemos darle un nombre único. La forma usual de hacerlo es llamarla 'Nueva carpeta' y agregar un número al nombre si esa carpeta ya existe. Escribí una función GetNewFolderName() que devuelve el nombre único que necesitaba usando un bucle While y la función DirectoryExists() de la unidad SysUtils.pas. Mi botón Crear Carpeta llama a esta función y luego usa CreateDir() de SysUtils.pas. Quería proveer un botón Propiedades pero los Shell Controls no tienen ningún método útil. Como presionar Alt+Enter en un TShellListView funciona, me metí en ShellCtrls.pas y revisé el código fuente. Inicial- mente parecía simple, todo lo que tenía que hacer era llamar a DoContextMenuVerb. O no, porque DoContextMenuVerb no es un método de TShellListView sino un procedimiento privado de ShellCtrls.pas. En esta etapa decidí que el plagio era el camino más fácil y lo copié en la unidad de mi marco. Hacer doble-clic a archivos en un TShellListView no funciona (en Win2k por lo menos), pero elegir Abrir en el menú contextual sí. Revisando el fuente tiene un método DblClick que llama a ShellExecute(). Entonces noté TShellFolder.ExecuteDefault. Como un TShellFolder puede ser un archivo o una carpeta y podemos obtener el elemento seleccionado como un TShellFolder llamando a TShellListView.SelectedFolder, escribir un evento OnDblClick fue fácil. Esto también asegura que doble-clic no intente abrir el archivo sino que realice la acción predeterminada de su menú contextual, que es lo que hace el Explorador. En el código fuente vea TconExplorerFrame.shlllstvwFilesDblClick. A esta altura tenía todo lo que quería, excepto arrastrar y soltar. Nunca había programado arrastrar y soltar antes, así que tuve que hacer algo de lectura antes de poner manos a la obra. Idealmente me hubiera gustado poder cambiar el cursor si el usuario pulsaba Ctrl, como hace el Explorador. Esto significaría usar un TDragControlObject para proveer una imagen de arrastrar, así que decidí mantener las cosas simples por ahora y descartar ese efecto. Comencé con arrastrando desde mi TShellListView a mi TShellTreeView. Los métodos y propiedades necesarias (con sus tipos de retorno correctos) parecen no existir hasta que uno se da cuenta que la propiedad SelectedFolder puede devolver tanto archivos como carpetas. Escribí un evento OnDragOver para el TShellTreeView de modo que acepte elementos del TShellListView comencé con su evento OnDragDrop. Rápidamente me encontré conque no podía acceder al archivo arrastrado desde este evento, así que decidí almacenarlo en una variable global a mi marco durante el evento TShellListView.OnStartDrag y luego limpiarla en el evento TShellListView.OnEndDrag. Tuve problemas también con la carpeta destino, TTShellTreeView.GetNodeAt y TTShellTreeView.DropTarget devuelven un TTreeNode pero para obtener el camino para una operación de archivos quería un TShellFolder así que selecciono el DropTarget para recuperar el SelectedFolder (un TShellFolder) y luego vuelvo a selec- cionar la carpeta que estaba seleccionada previamente. Esto hace que el TShellListView parpadee horriblemente (hasta puede verse el cambiar de directorio), así que probé usando TShellListView.Items.BeginUpdate y EndUpdate pero no resultó, de modo que tuve que desconectarlo del TShellTreeView, realizar las operaciones seleccionadas y luego volver a conectarlo. Es desagradable y no me gusta, pero funciona. El evento OnDragDrop no provee información acerca del teclado y deseaba una operación de Copia si el usuario está presionando Ctrl al terminar de arrastrar. Usé la función GetKeyState() de la Jedi Code Library (JCLSysInfo.pas) para esto. Una vez funcionando el arrastre desde mi TShellListView modifiqué mis eventos OnDragOver y OnDragDrop para también aceptar una carpeta arrastrada desde mi TShellTreeView y le agregué al mismo los eventos OnStartDrag y OnEndDrag. Estos seis eventos proveen todas las caracte- rísticas requeridas para soltar un archivo en el TShellTreeView desde dentro del marco. Para mantenerlo simple, sólo permito al usuario seleccionar y arrastrar de a un elemento por vez. El Explorador le permite arrastrar una carpeta desde el árbol hasta la lista de archivos, y arrastrar archivos a carpetas dentro de la lista. Pero arrastrar una carpeta de un TShellTreeView selecciona y muestra esa carpeta y en cualquier caso TShellListView.DropTarget siempre devuelve Nil! Debido a esto no pude encontrar ninguna forma de implementar esas características. :( Habiendo hecho lo que pude para proveer arrastrar y soltar dentro de mi marco, ahora quería hacerlo trabajar con el Explorador. Para aceptar un archivo soltado desde el Explorador usamos mensajes de Windows y no estaba seguro de si eso afectaría mis eventos de arrastrar y soltar, pero me complació descubrir que no. No obstante, tuve algunos problemas en hacerlo funcionar apropiadamente. Debemos llamar a DragAcceptFiles() con el manejador (handle) del control que aceptará archivos para decirle a Windows que le envía el mensaje de soltar archivos, pero TFrame no tiene un evento OnCreate y no podemos referirnos a sus componentes o a él mismo en la sección de inicialización. Hubiera querido que mi marco estuviera totalmente encapsulado pero tuve que resignarme a llamar a DragAcceptFiles() en el evento OnCreate del formulario que lo contiene. Inicialmente quería pasarle el manejador (handle) de mi TShellListView de modo que los archivos sólo pudieran soltarse allí, pero necesitaría un mensaje WMDROPFILES para el TShellListView, por lo que terminé aceptando archivos desde cualquier parte del marco pasándole su manejador (handle). Una vez que resolví estos problemas, el resto fue fácil. El procedimiento TconExplorerFrame.WMDROPFILES maneja el mensaje de soltar. Usa la API DragQueryFile() para determinar la cantidad de elementos siendo soltados y luego la usa de nuevo para obtener el camino completo de un elemento a medida que itera por la lista. Windows automáticamente nos provee con un cursor de Copia y presionar Ctrl o Shift no tiene efecto, de modo que copio los elementos a la carpeta actualmente mostrada en mi TShellListView. También quería poder arrastrar archivos al Explorador u otras instancias de mi programa de prueba, pero no pude encontrar ningún artículo o truco que explique cómo hacerlo. Hubiera esperado que habilitar arrastrar desde el Explorador pudiera darme una de esas características como un efecto colateral o ayudarme a descubrir cómo hacerlo, pero no fue así. Pienso que tal vez necesitaría construir mi propio descendiente de TCustomShellListView que fuera "drag-enabled" con el shell, pero no sé por dónde comenzar. Así que este es el fin de mi exploración con los Borland Shell Controls. Si alguien sabe como arrastrar de Delphi a otras aplicaciones o puede sugerir otras mejoras a mi marco, por favor contácteme. Los fuentes de mi marco y el programa de prueba están en el archivo adjunto; siéntanse libres de usarlos en sus propios programas. ________________________________________________________________________ ¡Vote por el Boletín Pascal en The Programming Pages! http://www.programmingpages.com/?r=latiumsoftwarecomenpascal ________________________________________________________________________ 5. Inline Assembler en Delphi (X) - Sonido con el altavoz del PC Las instrucciones ensamblador IN y OUT nos permiten leer y escribir un puerto de E/S respectivamente. Para leer un puerto: in acumulador, puerto IN lee un byte, palabra o doble-palabra (8, 16 o 32 bits) del puerto especificado, y almacena el resultado en el registro acumulador, es decir en AL, AX, o EAX para un puerto byte, palabra o doble-palabra respectivamente. El número de puerto puede ser una constante byte (0..255) o el registro DX (para así tener acceso a todos los puertos de E/S). Para escribir en un puerto: out puerto, acumulador OUT escribe en el puerto especificado el byte, palabra o doble-palabra que está en el registro acumulador (AL, AX, o EAX ). De nuevo, el número de puerto puede ser una constante byte en el registro DX. NOTA: Puesto que IN y OUT implican acceso directo al hardware y dado que Windows NT/2000/XP no permite eso para aplicaciones de usuario, entonces esas instrucciones no funcionarán (generarán una excep- ción) bajo esos sistemas operativos (a menos que corran en modo protegido en el anillo 0, también conocido como modo kernel). Aquí veremos un ejemplo de uso de ensamblador para leer y escribir puertos de E/S con el fin de programar los chips Contador/Temporizador 8253/8254 e Interfaz Periférica Programable 8255 (PPI) en la placa madre para hacer que el altavoz del PC ejecute un sonido. Los pasos para ejecutar un sonido usando esos chips son los siguientes: 1) Preparar el 8253/8254 para recibir la frecuencia. Esto se hace escribiendo el valor $B6 en el Registro de Control del Temporizador (puerto $43). 2) Escribir la frecuencia del sonido en el Registro de Frecuencia del 8253/8254 (puerto $42). En realidad, no es la frecuencia en Hertz lo que debemos escribir en el registro, sino el resultado de dividir 1331000 por esa frecuencia. Primero se escribe el byte de orden más bajo del resultado, y después el byte de orden más alto. 3) Activar el altavoz y hacer que use el Temporizador 8253/8254. Esto se hace encendiendo los primeros dos bits del Puerto B del PPI 8255 (puerto $61). 4) Apagar el altavoz cuando el sonido deba detenerse. Esto se hace apagando el segundo bit del Puerto B del PPI 8255 (puerto $61). La siguiente función en ensamblador nativo implementa los pasos listados arriba: procedure SpeakerSound(Frecuencia: word; Duracion: longint); // Copyright (c) 2003 Ernesto De Spirito // Visite: http://www.latiumsoftware.com // Ejecuta un tono por el altavoz del PC usando los chips // Contador/Temporizador 8253/8254 e Interfaz Periférica // Programable 8255 (PPI) en la placa madre de la PC. // NOTA: Este código no funcionará bajo Windows NT/2000/XP. asm push edx // Empujar Duracion en la pila (para Sleep) mov cx, ax // CX := Frecuencia; // Preparar el 8253/8254 para recibir los datos de la frecuencia mov al, $B6 // Función: Esperar datos de la frecuencia out $43, al // Escribir en el Timer Control Register // Calcular los datos de la frecuencia mov dx, $14 // DX:AX = $144F38 mov ax, $4F38 // = 1331000 div cx // AX := 1331000 / Frecuencia; // Enviar los datos de la frecuencia al chip 8253/8254 out $42, al // Escribir el byte de orden bajo mov al, ah // AL := Byte de orden alto de AX out $42, al // Escribir el byte de orden alto // Decirle al PPI 8255 que comience el sonido in al, $61 // Leer el Puerto B del PPI 8255 or al, $03 // Encender los bits 0 y 1: // bit 0 --> usar el 8253/8254 // bit 1 --> activar el altavoz out $61, al // Escribir al Puerto B del PPI 8255 // Esperar call Sleep // Sleep(Duracion); // requiere la unidad Windows // Decirle al PPI 8255 que detenga el sonido in al, $61 // Leer el Puerto B del PPI 8255 and al, NOT 2 // Limpiar el bit 1 (desactivar el altavoz) out $61, al // Escribir al Puerto B del PPI 8255 end; Llamada de ejemplo: procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin Randomize; for i := 1 to 3 do SpeakerSound(Random(900)+100, 200); end; NOTA: El uso del altavoz incorporado del PC para producir sonidos es OBSELETO. En su lugar, las aplicaciones deberían usar sonidos MIDI o WAVE. ________________________________________________________________________ ¿Errores Delphi? Capture y registre cada error mostrando unidad, clase, método y número de línea. http://www.eurekalog.com/bannerclick.php?id=15 ________________________________________________________________________ 6. Foros / listas de correo Recordamos a los suscriptores las direcciones de nuestros foros. Para unirse a algún foro, lo más recomendable es hacerlo desde la web para así tener acceso a todas las áreas del foro y la configuración de las opciones de suscripción, pero también es posible suscribirse por email. Para suscribirse desde la web es necesario poseer un ID de Yahoo! (si no tienes el tuyo, puedes conseguirlo gratis registrándote como usuario de Yahoo!). * Delphi-abierto. Programación en Delphi (todos los niveles). Si estás en la etapa de aprendizaje o si no te agradan los foros discriminados por niveles, este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-abierto Suscripción: http://espanol.groups.yahoo.com/group/delphi-abierto/join delphi-abierto-subscribe@gruposyahoo.com * Delphi-intermedio. Programación en Delphi (nivel intermedio). Si ya sabes mucho de Delphi, pero todavía te falta un largo trecho para ser un gurú (o no tanto), este foro es para ti. http://espanol.groups.yahoo.com/group/delphi-intermedio Suscripción: http://espanol.groups.yahoo.com/group/delphi-intermedio/join delphi-intermedio-subscribe@gruposyahoo.com * Delphi-avanzado. Programación en Delphi. Sólo para gurús. http://espanol.groups.yahoo.com/group/delphi-avanzado Suscripción: http://espanol.groups.yahoo.com/group/delphi-avanzado/join delphi-avanzado-subscribe@yahoogroups.com * GrupoKylix. Programación en Kylix. http://espanol.groups.yahoo.com/group/GrupoKylix Suscripción: http://espanol.groups.yahoo.com/group/GrupoKylix/join GrupoKylix-subscribe@yahoogroups.com * FreePascal-es. Programación en Free Pascal (freepascal.org). http://espanol.groups.yahoo.com/group/freepascal-es Suscripción: http://espanol.groups.yahoo.com/group/freepascal-es/join freepascal-es-subscribe@yahoogroups.com * Desarrolladores-Software. Un lugar para tratar todos aquellos temas relacionados con el desarrollo de software y su comercialización, y para compartir experiencias en el ámbito laboral, profesional o comercial con otros. http://es.groups.yahoo.com/group/desarrolladores-software Suscripción: http://es.groups.yahoo.com/group/desarrolladores-software/join desarrolladores-software-subscribe@yahoogroups.com * Componentes. Un foro para buscar/recomendar componentes de software (componentes VCL y CLX, objetos ActiveX, librerías DLL, etc.), así como utilidades, tutoriales, información, etc. http://espanol.groups.yahoo.com/group/componentes Suscripción: http://espanol.groups.yahoo.com/group/componentes/join componentes-subscribe@yahoogroups.com ________________________________________________________________________ Merlin's Delphi Forge Delphi and Kylix news, FAQ, downloads, links, forums and more. Accepting uploads and submissions. http://www.delphifaq.net/ ________________________________________________________________________ 7. Delphi en la Red Por Dave Murray <irongut @ vodafone.net> Componentes, librerías y aplicaciones ===================================== Shareware/Comercial ------------------- * InterBase 7.1 Trial - por Borland http://community.borland.com/article/0,1410,30157,00.html * Versión de prueba de C#Builder Enterprise disponible para descarga http://bdn.borland.com/article/0,1410,30278,00.html * Edición personal de C#Builder 1.0 disponible para descarga. Esta edición está limitada a desarrollo gratuito no comercial. http://bdn.borland.com/article/0,1410,30203,00.html Freeware -------- * TurboPower OfficePartner v1.64b - by TurboPower (with source) OfficePartner is the easy way to integrate your project with Microsoft Office. With OfficePartner you can access COM services in Office with easy to use VCL components. http://sourceforge.net/projects/tpofficepartner/ * KeyNote v1.6.1, by Marek Jedlinsky - Free (MPL 1.1) with source Keynote is a flexible, multi-featured tabbed notebook, based on Windows standard RichEdit control. It's always accessible with a single keypress, even if you work in another application. The basic idea in KeyNote is that you can include many separate notes within a single file. Features include strong data encryption, styles, macros, plugins, and templates. Delphi source code available. http://www.tranglos.com/free/keynote.html * DScriptVCL - by DelphiScript (freeware, source code available for $49) Give Winamp's look & feel and GUI quality to your applications with DScriptVCL, a set of visual components for Delphi 5/6/7. DScriptVCL includes Main Forms, Menus, Panels, Leds, Numeric Displays, Progress Bars, Buttons, Checkboxes and many more other graphical components. http://www.delphiscript.com/dscriptvcl/ * WinAmpDll - by Ivan Spiridonov (with source) A DLL Project which shows how to create WinAmp General Purpose Plugins for WinAmp. http://www.torry.net/vcl/mmedia/other/wagppdll.zip * Keyboard Macro Manager v1.0 - by Daniel Cunningham Delphi IDE Enhancement for saving / restoring keyboard macros. http://www.torry.net/vcl/experts/ide/keymac.zip * TssSimpleIPC v1.0 - by Sunisoft (with source) TssSimpleIPC is a component for Interprocess Communications. Properties: IPCName - specifies the name of IPC, communications will be valid between the components in different process with same name. Events: OnTextMsgRecieved - occurs when another component in different process with same name sent some text message; OnBinMsgRecieved - occurs when another component in different process with same name has sent a binary message. Methods: SendTextMessage - send text message; SendBinMessage - send binary message. http://www.torry.net/vcl/internet/irc/simpleipc.zip * QTest v1.9 - by Michael Johnson (with source) Delphi friendly way to create test cases for test-centric coding (ala, extreme programming). Update includes logging capability, more detail, and some expansion of the methods of testing. http://www.bigattichouse.com/qtest.php * QSetup Installation Suite 4.0.0.4 (28-AUG-2003) - by Pantaray Research Highly effective and powerful setup program featuring a user-friendly and intuitive user interface designed to let you create high quality sophisticated installation delivery with minimum effort and no script programming. QSetup is FREE for independent software developers. http://www.pantaray.com/ Actualizaciones de Delphi y otros productos Borland --------------------------------------------------- * Fixes for Kylix 3 issues on newer distros (updated) - Andrés Colubri Kylix 3 (particularly the C++ part) on newer Linux distributions (eg. RedHat 8 & 9, Madrake 9 & 9.1, SuSE 8.2) has a number of problems: compilation errors with STL, unresolved references when linking, installer and IDE hangs, etc. This package contains a collection of fixes that (hopefully) addresses these problems. http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=20136 * First Update Pack for C#Builder available to registered users http://bdn.borland.com/article/0,1410,30287,00.html Artículos, trucos y consejos ============================ * InterBase 7.1 Trial Technical Specifications - Sriram Balasubramanian Capabilities of the InterBase 7.1 Trial version. http://community.borland.com/article/0,1410,30151,00.html * The Coad Letter 110: Announcing UML 2.0 - by Randy Miller The UML 2.0 Specification has been approved by the OMG. The final editing process is going on and the specification is set to be released to the public by the end of the year. Here is what is new. http://community.borland.com/article/0,1410,30144,00.html * What's New in UML 2? The Use Case Diagram - by Randy Miller This article examines a new element of the use case diagram in UML 2.0 including multiplicities and conditions on "extends" relationships. http://community.borland.com/article/0,1410,30166,00.html * Business Rules - by Randy Miller This article looks at business rules in a modeling and development environment. http://community.borland.com/article/0,1410,30158,00.html * InterBase Community Tools and Solutions - by Aaron Ruddick Third party tools and solutions for InterBase. http://community.borland.com/article/0,1410,30126,00.html * Interview with Steve McConnell - by Clay Shannon Steve McConnell, the author of several important programming books including "Code Complete", "Rapid Development", "Software Project Survival Guide", and "After the Gold Rush" answers questions about his current projects. http://community.borland.com/article/0,1410,29921,00.html * Get Your Delphi Apps off to a Fast Start - by Clay Shannon Explains how and why you should create a template project. This can save you a lot of time whenever you begin a new Delphi project, as the normal "setup work" you do will already be done - setting properties, adding forms and units, etc. http://community.borland.com/article/0,1410,29907,00.html * Interview with Lino Tadros - by Clay Shannon Lino Tadros talks about creating the first ActiveX control ever written with Delphi, a practical joke he played on some of his employees, why he eschews the newsgroups lately, who he impersonates, and the new magazine he is writing for. http://community.borland.com/article/0,1410,30085,00.html * Simple Programming Tip #2 - by Charlie Calvert A discussion of benefits to be derived from using testing tools such as JUnit, DUnit, NUnit or CppUnit. The heart of the argument is that such tools encourage programmers to create highly modular, reusable classes that are easy to maintain. http://community.borland.com/article/0,1410,30049,00.html * Are We Not Geeks? - by Clay Shannon Why is programming the least understood of all professions? There is a conspiracy to defame us! Hollywood and Madison Avenue don't want us to come out from behind our cubicle walls. A tongue-in-cheek take on how programmes are viewed. http://community.borland.com/article/0,1410,29920,00.html * Interview with Chad "Kudzu" Hower - by Clay Shannon Chad "Kudzu" Hower, prime mover behind Indy and IntraWeb, talks about the future of Delphi, what he thinks of .NET, how to bring about world peace, why he rarely reads computer books, and other things. http://community.borland.com/article/0,1410,30038,00.html * Disseminating Your Software - by Clay Shannon The difference between deployment and dissemination of software is discussed, as is the relative merits of hosting your own software or outsourcing that chore. DIY vs. outsourcing is also examined relative to the processing of payments. http://community.borland.com/article/0,1410,29931,00.html * InterBase 7.1 DataType to ADO.NET C# Type mappings - by Borland Developer Support Staff InterBase SQL datatypes and C# Object Type mappings using the InterBase Borland Data Provider (BDP). http://community.borland.com/article/0,1410,30108,00.html * Distributed Information Systems, From A to Z: Part I - Serge Dosyukov This article is a first in a series discussing several aspects of building distributed information systems using Delphi 7 and Indy. http://community.borland.com/article/0,1410,30025,00.html * Interview with Ray Lischner - by Clay Shannon Ray Lischner talks about his books, how he backed into programming, his keyboard deafness, the extent of his multilingualism, C#, his predictions for a post-.NET Borland and what he's working on. http://community.borland.com/article/0,1410,30013,00.html * Life cycle of a Database Application - by Oleg Meeting Analyses a database project's life pattern and concludes some useful recommendations for developers. http://community.borland.com/article/0,1410,28994,00.html * This Old Pipe - by Randall Nagy Few appreciate how much modern computing relies upon pipes and streams. This article reviews how to apply these elegant IPC mechanisms to your console and GUI applications. http://community.borland.com/article/0,1410,29772,00.html * Using XMLBroker with IntraWeb - by Guinther Pauli This article will explain how to use the XMLBroker in a IntraWeb application, caching data and updates in browser. And finally, how to solve this updates to database server. http://community.borland.com/article/0,1410,29860,00.html * Advanced Dynamic Packages - by Vino Rodrigues Topics covered include: Calling Custom Class Methods, Calling Standard Functions and Procedures, Obtaining Package Information and Obtaining Knowledge of Class Names. http://community.borland.com/article/0,1410,29119,00.html * Creating Custom Windows Event Logs - by Dennis Passmore Explains what is involved in creating custom event logs and why they will come in handy to monitor your applications. http://www.thedelphimagazine.com/samples/1655/1655.htm * Adding Regular Expression Filtering to ShellListView - George Merriman How to add regular expression (filename) filtering to the Delphi file explorer application. http://delphi.about.com/library/weekly/aa052503a.htm * Shell Controls: Delphi's Hidden Gems - by George Merriman How to create a reasonable Delphi facsimile of the Windows Explorer, all without writing a single line of code. http://delphi.about.com/library/weekly/aa052503a.htm * Records in Delphi: Part 1 - by Zarko Gajic Learn about records, Delphi's Pascal data structure that can mix any of Delphi's built in types including any types you have created. http://delphi.about.com/library/weekly/aa062700a.htm * Records in Delphi: Part 2 - by Kevin S. Gallagher Why and when to use variant records and creating an array of records. http://delphi.about.com/library/weekly/aa070803a.htm * TNumEdit - by Michael Klaus TNumEdit is a TEdit descendant that only accepts numerical input. You can adjust whether to accept positive or negative numbers, integers or decimals. You can also limit the input by using MinValue and MaxValue. http://delphi.about.com/library/weekly/aa070603a.htm * About Delphi Programming *Current Headlines* - by Zarko Gajic Put About Delphi Programming *Current Headlines* on your web site for FREE! Get the *Current Headlines* without leaving the Delphi IDE using the free Delphi IDE add-on. http://delphi.about.com/library/blsticker.htm * How to execute a Javascript function in a Webbrowser/ IE Document? http://www.swissdelphicenter.ch/en/showcode.php?id=1732 * How to display the items in a listview control display as a group (XP)? http://www.swissdelphicenter.ch/en/showcode.php?id=1782 * How to know when a form is activated or deactivated? http://www.swissdelphicenter.ch/en/showcode.php?id=1775 * How to Determine if you are running inside Virtual PC? http://www.swissdelphicenter.ch/en/showcode.php?id=1756 * How to implement a Linked List Memory Table? http://www.swissdelphicenter.ch/en/showcode.php?id=1758 * How to get the server (router) and client IP address of your dial-up connection? - by Sunish Issac There are quite a lot of articles on retrieving IP addresses for LAN interfaces. Here's one for dialup using RAS(Remote Access Services). http://www.delphi3000.com/articles/article_3683.asp * Changing the z-order of controls - by Daniel Wischnewski Move your control step-by-step. http://www.delphi3000.com/articles/article_3684.asp * RAVE Export Device for EMF, WMF and Bitmaps - by Julian Ziersch How to implement a generic RAVE render device. http://www.delphi3000.com/articles/article_3685.asp * How To Use MSAccess In Delphi (using BDE Components) - by Ameenudeen M Methods to access data in MS Access Database from Delphi Application using standard BDE Components. http://www.delphi3000.com/articles/article_3687.asp * Handle OleExceptions - by Andreas Schmidt A EOleException has more information than the default handler shows. http://www.delphi3000.com/articles/article_3694.asp * DialogUnits To Pixels - by Jean Claude Servaye How to convert dialogs units in pixels if the dialog do not use the system font. http://www.delphi3000.com/articles/article_3695.asp * Check for exe files and DLLs - by Peter Johnson This article looks at how we examine a file to check if it is a DOS or Windows executable and, if so, whether it is a program file or a DLL. http://www.delphi3000.com/articles/article_3696.asp * TreeView+ComboBox - by Eugine Veselov How to create a combobox which has a popup treeview. http://www.delphi3000.com/articles/article_3699.asp * Converting ASCII to Paradox - by gourari noureddine Exports delimited file to a Paradox table. http://www.delphi3000.com/articles/article_3700.asp * Dynamic ODBC DSN create and ADV MS-SQL Login - by Mike Heydon This class adds dynamic ODBC Alias/DSN generation at run-time. Also featured is two login modes, one that lets the programmer handle returned errors and another that stays in a loop with error messages that allows retry and Alias/DSN user setup. There are also properties that set and retrieve ODBC Alias/DSN driver and dsn settings such as CPTimeout, Version etc. http://www.delphi3000.com/articles/article_3702.asp * Advanced exception handler to find the exception source file name, call stack and all other related information - by Clever Components This article describes how to replace the standard Delphi exception handlers with advanced ones in order to get more control over all errors occuring during run-time execution. It is possible to collect very detailed information about all occured exceptions and save this information for later use without any interference with end-user. http://www.delphi3000.com/articles/article_3703.asp * Using TList's and Pointers in Delphi - by Stewart Moss A small demonstration that shows how to use the TList helper object and how to use pointers. It creates a list of Pointers to Integers but they could be a list of pointers to any record or class type. http://www.delphi3000.com/articles/article_3705.asp * Component to Monitor Clipboard - by Enrique Ortuño http://www.delphi3000.com/articles/article_3708.asp * Direct File Access with a StringGrid - by Max Kleiner From time to time we need to populate a StringGrid from a file and save it to a file in a well defined structure like a record. Here's a way to handle this with a contol class. http://www.delphi3000.com/articles/article_3709.asp * Converting a floating point value to an integer value - by Jim Carter Real to Integer typecasting. http://www.delphi3000.com/articles/article_3712.asp * Methods for Cutting and Pasting SQL Select Order by Clause - A. Wijoyo Most of data access components don't have method for sorting in memory records. So the only way for sorting records is add an order by clause to the query and reopen it. These method make this task easier to do. http://www.delphi3000.com/articles/article_3715.asp * Inline-editing with a TTreeView - by Omer Can http://www.delphi3000.com/articles/article_3720.asp * TTreeView descendant showing LAN hierarchy - by Eugine Veselov This component shows your LAN resources represented as a tree. http://www.delphi3000.com/articles/article_3721.asp White Papers / Casos de estudio ------------------------------- * Case Study: Smart Restaurant Solutions See how Smart Restaurant Solutions took advantage of Delphi 7 Studio to deliver a Web Services-based solution to keep ahead of the competition. www.borland.com/products/case_studies/delphi_smart_restaurant.html Tutoriales y capacitación ========================= * BorCon 2003 to be be held in San Jose, California November 1-5, 2003 http://info.borland.com/conf2003/ * Borland Web Seminars The Borland Web Seminar Series is designed to address the latest in development, deployment, and integration technologies. http://info.borland.com/web_seminar/ Available Web Seminars include: - Delivering high-performance applications for the Microsoft .NET Framework - Simplifying Integration of the Microsoft .NET Framework with J2EE/CORBA - Driving Alignment of IT Initiatives with Business Goals - Why Upgrade to JBuilder 9 - Accelerating Productivity with Agile Modeling - Introduction to the Borland Embedded Databases - Performance Management for J2EE Systems * Writing MS SQL Server Extended Stored Procedures with Delphi By Berend de Boer Presents a framework which makes writing Microsoft SQL Server Extended Stored Procedures a breeze with four sample xp's (Extended Stored Procedures) shown and discussed. http://www.berenddeboer.net/article/1293.zip Source code: http://www.berenddeboer.net/article/1293_C.zip * Integrating with Outlook - By Berend de Boer This article explores the possibilities of using Microsoft Outlook as an extension of your program, or vice versa, your program as an extension of Outlook. The article gives you a good idea of Outlook's object model. You'll be able to integrate straight into Outlook itself by extending Outlook's menu and toolbars. After reading this article you should be able to program and control Outlook, sending mail and reading contacts. Also you should have a good start in writing Exchange Extensions. http://www.berenddeboer.net/article/1292.zip Source code: http://www.berenddeboer.net/article/1292_C.zip Otros enlaces ============= * i-griegavcl Sitio dedicado a la programación de componentes (VCL) Delphi con código fuente. http://www.i-griegavcl.com/ * TodoProgramacion Página dedicada a la programación en general. Aquí podrá encontrar documentación, código fuente, programas, foros, noticias, cursos on-line y muchas cosas más. http://www.todoprogramacion.miarroba.com * AjpdSoft Programas gratuitos con código fuente, y trucos para Delphi. http://www.ajpdsoft.com * Borland Partner CDs are online - by John Kaster The partner CD submissions for Borland's latest IDE products are available for download. http://community.borland.com/article/0,1410,29797,00.html * Delphi-PRAXiS Delphi community for German speaking programmers. http://www.delphipraxis.net Noticias ======== * Borland Upgrades Embedded Database - by Paul Krill Borland Software introduced InterBase 7.1, a cross-platform embeddable database that adds support for Windows Server 2003. http://www.infoworld.com/article/03/06/17/HNinterbase_1.html?platforms * BorCon 2003 to be be held in San Jose, California November 1-5, 2003 http://info.borland.com/conf2003/ Other Borland conferences around the world: - EKon 7 - 7th German/Borland Developers Conference - Frankfurt - September 21-26, 2003 http://www.entwicklerkonferenz.de http://www.entwicklerkonferenz.com/ - Borland Conference Europe - Amsterdam - November 10-12, 2003 http://www.europeanborlandconference.com/ - Borland Conference France - Paris - December 10-11, 2003 http://info.borland.fr/conference/2003/ * Open Letter to the Borland C++ Developer Community - by J.P. LeBlanc Learn about the future of the Borland C++ product line... http://bdn.borland.com/article/0,1410,30279,00.html ________________________________________________________________________ ¡Vote por el Boletín Pascal en The Programming Pages! http://www.programmingpages.com/?r=latiumsoftwarecomenpascal ________________________________________________________________________ ¡Tú puedes ayudarnos! Por favor danos una mano y ayúdanos a llegar a los 10.000 suscriptores en los próximos meses. Una forma en que puedes ayudarnos es enviando este enlace a tus amigos: http://www.latiumsoftware.com/es/pascal/index.php boletin-pascal-subscribe@gruposyahoo.com Otra forma es votándonos en alguno de estos rankings para darle más visibilidad a nuestro sitio web y aumentar así el número de suscrip- ciones al boletín: http://www.sandbrooksoftware.com/cgi-bin/TopSite2/rankem.cgi?id=latium http://news.optimax.com/topdelphi/links.exe/click?id=70C517ECAE6E http://www.programmingpages.com/?r=latiumsoftwarecomenpascal http://www.top219.org/cgi-bin/vote.cgi?delphi&83 http://top100borland.com/in.php?who=20 http://top200.jazarsoft.com/delphi/rank.php3?id=latium http://213.65.224.200/cgi-bin/toplist.cgi/hits?Id=80 http://www.programacion.net/votar-enlace.php?id=474 http://www.lawebdelprogramador.com/buscar/enlace.php?id=615 Por favor vota. Son sólo unos segundos para ti que REALMENTE pueden hacer la diferencia. Necesitamos tu ayuda para poder continuar. ________________________________________________________________________ Si no has recibido el archivo con el código fuente completo de los ejemplos que se presentan en este boletín, puedes descargarlo de la siguiente dirección: http://www.latiumsoftware.com/descarga/p0048.zip ________________________________________________________________________ Página principal: http://www.latiumsoftware.com/es/pascal/index.php Página del grupo: http://espanol.groups.yahoo.com/group/boletin-pascal/ Para suscribirse / apuntarse: boletin-pascal-subscribe@gruposyahoo.com Para cancelar / removerse: boletin-pascal-unsubscribe@gruposyahoo.com Para reportar problemas con la suscripción: eds2004 @ latiumsoftware.com ________________________________________________________________________ Este boletín se provee "TAL Y COMO ESTA", sin garantía de ninguna clase. Su uso implica la aceptación de nuestros términos de licencia y de la ausencia de garantía que puedes leer en nuestro sitio web. Allí también encontrarás una nota sobre marcas registradas. Te animamos a que redis- tribuyas este boletín, siempre y cuando lo hagas en forma completa (incluyendo la información de copyright), sin modificaciones y de manera gratuita. Los artículos son copyright de sus respectivos autores y se reproducen aquí con el permiso de los mismos. ________________________________________________________________________ Latium Software http://www.latiumsoftware.com/es/index.php Copyright (c) 2003 por Ernesto De Spirito. Todos los derechos reservados ________________________________________________________________________ |
Los ejemplos completos de código fuente de este número están disponibles para descargar.
![]() |
¿Errores? ¿Omisiones? ¿Comentarios? Por favor contáctanos!






