Archivo de la categoría: Delphi

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;
Anuncios
Etiquetado ,

Sayonara Delphi

Esta es una despedida oficial por mi parte al desarrollo Delphi. He meditado durante el fin de semana el estado actual de la industria y he llegado a la conclusión que seguir desarrollando (por el momento) aplicaciones Win32 no tiene sentido. Comparto la opinión del director de Valve que Windows 8 es un desastre para una industria ya de por si golpeada.

Pero no es precisamente Windows 8 el causante de mi decisión. Es el nuevo paradigma, la nube, imposible de ignorar, el que me ha forzado a tomar la decisión. Confieso que desde hace meses he estado haciendo EXCLUSIVAMENTE desarrollos para la Web y después de todo este tiempo me he convencido de no querer volver a desarrollar usando Delphi.

Delphi es un gran lenguage y herramienta. Disfruté moldear y hackear cosas con él. Creo que Delphi hace divertido el desarrollo para Win32. Pero de la diversión no se come y pensando en mi futuro he decidido irme 100% a la nube.

Por supuesto que volar hacia la nube no implica necesariamente dejar el desarrollo nativo. Pero por el momento, mis proyectos actuales corren perfectamente en un explorador. Por mi parte, desarrollar versiones nativas de mis aplicaciones es un esfuerzo innecesario.

Por eso, en el futuro cercano no pienso desarrollar para tabletas (iOS, Android, WinRT). Creo que, dependiendo del caso, desarrollar para una tableta puede ser contraproducente, inclusive podría ser como ponerte la soga en el cuello dependiendo del caso. En este sentido, se me vienen las ganas de trolear el estado actual de la industria del Software, pero hacerlo ahora no tiene sentido.

A Delphi le debo mucho. Aprendí muchas cosas de él. Y siempre le haré el honor con que mis desarrollos estén influenciados por su genial estructura, la VCL.

Tampoco estoy diciendo que a partir de ahora no escribiré una línea más en Delphi. Simplemente, no haré nada serio con él. Talvez sólo travesear cosas. Puede ser que uno que otro día haga una pequeña unidad con alguna utilidad. Pero nada más que eso. Sinceramente, ya no me veo desarrollando un nuevo proyecto completo con Delphi.

Por último compañeros, los animo a embarcarse en la nube, en el desarrollo Web como parte de nuestra evolución. Cuando vienes de Delphi es un poco complicado y confuso todas esas mezclas de Python/PHP/Ruby – Javascript – CSS – HTML, etc. Con Delphi nos acostumbramos a utilizar un solo lenguaje para hacerlo todo. Creo que es ésa costumbre la que nos reciente la primera vez que nos encontramos con la Web. Pero al final del día, es una experiencia gratificante personal y profesionalmente. Te sorprenderá la facilidad con la que lograrás cosas muy difíciles de hacer si utilizaras exclusivamente Delphi.

Fue un placer haber intercambiado experiencias y código Delphi con todos ustedes compañeros. Con esta transición profesional también me paso a Linux oficialmente (Ubuntu y su maravilloso Unity). Sayonara Windows! :)

Saludos,
Christopher

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 , ,

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 , , ,