29 de septiembre de 2006

Nuevas clases GDI+ en VFP-X

Artículo original: New VFP- X GDI+ classes
http://weblogs.foxite.com/vfpimaging/archive/2006/08/10/2194.aspx
Autor: Cesar Ch.
Traducido por: Ana María Bisbé York


En las últimas dos semanas, he estado realizado pruebas extensas y creando algunos ejemplos utilizando la nueva biblioteca VFP-X GDIPlusX. Debo decir que la clase está tremenda. Esta biblioteca está realmente haciendo mi vida con GDI+ mucho más sencilla.

Cuanto más la utilizo, más me gusta. Me estoy divirtiendo mucho.

Como dijo Craig Boyd en una de sus entradas de blog: (http://www.sweetpotatosoftware.com/SPSBlog/PermaLink,guid,c5ff0b43-a24d-43a6-b290-94fe9cfd4492.aspx) "La biblioteca GDIPlusX es una reproducción en código Visual FoxPro puro del espacio de nombre Drawing en .NET. Hemos escrito más de 40 000 líneas de código VFP y la librería consiste en más de 80 clases, por ahora: cerca del 95% está completo. Es seguro decir que no hay otra biblioteca en el planeta que brinde a los desarrolladores VFP la funcionalidad y el poder que esta brinda cuando se trabaja con GDI+." - Es totalmente cierto.

Si está planificando comenzar un nuevo proyecto y necesitará utilizar GDI+, o está interesado en ayudar en el proyecto, escribiendo código, haciendo pruebas, sugerencias, recomiendo fuertemente entrar en http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX, seleccionar la ficha "Releases" http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=VFPX, y descargar la versión más estable actualmente disponible.

Comience ejecutando el archivo DEMO.PRG en la carpeta Samples, y va a tener una mejor idea del poder de la clase.

Bo ha sugerido que desde ahora debemos mantener nuestra comunicación solamente vía CodePlex, utilizando las secciones Discussions y Issue Tracker. De esta forma, como dijo Bo "otras personas pueden contribuir y estar envueltos si ellos ven que aquí hay alguna actividad y que es muy sencillo para ellos colaborar también."

A propósito, ¡ El proyecto VFP-X ahora tiene también un nuevo logo !

vfpxbanner_small.gif
A partir de ahora, emplearé este espacio para mostrar algunos ejemplos de utilización de estas clases. Puede emplear el espacio de comentarios de este blog para hacer este tipo de peticiones.

EJEMPLOS DE CÓDIGO

Mi primer ejemplo viene de ayudar a Bernard Bout, a crear una imagen que será utilizada en su ejemplo "blueglass". Puede obtener más datos de esta información en: http://weblogs.foxite.com/bernardbout/archive/2006/06/15/1838.aspx

Crear una imagen de 2x2 píxeles, con un fondo azul y un píxel magenta en (0,0)

He aquí el código:
** Crea una imagen para ser utilizada en el ejemplo "blueglass" 
** por Bernard Bout
** imagen 2x2 píxeles, con fondo azul y un píxel magenta en (0,0)

_SCREEN.AddProperty("System", NEWOBJECT("xfcSystem", LOCFILE("system.vcx","vcx")))

* Define los colores a ser utilizados
lnRGBPointClr = RGB(0,0,255) && Azul
lnRGBBackgClr = RGB(255,0,255) && Magenta
WITH _SCREEN.System.Drawing
LOCAL loBitmap AS xfcBitmap
LOCAL loColor AS xfcColor
LOCAL loGfx AS xfcGraphics
* Crea un nuevo bitmap  2x2 en el predeterminado PixelFormat - 32bppARGB
loBitmap = .Bitmap.New(2,2)
* Crea un objeto Graphics para que sea capaz de utilizar la función Clear,
* que va a llenar todo el bitmap con el color deseado.
* Para este caso esto no es fundamental, porque el bitmap es
* pequeño, entonces podemos llamar "SetPixel" 4 veces para cubrir el bitmap.
loGfx = .Graphics.FromImage(loBitmap)
loGfx.Clear(.Color.FromRgb(lnRGBBackGClr))
* Dibuja el pixel
loBitmap.SetPixel(0,0, .Color.FromRgb(lnRGBPointClr))
* Guarda una imagen  PNG
loBitmap.Save("c:\BlueGlass.png", .Imaging.ImageFormat.Png)
ENDWITH



¡No puedo esperar por el siguiente entrada de blog de Bernard utilizándola!

27 de septiembre de 2006

Google Maps en un formulario de VFP

Como crear un formulario en Visual FoxPro, que nos muestre mapas e imágenes satelitales de Google Maps.

Ya es por todos conocido que con Visual FoxPro podemos hacer muchas cosas. Una de ellas es incorporar un control Explorador Web en un formulario y utilizar código HTML y JavaScript. Esto ya lo publicó mi amigo Antonio Muñoz de Burgos y Caravaca en su artículo "Control del Explorador Web (HTML & JS & VFP)".

En este artículo, vamos a ver un ejemplo de como incorporar dinámicamente código HTML y JavaScript, que nos permita navegar por Google Maps y poder desplazarnos virtualmente a diversos lugares del mundo a bordo de nuestro velóz y querido zorro ;-)

Lo primero que vamos a utilizar en este ejemplo, es una tabla con algunos lugares de interes, con sus respectivas coordenadas georeferenciales (latitud y longitud) y el nivel de acercamiento. Con estos datos, generaremos una página HTML que mostraremos en un control Explorador Web que incluiremos en nuestro formulario.

El código completo de este ejemplo es el siguiente:

PUBLIC oMiForm
oMiForm = CREATEOBJECT("MiForm")
oMiForm.SHOW
RETURN

DEFINE CLASS MiForm AS FORM
  HEIGHT = 365
  WIDTH = 475
  AUTOCENTER = .T.
  CAPTION = "Ejemplo con Google Maps"
  NAME = "MiForm"
  SetPoint = ""
  SHOWWINDOW = 2

  ADD OBJECT cboDescrip AS COMBOBOX WITH ;
    ROWSOURCETYPE = 6, ROWSOURCE = "MisLugares.descri", ;
    HEIGHT = 24, LEFT = 12, TOP = 12, WIDTH = 330, ;
    STYLE = 2, NAME = "cboDescrip"

  ADD OBJECT cmdMostrar AS COMMANDBUTTON WITH ;
    TOP = 10, LEFT = 350, HEIGHT = 27, WIDTH = 112, ;
    CAPTION = "Mostrar mapa", NAME = "cmdMostrar"

  ADD OBJECT oleIE AS OLECONTROL WITH ;
    TOP = 48, LEFT = 12, HEIGHT = 300, WIDTH = 450, ;
    NAME = "oleIE", OLECLASS = "Shell.Explorer.2"

  PROCEDURE LOAD
    SYS(2333,1)
    THIS.SetPoint = SET("Point")
    SET POINT TO .
    SET SAFETY OFF
    *-- Creo el cursor con los datos
    CREATE CURSOR MisLugares (Descri C(40), Lat N(12,6), Lon N(12,6), Zoom I(4))
    INSERT INTO MisLugares VALUES ("Torre Eiffel (Francia)", 48.858333, 2.295000, 17)
    INSERT INTO MisLugares VALUES ("Basílica de San Pedro (Vaticano)", 41.902102, 12.456400, 17)
    INSERT INTO MisLugares VALUES ("Estatua de la  Libertad (EEUU)", 40.689360, -74.044400, 17)
    INSERT INTO MisLugares VALUES ("Estadio Monumental (Argentina)", -34.545277, -58.449722, 17)
    INSERT INTO MisLugares VALUES ("Estadio Azteca (Mexico)", 19.302900, -99.150400, 17)
    INSERT INTO MisLugares VALUES ("Estadio Camp Nou (España)", 41.380906, 2.123330, 17)
    INSERT INTO MisLugares VALUES ("Cementerio de aviones (EEUU)", 32.174247, -110.855874, 14)
  ENDPROC

  PROCEDURE DESTROY
    SET POINT TO (THIS.SetPoint)
  ENDPROC

  PROCEDURE cboDescrip.INIT
    THIS.LISTINDEX = 1
  ENDPROC

  PROCEDURE cmdMostrar.CLICK
    TEXT TO lcHtml NOSHOW TEXTMERGE
    <html> <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Google Maps</title>
    <script src="http://maps.google.com/maps?file=api&v=2&key=123" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[
    function load()
    { if (GBrowserIsCompatible())
      { var map = new GMap2(document.getElementById("map"),G_SATELLITE_MAP);
      map.addControl(new GLargeMapControl());
      map.addControl(new GMapTypeControl());
      map.addControl(new GOverviewMapControl());
      map.setCenter(new GLatLng(<<ALLTRIM(STR(MisLugares.Lat,12,6))>>,
      <<ALLTRIM(STR(MisLugares.Lon,12,6))>>),<<TRANSFORM(MisLugares.Zoom)>>);
      map.setMapType(G_HYBRID_MAP);
    } }
    //]]> </script> </head>
    <body scroll="no" bgcolor="#CCCCCC" topmargin="0" leftmargin="0"
    onload="load()" onunload="GUnload()">
    <div id="map" style="width:450px;height:300px"></div>
    </body> </html>
    ENDTEXT
    STRTOFILE(lcHtml,"MiHtml.htm")
    THISFORM.oleIE.Navigate2(FULLPATH("MiHtml.htm"))
  ENDPROC

ENDDEFINE

Los resultados de ejecutar el código son los siguientes:





Google Maps posee muchísimas opciones que permiten añadir controles para el desplazamiento, etiquetas, marcadores, escalas, etc. Lo mejor para aprender a utilizarlo, es leer la documentación disponible en el sitio Google Maps API, como así también leer y ajustarse a los Términos de Uso.

Hasta la próxima.

Luis María Guayán

25 de septiembre de 2006

Inversa de DTOS(), cadenas a fechas

Muchas veces tenemos algunos datos en formato año-mes-dia (AAAAMMDD), ya sea basado en la función DTOS() (Date To String) de VFP, o provenientes de algún otro sistema/lenguaje. A continuación la forma de convertir esas cadenas a tipos de datos fecha.

Lo que tendremos que hacer es simplemente usar la evaluación en línea que ofrece VFP:
**************************************************************************
* Function: STOD()
* Convierte una cadena en formato AAAMMDD al tipo de datos Date de VFP.
* Parameters: tcFecha --> La fecha en formato AAAMMDD, de tipo caracter.
* Returns:
*      + La fecha correspondiente con tipo de datos Fecha (Date de VFP)
*      + .NULL. en caso de haber error, o no cumplir con los
*        requerimentos
* Developer: Esparta Palma 
* Uso:
*     lcFecha = "20060920" && 20 de Septiembre de 2006 como cadena
*     ldFecha = STOD(lcFecha)
**************************************************************************
    Function STOD(tcFecha)
       LOCAL ldFecha
       ldFecha = .NULL.
       IF (Vartype(tcFecha)=="C") AND (NOT EMPTY(tcFecha)) ;
           AND (NOT IsNull(tcFecha))
           TRY
              ldFecha = EVALUATE("{^"+TRANSFORM(tcFecha,"@R 9999-99-99")+"}")
           CATCH TO oError
                 ?oError.Message
                ldFecha = NULL
           ENDTRY
       ENDIF
       Return ldFecha
   EndFunc
La cuestión principal es formar la fecha en el formato necesario para evaluarla, por ello el uso de la función Transform(), la cuál, hará un cambio de por ejemplo: "20060920" a "2006-09-20", a partir de ahí sumamos los caracteres iniciales y finales, quedando una cadena (siguiendo el ejemplo): "{^2006-09-20}", solo resta aplicar una evaluación en tiempo de ejecución, con lo que así tendremos nuestro tipo de datos fecha.

Nota: El código está optimizado para VFP8 y posteriores, ya que usa el control de errores en bloques TRY..CATCH, si usas una versión anterior simplemente remueve ese bloque y usa tu propia rutina de captura de errores.

Espero les sea de utilidad.

Espartaco Palma Martínez

19 de septiembre de 2006

VFP puede hacer cualquier cosa que pueda imaginar...

Artículo original: VFP can do anything you can imagine...
http://weblogs.foxite.com/vassilisaggelakos/2006/05/22/vfp-can-do-anything-you-can-imagine
Autor: Vassilis Aggelakos
Traducido por: Ana María Bisbé York


La semana pasada escribí sobre ProfilSmart http://weblogs.foxite.com/vassilisaggelakos/2006/05/18/what-i-have-done-with-vfp-gdi-and-a-ton-of-help-from-vfp-community-or-why-vfp-is-cool; pero no esperé recibir tantos comentarios positivos. Recibí muchos correos de miembros de la lista ProFox y prometí preparar un vídeo para brindarles una mejor idea de la aplicación en su totalidad.

(Nota de la traductora: El escrito al que se refiere el autor, fue traducido al idioma Español y publicado en PortalFox bajo el título "Lo que he logrado con VFP, GDI+ y una tonelada de ayuda de la comunidad VFP (o porqué VFP es genial)")

Aquí está. Puede descargar un archivo de 2.5 MB WMV desde http://www.themelio.gr/zip/prfvideo.wmv

Si tiene algún problema con el WMV puede descargar el archivo EXE que contiene incluido el visualizador de vídeos Camtasia, desde http://www.themelio.gr/zip/prfvid2.zip

Vea el vídeo y hágame saber, por favor, sus comentarios.

Visual FoxPro puede hacer cualquier cosa que pueda imaginar.

P.S: En mi último post olvidé mencionar que he contado con la ayuda invaluable del sitio de referencia sobre API http://www.news2news.com/vfp/index.php de Anatoly Mogylevets. La suscripción merece mucho más que lo que Anatoly cobra por ella.


12 de septiembre de 2006

Permutaciones

Código de VFP para permutar una cadena. Por ejemplo, hay 6 permutaciones de "ABC": ABC, ACB, BAC, BCA, CAB y CBS. Y hay N! permutaciones de una cadena de longitud N.

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

-- Permutations --
http://blogs.msdn.com/calvin_hsia/archive/2005/01/18/355405.aspx

Ejemplo:
nn=0
permute("abcd",0)
 
PROCEDURE permute(cstr,nLev)
      LOCAL nTrylen,i
      nTrylen= LEN(cstr)-nLev
      IF nTryLen = 0
            nn=nn+1
            ?nn,cstr
      ELSE
            FOR i = 1 to nTrylen
                  IF i>1      && swap nlev+1 and nlev+i chars
                        cstr= LEFT(cstr,nlev) + SUBSTR(cstr,nLev+i,1) +;
                              SUBSTR(cstr,nLev+2, i-2)+SUBSTR(cstr,nlev+1,1)+SUBSTR(cstr,nLev+i+1)
                  ENDIF
                  permute(cstr,nlev+1)
            ENDFOR
      ENDIF
RETURN

7 de septiembre de 2006

Lo que he logrado con VFP, GDI+ y una tonelada de ayuda de la comunidad VFP

Artículo original: What I have done with VFP, GDI+ and a ton of help from VFP Community (OR why VFP is COOL)
http://weblogs.foxite.com/vassilisaggelakos/2006/05/18/what-i-have-done-with-vfp-gdi-and-a-ton-of-help-from-vfp-community-or-why-vfp-is-cool
Autor: Vassilis Aggelakos
Traducido por: Ana María Bisbé York


Mi compañía desarrolla aplicaciones para un mercado muy especial. Escribimos código para fabricantes de ventanas. (Ellos realmente fabrican ventanas y puertas, no sistemas operativos :-) )

Digo que tuvimos que trabajar con un grupo de usuarios muy especial, porque (al menos en mi país) los usuarios de nuestras aplicaciones frecuentemente no tienen ninguna experiencia previa en el uso del PC. Por tanto, nuestra aplicación debe tener una interfaz muy intuitiva y por otra parte, debe cubrir necesidades muy complejas.

Algunas características de esta aplicación son: Cálculos de coste, Obtención de ofertas, Cálculos de longitudes de corte. Automáticamente crea una lista de precios, Barra de optimización y otros ... Todas estas características requieren poderosos mecanismos de control y VFP nos los brinda muy generosamente. (Intentamos el mismo proyecto con Visual Basic, PowerBuilder y C++; pero más tarde o más temprano todos esos intentos fallaron porque no tuvieron un balance aceptable entre Presupuesto - Tiempo y sus funcionalidades).

VFP es nuestra arma. Nuestra aplicación utiliza un framework hecho a mano inspirado básicamente en el libro Build Your Own Framework with Visual FoxPro (http://www.hentzenwerke.com/catalog/buildfox.htm) escrito por Kenneth Chazotte. Además, robé algo de código (e ideas) de muchas clases base del libro MegaFox: 1002 Things You Wanted to Know About Extending VFP (http://www.hentzenwerke.com/catalog/megafox.htm) escrito por Marcia Akins, Andy Kramek y Rick Schummer. Todo esto bajo la guía de Advanced Object Oriented Programming with Visual FoxPro 6.0 (http://www.hentzenwerke.com/catalog/aoopvfp.htm) de Markus Egger.
Por supuesto, no podría hacer aquí una lista de todos los libros que he leído para programar esta aplicación; pero permítanme mencionar otros dos libros que me brindaron tremenda ayuda. El primero es el libro Hacker's Guide to Visual FoxPro 7.0 (http://www.hentzenwerke.com/catalog/hackfox7.htm) escrito por Tamar E. Granor, Ted Roche, Doug Hennig, Della Martin y el libro Deploying Visual FoxPro Solutions (http://www.hentzenwerke.com/catalog/deployfox.htm) escrito por Rick Schummer, Rick Borup y Jacci Adams.

En noviembre de 2004 sacamos nuestra primera versión de ProfilSmart que introdujo una interfaz moderna inspirada grandemente en Widows XP. Todos los controles de la aplicación fueron escritos en código VFP puro.



Las opiniones recibidas de nuestros usuarios fueron tan alentadoras que en Abril 2006 sacamos la segunda versión de nuestra aplicación que ofreció a nuestros usuarios la posibilidad de dibujar fácilmente sus propios modelos. Utilizar miles de líneas de código VFP, GDI+ con las clases FFCC (desafortunadamente aun no he explorado las clases GDI+ de SednaX), nos dio la posibilidad de enfocar nuestra atención (y código) en un nivel superior de codificación de sistema. Por tanto, preparé un CAD completo, como un paquete, empleando solamente VFP y GDI+ DLLs. Por cortesía de Craig Boyd, Cesar Ch., la revista FoxTalk, Walter Nicholl y otros muchos miembros de la comunidad VFP, nuestros usuarios están más que satisfechos.



Desafortunadamente, de momento la mayor parte de la aplicación está disponible únicamente en idioma griego.





En un futuro cercano, prepararemos una versión LAN con SQL Server 2005 como base de datos y una versión PDA con código C#. Todo esto en cooperación armónica que ofrece la tecnología para cada compañía de fabricación. (incluso aquí en Grecia).

Escribo todo esto, porque primeramente deseo expresar mi profundo agradecimiento a todas esas personas que me han ayudado a implementar un sistema grande (tiene más de 160 KLOC para un único desarrollador no es tan sencillo) y entonces, creo que mi caso demuestra un ejemplo real de una aplicación moderna en respuesta a todos los que dicen que VFP es una lengua muerta o que es una base de datos antigua o o etc ... No quiero pelear todas las batallas de VFP; pero recomiendo fuertemente a otras personas de la comunidad VFP a que muestren ejemplos reales de sus aplicaciones para que las personas que no son de VFP puedan comprender el poder de Visual FoxPro.