16 de septiembre de 2003

Leer valores del Registry versión OOP

Leer valores del Registro de Windows es fácil, si usas Visual FoxPro y las Fox Foundation Classes (FFC), aquí te enseñamos cómo....

Otra de las clases que se encuentran en las Fox Foundation Classes es la llamada Registry Access, la cual está accesible por medio del IDE de VFP.

Tools -> Component Gallery -> FFCs -> Utilities

Con esta clase se pueden hacer multitud de cosas con respecto al Manejo del Registry, a continuación un pequeño ejemplo (cortesía de Alex Feldstein en las newsgroups de Microsoft):

** Ejemplo de Registry.vcx:
** Abrir una llave (key) usando el metodo OpenKey().
** Si no especificas una llave, el default es HKEY_CLASSES_ROOT
 
 oReg = NEWOBJECT("registry",HOME(1)+"ffc\registry.vcx")
 lcKey = "VisualFoxPro.ApplicationCurVer"
 if oReg.OpenKey(lckey) = 0
   * sin error
   lcvalue = ""
   if oReg.GetKeyValue("", @lcvalue) = 0
     * sin error
     ? lcvalue
   endif
   oReg.CloseKey()
 endif 
Espero les sea de utilidad.

Espartaco Palma Martínez

12 de septiembre de 2003

Números a Letras en Inglés

Rutina que convierte un importe a letras en Inglés.

Ejemplo:

? Num2Word(123456.78)
"ONE HUNDRED TWENTY THREE THOUSAND FOUR HUNDRED FIFTY SIX AND 78/100"

*-------------------------------------------
* FUNCTION Num2Word(tcNro)
*-------------------------------------------
* Pasa un Importe a Letras (en Inglés)
* USO: ? Num2Word(123456.78)
* PARAMETRO: Importe a convertir (Numérico)
* RETORNO: Caracter
* AUTOR: Luis María Guayán
*-------------------------------------------
FUNCTION Num2Word(tcNro)
  LOCAL lnEnt, lcRet, lcCad, lnTerna,;
    lnUni, lnDec, lnCent, lnFrac
  lnEnt = INT(tcNro)
  lnFrac = (tcNro - lnEnt) * 100
  lcRet = ''
  lnTerna = 1
  DO WHILE lnEnt > 0
    *-- Recorro terna por terna
    lcCad = ''
    lnUni = lnEnt % 10
    lnEnt = INT(lnEnt/10)
    lnDec = lnEnt % 10
    lnEnt = INT(lnEnt/10)
    lnCent = lnEnt % 10
    lnEnt = INT(lnEnt/10)
    *-- Analizo las unidades
    DO CASE && UNIDADES
      CASE lnUni = 1
        lcCad = 'ONE ' + lcCad
      CASE lnUni = 2
        lcCad = 'TWO ' + lcCad
      CASE lnUni = 3
        lcCad = 'THREE ' + lcCad
      CASE lnUni = 4
        lcCad = 'FOUR ' + lcCad
      CASE lnUni = 5
        lcCad = 'FIVE ' + lcCad
      CASE lnUni = 6
        lcCad = 'SIX ' + lcCad
      CASE lnUni = 7
        lcCad = 'SEVEN ' + lcCad
      CASE lnUni = 8
        lcCad = 'EIGHT ' + lcCad
      CASE lnUni = 9
        lcCad = 'NINE ' + lcCad
    ENDCASE && UNIDADES
    *-- Analizo las decenas
    DO CASE && DECENAS
      CASE lnDec = 1
        DO CASE
          CASE lnUni = 0
            lcCad = 'TEN '
          CASE lnUni = 1
            lcCad = 'ELEVEN '
          CASE lnUni = 2
            lcCad = 'TWELVE '
          CASE lnUni = 3
            lcCad = 'THIRTEEN '
          CASE lnUni = 4
            lcCad = 'FOURTEEN '
          CASE lnUni = 5
            lcCad = 'FIFTEEN '
          CASE lnUni = 6
            lcCad = 'SIXTEEN '
          CASE lnUni = 7
            lcCad = 'SEVENTEEN '
          CASE lnUni = 8
            lcCad = 'EIGHTEEN '
          CASE lnUni = 9
            lcCad = 'NINETEEN '
        ENDC
      CASE lnDec = 2
        lcCad = 'TWENTY ' + lcCad
      CASE lnDec = 3
        lcCad = 'THIRTY ' + lcCad
      CASE lnDec = 4
        lcCad = 'FORTY ' + lcCad
      CASE lnDec = 5
        lcCad = 'FIFTY ' + lcCad
      CASE lnDec = 6
        lcCad = 'SIXTY ' + lcCad
      CASE lnDec = 7
        lcCad = 'SEVENTY ' + lcCad
      CASE lnDec = 8
        lcCad = 'EIGHTY ' + lcCad
      CASE lnDec = 9
        lcCad = 'NINETY ' + lcCad
    ENDCASE && DECENAS
    *-- Analizo las centenas
    DO CASE && CENTENAS
      CASE lnCent = 1
        lcCad = 'ONE HUNDRED ' + lcCad
      CASE lnCent = 2
        lcCad = 'TWO HUNDRED ' + lcCad
      CASE lnCent = 3
        lcCad = 'THREE HUNDRED ' + lcCad
      CASE lnCent = 4
        lcCad = 'FOUR HUNDRED ' + lcCad
      CASE lnCent = 5
        lcCad = 'FIVE HUNDRED ' + lcCad
      CASE lnCent = 6
        lcCad = 'SIX HUNDRED ' + lcCad
      CASE lnCent = 7
        lcCad = 'SEVEN HUNDRED ' + lcCad
      CASE lnCent = 8
        lcCad = 'EIGHT HUNDRED ' + lcCad
      CASE lnCent = 9
        lcCad = 'NINE HUNDRED ' + lcCad
    ENDCASE && CENTENAS
    *-- Analizo la terna
    DO CASE && TERNA
      CASE lnTerna = 1
        lcCad = lcCad
      CASE lnTerna = 2 AND (lnUni + lnDec + lnCent # 0)
        lcCad = lcCad + 'THOUSAND '
      CASE lnTerna = 3 AND (lnUni + lnDec + lnCent # 0)
        lcCad = lcCad + 'MILLON '
      CASE lnTerna = 4 AND (lnUni + lnDec + lnCent # 0)
        lcCad = lcCad + 'BILLON '
    ENDCASE && TERNA
    *-- Armo el retorno terna a terna
    lcRet = lcCad  + lcRet
    lnTerna = lnTerna + 1
  ENDDO && WHILE
  IF lnTerna = 1
    lcRet = 'ZERO '
  ENDIF
  RETURN lcRet + 'AND ' + ;
    TRANSFORM(lnFrac,"@L 99") + '/100'
ENDFUNC
*-------------------------------------------

Luis María Guayán

9 de septiembre de 2003

Crear una funcionalidad Deshacer en cuadros de texto de Visual FoxPro

Artículo original: Creating Undo functionality in a Visual FoxPro TextBox
http://west-wind.com/weblog/posts/3296.aspx
Autor: Rick Strahl
Traducido por: Ana María Bisbé York


El cuadro de texto de Visual FoxPro no es precisamente un gran control como el que yo tengo en el Help Builder (http://www.west-wind.com/wwHelp/). Tuve que trabajarlo para hacer que funcione como si estuviera basado en un editor de textos que incluye formato. Pero al mismo tiempo no era capaz de encontrar una forma decente de sustitución. La mayoría de los controles ActiveX basados en textos son poco menos que un infierno (al menos en VFP) o son muy muy lentos si trata de enganchar algún evento COM a la clave al procesar, como necesito que haga el Help Builder.

En general el TextBox de VFP funciona bien, salvo en dos cosas:
  1. Existe un bug en el control que provoca que el control envuelva al original si existen avance de línea en un área específica del margen derecho. Puede causar avances de línea que sean "comidos" por el cuadro de texto con el texto que puede ser un salto súbito cuando el cuadro de texto es redimensionado u otros cuadros de texto entren  fuera del margen. Esto se puede ver como un bug muy oscuro; pero si trabaja modificando grandes cantidades de textos se lo encontrará muy pronto. Según Calvin Hsia se corrige en el VFP 9.0 SP1...
  2. Comportamiento para Deshacer. El cuadro de texto de Visual FoxPro no tiene un comportamiento para Deshacer - el buffer para Deshacer se pierde cada vez que hay cualquier tipo de actualización del dato. Esto incluye el enlace al origen de datos (ControlSource), establecer el valor explícitamente, cambiar SelText o incluso pasar texto al control. Se limpia también si se oprime la tecla Tab y sale del control e inmediatamente regresa. Todo esto es realmente limitado y no es un comportamiento estándar.
Hasta la salida del SP1 no puedo hacer nada con el punto 1; pero he pensado que puedo controlar mi propio Deshacer con buffer en mi control TextBox personalizado. Mientras hablaba con Calvin en SoutWest Fox comenzamos a colocar un mejor comportamiento en el TextBox; pero sobre el comportamiento Deshacer está profundamente dentro del runtime de VFP y cambiar eso es algo como romper mucho del código que ya está. Por tanto no hay ayuda en este sentido. Entonces Calvin me sugirió... escribe el tuyo propio....

Lo primero que pensé - sí, bien. Controlar Deshacer buffer con código Fox es muy lento y ocuparía mucha memoria, porque hay que guardar el buffer entero del valor del control ya que los eventos InteractiveChange y ProgrammaticChange no brindan información de qué es lo que ha cambiado, entonces, no hay una forma fácil de capturar cuál de los cambios es el que hay que deshacer.

2 de septiembre de 2003

Cambios en el comportamiento de SELECT SQL en Visual FoxPro 8

Artículo en la Base de Conocimientos de Microsoft que describe los cambios de comportamiento en la instrucción SELECT SQL en Visual FoxPro 8.

Los cambios descriptos en el artículo son:

. Cambios en las cláusulas GROUP BY y HAVING
. Cambios en la cláusula DISTINCT
. Cambios en SELECT ... UNION
. Cambios en SELECT ... LIKE

Para compatibilidad con versiones anteriores existen dos nuevos comandos:

SET ENGINEBEHAVIOR 70 y SYS(3099,70)

Para ver el artículo completo: http://support.microsoft.com/default.aspx?scid=kb;ES;813361

Luis María Guayán