Archivo de la categoría: Programación

Barra de Progreso Infinitas.

Ventana con barra de progreso infinita

Estaba dando una de mis recurrentes revisiones al ClubDelphi. Cuando me encontré con un hilo en dónde un colega pedía un sugerencia para medir mediante un TProgressBar el proceso de conexión al servidor de Base de datos. A cómo ya sabrán algunos, medir cuánto tardará en establecerse una conexión, es cómo tratar de determinar el movimiento de las partículas cuánticas.

Por eso, le he sugerido cambiar de paradigma y utilizar una barra de progreso infinita (tienen varios nombres, pero así las conozco yo). Nunca había intentado hacer una, pero dando una pequeña hojeada a MSDN, veo que no es tan difícil de conseguirla con Delphi. A continuación el código necesario:

procedure TForm1.FormCreate(Sender: TObject);
var
    CS: Cardinal;
begin
    CS := GetWindowLong(Self.ProgressBar1.Handle, GWL_STYLE);
    CS := CS or PBS_MARQUEE;
    SetWindowLong(Self.ProgressBar1.Handle, GWL_STYLE, CS);
    SendMessage(Self.ProgressBar1.Handle, PBM_SETMARQUEE, Integer(True), 0);
end;

Para utilizar el código anterior, debes agregar la unidad CommCtrl a la sección de Uses de tu unidad. Es esa unidad está definida las constantes PBM_SETMARQUEE y PBS_MARQUEE.
Referencias:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb760816(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/bb760820(v=vs.85).aspx#PBS_MARQUEE

http://msdn.microsoft.com/en-us/library/windows/desktop/bb760842(v=vs.85).aspx

PD: El código requiere de la versión 6 de los Common Controls de Windows. Por lo que sólo se ejecutará en Windows XP y posteriores. Además, requiere que tu aplicación tenga activo los temas visuales.

[ACTUALIZACIÓN]: A cómo oportunamente apunta Román, Delphi 7 no trae definidas las constantes PBM_SETMARQUEE y PBS_MARQUEE. Así que hay que declararlas.

const
  PBS_MARQUEE = $08;
  PBM_SETMARQUEE = WM_USER+10;
Etiquetado ,

Indy y sus problemas con acentos y otras letras

Hace un par de semanas trabajando en un nuevo proyecto en dónde por primera vez utilizo en gran medida los componente INDY encontré un problema muy grave al enviar datos al servidor. Los caracteres fuera de la tabla ASCII[áski] se perdían. O sea los caracteres cómo

Ñ, Á, É, Ö, Ü,

etc. Pasé días buscando en la red el origen y solución a este problema. Entre todo lo que busqué y leí, lamentablemente lo único que me sirvió es saber que en las nuevas versiones de éstos componentes el problemas ya estaba resuelto. Sigue leyendo

Etiquetado , ,

Podría crearse algo regular sin escribir código?

Esta leyendo un artículo de la Smashing Magazine, pero me llamó la atención el siguiente anuncio de Adobe, que por ser yo un programador me pareció muy perculiar.

Adobe Dreamweaver + Business Catalyst - Build dynamic websites without programming

Dreamweaver + Business Catalyst – Haz websites dinámicos sin programar

Lo primero que se me vino a la mente fue: ¿Realmente se podrá hacer un sitio web dinámico sin escribir una sola linea de código? En realidad sí es posible. Pero la verdad es que nunca podrás hacer algo medianamente bueno sin echarte a teipiar código. Entonces se me vino a la mente otra pregunta: ¿A qué mercado está dirigido esta publicidad? Pensé: quizás a los malos programadores tal vez, o a las personas que les gusta hacer todo por si mismos y lo que quieren hacer es algo básico y creen que pueden prescindir de un programador para la tarea. Los últimos los entiendo, aunque creo que es más barato pedirle a un programador que te programe algo sencillo, que invertir en la licencia de una herramienta como ésta.

Pero lo que realmente me llama la atención del anuncio, es la probabilidad que existan programadores a los que ya no les guste programar. Tal vez serán aquellos programadores que nacieron atraídos por el boom del punto com, o tal vez “programadores” que nunca tuvieron la aptitud para serlo. No sé cómo un programador puede llamarse programador sino le gusta programar, sería como si un pintor no le gustase pintar. Alguien así no sería un verdadero pintor. Muchos nos iniciamos en esta arte por mero gusto, iniciamos programando como un pasa tiempo. Nos encanta tanto que lo haríamos gratuitamente -ese entusiasmo es el motor del software libre-.

En lo personal admiro el código bellamente escrito cómo si de una obra de arte se tratase , me deleita. Aún utilizando Dreamweaver siempre uso la vista dividida (código HTML y WYSIWYG) trabajando el 85% del tiempo en el código. Me siento en mi mundo, me siento que soy capaz de expresar libremente mis ideas, me siento en el control total.

Esa es mi opinión, no sé que opinarán ustedes al respecto.

Saludos.

Etiquetado , , , ,

Mejorando el evento OnBeforePaint

¡Hola nuevamente a todos! Lamentablemente he tenido un poco desatendido el blog por unos largos meses. Pero ahora vuelvo con la intensión de liberar una ligera modificación hecha al código de  JVLC. La licencia Mozilla me obliga a liberar mis aportaciones y/o modificaciones hechas a un código liberado originalmente con esta licencia. Es por esta razón que siendo un ciudadano muy respetuoso de la ley hago la público mi código. Sinceramente no solo lo hago porque la licencia me obliga, sino porque espero que otros desarrollares se beneficien de esta pequeña, pero muy útil modificación.

Primero quiero hacer una breve reseña sobre el origen de esta modificación. Resulta que últimamente me he vuelto un poco paranoico con la cuestión del Custom Drawing en el DBGrid. Es por eso que llegué a la necesidad de querer pintar toda la apariencia, no sólo de una simple celda, sino la de un Grid entero. En mi búsqueda de una solución eficiente y sencilla, trabajando con el componente TJvDBGrid me encontré con el evento “OnBeforePaint“. Me pareció una genial idea que alguien halla incluido tan útil evento a este componente. Lamentablemente, parece que a la persona que se le ocurrió esta idea no pensó en algunas posibilidades más que se le podrían dar a este evento, pues simplemente era un evento de tipo TNotifyEvent. En mi caso, lo que necesitaba era cancelar el pintado normal del DBGrid y proceder a mi manera si se daba el caso. Sin embargo, el evento tal y como estaba no me permitía cancelar el pintado normal que inevitablemente siempre ocurriría después. Es por la gracia y libertad del código abierto que pude indagar en el código fuente de dicho componente y modificar la declaración e implementación del evento OnBeforePaint.

Lo que hice fue lo siguiente:

1. Declare un nuevo tipo de evento llamado TJvBeforePaintEvent, que sería una extención del tipo TNotifyEvent, pero que contendría un último parámetro DoDefaultDrawing que cuando sea devuelto como False detendrá la consecutiva pintada estándar del Grid.:

TJvBeforePaintEvent = procedure(Sender: TJvDBGrid; var DoDefaultDrawing: Boolean) of object;

2. Cambié el tipo de la variable de FOnBeforePaint y propiedad OnBeforeEvent de la clase TJvDBGrid para que fuera del nuevo tipo TJvBeforePaintEvent .

TJvDBGrid = class(TJvExDBGrid, IJvDataControl)
    .....
    FOnBeforePaint: TJvBeforePaintEvent;
    .....
    property OnBeforePaint: TJvBeforePaintEvent read FOnBeforePaint write FOnBeforePaint;

3. El último paso fue cambiar ligeramente la implementación del procedimiento Paint de la clase TJvDBGrid para que hiciera uso del nuevo parámetro DoDefaultDrawing en TJvBeforePaintEvent.

procedure TJvDBGrid.Paint;
var
    DoDefaultDrawing: Boolean;
begin
    DoDefaultDrawing := True;
if Assigned(FOnBeforePaint) then
 FOnBeforePaint(Self, DoDefaultDrawing);
if not DoDefaultDrawing then
 exit;

.....

Esta simple modificación me ha permitido, en mi caso, darle más funcionalidades al DBGrid. Por ejemplo, pintar unas breves instrucciones en el formulario dónde está la rejilla. O pintar un mejor mensaje cuando por ejemplo no hay registros en la consulta realizada, por ejemplo:

En donde dice “Ningún registro coincide con su búsqueda…” pareciera algún tipo de TPaintBox, pero en realidad es un TJvDBGrid que ocupa casi todo el formulario. El texto y el degradado mostrado lo pinto en el evento OnBeforePaint con la ayuda de la modificación que os he expuesto. Esta es la ventana donde se muestran los registros de pacientes para un sistema que he estado desarrollando llamado Biolab.

Etiquetado , , ,

Usando las funciones de la Barra de Tareas de Windows 7

Acabo de leer en el blog de la JEDI Windows API que un grupo de desarrollares están creando un set de componentes para implementar desde Delphi las nuevas funcionalidades brindadas por la nueva barra de tareas en Windows 7. Un inconveniente es que estos componentes están basados en la implementación JEDI de la api de Windows. Por esto puede ser que sea un poco complicado utilizarlos para desarrollares noveles. Aúnque la recomiendo porque es muchísimo más completa que la que trae Delphi.

Estaré atento a este proyecto y cuando llegue a entenderlo e implementarlo es casi seguro que les comentaré y brindaré un pequeño tutorial. Por el momento solo he leído la documentación MSDN al respecto, y creanme, no está muy complicado trabajar con la genial barra de herramientas de Windows 7.

Pueden revisar el código de los mencionados componentes desde este enlace.

Etiquetado

Messagebox con etiquetas personalizadas

El problema:

Con la llegada de Windows Vista, los clásicos mensajes de dialogo en Windows serían -según muchos- cosa del pasado. Estoy hablando de la llegada de los nuevos TaskDialogs. Siendo muy potentes tienen unos inconvenientes que nos impide acogerlos al cien por ciento. Primero: como desarrollares responsables, no podemos -por el momento- desarrollar exclusivamente para Windows Vista y versiones posteriores. Además, desde Delphi y su implementación de los TaskDialogs mediante la clase TTaskDialog no puedes mostrar este tipo de mensajes cuando los temas del sistema están deshabilitados. Por último, al ser muy potentes tienen cierta complejidad que para tareas sencillas sería más cómodo hacer una simple llamada a la función Messagebox.

Sin embargo, los viejos MessageBox de Windows tienen un problema de usabilidad: El usuario tiene que leer todo el mesaje para poder tomar una decisión. La solución a este problema está en usar etiquetas descriptivas en los botones y dejar a un lado los viejos “SÍ/NO/CANCELAR/etc.”. Obviamente surge la pregunta: ” ¿Cómo puedo cambiar las etiquetas de este tipo de dialogo desde Delphi? Es muy sencillo y pasa por utilizar Hooks proporcionados por la misma API de Windows.

Sigue leyendo

Etiquetado , , ,