29 de marzo de 2007

ComboBox Multicolor

El código no es propio, no recuerdo su fuente pero hace años que lo tengo.

Para crear los Items multicolores en un combobox se debe indicar la propiedad RowSourceType = 9 && Popup, y la propiedad de RowSource lleva el nombre con el que se define el popup (Sin comillas).

Los pasos a seguir son los siguientes:

1. Creado el formulario que lo contiene, colocar el siguiente código en el evento Load del formulario:
    #DEFINE RedBar RGB(128,0,0)
    #DEFINE GreenBar RGB(0,128,0)
    #DEFINE BlueBar RGB(0,0,255)
    #DEFINE YellowBar RGB(255,255,0)

    DEFINE POPUP MultiColor
    DEFINE BAR 1 OF MultiColor PROMPT "Rojo" COLOR ,RedBar
    DEFINE BAR 2 OF MultiColor PROMPT "Verde" COLOR ,GreenBar
    DEFINE BAR 3 OF MultiColor PROMPT "Azul" COLOR ,BlueBar
    DEFINE BAR 4 OF MultiColor PROMPT "Amarillo" COLOR ,YellowBar
2. Agregadoo el objeto ComboBox indicar las propiedades siguientes:
    ROWSOURCETYPE = 9 && Popup
    ROWSOURCE = "Multicolor" && (sin las comillas)  
3. En el evento de Valid del ComboBox, poner el código siguiente:
    DO CASE
      CASE THIS.VALUE = "Rojo"
        THIS.FORECOLOR = RedBar
      CASE THIS.VALUE = "Verde"
        THIS.FORECOLOR = GreenBar
      CASE THIS.VALUE = "Azul"
        THIS.FORECOLOR = BlueBar
      CASE THIS.VALUE = "Amarillo"
        THIS.FORECOLOR = YellowBar
    ENDCASE
Cuando se ejecute el formulario al pulsar el combo se despliegan los items con sus respectivos colores.

Dario David Puccio


Nota del editor: El siguiente es un ejemplo completo de esta técnica
PUBLIC oMiForm
oMiForm=NEWOBJECT("MiForm")
oMiForm.SHOW
RETURN

DEFINE CLASS MiForm AS FORM
  AUTOCENTER = .T.
  CAPTION = "Combo Multicolor"
  NAME = "MiForm"

  ADD OBJECT combo1 AS COMBOBOX WITH ;
    ROWSOURCETYPE = 9, ROWSOURCE = "Multicolor", ;
    HEIGHT = 24, LEFT = 24, TOP = 24, WIDTH = 132, ;
    NAME = "Combo1"

  PROCEDURE LOAD
    #DEFINE RedBar RGB(128,0,0)
    #DEFINE GreenBar RGB(0,128,0)
    #DEFINE BlueBar RGB(0,0,255)
    #DEFINE YellowBar RGB(255,255,0)

    DEFINE POPUP MultiColor
    DEFINE BAR 1 OF MultiColor PROMPT "Rojo" COLOR ,RedBar
    DEFINE BAR 2 OF MultiColor PROMPT "Verde" COLOR ,GreenBar
    DEFINE BAR 3 OF MultiColor PROMPT "Azul" COLOR ,BlueBar
    DEFINE BAR 4 OF MultiColor PROMPT "Amarillo" COLOR ,YellowBar
  ENDPROC

  PROCEDURE INIT
    THIS.Combo1.LISTINDEX = 1
    THIS.Combo1.VALID
  ENDPROC

  PROCEDURE combo1.VALID
    DO CASE
      CASE THIS.VALUE = "Rojo"
        THIS.FORECOLOR = RedBar
      CASE THIS.VALUE = "Verde"
        THIS.FORECOLOR = GreenBar
      CASE THIS.VALUE = "Azul"
        THIS.FORECOLOR = BlueBar
      CASE THIS.VALUE = "Amarillo"
        THIS.FORECOLOR = YellowBar
    ENDCASE
  ENDPROC
ENDDEFINE

26 de marzo de 2007

Nueva versión de GPIMAGE2

Artículo original: NEW VERSION OF GPIMAGE2
http://weblogs.foxite.com/vfpimaging/archive/2007/02/06/3245.aspx
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York



Luego de algunas solicitudes, estoy enviando la nueva versión de GPIMAGE2, una clase adaptada de la clase original GPIMAGE de Alexander Golovlev.

Esta nueva versión tiene 3 nuevas características:  Control del modo pulido, Modo interpolación y una brocha de degradado. (Control Smoothing Mode, Interpolation Mode and a Gradient Brush.)

GDIplus originalmente ofrece 6 tipos de brochas de degradado lineal, y muchas posibilidades para las brochas de degradado de ruta; pero actualizar GPIMAGE2 no es una prioridad porque yo pienso que la biblioteca de clases GDIPlusX, ofrece mucho más valor y es compatible con el espacio de nombre "System.Drawing" de .NET

Así que si aún no se ha actualizado a VFP 9, puede descargar esta nueva versión, y ejecutar algunos degradados.

He incluido 3 ejemplos que crean degradados. Los encontrará en la carpeta "EXAMPLES"

BRUSHESGRADIENT.PRGCrea algunas formas utilizando degradados.
GRADIENTFORM.SCXCrea un formulario ejemplo con efectos de degragado.
GRADIENTFORM2.SCXCrea un formulario de ejemplo con efectos de degradado, que permite cambiar los colores y la dirección del gradiente durante la ejecución.

Otro ejemplo nuevo, SMOOTHING.SCX, de Rafael Lippert, que demuestra cómo controlar el modo liso o pulido si hay imágenes.

¡ Que lo disfrute !





GPIMAGE2 GDI+ Class

23 de marzo de 2007

Reportes de VFP en formato PDF usando BullZip PDF Printer

BullZip PDF Printer trabaja como una impresora de Microsoft Windows y permite escribir documentos PDF desde cualquier aplicación de Microsoft Windows.

Este programa es FREEWARE lo que significa que es GRATIS! Para uso personal y comercial. Este no contiene ninguna publicidad o popups.

Ver las características en: http://www.bullzip.com/products/pdf/info.php

Requerimientos del sistema
  • Microsoft Windows 2000/XP/XP x64/2003/2003 x64/Vista/Vista x64
  • GPL Ghostscript 8.54 o superior
Descargar e Instalar
  1. Descargar Ghostscripts e instalarlo
  2. http://www.bullzip.com/products/pdf/gs854w32.exe
  3. Descargar el PDF Printer y correr el programa de instalación.
  4. http://www.bullzip.com/downloadmgr.php?download=pdf
Cuando el programa de instalación termina, tendremos instalado en el sistema un impresora llamada BullZip PDF Printer. Ahora podremos imprimir desde cualquiera de las aplicaciones instaladas en nuestro sistema.

Como usarlo desde Visual Foxpro 9

Mi problema era como poder enviar un reporte de Visual FoxPro por correo electrónico en algun formato que todo el mundo pueda abrir y usar. Entonces pense si puedo hacer que los reportes de VFP se conviertan en archivos PDF, puedo usar Acrobat Reader como preview de mis reportes y desde Acrobat, imprimirlos, enviarlos, etc.

Estuve buscando clases _reportlistener, pero la que encontre no las pude hacer funcionar. Fue entonces que me tope con BullZip PDF Printer.

Lo que hice fue lo siguiente:
  1. Configure la impresora (BullZip PDF Printer), para que no muestre mensajes al crear el .pdf y que abra el documento después de crearlo.
  2. Modifique mis reportes de la siguiente manera:
  3. Haciendo que BullZip PDF Printer sea la impresora predeterminada de Windows y luego en el reporte en propiedades, save printer environment.
  4. En mis programas cambien las llamadas a los reportes de la siguiente manera:
  5. REPORT FORM mireporte.frx TO PRINTER ENVIRONMENT
Importante:

No es necesario que BullZip PDF Printer sea la impresora predeterminada de Windows, eso se hace unicamente en el momento en que se cambian los reportes y se graba la configuración de impresoras en el reporte.

No es necesario usar el Adobe Acrobat Reader, funciona con el lector PDF que tenemos instalado por defecto en nuestro sistema.

Saludos cordiales.

Marcelo ARDUSSO
Rafaela, Santa Fe. Argentina


Enlaces:
http://www.bullzip.com/products/pdf/info.php
http://www.bullzip.com/products/pdf/gs854w32.exe
http://www.bullzip.com/downloadmgr.php?download=pdf

15 de marzo de 2007

¿Cual es la verdadera noticia?

Ayer (14/03/2007) ha sido un día distinto para muchos desarrolladores en Visual FoxPro, el Equipo de Visual FoxPro de Microsoft hizo un anuncio que fue ampliamente comentado en las distintas comunidades de VFP.

El conocido anuncio hecho por Yair Alan Griver (YAG), uno de los responsables del VFP Team, es que no habrá una versión 10 para Visual FoxPro, y que antes de finales de Setiembre de 2007 serán lanzados el SP2 para VFP9 y Sedna.

La primer parte de este anuncio, es algo que ya estaba latente desde hace mucho tiempo y MS no tenía un plan para una próxima versión de Visual FoxPro. Seguramente habrá gente triste (me incluyo en la lista) de saber que la última versión de nuestra herramienta, que a muchos nos acompaña por mas de una década, será VFP9 SP2 y tendrá soporte por parte de Microsoft hasta el año 2015.

¿Qué es lo nuevo entonces de este anuncio?

Sedna, el nuevo componente que contiene nuevas características ya vistas en los últimos CTPs liberados, y comentados en las distintas Cartas mensuales de Milind Lele, será liberado gratis y como código abierto en CodePlex.com, tal como están los actuales proyectos VFPx y VFPy llevados a cabo por varios integrantes de la comunidad internacional de VFP (Cesar Ch. y Carlos Alloatti entre otros).
El equipo de VFP también esta trabajando en el Service Pack 2, en el cual se incluirán correcciones, mejoras en el sistema de reportes y una mayor compatibilidad con Windows Vista.

¿Y ahora qué?

Visual FoxPro 9 continuará vigente, aun mucho mas allá de 2015. El verdadero soporte dado por la gran comunidad de desarrolladores no tiene fecha de finalización. Solo basta leer los Blogs de varias personalidades internacionales de VFP que ya dieron su punto de vista sobre el anuncio del VFP Team, para darse cuenta que ellos continuarán participando en foros y conferencias y apoyando los nuevos proyectos compartidos de Visual FoxPro.

En este portal, en el cual venimos recopilando colaboraciones de la comunidad hispana desde hace 7 años, vamos a continuar recibiendo y publicando material sobre Visual FoxPro. Vamos a continuar dando nuestro apoyo a todos los desarrolladores de Visual FoxPro.

¿Creen que estoy loco?

Quienes hayan leído hasta aquí, pensarán que estoy loco, (quizás tengan razón, pero cuando escucho tiros me agacho), o quizás crean que por ser MVP, tenga que estar del lado de Microsoft (esto es falso). Estoy y estaré del lado de Visual FoxPro. Sé (y muchos lo saben) que contamos con una herramienta muy potente, que nos dió mas satisfacciones que dolores de cabeza a lo largo de todos estos años. Una herramienta completa que, solo con ella, nos permitió realizar aplicaciones para distintos tipos de necesidades. Esto significa que aun nos queda muchos años para continuar explotando a VFP. Aunque a algunos les parezca extraño (y muchos coincidiran conmigo) aun mantengo aplicaciones en FoxFro 2.6 para Windows en producción y corren muy bien para lo que fueron diseñadas hace mas de una década.

Por último quiero aclarar que no vivo dentro de una burbuja. Tenemos mucho tiempo aun para aprender nuevas herramientas y conocer otras plataformas. Esto ya lo sabemos desde hace tiempo y tarde o temprano lo deberemos hacer. Actualmete ya muchos utilizamos SQL Server o MySQL para extender la capacidad de almacenamiento y seguridad de datos de VFP y muchos ya interactuamos con los lenguajes .NET. A no desesperar, Visual FoxPro aun está vivo, y su comunidad continuará dándole apoyo.

Luis María Guayán
SysOp de www.PortalFox.com
Microsoft Visual FoxPro MVP

14 de marzo de 2007

Serie FoxNet protegido es protegido o no

Artículo original: The foxNET series: protected is protected, or is it?
http://www.foxpert.com/knowlbits_200702_2.htm 

Autor: Christof Wollenhaupt
Traducido por: Ana María Bisbé York


Como desarrollador Visual FoxPro, va a descubrir mucha familiaridad cuando lea (o escriba) código .NET. Después de todo, ha trabajado en un entorno orientado a objeto por más de una década mientras la pobre gente de VB tiene que saltar directamente de la infancia a ser adultos, ¿cierto?

Hay algunas diferencias sutiles entre estas dos plataformas, incluso para algunas cosas tan básicas como la visibilidad de los miembros. En Visual FoxPro usted tiene oculto, protegido y público. El último no está disponible como una palabra clave, sin embargo. En .NET tiene algunos modificadores. Entre ellos están privado y protegido; pero no público. Protegido y público suena idéntico. Oculto puede relacionarse fácilmente a lo privado.

¿Es tan sencillo? No. En Visual FoxPro el alcance de esto modificadores es el objeto. El siguiente programa provoca un error en Visual FoxPro:
ox = CreateObject("Sample")
? ox.SetValue(ox,"ox")
oy = CreateObject("Sample")
? oy.SetValue(ox,"oy")

Define Class Sample as Custom
  Protected cValue
  Procedure SetValue( toRef, tcValue )
    toRef.cValue = m.tcValue
    Return m.tcValue
  EndProc
EndDefine
El primer método trabaja bien. Puede llamar a un método de ox y luego utiliza una referencia de ox para cambiar de propiedad. Si pasa una instancia diferente de la misma clase, no puede acceder a la propiedad protegida del segundo objeto. Este comportamiento es una razón que las propiedades protegidas no se emplean mucho por los desarrolladores Visual FoxPro (al menos, comparando con otros lenguajes). Si tiene una clase donde dos instancias necesitan intercambiar datos, tiene que utilizar también una interfaz pública que esté abierta para todos. Vea ahora, el mismo programa escrito en C#.
class Program
  {
  static void Main(string[] args)
    {
    Sample ox = new Sample();
    Console.WriteLine(ox.SetValue(ox, "ox"));
    Sample oy = new Sample();
    Console.WriteLine(oy.SetValue(ox, "oy"));
    }
  }
class Sample
  {
  protected string cValue;
  public string SetValue(Sample toRef, string tcValue)
    {
    toRef.cValue = tcValue;
    return tcValue;
    }
  }
Este código compila y se ejecuta bien. En Visual FoxPro la visibilidad de los miembros está limitada a la instancia del objeto. En .NET está limitada a la clase (realmente el tipo). Cualquier instancia de una clase tiene acceso a cada miembro privado de cada otra instancia de la misma clase. Esto hace que los miembros no públicos sean mucho más útiles que en Visual FoxPro.

9 de marzo de 2007

Extraer íconos de archivos EXE- DLL e ICO con GdiplusX

Artículo original: Extract icons from EXE, DLL and ICO files with GdiPlus-X
http://weblogs.foxite.com/vfpimaging/archive/2007/02/09/3255.aspx
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York


Algunos tipos de archivos admiten guardar varios iconos junto a otros datos binarios, como EXEs y DLLs. Los archivos .ICO admiten además almacenar más de un icono en un archivo único. Windows utiliza mucho esto, y guarda casi todos los íconos que utiliza todo el tiempo en algunas bibliotecas DLL o EXE.

La biblioteca GdiPlusX puede fácilmente extraer estos íconos, utilizando la función "ExtractAssociatedIcon" de la clase xfcIcon como se muestra a continuación:

IMPORTANTE:
Todos los ejemplos que se muestran a continuación utilizan la nueva biblioteca GDIPlus-X desde XFP-X y requiere que usted tenga al menos la versión RELEASE 0.07. GdiPlusX está aún en versión ALPHA, pero es realmente estable y fiable para hacer la gran mayoría de las tareas de GDI+. Descargue la versión más estable de Codeplex:

http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX&title=GDIPlusX

* El siguiente código demuestra cómo extraer un ícono de un archivo EXE 
lcPath = ADDBS(JUSTPATH(SYS(16)))+"..\source\"
_SCREEN.AddProperty("System", NEWOBJECT("xfcSystem", LOCFILE(lcPath+"system.vcx","vcx")))
LOCAL lcFile, lnIndex
LOCAL loIcon as xfcIcon
LOCAL loBmp as xfcBitmap
lcFile = GETFILE("exe;ico;dll") && _vfp.ServerName
lnIndex = 0
WITH _SCREEN.System.Drawing
  DO WHILE .T.
    loIcon = .Icon.ExtractAssociatedIcon(lcFile, lnIndex)
    IF ISNULL(loIcon)
      EXIT
    ENDIF
    lcNewFile = "C:\" + JUSTFNAME(lcFile) + TRANSFORM(lnIndex) + ".png"
    loBmp = loIcon.ToBitmap()
    loBmp.Save(lcNewFile, .Imaging.ImageFormat.Png)
    lnIndex = lnIndex + 1
  ENDDO
ENDWITH
RETURN

El archivo ExtractIcons.scx en la carpeta Samples ofrece un formulario que permite seleccionar cualquier archivo, y GdiPlusX va a dibujar todos los íconos asociados dentro de un objeto ImageCanvas, como muestra la siguiente imagen:



¿Necesita más iconos?

En mis pruebas, después de creada esta función, tuve curiosidad por saber qué iconos podría guardar mi PC dentro de tantos ejecutables y DLLs instaladas, entonces, he creado un sencillo programa que va a buscar por las carpetas seleccionadas, y hará búsqueda recursiva en todas sus subcarpetas, buscando todos los archivos que pudieran guardar iconos.

Para mi sorpresa, muchos, en realidad MILES de íconos emergieron ... y los resultados fueron muy interesantes, ¡ se lo aseguro !

Puede intentarlo también en su PC.

Guarde el programa que aparece a continuación como HowTo_ExtractIconsFromDir2.prg en la carpeta HELP de la biblioteca. Utiliza una rutina muy buena de Michael Reynolds que publicó amablemente en www.fox.wikis.com para obtener los nombres de todos los archivos de las subcarpetas. Observe que esto va a requerir un gran esfuerzo para su PC, por lo que debe preparase para esperar cerca de un minuto hasta que se termine esta tarea. Después de ejecutar este ejemplo, todos los iconos se almacenarán en "C:\MyIcons\".

* Archivo : HowTo_ExtractIconsFromDir2.prg
* Autor : Cesar Ch.
* Guarde este archivo en el directorio HELP de la carpeta de la biblioteca GdiPlus-X 
*
* El siguiente código realiza las acciones siguientes :
*
* Pregunta al usuario por una ruta
* Crea un cursor que contiene todos los nombres de archivos disponibles (EXE, DLL e ICO)
* del directorio seleccionado y sus subdirectorios
* Recorre el cursor y extrae todos los iconos asociados a cada archivo

* Inicia GDI+
LOCAL lcPath
lcPath = ADDBS(JUSTPATH(SYS(16)))+"..\source\"
_SCREEN.AddProperty("System", NEWOBJECT("xfcSystem", LOCFILE(lcPath+"system.vcx","vcx")))
* Crea el directorio destino para guardar los iconos extraídos
lcDir = "c:\MyIcons\"
IF NOT DIRECTORY(lcDir)
  MKDIR (lcDir)
ENDIF
* Crea el cursor que va a guardar la localización válida del archivo
CREATE CURSOR Recursive (cFile c(250))

LOCAL lcCurDrive, lcCurDir, lcSelectedDir
lcCurDrive = JUSTDRIVE(FULLPATH(CURDIR()))
lcCurDir = CURDIR()
lcSelectedDir = GETDIR()
IF EMPTY(lcSelectedDir)
  WAIT WINDOW "Directorio no válido"
RETURN .F.
ENDIF

WAIT WINDOW "Recibiendo información de las carpetas" NOWAIT

* Busca el directorio seleccionado y sus subdirectorios
=Recurse(GETDIR())
CHDIR &lcCurDrive.&lcCurDir.
* BROWSE

WITH _SCREEN.System.Drawing
  LOCAL lcFile, lnIndex, lnTotRec
  LOCAL lnOldPercentage, lnPercentage
  LOCAL loIcon as xfcIcon
  LOCAL loBmp as xfcBitmap
  STORE 0 TO lnPercentage, lnOldPercentage
  lnTotRec = RECCOUNT()
  SCAN
    lcFile = Recursive.cFile
    lnIndex = 0
    DO WHILE .T.
      loIcon = NULL
      * Extrae el icono asociado
      loIcon = .Icon.ExtractAssociatedIcon(lcFile, lnIndex)
      IF ISNULL(loIcon)
        EXIT
      ENDIF
      lcNewFile = lcDir + JUSTFNAME(lcFile) + TRANSFORM(lnIndex) + ".png"
      loBmp = NULL
      * Envía el icono a un objeto GDI+ 
      loBmp = loIcon.ToBitmap()
      IF VARTYPE(loBmp) <> "O"
        EXIT
      ENDIF
      * Guarda el  Bitmap como PNG
      loBmp.Save(lcNewFile, .Imaging.ImageFormat.Png)
      lnIndex = lnIndex + 1
    ENDDO
    * Muestra la progresión
    lnRec = RECNO()
    lnPercentage = ROUND((lnRec / lnTotRec),1)
    IF lnPercentage > lnOldPercentage
      WAIT WINDOW "Extrayendo iconos de archivos..." + CHR(13) + ;
        "Pasado: " + TRANSFORM(lnPercentage * 100) + " %" NOWAIT
      lnOldPercentage = lnPercentage
    ENDIF
  ENDSCAN
ENDWITH
RETURN

*****************************************************************************************
* FUNCIÓN : RECURSE
* AUTOR : MICHAEL REYNOLDS
* DESCRIPCIÓN : Buena para realizar el procesamiento de archivos a través de todo el árbol de directorios. 
* La función, RECURSE(), se llama con toda la ruta del directorio.
* RECURSE() leerá todos los archivos y directorios.
* Puede llamar a una función para procesar los archivos que encuentra.
* Además, la función se llama a sí misma para procesar los subdirectorios
* http://fox.wikis.com/wc.dll?Wiki~RecursiveDirectoryProcessing~VFP 
*****************************************************************************************
FUNCTION Recurse(pcDir)
  LOCAL lnPtr, lnFileCount, laFileList, lcDir, lcFile
  CHDIR (pcDir)
  DIMENSION laFileList[1]
  *--- Lee el directorio seleccionado
  lnFileCount = ADIR(laFileList, '*.*', 'D')
  FOR lnPtr = 1 TO lnFileCount
    IF 'D' $ laFileList[lnPtr, 5]
      *--- Obtiene el nombre del directorio
      lcDir = laFileList[lnPtr, 1]
      *--- Ignora los punteros del directorio actual y el padre
      IF lcDir != '.' AND lcDir != '..'
        *--- Call this routine again.
        Recurse(lcDir)
      ENDIF
    ELSE
      *--- Obtiene el nombre del archivo
      lcFile = LOWER(FULLPATH(laFileList[lnPtr, 1]))
      *--- Insert into cursor if .EXE, .ICO or .DLL
      IF INLIST(LOWER(JUSTEXT(lcFile)),"dll","exe","ico")
        INSERT INTO Recursive (cFile) VALUES (lcFile)
      ENDIF
    ENDIF
  ENDFOR
  *--- Regresa al directorio padre.
  CHDIR ..
ENDFUNC
IMPORTANTE:

Este procedimiento muestra cómo extraer los iconos asociados a algunos archivos. Antes de utilizar estos iconos en sus aplicaciones, debe estar seguro de que tiene los derechos para hacerlo. ¡ Lea detenidamente lo normado en EULA para estas aplicaciones antes de utilizarlas !

¡ Espero que lo disfrute !

8 de marzo de 2007

Otra forma de obtener datos en una página Web: usando OleDB u ODBC

Artículo que muestra una manera diferente de obtener datos en una página Web para ser vista por un navegador de Internet.

El ejemplo usa el proveedor OLEDB o el controlador ODBC de Visual FoxPro para acceder a los datos de los ejemplos de VFP.

Artículo en inglés en el Blog de Calvin Hsia.

-- Another way to get data into a web page: using OleDB or ODBC --
http://blogs.msdn.com/calvin_hsia/archive/2007/02/21/another-way-to-get-data-into-a-web-page-using-oledb-or-odbc.aspx