autocompletado en FWH

Prologo: Quitando comboboxes – hace seis años.

En el caso de campos que son claves ajenas sobre otras tablas, pienso que se debe combinar la facilidad de la introducción de los datos correctos con la capacidad para dar de alta valores nuevos en la tabla auxiliar de una manera directa, y esto último no se puede hacer con comboboxes. Para ello utilizo una combinación de cuadro de texto donde el usuario escribe el valor del campo, y un botón que muestra un formulario de selección de valores. Si el usuario quiere escribir el valor de la clave ajena lo puede hacer directamente y el programa lo valida sobre la tabla auxiliar. Si el valor no está dado de alta en la tabla auxiliar el programa pregunta si se quiere dar de alta, y en caso afirmativo presenta el formulario de alta de la tabla auxiliar. Si el usuario no quiere escribir el valor, puede usar el botón que muestra el formulario de selección y elegir un valor o darlo de alta.Esta manera de hacer las cosas está bien, pero no es perfecta. Como me han comentado varios usuarios de mis programas, lo correcto sería que funcionase un autocompletado del campo de texto sobre el campo que es clave ajena en el mismo. Teclear los valores cada vez es pesado y lleva a errores si no recuerdas como has dado de alta cada valor. Por otra parte el soltar el teclado para hacer click en el botón y seleccionar el valor es un engorro que te hace perder tiempo, sobre todo si tienes que dar de alta muchos registros.

Fisgoneando por los foros de Fivetech encontré una clase TAutoGet que hace precisamente esto, un autocompletado sobre un array donde previamente se han introducido los valores. Incorporar esta clase a un programa es muy sencillo, basta con cargar los valores de los arrays de autocompletado antes de editar el campo correspondiente. Los resultados son espectaculares. Conforme tecleas las primeras letras del valor, te van apareciendo los valores que coinciden coon ellas. Una vez tienes el valor que quieres, con un tab validas el nombre y saltas al siguiente campo. Es mucho más cómodo que soltar el teclado, hacer click en el botón de al lado y ponerte a buscar el valor que quieres introducir. Pocas veces una clase tan pequeña me ha dado unos resultados tan espectaculares. Pura dinamita.

Para los perezosos de visitar el foro de Fivetech dejo un fichero con la clase TAutoGet completa: código fuente, fichero de preprocesado y un pequeño ejemplo, todo sacado del foro. Tengo ya el autocompletado implementado en Findemes, y estará disponible en la próxima versión que vamos a publicar el breve. Ahora estoy pensando en si el autocompletado irá en la edición gratuita o unicamente en la registrada, pero eso es otra historia.

msgbox a la windows vista

En mis programas tengo los mensajes del sistema personalizados. De esta manera controlo que mis programas siempre muestren los típicos mensajes de confirmación, información, alerta y parada de la misma manera en todas las versiones de Windows. También uso mis propios iconos para los mensajes, sacados de las colecciones de iconexperience que uso también en mis programas. De esta manera consigo uniformidad en los programas.

En Windows Vista los mensajes del sistema presentan un aspecto distinto a las anteriores versiones de Windows. Además de los iconos característicos de la nueva versión de Windows, el formulario está visualmente dividido en dos zonas, la de arriba es blanca y contiene el icono y el texto del mensaje, mientras que la parte de abajo es del color habitual del formulario y contiene el botón o botones del mismo.Con FWH es fácil hacer un formulario de estas características usando el control Pages. No hay más que definir el formulario con un control pages donde va la zona blanca y luego crear otro formulario que se solapará encima del anterior. La definición del formulario principal en el fichero RC es de la siguiente manera:

UT_INFO DIALOG DISCARDABLE 29, 34, 206, 88
STYLE WS_POPUP|DS_MODALFRAME|WS_CAPTION|WS_SYSMENU
CAPTION "Cuaderno de Bitácora"
FONT 8, "Ms Sans Serif"
{
  CONTROL "&Aceptar", IDOK, "Button", BS_DEFPUSHBUTTON|WS_TABSTOP, 144, 66, 50, 16
  CONTROL "", 110, "Static", SS_WHITERECT, 0, 0, 206, 60
}

El control que va a contener el control page es el identificado con 110. La definición del formulario que va dentro del control Page del formulario principal es como sigue:

UT_INFO_PAGE DIALOG DISCARDABLE 77, 112, 203, 60
STYLE WS_CHILD|WS_CLIPCHILDREN
FONT 8, "MS Sans Serif"
{
  CONTROL "", 10, "Static", WS_GROUP, 48, 8, 142, 44
  CONTROL "", 111, "TBitmap", 0x00000000, 8, 4, 36, 36
}

El código de la función que muestra el formulario es el siguiente:

FUNCTION msginfo(cText, cCaption)
   LOCAL oDlgInfo, oPage
   LOCAL oBmp

   DEFAULT cCaption := oApp():cAppName+oApp():cVersion

   DEFINE DIALOG oDlgInfo RESOURCE "UT_INFO" TITLE cCaption
   oDlgInfo:oFont  := oApp():oFont

   REDEFINE PAGES oPage ID 110 OF oDlgInfo ;
      DIALOGS "UT_INFO_PAGE"
	oPage:oFont := oApp():oFont

   REDEFINE SAY PROMPT cText ID 10 OF oPage:aDialogs[1]
   REDEFINE BITMAP oBmp ID 111 OF oPage:aDialogs[1] RESOURCE "xpinfo" TRANSPARENT

   REDEFINE BUTTON ID IDOK OF oDlgInfo  ;
      ACTION oDlgInfo:End()

   ACTIVATE DIALOG oDlgInfo ;
      ON INIT oDlgInfo:Center( oApp():oWndMain )

RETURN Nil

con lo que conseguimos un formulario como el siguiente:

escritorio mac – octubre 2007

Cada día voy pasando más tiempo con OS X. Siempre he tenido costumbre de personalizar el escritorio y en mac no iba a ser menos. Sigo con la costumbre de tener un escritorio organizado con carpetas, dentro de las cuales tengo el acceso directo a los programas. Se que es una costumbre muy Windows, pero de momento la cosa está así. No me gustan los dock que van de punta a punta de escritorio y prefiero tenerlo despejadito, unicamente con los programas que uso habitualmente. Quiero probar QuickSilver en cuanto tenga un poco de tiempo, y si me apaño bien con el programa quitaré las carpetas del escritorio.

Este es mi escritorio:

escritorio mac octubre 2007

El fondo de escritorio es de hicksdesign y he cambiado los iconos del sistema por los iconos agua de David Lanham, usando la aplicación gratuita LiteIcon. Por cierto, la captura de escritorio está retocada con Pixelmator, un programa de retoque gráfico que tiene una pinta estupenda y que estoy probando.

¿ Y de programar ? Pues la cosa anda revuelta, así que lo contaré cuando esté todo un poco mas tranquilo.

más iconos y un programa

Una de las cosas que debe tener cualquier programador es una carpeta llena de iconos para sus programas. Como ya dije uso los de iconexperience. Hace como un par de meses pasé por su sitio buscando iconos para una nueva aplicación que estoy preparando y me encontré con la versión 2.0 de sus colecciones, que añade un montón de iconos a los que ya había. Y lo mejor de todo es que la actualización a la versión 2.0 de las colecciones es gratuita para los usuarios que hayan hecho el registro después de Julio de 2005, como es mi caso. Así que de gratis me he llevado un montón de nuevos iconos.

Un sitio donde podemos encontrar iconos gratis es famfamfam. Sus silk-icons son de tamaño 16*16px y son estupendos para usar en task-box como las que uso en mis programas. La licencia de estos iconos es la CC-Atribución lo que nos permite usar en nuestros programas siempre que reconozcamos su autoría.

Y si lo que quieres es crearte tus iconos o retocar uno existente puedes usar un programa freeware llamado IcoFX que no tiene nada que envidiar a ningún programa comercial.

el menú de apagado de Vista

Internet tiene cosas impagables, como la reciente polémica sobre el menú de apagado del inminente Windows Vista.

La cosa comenzó con un artículo de Spolsky criticando la usabilidad del menú en cuestión. Al par de días apareció una traducción del artículo al castellano, por si la cosa no quedaba clara.

La cosa no acaba ahí, pues a los pocos días el autor del menú explicaba los motivos del desaguisado en otro post, que también ha sido traducido.

La cosa tiene su miga. Mientras que los seguidores de las ventanas esperan como agua de mayo la salida e implanteación de Vista, cada vez hay más gente crítica con la manera de hacer las cosas de esta empresa. Y sobre todo, hay alternativas. Recuerdo que hace cosa de un año, comentaba con un amigo la jugada de Apple de usar procesadores de intel. La discusión era sobre si la intención de Mac era que los usuarios de PC se pasaran a Mac o si por el contrario querrían vender OSX a los usuarios de PC. Ahora creo que hay una tercera via, que los usuarios de PC y Windows se pasen a Mac y OSX. Al menos será más fácil apagar la máquina.

guía de diseño de formularios

Los lectores de este blog saben de mi insistencia en cuidar los detalles a la hora de diseñar el interfaz de una aplicación. No basta con saber dónde hay que poner los botones, usar unos bonitos iconos o tooltips de balón.

El asunto más importante a la hora de diseñar el interfaz de una aplicación es el diseño de formularios. Situar controles en un formulario no consiste en arrastrarlos desde un editor de recursos y soltarlos donde caigan. Hay que situarlos correctamente, vigilando las distancias entre controles y las alineaciones entre ellos. No está de más tener una guía de formularios que marque como hay que hacer las cosas. En alanit los formularios se dibujan de esta manera:

dialog1.jpg

dialog2.jpg

fsdi2006

Desde hace bastante tiempo vengo usando en mis programas una clase llamada FSDI que pretende emular un interfaz de documento único a ventana completa. El primer post donde hablaba de esto se llamaba Full Document Single Interfaz y estaba en Software* que fue mi primer blog. Luego hubo modificaciones de la clase, primero con su adaptación a xHarbour, luego el diálogo contenedor pasó a ser no modal, y hace poco conseguí que el diálogo contenedor se redimensionara al redimensionar la ventana principal de la aplicación gracias al uso del método SetSize().

Ahora publico como ha quedado la clase FSDI con todas estas características, así como un pequeño ejemplo de como montar la ventana principal y un diálogo FSDI sobre ella. El código que acompaña al ejemplo es el siguiente:

  • main.prg – punto de entrada de la aplicación y construcción de la ventana principal. El redimensionamiento de esta se hace en la función ResizeWndMain(). Está incluido el soporte de fuentes grandes en caso de que el usuario de la aplicación las tenga seleccionadas.
  • tfsdi.prg – la clase FSDI.
  • pcustomer.prg – construcción de un diálogo FSDI con la TaskBar de Canalfive a la izquierda y una rejilla de datos a la derecha.
  • tabs.prg – las tab que uso para la parte inferior del diálogo fsdi.

Aquí está el ejemplo para descargar: FSDI2006

completando FSDI: un método llamado SetSize()

Una de las cosas de las que carecía nuestro interfaz TFSDI era del ajuste a la ventana principal de la aplicación al redimensionar esta. En el post anterior se ve en una de las capturas que se publicaron en el artículo de PcActual como queda un trozo de ventana sin el diálogo FSDI encima. Esto es debido a que al crear el diálogo FSDI calculamos las coordenadas que debe tener este y lo ponemos en la zona cliente de la ventana principal de la aplicación, pero al cambiar el tamaño de esta no sabiamos como ajustar el diálogo FSDI con sus controles.

La verdad es que la cosa parecía difícil de resolver. Habiamos hecho varios intentos sin resultado, y en la última reunión de GO2000 José Luis Capel nos enseñó una aplicación con un aspecto similar a las nuestras pero con el ajuste a la ventana perfectamente conseguido. La manera de hacer esto por parte de José Luis era usando paneles, y estuve preguntándole varias cosas pero sin resultado. Lo de los paneles era un auténtico lio, o eso me parecía. El caso es que buscando la manera de ajustar di con un ejemplo en la carpeta SAMPLES de FWH en el que nunca había reparado: fwbios.prg. En este ejemplo se hace un ajuste de un listbox definido por código a una ventana mediante el método SetSize() de aquel, invocado al redimensionar la ventana. El caso es que el método SetSize() pertenece a la clase Window y lo heredan todas las clases que derivan de ella, o sea
todos los controles. Este método permite ajustar el tamaño de cualquier control que haya sido definido por código, como por ejemplo el taskbar, xbrowse y tabs que uso en mis diálogos FSDI además del propio diálogo. Y yo sin enterarme ni de que existía este método.

Lo único que he tenido que hacer es que los objetos taskbar, xbrowse y tabs que aparecen el cada diálogo FSDI sean datas de mi clase TApplication que es la que controla la ventana principal, de manera que al redimensionar la ventana pueda acceder a estos controles para ajustarles el tamaño mediante el método SetSize(). En breve publicaré la edición gratuita de Azeta que es el primer programa donde implemento esto.

sistema de búsquedas

Hasta ahora en mis programas la búsqueda de registros era mediante SEEK. Esto quiere decir que al buscar un término, por ejemplo ‘software’ en un fichero de libros, la búsqueda devolvía como resultado el primer registro que empezase por ese término. Si el título del libro era Ingeniería de software la búsqueda anterior ni le rozaba.

A partir de ahora las búsquedas no van a ser por SEEK sino que van a permitir realizar búsquedas en cualquier parte del campo por el que se quiera buscar. Asi ya podré encontrar mis libros de Ingeniería de software al introducir software en el formulario de búsqueda de Cuaderno de Bitácora. El resultado es este:

20060325.jpg

El mayor problema que he tenido para implementar este tipo de búsquedas no ha sido la manera de hacer la búsqueda sino como presentar el resultado. Al final la decisíón ha sido mostrar un formulario con la relación de ejemplares que cumplen la condición para ahi hacer la selección definitiva del ejemplar a consultar. Una lista sobre otra lista, como dice mi amigo Manuel, pero creo que es la mejor manera de hacerlo.