fuentes grandes en FWH

Una de las cosas que nos están pidiendo los usuarios de nuestros programas ultimamente es la posibilidad de modificar el tamaño de la fuente de los mismos. Con el aumento de tamaño de los monitores actuales es perfectamente posible tener una fuente grande para no tener que forzar la vista. Es posible definir en el programa una fuente y un tamaño, pero creo que la manera correcto de hacer esto es que el usuario defina en Windows que fuente y que tamaño quieren usar y que los programas tomen la fuente de la configuracíón de Windows. Además Windows permite usar el sistema de alisado de fuentes ClearType que permite tener una fuente muy nítida en monitores grandes.

Un formulario típico con fuentes pequeñas sería el siguiente:

20060306e.jpg

Para pasar el programa a fuentes grandes, o mejor dicho, para que siempre coja las fuentes del sistema, tenemos que evitar usar tamaños de fuente fijas en nuestro programa y coger la del sistema. En FWH existe la función GetSysFont() que permite coger la fuente del sistema. Contando que al usar fuentes grandes el propio Windows se encarga de redimensionar los diálogos tenemos que nuestro anterior diálogo se ha trasformado en este:

20060306c.jpg

Perfecto, ¿ no ?

Pues no. Usando GetSysFont() cogemos las fuentes del sistema, pero no se el motivo por el cual determinadas partes del formulario no usa el suavizado de fuentes cuando se le pide a Windows que lo haga. Así, si nos fijamos en la imagen de arriba vemos que realmente hay dos tipos de fuentes en el diálogo, una para los GET y otra para los SAY.

Fijándonos en el menú de la aplicación veremos que este sí que usa el suavizado de fuentes, tal como se aprecia en la siguiente imagen:

20060306g.jpg

¿ Que hacer para que la aplicación tome la fuente de Windows con el suavizado ? La solución me la dió mi amigo Paco – gracias otra vez más – y consiste en usar las siguientes funciones:

//___ manejo de fuentes - Paco García 2006 ___________________________________//
#pragma BEGINDUMP
#include "Windows.h"
#include "hbapi.h"
HB_FUNC( GETDEFAULTFONTNAME )
{
LOGFONT lf;
GetObject( ( HFONT ) GetStockObject( DEFAULT_GUI_FONT )  , sizeof( LOGFONT ), &lf );
hb_retc( lf.lfFaceName );
}
HB_FUNC( GETDEFAULTFONTHEIGHT )
{
LOGFONT lf;
GetObject( ( HFONT ) GetStockObject( DEFAULT_GUI_FONT )  , sizeof( LOGFONT ), &lf );
hb_retni( lf.lfHeight );
}
#pragma ENDDUMP

y en el programa definir de esta manera la fuente de la ventana principal:

::oFont = TFont():New( GetDefaultFontName(), 0, GetDefaultFontHeight(),, )</p>

y luego heredar en las ventanas y dialogos del programa esta fuente. Con esto nuestro diálogo queda de esta manera:

20060306d.jpg

donde se ve claramente que ya toma bien la fuente del sistema con el suavizado de bordes.

El último paso para que nuestra aplicación FWH tome bien las fuentes del sistema es modificar las clases de FWH que usan fuentes de paso fijo, como MsgBar, MsgItem y Ttabs para que cojan la fuente de nuestra ventana principal.

Las próximas versiones de nuestros programas ya funcionarán bien con fuentes grandes.

tooltips de balón en FWH

Muchas veces la diferencia entre un programa y un buen programa está en los detalles. Por eso, un programador debe visitar con asiduidad los foros del lenguaje o herramienta de desarrollo que utiliza y estar al tanto de cualquier comentario que se pueda hacer sobre el mismo.

Hace un par de semanas en el foro de FWH Antonio Linares publicó la manera de cambiar los tradicionales tooltips cuadrados por unos de tipo balón. Los cuadrados son estos:

20050919a.jpg

Para conseguir los tooltips de balón lo único que hay que hacer es ir al código fuente de la clase Window y quitar un comentario que aparece en la linea 2762 – o simplemente buscar ballon en el prg -. Hay que dejar la llamada a CreateTooltip con el último paráametro a .t.

hWnd = CreateToolTip( Self:hWnd, cToolTip, .t. ) // for ballon tooltips !

Luego se recompila la librería y nuestro programa. Ya tenemos tooltips de balón 😉

20050919b.jpg

septiembre, el primer mes de curso

Para mi Septiembre es casi siempre el primer mes del año. En verano suelo reflexionar sobre lo que he estado haciendo durante el año anterior y de alguna manera tratar de planificar el próximo. Supongo que ayuda la faceta de docente, que de alguna manera te liga al calendario escolar.

Para este año, la idea es terminar durante el mes de septiembre las nuevas versiones de Cuaderno de Bitácora y el Puchero con la supresión de BtnGet y las altas dinámicas de claves ajenas. Una vez hecho esto intentar queremos jugar en las major leagues: internacionalizar los programas y lanzarnos a vender en el mundo mundial. Antes de eso tenemos que terminar algunas cosas de la web, como la gestión de la lista de correo que se nos está atragantando. Intentamos instalar phplist pero la cosa se complicó, y vamos a probar con dadamail que parece más sencillo aunque menos potente.

Los iconos de los nuevos programas van a ser de iconexperience. Hemos comprado las colecciones Application Basics y Objects & People y estamos adaptando los progamas con los nuevos iconos. Realmente quedan impresionantes… como en esta captura de azeta:

20050914.jpg

Y para este invierno los libros que tengo en cartera son:

altas de claves ajenas

Una de las nuevas funcionalidades que estamos implementando de cara a las nuevas versiones de los programas que queremos tener listas a vuelta de verano es el alta de claves ajenas. Al introducir un valor que es clave ajena de una tabla, si el valor no existe en la tabla se va a poder introducir en ese momento.

Por ejemplo, en este diálogo introduzco una temática en el artículo que no está dada de alta en la tabla de temáticas:

20050718.jpg

El programa detecta que la clave no existe y avisa

20050718b.jpg

y permite introducirla en ese momento

20050718c.jpg

Aunque parezca una tontería, de esta manera se hace mucho más sencillo introducir grandes volúmenes de datos en los programas, porque no pierdes el hilo de lo que estás haciendo. Si estás dando de alta una artículo no tienes que ponerte a pensar en dar de alta antes la temática sino que se hace sobre la marcha.

cambios en el interfaz

Hasta ahora en los formularios de edición de los programas, cuando un campo podía ser rellenado en base a una tabla auxiliar en la parte derecha del campo aparecía una imagen que al pincharla permitía abrir un formulario de selección sobre la tabla auxiliar. La manera de hacer esto está explicado en un post de mi anterior blog. Un formulario típico podía ser este:

pch4-02a.jpg

En las nuevas versiones de los programas, las imágenes a la derecha de los Get desaparecen y son sustituidas por botones, de esta manera:

20050701.jpg

El motivo del cambio es quitarnos de enmedio tanto gráfico como usamos ahora para tener una interfaz menos recargada, poder recorrer todo el formulario con el teclado, incluyendo la selección de tablas auxuliares, y poder tener dos botones al lado de un campo para permitir seleccionar y lanzar un archivo, cosa que necesito para la nueva versión de Hemerot que estoy preparando y al que corresponde la imagen.

montar un tree desde una DBF con FWH

En el Puchero se usa una clasificación arborescente denominada clasificación francesa y para jugar con ella la monto en un tree. Como he recibido varios correos preguntando la manera de montar el tree desde la dbf, aqui lo explico un poco.

Lo primero es montar una estructura de datos que permita ser representando en forma de arbol. Un arbol no es más que una jerarquía con varios niveles, y lo que tengo en mi dbf son varios campos -hasta 5 – para indicar en que rama del arbol estoy. Los campos se llaman FrN1, FrN2, FrN3, FrN4 y Frn5 de manera que el arbol lo veo así:

(1,0,0,0,0)
···(1,1,0,0,0)
······(1,1,1,0,0)
······(1,1,2,0,0)
···(1,2,0,0,0)

Una vez esto claro el arbol se monta así:

FUNCTION FrTreeLoad( oTree )
LOCAL oDatabase
LOCAL nStep
LOCAL oLink
LOCAL oLink1, oLink2, oLink3, oLink4, oLink5
LOCAL N1	:= 0
LOCAL N2	:= 0
LOCAL N3	:= 0
LOCAL N4	:= 0
oLink := oTree:GetRoot()
SELECT FR
FR->(DbGoTop())
DO WHILE ! FR->(EOF())
···IF FR->FrN2 == 0
······oLink1 := oLink:AddLastChild(FR->FrTipo,IIF(FR->FrHoja,1,2),IIF(FR->FrHoja,1,2),.t.)
······oLink1:Cargo := Str(FR->Frn1,2)+Str(FR->Frn2,2)+Str(FR->Frn3,2)+Str(FR->Frn4,2)+Str(FR->Frn5,2)
···ELSEIF FR->FrN3 == 0
······oLink2 := olink1:AddLastChild(FR->FrTipo,IIF(FR->FrHoja,1,2),IIF(FR->FrHoja,1,2),.t.)
······oLink2:Cargo := Str(FR->Frn1,2)+Str(FR->Frn2,2)+Str(FR->Frn3,2)+Str(FR->Frn4,2)+Str(FR->Frn5,2)
···ELSEIF FR->FrN4 == 0
······oLink3 := olink2:AddLastChild(FR->FrTipo,IIF(FR->FrHoja,1,2),IIF(FR->FrHoja,1,2),.t.)
······oLink3:Cargo := Str(FR->Frn1,2)+Str(FR->Frn2,2)+Str(FR->Frn3,2)+Str(FR->Frn4,2)+Str(FR->Frn5,2)
···ELSEIF FR->FrN5 == 0
······oLink4 := olink3:AddLastChild(FR->FrTipo,IIF(FR->FrHoja,1,2),IIF(FR->FrHoja,1,2),.t.)
······oLink4:Cargo := Str(FR->Frn1,2)+Str(FR->Frn2,2)+Str(FR->Frn3,2)+Str(FR->Frn4,2)+Str(FR->Frn5,2)
···ELSE
······oLink5:= oLink4:AddLastChild(FR->FrTipo,IIF(FR->FrHoja,1,2),IIF(FR->FrHoja,1,2),.t.)
······oLink5:Cargo := Str(FR->Frn1,2)+Str(FR->Frn2,2)+Str(FR->Frn3,2)+Str(FR->Frn4,2)+Str(FR->Frn5,2)
ENDIF
FR->(DbSkip())
ENDDO
oTree:UpdateTV()
oTree:SetFocus()
RETURN NIL

Lo que hago es recorrer el DBF que tengo ordenado por la concatenación de los 5 campos y cuando cambio de nivel añado una rama al nivel inferior.

El resultado:

20050511.jpg

sobre DSay y SayRef o agradecimiento a Ramón Avendaño

Uno de los efectos que siempre me han gustado en los formularios de ‘acerca de’ de los programas es el efecto que yo llamo starwars. Consiste en un texto que se va deslizando de abajo arriba del formulario para desaparecer y luego volver a salir por abajo.

20050506.jpg

Uno de los mejores creadores de controles que ha habido para Fivewin – lo pongo en pasado porque hace años que no se nada de este señor – ha sido Ramón Avendaño. Una de sus clases – DSay o Dynamic Say – sirve para hacer precisamente esto, mover un texto por un área de un formulario. Otra de sus clases – SayRef – sirve para poner un hiperenlace a un texto, de manera que al pinchar en él nos enlace con un sitio web o envie un correo.

Dejo un fichero con un ejemplo de lo que se puede hacer con esta clase. Dentro del fichero va el ejecutable que muestra el efecto, así como los fuentes de las clases DSay y SayRef de Ramón. El ejecutable usa dos BMP que están en ficheros separados, por lo que hace falta descomprimir el ZIP para que el ejecutable se vea bien.

Las clases se pueden encontrar por internet con fuentes y ejemplos, y no he tenido que retocar nada para hacerlas correr con FWH. El ejemplo está compilado con el compilador comercial de xHarbour, pero se puede hacer facilmente con la version open source.

diseño de sistemas interactivos

Ayer fue mi cumpleaños y tuve varios regalos. Aparte de los de mi mujer y mi hija, yo me hice un regalo de un libro que llevaba mucho tiempo queriendo comprar. El título en cuestión es ‘Diseño de sistemas interactivos’ que es la traducción a castellano del libro ‘The human interface’ del recientemente fallecido Jef Raskin. Esta traducción está editada en Argentina y no está disponible en España, asi que la he pedido a una librería de aquel país, concretamente a Cuspide.

iconexperience

Hace unas semanas María me mandó un e-mail con la dirección de un sitio de iconos que desconocía: iconexperience. Los iconos están muy bien y me chocó la cantidad de iconos disponibles, más de 1100, y su precio de 379$ que al cambio son sobre 280€. Vamos que el icono sale a 0,25€. La verdad es que hay muchos iconos repetidos con distintos emblemas, pero la colección es impresionante. Por poner un ejemplo, los iconos del nuevo antispyware de Microsoft son los de esta colección.

ap_sample.pngbd_sample.pngfl_sample.pngns_sample.pngop_sample.pngsd_sample.png

editor de recursos pellesc 2.90

Desde hace algún tiempo uso como editor de recursos el que viene con PellesC. Me acabo de instalar la última versión – 2.90 – y hay algunas mejoras realmente interesantes. Ahora permite ordenar los recursos de un mismo tipo por su nombre, cosa que antes no hacia. También ha mejorado el interfaz, que ahora está basado en pestañas y se han añadido nuevas herramientas de bloqueo y alineación de controles. PellesC es freeware y como editor de recursos es realmente bueno, recomendable 100{480d580d36768405d93963bdd82c570c8132a231e8d2b870ef0b18322d1f72b2}.

20050128.jpg

carrera de gui

Esta semana parece haberse desatado una auténtica carrera de GUI para [x]Harbour, al coincidir el lanzamiento de la beta 9 de Xailer, el Preview4 de VisualxHarbour y el build de enero de 2005 de FivewinHarbour. La impresión sigue siendo la misma:

  • FWH es el GUI consolidado y en esta revisión Antonio Linares ha documentado – por fin ! – muchas funciones y clases que antes no lo estaban.
  • la combinación de GUI+IDE de Xailer la hacen una herramienta poderosa, quizá técnicamente la mejor de las tres.
  • Visual xHarbour es un proyecto verde, pero apunta maneras. Sin embargo creo que es a estos a los que hay que seguir de cerca.

No digo nada de MiniGUI ni de otras GUI como TGTK pues realmente las desconozco o conozco poco de ellas y prefiero no pisar charcos. El atractivo de MiniGUI es su licencia GPL, lo cual ha hecho florecer un nutrido grupo de usuarios de esta librería. De GTK+ me llama la atencíón su capacidad multiplataforma (Windows-Linux). Estoy de acuerdo con Rafa en que hay bastante dispersión.

La mayoría de programadores xbase coincierán conmigo en el efecto revitalizador que xHarbour ha supuesto en nuestro entorno. Ahora mismo nadie pone en duda de que el proyecto puesto en marcha por Patrick Mast y Ron Pinkas es el espejo en que mirar la evolución del lenguaje xbase. Aparte de las bondades del compilador, creo que el aspecto más importante de xHarbour ha sido la revitalización del lenguaje y la generación de un efecto de atracción de nuevos programadores o viejos clipperos que cambiaron de lenguaje de programación y ahora se plantean volver a xbase. Este efecto de atracción sin duda se va a dar también en su Visual xHarbour, y por eso digo que a estos es a los que hay que seguir de cerca. En privado ya he oido algunas críticas a la herramienta, como que cada control que genera el IDE no crea una instancia del control tipo, sino que hereda del mismo y esto va a hacer los ejecutables muy pesados y lentos, pero creo que el posible éxito de la herramienta va a tener más que ver con la a
tracción y las expectativas que genere que con sus características técnicas.

FSDI no modal

Una de las últimas mejoras que hemos incorporado a los programas ha sido convertir la interfaz FSDI en no modal. De esta manera se puede pasar de un mantenimiento a cualquier opción de la barra de menús o de la barra de botones sin cerrar el mantenimiento en el que se está y tambien minimizar la ventana de la aplicación sin cerrar el mantenimiento. Todavía quedan cositas por arreglar pero con esta mejora los programas han ganado bastante.

20041103.jpg

Para hacer esto hemos tenido que añadir la clausula NOWAIT en el ACTIVATE del diálogo, pues hay que recordar que la clase TFSDI está basada en diálogos y no en ventanas. Al hacer esto el diálogo pasa a ser no modal y se puede elegir otra opción de la ventana principal sin cerrarlo, con lo que tuvimos que controlar por código que al abrir un diálogo FSDI no hubiese abierto otro. Otro problema fue que FWH se comporta de una manera extraña: al añadir la clausula NOWAIT a un dialogo pasan a ser no modales el propio dialogo y todos los que se creen a partir de él, con lo cual teniamos el problema de que se podia pasar a otra acción con el dialogo de edición de un registro con el registro a medio editar, lo que no parece muy conveniente. Ya tenemos todo listo, y salvo problema de última hora, en unos dias haremos públicas las versiones candidatas – RC – 1 de Cuaderno de Bitácora y el Puchero.

El XAAC espera.