21 de julio de 2012

Arrastrar, soltar y conservar posiciones

Artículo original: Drag, Drop and Retain Positions
http://sandstorm36.blogspot.com/2012/07/drag-drop-and-retain-positions.html
Autor: Jun Tangunan
Traducido por: Luis Maria Guayán


Arrastrar, soltar y conservar posiciones

Aquí otro ejemplo moviendo objetos a su alrededor y conservando las posiciones en la siguiente ejecución del formulario. Esto es sólo una simple demostración de cómo podemos hacer lo siguiente:



Mientras que la parte de arrastrar y soltar parece ser fácil, además de conservar y recuperar esos valores posteriormente, lo que me llevó más tiempo de averiguar es cómo el reordenamiento de estos objetos que afectan las propiedades tabIndex de cada objeto dentro del contenedor. De todos modos, esto no está perfecto aun, pero al menos usted tendrá algo con que empezar y perfeccionar.

Copie y pegue el código a un .PRG, ejecute y tilde "Permitir mover", a continuación, arrastre los botones alrededor. Después de eso, cierre el formulario y a continuación, ejecutelo de nuevo. Vea si se mantiene las últimas posiciones cuando se cerró el formulario y si el tabindex es el adecuado.
Aquí el código del ejemplo si le interesa:
LOCAL oForm AS FORM
oForm = CREATEOBJECT('TestForm')
oForm.SHOW(1)
RETURN

DEFINE CLASS TestForm AS FORM
  AUTOCENTER = .T.
  WIDTH = 300
  HEIGHT = 440
  MINWIDTH = 200
  MINHEIGHT = 100
  CAPTION = 'Drag, Drop & Retain Positions'

  ADD OBJECT chkMove AS CHECKBOX WITH CAPTION = 'Permitir mover los objetos',;
    TOP = 400, LEFT = 5, AUTOSIZE = .T., VALUE = .F., ANCHOR = 6
  ADD OBJECT Command1 AS MyButton WITH CAPTION='One', TOP = 5, LEFT = 5
  ADD OBJECT Command2 AS MyButton WITH CAPTION='Two', TOP = 70, LEFT = 5
  ADD OBJECT Command3 AS MyButton WITH CAPTION='Three', TOP =135, LEFT = 5
  ADD OBJECT Command4 AS MyButton WITH CAPTION='Four', TOP = 200, LEFT = 5
  ADD OBJECT Command5 AS MyButton WITH CAPTION='Five', TOP = 265, LEFT = 5
  ADD OBJECT Command6 AS MyButton WITH CAPTION='Six', TOP = 330, LEFT = 5

  PROCEDURE LOAD
    CLOSE DATABASES ALL
    * Check if table is there for preserving/restoring values
    IF !FILE('DragDrops.dbf')
      CREATE TABLE dragdrops FREE (ObjectName c(40),xTop I,xLeft I,xTabIndex I)
      INDEX ON xTop+xLeft TAG xTabIndex
    ELSE
      USE dragdrops ORDER xTabIndex
    ENDIF
  ENDPROC

  PROCEDURE INIT
    * Check if first run or not, if first run, make an entry in the table
    IF RECCOUNT() == 0
      FOR EACH loCtrl IN THISFORM.CONTROLS FOXOBJECT
        INSERT INTO dragdrops VALUES (loCtrl.NAME,loCtrl.TOP,loCtrl.LEFT,0)
      NEXT
    ENDIF
    THIS._reorder()
  ENDPROC

  PROCEDURE _TabIndex
    * recreate tab indexes
    LOCAL lnTab
    lnTab = 1
    SCAN
      REPLACE xTabIndex WITH m.lnTab IN dragdrops
      lnTab = m.lnTab + 1
    ENDSCAN
  ENDPROC

  PROCEDURE _reorder
    * Reorder Tab Index
    FOR EACH loCtrl IN THISFORM.CONTROLS FOXOBJECT
      SELECT dragdrops
      LOCATE FOR UPPER(loCtrl.NAME) = UPPER(ObjectName)
      loCtrl.TABINDEX = dragdrops.xTabIndex
    NEXT
  ENDPROC

ENDDEFINE

DEFINE CLASS MyButton AS COMMANDBUTTON
  HEIGHT = 60
  WIDTH = 100

  PROCEDURE INIT
    * Get previous positions
    SELECT dragdrops
    LOCATE FOR UPPER(THIS.NAME) = UPPER(ObjectName)
    THIS.TOP = dragdrops.xTop
    THIS.LEFT = dragdrops.xLeft
  ENDPROC

  PROCEDURE MOUSEMOVE
    LPARAMETERS nButton, nShift, nXCoord, nYCoord
    IF m.nButton = 1 AND THISFORM.chkMove.VALUE = .T.
      THIS.MOVE(m.nXCoord, m.nYCoord)
      * update new coordinates
      REPLACE xTop WITH m.nYCoord, xLeft WITH m.nXCoord FOR;
        UPPER(THIS.NAME) = UPPER(ObjectName) IN dragdrops
      THISFORM._TabIndex()
    ENDIF
  ENDPROC

  PROCEDURE CLICK
    MESSAGEBOX("You've clicked "+THIS.NAME+CHR(13)+;
      "Tab Index: "+TRANSFORM(THIS.TABINDEX))
  ENDPROC

ENDDEFINE

14 de julio de 2012

Cambiar la resolución del monitor desde VFP

Una excelente función del turco Cetin Basoz que nos permite cambiar la resolución de la pantalla desde Visual FoxPro.

? SetScreenresolution(1024,768)

FUNCTION SetScreenresolution(tnWidth,tnHeight,tnFrequency)

  #DEFINE ENUM_CURRENT_SETTINGS -1
  #DEFINE CDS_UPDATEREGISTRY = 0x01
  #DEFINE CDS_TEST 0x02
  #DEFINE DISP_CHANGE_SUCCESSFUL 0
  #DEFINE DISP_CHANGE_RESTART 1
  #DEFINE DISP_CHANGE_FAILED -1
  #DEFINE DM_PELSWIDTH 0x00080000
  #DEFINE DM_PELSHEIGHT 0x00100000
  #DEFINE DM_DISPLAYFREQUENCY 0x00400000

  LOCAL lpDevMode,result
  DECLARE INTEGER EnumDisplaySettings IN win32API ;
    STRING deviceName,;
    INTEGER modeNum, ;
    STRING @ lpdevMode

  DECLARE LONG ChangeDisplaySettings IN win32API ;
    STRING lpDevMode, ;
    INTEGER dwflags

  lpdevMode = REPLICATE(CHR(0),512)

  EnumDisplaySettings(0,ENUM_CURRENT_SETTINGS,@lpdevMode)

  *!*    ? "Current settings are:",;
  *!*        CTOBIN(Substr(m.lpdevMode,109,4),"4RS"),;
  *!*        CTOBIN(Substr(m.lpdevMode,113,4),"4RS")

  * Width and Height
  lpdevMode = STUFF(m.lpdevMode,109,4,Int2DWord(m.tnWidth))
  lpdevMode = STUFF(m.lpdevMode,113,4,Int2DWord(m.tnHeight))

  IF !EMPTY(m.tnFrequency)
    lpdevMode = STUFF(m.lpdevMode,121,4,Int2DWord(m.tnFrequency)) && Frequency
    lpdevMode = STUFF(m.lpdevMode,41,4,;
      Int2DWord(BITOR(DM_PELSWIDTH,DM_PELSHEIGHT,DM_DISPLAYFREQUENCY))) && dmFields
  ELSE
    lpdevMode = STUFF(m.lpdevMode,41,4,;
      Int2DWord(BITOR(DM_PELSWIDTH,DM_PELSHEIGHT))) && dmFields
  ENDIF

  result = ChangeDisplaySettings(m.lpdevMode,CDS_TEST)

  IF !( result = DISP_CHANGE_SUCCESSFUL )
    MESSAGEBOX("Mode is not supported",0+48,'Monitor settings')
  ELSE
    ChangeDisplaySettings(m.lpdevMode,0)
    TEXT to m.lcSetting noshow
La resolución de su pantalla ha sido cambiada.
Presione [Si] para confirmar el cambio.
Se restablecerá automáticamente la resolución en 30 segundos.
    ENDTEXT

    IF MESSAGEBOX(m.lcSetting,4+64,'Monitor settings',30000) != 6
      ChangeDisplaySettings(0,0) && restore
    ENDIF

  ENDIF
ENDFUNC

FUNCTION Int2DWord(tInt)
  LOCAL lcDWord,ix
  lcDWord = ''
  FOR ix=1 TO 4
    lcDword = m.lcDword + CHR( INT(m.tInt / 256^(m.ix-1)) % 256 )
  ENDFOR
  RETURN m.lcDword
ENDFUNC

23 de junio de 2012

Implementación de Aspell desde Visual FoxPro (corrector ortográfico)

Que es Aspell

GNU Aspell, generalmente llamado simplemente Aspell es un corrector ortográfico de software libre diseñado para reemplazar Ispell. Es el corrector ortográfico estándar para el sistema de software GNU. También compila para otros sistemas operativos tipo Unix y Windows. El programa principal está licenciado bajo la GNU Lesser General Public License (GNU LGPL), la documentación bajo la GNU Free Documentation License (GNU FDL). Diccionarios para que estén disponibles para alrededor de 70 idiomas. El mantenedor principal es Kevin Atkinson. (Fuente Wikipedia)

Donde puedo descargar Aspell para windows

En los siguientes links se puede descargar el paquete para Windows con sus respectivos diccionarios en varios idiomas

Implementacion de Aspell en Visual FoxPro

Después de mucho navegar e investigar por toda la web fue imposible encontrar una implementación de Aspell en Visual FoxPro, así que realice la tarea de implementarlo, para esto fue necesario el análisis de distintas implementaciones es lenguajes como C++, Pascal, Delphi entre otros. Debemos tener claro que estamos usando una librería dinámica externa propia de Aspell compilada para Windows, así que como prerrequisitos tenemos:
Con estos elementos instalados aclaremos, la librería dinámica a usar es ASPELL-15.DLL la cual se encuentra en C:\PROGRAM FILES\ASPELL\BIN\, la ruta puede variar dependiendo el sistema operativo como por ejemplo en equipos con SO de 64Bits seria C:\PROGRAM FILES (X86)\ASPELL\BIN\.

Ejemplo basico de Aspell desde Visual FoxPro

*!* Ubicación de la DLL
#DEFINE ASPELL_DLL "C:\PROGRAM FILES\ASPELL\BIN\ASPELL-15.DLL"
#DEFINE ASPELL_LANG "es"

*!* Funciones de la DLL
IF FILE(ASPELL_DLL)==.t.
 DECLARE INTEGER new_aspell_config IN (ASPELL_DLL)
 DECLARE INTEGER aspell_config_replace IN (ASPELL_DLL) INTEGER, STRING, STRING
 DECLARE INTEGER new_aspell_speller IN (ASPELL_DLL) INTEGER
 DECLARE INTEGER aspell_error_number IN (ASPELL_DLL) INTEGER
 DECLARE INTEGER to_aspell_speller IN (ASPELL_DLL) INTEGER
 DECLARE INTEGER aspell_speller_check IN (ASPELL_DLL) INTEGER, STRING, INTEGER
 DECLARE INTEGER aspell_speller_suggest IN (ASPELL_DLL) INTEGER, STRING, INTEGER
 DECLARE INTEGER aspell_word_list_elements IN (ASPELL_DLL) INTEGER
 DECLARE INTEGER delete_aspell_string_manag IN (ASPELL_DLL) INTEGER
 DECLARE STRING aspell_string_enumeration_next IN (ASPELL_DLL) INTEGER
 DECLARE STRING aspell_error_message IN (ASPELL_DLL) INTEGER
ELSE
 =MESSAGEBOX("La libreria de Aspell no fue encontrada, descarguela e instalela desde:"+CHR(13)+;
    "http://aspell.net"+CHR(13)+;
    "http://aspell.net/win32/dicts",0+64+256,"Libreria no instalada")
 RETURN .f.
ENDIF 

*!* Variables
LOCAL lnSpellConfig, ;
   lnPossibleErr, ;
   lnSpellChecker, ;
   lcPalabra, ;
   lnPalabra, ;
   lcSuggestions, ;
   lnElements, ;
   lcSugerencias, ;
   llSalir

*!* Iniciando instancia
lnSpellConfig = new_aspell_config()

*!* Cargando diccionario ESPAÑOL (es)
IF aspell_config_replace(lnSpellConfig, "lang", ASPELL_LANG)==1
 
 lnPossibleErr = new_aspell_speller(lnSpellConfig)
 lnSpellChecker = 0

 *!* Comprobando Inicio
 IF aspell_error_number(lnPossibleErr) != 0
  =MESSAGEBOX(aspell_error_message(lnPossibleErr),0+16+256+4096,"Error Aspell")
  RETURN .f.
 ELSE 
  lnSpellChecker = to_aspell_speller(lnPossibleErr)
 ENDIF

 *!* Palabra a comprobar
 lcFrase=INPUTBOX("Ingrese la frase a comprobrar","Frase","",0,"","")
 
 *!* Recorriendo palabras
 FOR lnItem=1 TO GETWORDCOUNT(lcFrase,' ')
  lcPalabra=GETWORDNUM(lcFrase,lnItem,' ')
  lnPalabra=LEN(lcPalabra)


  IF aspell_speller_check(lnSpellChecker,lcPalabra,lnPalabra)==0
   lcSuggestions =aspell_speller_suggest(lnSpellChecker,lcPalabra,lnPalabra)
   lnElements = aspell_word_list_elements(lcSuggestions)
   lcSugerencias=''
   llSalir=.f.

   DO WHILE llSalir==.f.
    TRY 
     lcSugerencias=lcSugerencias+aspell_string_enumeration_next(lnElements)+CHR(13)
    CATCH TO loError
     llSalir=.t.
    ENDTRY 
   ENDDO 
   =MESSAGEBOX("Incorrecta, sugerencias para "+lcPalabra+CHR(13)+lcSugerencias,0+512+4096,"Incorrectar")
  ELSE
   =MESSAGEBOX("Correcta, "+lcPalabra,0+512+4096,"Correctar")
  ENDIF 
 ENDFOR 
ELSE
 =MESSAGEBOX("Imposible iniciar la configuracion de Aspell",0+16+256+4096,"Fallo configuración")
ENDIF 

Jose Guillermo Ortiz Hernandez

Clase para corregir la ortografia en un EditBox o TextBox

Esta clase implemente la libreria Aspell (spell checker) en un objeto de clase EditBox, tambien puede ser usar en un TextBox. Al implementar Aspell (GNU) no requiere que el cliente tenga instalado MS Word.

QUE ES ASPELL

GNU Aspell, generalmente llamado simplemente Aspell es un corrector ortográfico de software libre diseñado para reemplazar Ispell. Es el corrector ortográfico estándar para el sistema de software GNU. También compila para otros sistemas operativos tipo Unix y Windows. El programa principal está licenciado bajo la GNU Lesser General Public License (GNU LGPL), la documentación bajo la GNU Free Documentation License (GNU FDL). Diccionarios para que estén disponibles para alrededor de 70 idiomas. El mantenedor principal es Kevin Atkinson. (Fuente Wikipedia)

DONDE PUEDO DESCARGAR ASPELL PARA WINDOWS

En los siguientes links se puede descargar el paquete para Windows con sus respectivos diccionarios en varios idiomas

IMPLEMENTACION DE ASPELL EN VISUAL FOXPRO

Después de mucho navegar e investigar por toda la web fue imposible encontrar una implementación de Aspell en Visual FoxPro, así que realice la tarea de implementarlo, para esto fue necesario el análisis de distintas implementaciones es lenguajes como C++, Pascal, Delphi entre otros. Debemos tener claro que estamos usando una librería dinámica externa propia de Aspell compilada para Windows, así que como prerrequisitos tenemos:

CARACTERISTICAS

  1. Interface Nativa en VFP
  2. Incluye las caracteristicas de busqueda http://jgohortiz.blogspot.com/search/label/editbox

DESCARGAR

Descargue la clase desde este enlace

SCREENSHOT



Jose Guillermo Ortiz Hernandez

3 de junio de 2012

Nueva versión 1.10 de Foxbarcode

FoxBarcode es una clase 100% Visual FoxPro que ofrece una herramienta para la generación de imágenes con distintas simbologías de códigos de barras, para ser usadas en informes y formularios de VFP, o exportadas a otras aplicaciones. Su uso y distribución es libre para toda la Comunidad de Visual FoxPro.

FoxBarcode soporta las simbologías: Código 128, Código 39, Código 39 Extendido (Full ASCII), Código 93, Código 93 Extendido (Full ASCII), Standard 2 de 5, Interleaved 2 de 5, EAN-8, EAN-13, UPC-A, UPC-E (EAN y UPC con suplementos de 2 y 5 dígitos), ITF-14, GS1/EAN/UCC-128, Codabar, Código 11, MSI / Plessey, Telepen, PostNet, RM4SCC, KIX-Code, One Track Pharmacode y Two Track Pharmacode.

FoxBarcode soporta los tipos de imagenes: JPG, BMP, GIF, PNG y TIFF

Pueden descargar la nueva versión desde la página de FoxBarcode:
http://sites.google.com/site/foxbarcode

¿Que hay de nuevo?
  • Nuevo lenguaje: ITALIANO por Roberto Saccomanno
  • Cambio en la propiedad nImageWidth: Ahora se puede configurar el ancho de la imagen
  • Nueva propiedad nAlignBarcode: Permite alinear el código de barras a la izquierda, centro o derecha de la imagen.
  • Corrección de pequeños errores.