Por Abel Sorzano formanimado.zip
Si
en Word invocas la opción de ‘encontrar’ verás que la pantalla se te abre no de
golpe sino con un efecto especial empezando, al menos en mi caso, desde el
angulo inferior derecho.
¿Cómo
hacer eso en Fox? No es fácil pero se puede hacer. El truco consiste en usar la
función del API llamada DrawAnimatedRects. La ayuda del API nos la define
así:
BOOL WINAPI DrawAnimatedRects(
HWND hwnd, // handle to clipping window
int idAni, // type of animation
CONST RECT *lprcFrom, // rectangle coordinates (minimized)
CONST RECT *lprcTo // rectangle coordinates (restored)
);
|
|
|
|
Return Values |
|
|
|
|
La primera dificultad es cómo traducir a Fox esta
función del API. La traducción sería:
DECLARE Integer
DrawAnimatedRects IN User32.dll Integer, Integer, String @, String @
(recuerdo
que las funciones del API son sensibles a mayúsculas/minúsculas)
El
ejemplo más sencillo que he conseguido hacer con el uso de esta función es el
siguiente que implica usar otras dos funciones del API:
DECLARE Integer
DrawAnimatedRects IN User32.dll Integer, Integer, String @, String @
DECLARE Integer SetRect
IN User32.dll String @, Integer, Integer, Integer, Integer
DECLARE Integer
GetActiveWindow IN user32.dll
lc_FromRect = SPACE(16)
lc_ToRect = SPACE(16)
SetRect(@lc_FromRect,
10, 10, 10, 10)
SetRect(@lc_ToRect,
200, 200, 600, 400)
DrawAnimatedRects(GetActiveWindow(),
3, @lc_FromRect, @lc_ToRect)
Ejecútalo
desde Fox con una ventana abierta o sin ninguna ventana abierta y verás el
efecto óptico que se produce.
El
código es curioso pero aparentemente poco útil. La principal dificultad estriba
en que no tenemos un handle de ventana que queramos tratar y por eso realiza
esos efectos.
Para
continuar con el ejemplo nos construiremos un
formulario (formulario origen) y pondremos en un botón de comandos y
escribiremos en el click del botón de comandos:
DO FORM nuevo.scx
NOSHOW NAME toWindow
DECLARE Integer
DrawAnimatedRects IN User32.dll Integer, Integer, String @, String @
DECLARE Integer SetRect
IN User32.dll String @, Integer, Integer, Integer, Integer
Set Library to (Home()+"\FoxTools.Fll")
Additive
LOCAL lc_FromRect,
lc_ToRect, lnHwnd
lc_FromRect = SPACE(16)
lc_ToRect = SPACE(16)
lnHwnd = 0
SetRect(@lc_FromRect,
10, 10, 10, 10)
SetRect(@lc_ToRect,
200, 200, 600, 400)
* conseguimos el Hwnd
(window handle)
lnHwnd = _WhToHwnd(
_WFindTitl(toWindow.Caption) )
DrawAnimatedRects(lnHwnd,
3, @lc_FromRect, @lc_ToRect)
toWindow.visible = .t.
A
continuación nos construiremos un formulario de destino que en mi caso he
llamado Nuevo.
En
el código anterior fíjate como llamamos al formulario con la instrucción:
DO
FORM nuevo.scx NOSHOW NAME toWindow
La
opción de NAME nos permite meter el objeto formulario destino en una variable y
como le decimos que no lo muestre, tenemos que el formulario se ha lanzado pero
no se ha mostrado.
Al
tener el formulario en una variable, puedo conseguir su handle (el handle de
cada ventana es único) pero para eso tengo que acudir a la Foxtools.
Mediante
la instrucción:
lnHwnd
= _WhToHwnd( _WFindTitl(toWindow.Caption) )
consigo
el handle del formulario que hemos ejecutado (pero no mostrado). Fíjate como
para conseguir el handle se usa el nombre del Caption. En lnHwnd ya tengo el
Handle de la ventana sobre la que quiero efectuar el efecto optico en la
apertura. Para realizar ese efecto óptico basta con primero ejecutar el
DRAWAnimatedRects y después hacerla visible y Voila!
DrawAnimatedRects(lnHwnd,
3, @lc_FromRect, @lc_ToRect)
toWindow.visible
= .t.
La
función del API SetRect nos define la posición de la ventana. En nuestro
ejemplo como le ponemos unos valores fijos verás que te la posiciona en el
angulo superior izquierdo y el tamaño de la ventana que se abre no es igual al
del formulario que habíamos diseñado.
Para
calcular la posición y el tamaño tenemos que escribir otro poco más de código.
Además como los valores hay que pasarselos en hexadecimal la cosa se complica
un poco pero por el contrario nos liberamos de esta función del API.
La
nueva forma de llamarla sería:
DO FORM nuevo.scx
NOSHOW NAME toWindow
DECLARE Integer
DrawAnimatedRects IN User32.dll Integer, Integer, String @, String @
Set Library to
(Home()+"\FoxTools.Fll") Additive
LOCAL lc_FromRect,
lc_ToRect, lnHwnd
lc_FromRect = SPACE(16)
lc_ToRect = SPACE(16)
lnHwnd = 0
nTop1 = thisform.Top +
SYSMETRIC(4) + SYSMETRIC(9) + Thisform.Top
nLeft1= thisform.Left +
SYSMETRIC(4) + Thisform.left
nTop2 = thisform.Top +
SYSMETRIC(4) + SYSMETRIC(9) + Thisform.Top + Thisform.Height
nLeft2= thisform.Left +
SYSMETRIC(4) + thisform.left + Thisform.width
lc_FromRect =
lc_FromRect + THISFORM.DecToHex(nLeft1)
lc_FromRect =
lc_FromRect + THISFORM.DecToHex(nTop1)
lc_FromRect =
lc_FromRect + THISFORM.DecToHex(nLeft2)
lc_FromRect =
lc_FromRect + THISFORM.DecToHex(nTop2)
lc_ToRect = THISFORM.DecToHex(ABS(toWindow.left))
lc_ToRect = lc_ToRect + THISFORM.DecToHex(ABS(toWindow.top))
lc_ToRect = lc_ToRect +
THISFORM.DecToHex(ABS(toWindow.left) + toWindow.width)
lc_ToRect = lc_ToRect +
THISFORM.DecToHex(ABS(toWindow.top) + toWindow.height)
* conseguimos el Hwnd
(window handle)
lnHwnd = _WhToHwnd( _WFindTitl(toWindow.Caption)
)
DrawAnimatedRects(lnHwnd,
3, @lc_FromRect, @lc_ToRect)
toWindow.visible = .t.
que
además necesita una función para convertir a Hexadecimal del tipo:
LPARAMETERS lnNumber
LOCAL ln1, ln2,
lcResult
lnNumber =
ABS(lnNumber)
lcResult = ""
FOR ln1 = 3 TO 0 STEP
-1
ln2 = INT(lnNumber / 256 ^ ln1)
lnNumber = lnNumber - ln2 * (256 ^ ln1)
lcResult = CHR(ln2) + lcResult
ENDFOR
RETURN lcResult
Pero
como lo mejor es un ejemplo. En los fuentes tenéis un ejemplo más acabado y
ordenado que te permite ver lo que quizás tanto código seguido no permite
vislumbrar.
En
el ejemplo verás los dos formularios y como uno al llamar al otro realiza ese
efecto. También al cerrar el formulario llamado se ve la misma operación pero a
la inversa.
FoxPress – Noviembre de 2001
© 2001 FoxPress. All rights reserved