Colección de Trucos

Colección de trucos recopilados por J.O. Oconnory otras fuentes

© Copyrights 1996 by FoxPress, All rights reserved

FoxPress, Mayo 1996( www.datapress.com)


P./ Tengo una aplicación que tiene varias ordenes SET en el programa de inicio. Cuando creo un formulario , observo que el valor de estas ordenes se cambia al valor por defecto en lugar de usar la opción que les he indicado en mi programa de inicio.
R./
Tu Formulario tiene una "Sesión Privada de Datos". Cuando tienes una Sesión Privada de Datos , debes re-establecer tus SET de entorno. La forma más fácil de hacer eso es crear una clase que establezca tu entorno y las revierta a sus valores originales en el evento de destroy. A continuación se puede instanciar la clase recientemente creada en el evento Load de la clase base tipo formulario.

P./ El asistente de documentación usa caracteres Gráficos tipo DOS cuando crea archivos que contienen diagramas. No puedo verlo o imprimirlo correctamente desde cualquier programa Windows. Tengo que volver a DOS para ver estos archivos correstamente.
R./
Abre los archivos en un procesador de Windows y cambia el fuente de todo el documento a "MS Line Draw" que convertirá estos caracteres ASCII a línea.

P./ Tengo un Formulario con tres pages de un pageframe. El problema es que cuando selecciono un registro en la primera página y pulso la tecla del tabulador para la segunda página, veo todos los campos pero de mi primer registro.
R./
Esto es un problema del Refresh(). En concreto, lo que necesitas es tener código en el Activate() de cada una de las pestañas para asegurar que lo que se va a mostrar va a ser lo correcto. Si has hecho algún Thisform.Refresh() en algún punto de tu Grid, VFP solo refresca la página Activa del PageFrame. Esto es bueno desde el punto de vista de la optimización. Sin embargo en el Activate() de cada página escribe esto:

THIS.Refresh()

Otra forma de hacer lo mismo evitando añadir código a cada página del pageframe es añadir una propiedad al pageframe y algo de código a los métodos Init() y click() del pageframe. Añade una propiedad al pageframe llamada nCurrentPage. Inicializala a = y en el método Click() añade el siguiente código:

LOCAL nPage, lOldLockScreen

lOldLockScreen = ThisForm.LockScreen

ThisForm.LockScreen = .T.

WITH This

nPage = .Pages[.ActivePage].PageOrder

IF nPage <> .nCurrentPage

.nCurrentPage = nPage

.Pages[nPage].Refresh()

ENDIF

ENDWITH

ThisForm.LockScreen = lOldLockScreen

En el método Init() del pageframe, añade el siguiente código:

This.nCurrentPage = This.Pages(This.ActivePage).PageOrder

P/ Cómo puedo pasar un Array a un Formulario como un parámetro?
R/
Los Arrays deben ser pasados en FoxPro por referencia. SET UDFPARMS determina cómo se pasan los parametros. Por defecto, cuando llamas a un procedimiento o a un Formulario usando DO...WITH, los parámetros se pasan por referencia:

DIMENSION miarray[2]

DO FORM miForm WITH miarray

También por defecto, los parámetros se pasan por valor con llamadas a funciones, incluyendo funciones definidas por el usuario y métodos. en este caso, para forzar el pasar un parámetro por referencia, precédelo con un ampersand (@):

DIMENSION miarray[2]

miForm = CREATEOBJECT("Miform", @miarray)

P./¿Hay alguna forma de quitar totalmente el título de un formulario?
R./
Haz lo siguiente:
1.- Pon la propiedad Caption a " "(vacía)

2.- Pon la propiedad ControlBox a .F.

3.- Pon la propiedad MaxButton a .F.

4.- Pon la propiedad MinButton a .F.

5.- Pon la propiedad Movible a .F.

P./ Me gustaría añadir un botón de "Llamar" a mi Grid de VFP con nombres y números de teléfono y que después de pulsar el botón, mi modem debería llamar al número marcado.
R./
Si trabajas con NT o Win95 puedes usar la .OCX MSCOMM32.OCX que viene con VFP. MSCOMM32.OCX sólo se instala si estás corriendo el Fox sobre Win95 o NT. En caso contrario puedes usar esta rutina que acude al API de Windows. Trabaja bien bajo 3.1 y es muy estabole en Win95 o NT. Necesitarás proveer los parámetros adecuados a la hora de empezar con THISFORM.

* write data to the serial port.

SET LIBRARY TO 'FOXTOOLS.FLL'

* Assumes that the number to dial is stored in ThisForm.CallNumber

M.Output = "ATDT" + ThisForm.CallNumber + '^M' + CHR(13)

LOCAL lccomport, lcdstring, lnport,

lccomport = LEFT(THISFORM.ComPort,4)

lcdstring = m.output

OPENCOMM = REGFN("OPENCOMM","CII","I",'USER.EXE')

WRITECOMM = REGFN('WRITECOMM','ICI','I','USER.EXE')

CLOSECOMM = REGFN('CLOSECOMM','I','I','USER.EXE')

LNPORT = CALLFN(OPENCOMM,LCCOMPORT,100,100) && open comm port

x = SECONDS()

DO WHILE SECONDS() - X < 1

ENDDO

=CALLFN(WRITECOMM,LNPORT,LCDSTRING,LEN(LCDSTRING)) && send string to modem

mTime = SECONDS()

DO While INKEY("HM") = 0 AND SECONDS() - mTime < 15 && wait for KeyPress or timeout

ENDDO

M.Output = 'ATH0^M' + CHR(13) && hang up modem

=CALLFN(WRITECOMM,LNPORT,LCDSTRING,LEN(LCDSTRING))

=CALLFN(CLOSECOMM,LNPORT)

x = SECONDS()

DO WHILE SECONDS() - X < 2

ENDDO

RELEASE LIBRARY 'FOXTOOLS'

P./ ¿Hay alguna forma de imprimir las páginas 10 y 11 de un Report especificando sólo 10-11?
R./
Usa la clausula PROMPT de la orden REPORT FORM para mostrar el diálogo de impresión. Aquí se puede señalar el rango de páginas para ser impresos

P./ De qué forma puedo usar la tecla ESC para salir de un Formulario?
R./
La mejor forma es poner la propieda Cancel del botón de comandos a .T.. Esto sería la forma más correcta de trabajar en perfecta consonancia con el diseño de Interfaces de windows. En el evento Click() de el botón de comandos escribe:

Thisform.Release()

También se podría usar el evento KeyPress del formulario con:

PROCEDURE KeyPress

LPARAMETERS nKeyCode, nShiftAltCtrl

IF nKeyCode = 27

RELEASE THISFORM

ENDIF

ENDPROC

P./ ¿Cómo puedo crear un report que usa un array como origen de datos?
R./
Las tablas son el origen de datos para los reports, así que deberás hacer lo siguiente:

CREATE CURSOR TEMP ( list of fields)

INSERT INTO DBF('temp') FROM ARRAY X

REPORT...

Tu report referenciará a los campos:

CREATE CURSOR TEMP (DUMMY C(1))

INSERT INTO DBF('TEMP') FROM ARRAY X

SELECT TEMP

REPORT...

P./ ¿Cómo puedo hacer una referencia a un formulario que pertenece a un conjunto de Formularios (FormSet)? He tratado de usar _Screen pero parece que sólo hace referencias al formulario actual.
R./
Se puede usar el _SCREEN, pero sólo puedes usar una propiedad llamada Forms que se encuentre en un Array conteniendo una referencia a los objetos formularios. Una forma simple de hacer esto es correr un bucle através de un array de formularios buscando por un formulario que cumpla ciertos criterios y a continuación decirle que haga lo que quieres. Digamos que si quieres refrescar cada formularios de la clase "myClass"· deberías hacer esto:

FOR I = 1 TO _SCREEN.FormCount

IF TYPE("_SCREEN.Forms[I]") = "O" ;

AND !ISNULL(_SCREEN.Forms[I]) ;

AND _SCREEN.Forms[I].Class = 'myclass'

_SCREEN.Forms[I].Refresh()

ENDIF

ENDFOR

La única forma que conozco de referenciar formsets desde _SCREEN es comprobar la existencia de un objeto parent para el formulario.

IF TYPE("_SCREEN.Forms[I].Parent") = "O"

IF TYPE("_SCREEN.Forms[I].Parent.MyForm") = "O"

_SCREEN.Forms[I].Parent.MyForm.Refresh()

ENDIF

ENDIF

P./ ¿Cómo puedo evitar que un formulario se instancie desde dentro del Formulario?
R./
Se puede evitar la instanciación de un Formulario devolviendo RETURN .F. en el método INIT(). Esto funciona con todos los objetos

P./ Cómo puedo evitar que un usuario se salga de un caja de texto?
R./
Hay varias formas. Puedes devolver .F. o 0 desde el evento Valid. O se puede usar el comando NONDEFAULT en el evento del LostFocus(). si quieres forzar a tus usuarios, puedes añadir la siguientes líneas al evento KEYPRESS()

LPARAMETERS nKeyCode, nShiftAltCtrl

IF nKeyCode = 13 && Trap the Return Key

NODEFAULT

ENDIF

P./ Hay alguna forma de obetener un checkbox desactivado pero con el look normal? Siempre aparece de color gris y es ignorado el color de background.
R./
En lugar de desactivar el checkbox, añade un RETURN .F. al evento When()

P./ En Win95 existen iconos de 32 * 32 y de 16 * 16 sin embargo la utilidad que viene con el VFP no permite tratar esto iconos reducidos. Este es un tema importante pues no quiero que el logotipo del zorro aparezca por todas partes en mi aplicación.
R./
Lo único que tienes que hacer es modificar el fichero ImagEdit.INI en el directorio de Windows añadiendo las siguientes líneas:

[ImagEdit.Icon]

Win95=16,16,16

Cuando se carga el ImagEdit y se añade un icono, se pulsa en el Edit ...nueva imagen y seleccionar Win95 16 * 16 como el tipo de recurso.

P./ Cómo devolver un valor desde un formulario?
R./
Hay varios pasos a realizar a la hora de devolver un valor desde un Formulario. En primer lugar el Formulario debe estar como Modal. Para devolver el valor, abre el evento unload del Formulario. Por ejemplo, si el valor está siendo guardado en una propiedad del formulario llamada cMiValor, sitúa el "RETURN Thisform.cMivalor" en el UNLOAD evento del Formulario.

P./ ¿Cómo puedo evitar el mensaje de "Inválida entrada de datos" cuando devuelvo .F. desde un evento Valid?
R./
En orden a prevenir que VFP nos muestre esa ventana de error, tienes que devolver 0 en lugar de .F. Cuando se devuelve un número desde el evento Valid, le estás diciendo a FoxPro cuantos controles en el Tab order quieres que se adelante. Si devuelves un valor negativo, se movera hacia atrás en el Tab Order.

P./ Se ejecutan los desencadenantes (Trigger) si uso un SQL INSERT desde un array de dos dimensiones?
R./
Los desencadenantes se ejecutan siempre que se añade un nuevo registro, incluso cuando se usa RECALL.

P./ ¿Cómo puedo suspender la ejecución de un programa cuando esté activo un Formulario?
R./
En la ventana de depuración escribe:

PROGRAM() Y sitúa un punto de ruptura en esa función.

2.- En la ventana de Comandos escribe:

_SCREEN.ActiveForm. Name= "MI Form"

3.- Abre la ventana de seguimiento, escoje Ejecutar y selecciona tu .SCX

P./ Cuales son las mejores direcciones de Internet sobre FoxPro.
R./
Aquí van unas cuantas:

Sin duda la primera y principal es la página Web de Microsoft en (HTTP://MICROSOFT.COM).

Un lugar más especializado también dentro del mismo Microsoft es :

HTTP://MICROSOFT.COM/DEVONLY

que contiene una gran cantidad de información acerca de Visual FoxPro. El único problema es que nos puede preguntar tus dudas pues son cerradas. Por suerte existe un grupo de news USENET "COMP.DATABASE.XBASE.FOX". Otras buenas direcciones las puedes encontrar en:

Marcus Egger's (MS MVP) Home Page:

http://ourworld.compuserve.com/homepages/MarkusEgger

FoxPro Yellow Pages:

http://www.transformation.com/foxpro/index.html

El FoxPro Yellow Pages guarda una completa información sobre Grupos de Usuarios y otros eventos de relieve.

The Fox Page:

http://www.state.sd.us/people/colink/fox_page.htm

FoxWeb

http://totw.com/fox.htm

BMC FoxPage:

http://turnpike.net/emporium/B/bmc/foxpage.htm

Electric FoxPro

http://discover-net.net/%7Edhenton/ghtml/efox.html

WebLink for Visual FoxPro (Link VFP to the WWW)

http://ciint1.ciinc.com/weblink/vfpdemo.htm

FoxPro I/O Address:

http://www.hop.man.ac.uk/staff/mpitcher/foxpro.html

Montreal FoxPro User's Group

http://www.transformation.com/mfug/mfug2.html

Chicago FoxPro Users/Developer's Group

http://www.imginfo.com/fudg.htm

P./ ¿Cómo crear Captions Verticales ?
R./ Los Caption de los Label son normalmente horizontales. Para hacer que un Label sea vertical, bastaría con escribir un salto de carro, CHR(13) entre cada uno de los caracteres del Label. Por ejemplo, para mostrar verticalmente la palabra "Test" se usaría este código:

Label.Caption = "T" + CHR(13)+ "E"+CHR(13)+ "S" + CHR(13)+ "T"+CHR(13)