Sábado 15 de Octubre - Jornada de la tarde
PorAmby
Temas:
Técnicas
para obtener más de los controles grids (Drew Speedie) por Marcia Akins
Control de eventos por Marcia Akins
Utilizar el Explorador de Internet en Aplicaciones de escritorio con Visual
FoxPro por Rick Stralh
En esta sesión de la tarde me dispongo a ver algunas trucos y
técnicas aplicadas por Drew Speedie para obtener lo máximo posible de los
controles grids, es una sesión preparada por Drew Speedie que impartirá
Marcia Akins. Luego me quedaré en el sitio para ver a la propia Marcia
contando sobre el Control de eventos, tema de gran importancia y del que
nos queda mucho por aprovechar y para terminar, con broche de oro la tarde,
voy a ver la presentación de Rick Stralh titulada Utilizar el Explorador de
Internet en aplicaciones de escritorio con Visual FoxPro... ¡¡ cómo suena
!!... Pues, manos a la obra, a disfrutar !!
Técnicas
para obtener más de los controles grids (Drew Speedie) por Marcia
Akins
Como comentaba ayer, las sesiones que había preparado Drew Speedie
fueron presentadas por Marcia Akins y Andy Kramek. Ambos pusieron todo su
entusiasmo en la presentación del trabajo de Drew. Con gran respeto y
admiración nos trajeron sus ejemplos y trucos. Una vez más, Muchas gracias
a ambos. Marcia está encantada de mostrarnos esta sesión de Drew Speedie,
ella misma es una amante de los grids y ha escrito mucho sobre esto,
existen una gran cantidad de trucos de Marcia publicados en la revista
FoxTalk 2.0 y además nos comenta del artículo "How to Put a Combo Box in a
Grid" que podemos descargar libremente de
http://www.tightlinecomputers.com/Downloads.htm
Esta sesión no tiene texto que traducir, lo que tenemos son muchos
ejemplos de técnicas que podemos aplicar con los grids. Estas técnicas las
vamos a resumir hoy y luego las iremos mostrando poco a poco.
Marcia comenzó explicando la forma en que tradicionalmente Drew Speedie
realizaba sus presentaciones. La base para sus presentaciones era
precisamente un formulario con un control grid, que en cada registro tenía
un truco diferente y además, algunos comandos que nos permiten Ejecutar,
ver el código de los ejemplos, acceder a la Ayuda, etc. Veamos algunos de
los ejemplos.
Marcia mostró algunas técnicas para hacer que tanto una fila como una
celda determinada de un grid sean de sólo lectura de forma dinámica. Nos
mostró como emplear controles con dos columnas en una columna del grid.
También el caso de cómo trabajar con múltiples controles que se alternan
dinámicamente en una celda del grid.
Se
muestra la técnica de cómo establecer una propiedad DynamicCurrentControl
compleja para un método de usuario. Una propiedad DynamicCurrentControl
típica se realiza con un IIF() especificando dos o tres controles de
condición. Pero cuando estas condiciones pasan de dos, no sólo es complejo
de mantener y leer, sino que puede pasar del límite de 254 caracteres de la
ficha Propiedades. VFP falla frecuentemente al evaluar largos IIF anidados.
La técnica de Drew consiste en que al mover todo esto a una estructura
DO CASE ... ENDCASE se eliminan todos estos problemas. Este método se puede
llamar directamente desde la ventana propiedades de esta forma:
="THISFORM.RealizarDynamicCurrentControl()", asegurándonos de que esté
entre comillas.
Una aplicación interesante es mostrar las columnas, filas o celdas de un
grid inhabilitados con el mismo aspecto que tienen los controles textbox
inhabilitados. Otro ejemplo fue cómo cambiar el orden de las columnas,
incluyendo el desplazamiento de los objetos de la ventana Propiedades. El
problema es que es muy pesado estar recordando el orden de las columnas una
vez ha sido creado en control. Se puede establecer la propiedad
ColumnOrder para actualizar el orden en que van a aparecer las columnas en
este control; pero no se actualiza el nombre de la columna, por lo que una
cosa es lo que se muestra en el Diseñador y otro orden en la ventana
Propiedades. Entonces, la idea de Drew consiste en "tocar" el .SCX/.VCX,
para que cambie el orden de la columna en ambos sitios. Para este caso hay
un pequeño documento con una explicación más detallada, que el futuro
podremos publicar.
En VFP 8.0 apareció una nueva propiedad LockColumns que permite bloquear
columnas al panel derecho del grid, lo que significa que no se van a mover
estas columnas aunque el grid sea más ancho que el contenedor donde se
muestra. Vimos como eliminar la posibilidad de Bloquear las columnas si no
lo deseamos. Otros aspectos sobre el bloqueado de columnas también fueron
mostrados. Otro aspecto interesante fue que vimos un caso en el que la
columna que se encuentra más a la derecha del grid reajusta su tamaño en
dependencia del tamaño del resto de las columnas, de esta forma no queda el
espacio vacío que muchas veces se ve al final de los grids y que es muy
feo.
Algo
que siempre nos interesa en un grid es poder resaltar determinados
registros, lo que logramos con la propiedad DynamicForeColor. El
comportamiento nativo para resaltar una fila, cuando HighlightStyle es 1 ó
2, establece que las propiedades HighlightForeColor/HighlightBackColor
tiene preferencia sobre cualquier color que exista en las propiedades
column.DynamicBackColor, column.DynamicForeColor, column.BackColor,
column.ForeColor, column.control.BackColor y column.control.ForeColor. La
técnica aplicada es combinar las propiedades DynamicForeColor,
DynamicBackColor ya que cuando la fila actual es a su vez una de las filas
con colores resaltados, la combinación provoca el efecto que se muestra en
la imagen.
Hay un aspecto del trabajo con los grids que a mí me molestaba mucho y
ahora, ya no tendré más problemas gracias al ingenio de Drew Speedie. Se
trata de cuando realizamos búsqueda y resaltamos el artículo encontrado.
Normalmente este artículo no es el primero mostrado arriba del todo del
grid, lo cual, por una parte, se puede prestar a confusiones y por otra
parte es incómodo porque nos impide mostrar la mayor cantidad de elementos
del grupo, si fuera el caso. Por eso, en este caso voy a mostrar el código:
* Si es Fin de fichero, no se hace nada
IF EMPTY(THIS.RecordSource) OR EOF(THIS.RecordSource)
RETURN
ENDIF
IF THIS.RelativeRow = 1
* No se hace nada, ya se muestra en la primera fila.
RETURN
ENDIF
LOCAL lcSaveFilter, lcFilter
lcSaveFilter = FILTER(THIS.RecordSource)
* Inhabilito que se muestren los cambios que van a ocurrir
THISFORM.LockScreen = .t.
* Filtra el grid para el registro actual
lcFilter = "RECNO() = " + TRANSFORM(RECNO(THIS.RecordSource))
SET FILTER TO &lcFilter
* Refresca el grid para obligar al registro actual a ser el primero a mostrar
THIS.Refresh()
* Restablece las condiciones
IF EMPTY(m.lcSaveFilter)
SET FILTER TO
ELSE
SET FILTER TO &lcSaveFilter
ENDIF
* Vuelve a refrescar el grid
THIS.Refresh()
THISFORM.LockScreen = .f.
¿Qué les parece? Como siempre genial !!! Así estuvimos viendo otros
ejemplos que nos ayudan a obtener el máximo rendimiento posible del control
grid, que es muy poderoso y es posible que aun no sepamos aprovechar al
máximo. Muchas gracias a Marcia, ella ha estado emocionada recordando al
maestro y amigo Drew Speedie y transmitiendo su legado con toda pasión. Ha
sido útil y hermoso... ufff yo también estoy emocionada, me voy a tomar un
poco de agua y regreso a seguir aprendiendo de esta mujer incansable.
Control de eventos por Marcia
Akins
Marcia dedica esta sesión al importantísimo tema de control de eventos.
Vamos a hacer un recorrido del trabajo con eventos desde los inicios de VFP
hasta la última versión liberada. No es un tema nuevo, viene desde Visual
FoxPro 3.0 cuando podíamos colocar código en un evento Valid(). Esta
sesión la tendremos traducida, muchas gracias, Marcia.
Marcia realizó una interesante comparación entre los métodos y los
eventos en Visual FoxPro; pero no me voy a detener en esta explicación tan
interesante, porque la podemos ver con más detalle en este artículo que
publicó su esposo, Andy Kramek y que tenemos traducido y publicado en
PortalFox: "Escribir código en métodos, no en eventos: pero ¿por qué?"
http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=72
Siguiendo
con la evolución del enlace de eventos en VFP... pasó el tiempo, cambiaron
las versiones y vemos que fue posible enlazar eventos provocados por
objetos COM, a partir la versión 7.0. con la función EVENTHANDLER(). Esta
función permite enlazar una clase Visual FoxPro que implemente una interfaz
definida por un componente COM a los eventos en ese componente. Todos la
hemos utilizado al emplear automatización Ofiice manteniendo la aplicación
servidor visible. Entonces tenemos que algunos ejemplos de enlaces de
eventos pueden ser, programar el envío de un correo electrónico, conectar
PCs a un servidor y crear archivos en carpetas determinadas. Lo que ocurre
es que se ejecuta código VFP cuando ocurre un evento en el servidor, se
emplea la cláusula IMPLEMENTS del comando DEFINE CLASS para implementar la
interfaz determinada.
Nos muestra con un ejemplo como se realiza la implementación de la interfaz
del COM en VFP, para ello se trabaja con el Examinador de Objetos, se
arrastra a un archivo de programa, ya que debe quedar definida en la clase
VFP toda la interfaz del COM, se vayan o no, a emplear los métodos.
x=NEWOBJECT("myclass")
DEFINE CLASS myclass AS session OLEPUBLIC
IMPLEMENTS ApplicationEvents2 IN "d:\officexp\office10\msword.olb"
PROCEDURE ApplicationEvents2_Quit() AS VOID
* add user code here
ENDPROC
PROCEDURE ApplicationEvents2_DocumentChange() AS VOID
* add user code here
ENDPROC
...(todos los procedimientos que forman la interfaz)
ENDDEFINE
También mostró como enlazar objetos nativos de VFP, para ello el
adelanto real vino con la aparición de la función BINDEVENT() en VFP 8.0
que aportó la forma para enlazar eventos, propiedades y métodos para
objetos nativos de Visual FoxPro a otros objetos Visual FoxPro. El enlace
se produce de esta forma: El evento origen en una instancia de una clase
VFP, (ya sea clase base o de usuario), hay un evento destino perteneciente
a un objeto determinado, que es el desencadenado por la acción. Por tanto,
se dispara un evento de un objeto debido al evento que se ha realizado en
otro objeto.
Otra función que vino con VFP 8.0 es RAISEEVENT() que permite provocar
un evento en un método de usuario. Marcia nos aconseja ver estos temas en
el Wiki de Visual FoxPro en:
http://fox.wikis.com/wc.dll?Wiki~EventBindingSample y en
http://fox.wikis.com/wc.dll?Wiki~NativeEventBinding
Lo más interesante llegó justo cuando Marcia mostró su clase ddlBase
para el control de los valores de algunos controles utilizando BindEvent().
Esto lo veremos en detalle al traducirlo. También nos dejó ver cómo al
emplear BINDEVENT reduce la necesidad de crear subclases y empleó para ello
una clase grdBase en la que hace que el dobleclic realizado sobre un
textbox provoque el doble clic del grid.
Para finalizar, vimos cómo enlazar eventos de Windows. Y la posibilidad
de hacerlo nos llega de la mano de VFP 9.0 ya que se agregó funcionalidad
extendida a la función BINDEVENT(). Hay diferencias de comportamiento al
controlar eventos nativos de VFP y eventos de Windows, ya que, si por una
parte, al emplear BINDEVENT con eventos nativos de VFP, varios
controladores diferentes pueden ser enlazados a un evento único, por su
parte, para los eventos de Windows, una combinación hWnd (controlador de la
ventana que recibe el mensaje) y nMessage (número del mensaje de Windows)
puede enlazar únicamente a un controlador. VFP no controla, ni provoca
errores si los valores hWnd y nMessage no son válidos.
Algunos ejemplos pueden ser: detectar que empieza una aplicación,
detectar eventos de puesta en marcha como por ejemplo, batería baja, paso a
modo standby y detectar eventos shell, crear, eliminar y renombrar archivos
y directorios.
No dejemos de revisar el archivo de ayuda para dominar en detalles estos
tres casos de enlaces de eventos:
- Con objetos COM
EVENTHANDLER(oComObject, oVfpObject, lunbind)
- Con objetos nativos de VFP
BINDEVENT(oEventSource, cEvent, oHandler, cDelegate, nFlags)
- Mensajes de Windows
BINDEVENT(hWnd, nMessage, oHandler, cDelegate, nFlags)
- Marcia le pone tanto entusiasmo a su explicación que nos dan
deseos de seguir profundizando en el tema y para ello, nos deja unas
sugerencias:
- Web de Calvin Hsia MS VFP (
http://blogs.msdn.com/calvin_hsia/ )
- Artículo de Doug Hennig “Windows Event Binding Made Easy” de enero
2005 de la revista FoxTalk disponible en
http://msdn.microsoft.com/library/en-us/dnfoxtk05/html/ft05a1.asp En
este caso ha habido suerte, ya está traducido y publicado en PortalFox
en:
http://www.portalfox.com/modules.php?op=modload&name=Sections&file=index&req=viewarticle&artid=50
En
esta Conferencia vimos un grupo interesante de aplicaciones con BINDEVENTS
en varias sesiones, es muy útil que comprendamos su esencia, para poderle
sacar el máximo de provecho. Marcia ha estado grande, como siempre. Voy a
mi última sesión de la tarde y del día, estoy toda motivada, ¡¡ hay tanto
que estudiar cuando salga de aquí, es impresionante !! Desde luego que la
posibilidad de "tocar" y "percibir" el entusiasmo de los gurús al
transmitir sus ideas es un regalo. Siempre supera las expectativas.
Ahora me encontraré con otro de los grandes, es la primera vez que
voy a presenciar una sesión de Rick Stralh y es una mezcla de curiosidad y
emoción. En este año que ha pasado desde la Conferencia de Kansas he
aprendido mucho con sus escritos y ahora aprenderé, eso es seguro, con su
presentación ... pero primero ... un cafecito.
Utilizar el Explorador de Internet en Aplicaciones de escritorio con Visual
FoxPro por Rick Stralh
Será muy difícil comentar en breves líneas esta presentación. La
vamos a poder traducir y estoy segura que será de utilidad para los que
trabajen combinando el Explorador de Internet con aplicaciones VFP. De
momento intentaré comentar los tópicos que vimos. No llegaré a cubrir las
expectativas, la calidad de la presentación y la calidad extraordinaria del
ponente superan cualquier intento que pueda hacer yo de resumirlo.
Así, que... manos a la obra !!!
Vimos una comparación entre el poder de aplicaciones de escritorio
(interfaz centrada en formularios, interfaz de usuario muy rica, intuitiva,
modelo de programación poderoso) y el poder de HTML (interfaz centrada en
documentos, diseño atractivo, controles embebidos, personalizable a los
usuarios), entonces combinando ambas tendremos lo mejor de ambos mundos,
empleamos HTML para mostrar muchas tareas y campos fijos para entrada de
datos y tareas interactivas.
La primera opción que nos ofrece Rick Stralh para interactuar con el
Explorador de Internet es la función API ShellExecute, que es bastante
sencilla de utilizar; pero así y todo se propone envolver en una función de
usuario a la que se pasan parámetros y permite ser reutilizarla.
FUNCTION GoUrl(tcUrl, tcAction, tcDirectory, tcParms)
IF EMPTY(tcUrl)
RETURN -1
ENDIF
IF EMPTY(tcAction)
tcAction = "OPEN"
ENDIF
IF EMPTY(tcDirectory)
tcDirectory = SYS(2023)
ENDIF
IF EMPTY(tcParms)
tcParms = ""
ENDIF
DECLARE INTEGER ShellExecute ;
IN SHELL32.dll ;
INTEGER nWinHandle,;
STRING cOperation,;
STRING cFileName,;
STRING cParameters,;
STRING cDirectory,;
INTEGER nShowWindow
DECLARE INTEGER FindWindow ;
IN WIN32API STRING cNull,STRING cWinName
RETURN ShellExecute(FindWindow(0,_SCREEN.caption),;
tcAction,tcUrl,;
tcParms, tcDirectory,1)
ENDFUNC
Una vez creada podemos ejecutarla (DO ShellExec)
- Para abrir una página web:
GoUrl("http://www.west-wind.com/")
- Para realizar búsquedas concatenando cadenas a buscar:
lcSearchString = "FoxPro Tools"
GoUrl("http://www.google.com/search?hl=en&ie=UTF-8&oe=UTF-8&q=" + ;
lcSearchString )
- Buscar el mapa de un sitio pasando los valores correspondientes en
parámetros:
GoUrl("http://www.mapquest.com/maps/map.adp?country=" + ;
lcCountry + "&addtohistory=&address=" + ;
UrlEncode(lcStreet) + ;
"&city=" + UrlEncode(lcCity) + "&state=" + ;
UrlEncode(lcState) + "&zipcode=" + ;
UrlEncode(lcZip) + "&homesubmit=Get+Map&size=big")
Esto lo podemos envolver en una función que haga el llamado de esta
forma:
ShowMap( "32 Kaiea Place","Paia","HI","96779","US")
GoUrl("ftp://www.west-wind.com/")
y si queremos con contraseña y todo:
GoUrl("ftp://ricks:password@www.west-wind.com/uploads")
- Acceso a documentos. Los documentos se mostrarán en su aplicación al
reconocer la extensión:
GoUrl("d:\articles\fpa\shellexecute.doc")
GoUrl("d:\articles\fpa\shellexecute_SourceCode.zip")
GoUrl("d:\articles\fpa\shellExecute.pdf")
GoUrl("d:\Articles\fpa\ShellExecute.htm")
GoUrl("d:\Articles\fpa\ShellExecute_Data.xml")
Mostró funciones para tratamiento de texto en formato HTML y XML. En
este caso nos comenta que al trabajar con tal cantidad de texto en
formato XML y HTML es necesario encontrar una vía amigable para la
depuración.
- Controlar el cliente de correo
GoUrl("mailto:rstrahl@west-wind.com")
y si desea colocar más información puede hacer:
GoUrl("mailto:rstrahl@west-wind.com?subject=Surf's up," + ;
" Rick&Body=Drop everything, it's going big!")
Rick Stralh resume esta primera parte, que ya ha estado grande, diciendo
que ShellExecute ofrece una excelente vía para enlazar a contenidos varios,
pasando más o menos información en parámetros y que nos da mucho juego,
permitiendo crear funciones que envuelvan las diferentes funcionalidades. Pero
... esto no se queda aquí... qué va !!! Seguimos...
Es muy posible que necesitemos mayor control sobre el documento abierto,
necesitaremos herramientas más sofisticadas ... pues bien, vamos a ver
ahora cómo realizar Automatización con el Explorador de Internet. Hay dos
vías para exponer la automatización desde Internet y son: el objeto de
automatización InternetExplorer.Application y el control Web Browser.
La sintaxis que necesitamos para abrir una URL en el Explorador de
Internet (IE) es:
oIE = CREATEOBJECT("InternetExplorer.Application")
oIE.Visible = .t.
oIE.Navigate("http://www.west-wind.com/")
... haga cualquier cosa que necesite y luego salga
oIE.Visible = .f.
oIE = null
Y se puede, como hicimos antes, navegar por el contenido, veamos:
oIE.Navigate("d:\articles\fpa\IE.doc")
oIE.Navigate("d:\articles\fpa\IE.pdf")
oIE.Navigate("ftp://www.west-wind.com/")
oIE.Navigate("http://www.west-wind.com/files/wwIPStuff.zip")
Una vez aquí se sucedieron un grupo de ejemplos que demuestran cómo se
puede trabajar con los documentos, por ejemplo, si queremos traer el cuerpo
(Body) de un archivo html lo podemos lograr de la siguiente forma:
lcHtml = oIE.Document.Body.OuterHtml
Se pueden capturar eventos del Examinador (Browser)
DEFINE CLASS WebBrowserEvents as Custom
IMPLEMENTS DWebBrowserEvents2 IN "SHDOCVW.DLL"
... implementación de los eventos
ENDDEFINE
mmm ... esto me suena, me suena ... ¿a que va a ser lo mismo que
explicaba Marcia hace unos momentos? Exacto !! Se trata de Control de
eventos con EVENTHANDLER(). Gracias Rick, otro ejemplo para complementar
los de Marcia. ¡¡ Qué lujo !! Y aun no termina .... nos queda una tercera
parte del tiempo aun....
Veamos en detalle el control Web Browser, algunos ejemplos de empleo
son:
THISFORM.oBrowser.Navigate("http://www.west-wind.com")
THISFORM.oBrowser.Navigate("about:blank")
THISFORM.oBrowser.Document.Body.InnerHtml = "<h1>Hello World</h1>"
Pero
el control Browser es muy poderoso y ofrece muchas posibilidades más allá
de la Web, tendremos que estudiarlo a fondo... queda mucho por ver, este
control permite visualizar archivos HTML que no estén en la Web, sino
físicamente en discos. En esta imagen Rick Stralh muestra cómo se puede
emplear texto HTML como forma elegante y moderna de mostrar una lista de
datos con hiperenlaces vivos. Es una excelente idea y nos comenta que el
trabajo con campos memo, por ejemplo, son un buen candidato para mostrarlos
en formato HTML. Rick mostró otro grupo de aplicaciones para este control.
Este otro ejemplo, combina interfaz VFP (un control lista con los
nombres, en el panel de la izquierda) con interfaz HTML que es
dinámicamente generada a través de un control Web Browser (panel de la
derecha). Como se puede ver los datos son actualizables. Cuando tengamos el
artículo disponible podremos ver todo el código en detalles.

Así
que se puede resumir esta segunda gran parte de la sesión dedicada a los
controles del Explorador de Internet, diciendo que tienen unas
posibilidades amplísimas de implementación y pueden enriquecer muchísimo
nuestras aplicaciones. Dice Rick Stralh que si no lo hemos intentado, que
lo hagamos y que seguramente nunca más dejaremos de "jugar" con estas
ventajas y querremos seguir más y más adelante.
Muchísimas gracias Rick Stralh, me quedo sin palabras, ha sido de
Matrícula de honor, de verdad. Yo estoy impresionada de la facilidad conque
se pueden manejar estos aspectos. Y lo útiles y enriquecedores que son.
Uffff Rick..... eres Muy grande, Gracias !!!!!!!!
Yo estoy muy emocionada y así se lo comento a mis amigos. Este día
también ha sido maravilloso, estoy francamente cansada... es mucho
contenido, mucho inglés, muchas emociones, son 9 horas de diferencia con
casa .... pero no pasa nada, es una gran fiesta y lo estoy disfrutando....
ya descansaré al regreso.... o al menos eso creo :)
Pues
nada, termina el segundo día de Conferencias, sólo nos quedan un par de
sesiones en la mañana de mañana día 16 y va a tocar despedirse. Por ahora
nos reunimos en el salón principal, los cuatro latinos, y se nos presenta
la oportunidad para intercambiar un rato con miembros del FoxTem y varios
gurús que se encontraban allí, ya les digo que es un no parar, cada uno
cuenta sus experiencias en las sesiones, sus motivaciones y sus ideas de
cómo aplicar los nuevos conocimientos. Hemos aprovechado para hacer una
foto de aquel encuentro.
Se incorpora nuestra amiga rusa, Vera y el amigo Huge,
norteamericano, nos vamos todos juntos a cenar.... no hay descanso,
hablaremos en inglés... pero no hablaremos de Fox, creo que no, ¿o si? Nos
iremos a dar un paseo por la ciudad de Tempe, comeremos en un restaurante
muy acogedor y tendremos una velada muy agradable... y al regresar al
hotel, pues encuentro con los gurús y el Foxteam que estaban en la cena de
Gala del evento... y .... hablamos de Visual FoxPro, especialmente recuerdo
a Andy Kramek y Doug Hennig compartiendo experiencias, era un bonus track a
esas horas !!! .... allí seguimos, hasta las ....
Nos vemos en la próxima entrega, Reporte de la Conferencia Southwest
Fox 2005 - Día 16 de Octubre Jornada de la mañana y final.
Saludos,
Ana
www.amby.net
|