ShouthwestFox
Inicio

PreConferencia

Encuentros

Vie 14 Mañana

KeyNote

Vie 14 Tarde

Drew Speedie

Sáb 15 Mañana

Sáb 15 Tarde

Dom 15 Mañana

Galerías

... a Conferencias

 
Anuncios






 
© PortalFox

Southwest Fox 2005

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:

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")
  • Acceso por FTP
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

 


Todas las marcas y los logos utilizados en este sitio son propiedad de sus respectivos dueños.
Los artículos, noticias y comentarios son propiedad y responsabilidad de sus respectivos autores.
Copyright © 2000-2007 PortalFox. Todos los derechos reservados.