Un problema con TWCapture()

Post Reply
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Un problema con TWCapture()

Post by Rafael Clemente »

Tengo el siguiente problema que no sé por dónde atacar:

Supongamos que tenemos una ventana abierta correspondiente a una aplicación que puede o no estar escrita con FWH. Por ejemplo, un Word, o un programa comercial de Contabilidad...

La clase TWCapture() me permite tomar cierto control sobre esa ventana: Redimensionarla, ocultarla, moverla...

Ahora bien, lo que me gustaría saber es cómo podría recoger una lista de todos los controles (objetos) que presenta esa ventana. Por ejemplo: {oBtn1, oBtn2, oGet1, oGet2, oGet3, oLbx1....}

La idea es que a partir de esa lista debiera ser posible leer, entre ortras cosas, las coordenadas y contenido de Botones o campos Get. Más o menos, así: ? oBtn2:nTop, oBtn2:nLeftd, oGet1:VarGet()...

He hecho algunas pruebas con GetData() pero sin éxito. Quizá GetObject() sirviera, pero en mi manual no vienen referencias sobre cómo utilizarlo.

¿Alguien podría echarme una mano con un ejemplo sencillo de cómo hacerlo?

Gracias

Rafael
User avatar
Paco Garcia
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm
Contact:

inspeccionar

Post by Paco Garcia »

hola
tienes que utilizar funciones del API.
Una vez obtenido el hwnd existen funciones para:
obtener el texto GetWindowText
coordenadas Getcoors
clase Getclassname
Piensa que si la aplicacion no es la que estas ejecutando nopuedes llamar a las funciones que decias

Para sacar los controles tienes que utilizar GetWindow con el hwnd de la ventana en primer lugar y GW_CHILD
Lueqo con el hwnd del control que obtengas se lo pasas a GetWindow pero ahora con GW_NEXT o algo asi mira los parametros de GetWindow.

Un saludo
Paco
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Paco:
Sí; todo lo que dices es cierto y ya me funciona bien. Parte de mi código:

Code: Select all

     oWnd := TWCapture():New( "OtraApp" ) 
     hWnd := oWnd:hWnd
     oWnd:Say(40, 20, "Hola que tal???", CLR_YELLOW, CLR_RED,, .T., .F.)
     ? getClassName(oWnd:hWnd)
El problema es que una vez tengo oWnd, debería poder pedir sus controles:

? LEN(oWnd:aControls)

y eso me da un error. En otras palabras: ¿Cómo puedo leer el array aControls? Una vez lo tenga, supongo que a partir de ahí podré leer las coordenadas, tipo, etc de cada uno ¿no?

Gracias y saludos,

Rafael
User avatar
Paco Garcia
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm
Contact:

inspect

Post by Paco Garcia »

no puedes
los programas que tu dices no tienen esas propiedades tienes que hacerlo conel api
Si fueran programas tuyos podrias hacer que se comunicaran por ejemplo con SendMesage y HandleEvent
También puedes con WM_COPYDATA

dime por donde quieres ir
paco
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Paco:
En resumen: Desde mi aplicación quiero leer el contenido de un Get en la ventana de otra aplicación.

Para ello, pretendo definir el Get que me interesa según sus coordenadas en la ventana de la otra aplicación. Si tengo todos los controles en oWnd:aControls... bastaría hacer un bucle así (código inventado, por supuesto):

For i := 1 TO LEN(aControles)
IF Coords(aControles == MisCoords de Referencia()
oGet := aControles
cMiValor := oGet:VarGet()
Exit
ENDIF
Next
Return cMiValor

Hasta ahora, con TWCapture() puedo contolar dimensiones, esconder la ventana, cambiar su título e incluso conocer las coordenadas del cursor dentro de esa ventana. Pero me falta poder leer sus controles. Alguna idea?

Rafael
User avatar
Paco Garcia
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm
Contact:

Inspect

Post by Paco Garcia »

Hola

Mira, tu puedes hacer lo que hace TWCapture

DEFINE WINDOW oWnd

luego con un hWnd que hayas obtenido con FindWindow haces:

oWnd:hWnd := hWnd

Esto no quiere decir que aControls de oWnd se rellene automáticamente con los controles que sean hijos de hWnd.

Si quieres obtener el contenido de un Get tienes que utilizar:

GetWindowText( hWnd )

Como te devuelve una cadena de texto luego lo conviertes al tipo que tu sepas que tiene que contener.

Para obtener todos los controles de una ventana tienes que hacer esto:

Code: Select all


       local aControls := {}
       hCtrl := GetWindow( hWnd, GW_CHILD )
       do while hCtrl != 0
           hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
           if hCtrl != 0
              aadd( aControls, hCtrl )
           endif
        enddo
¿Capichi? :)

Una vez que tienes los controles en un array puedes preguntar por su classname y si sabes que siempre va a estar el Get en el mismo orden pues lo tienes fácil. Solo tienes que pillar su GetWindowText

Dime si necesitas mas cosas.

Paco
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Paco:
Ho capito :D . Gracias. Funciona casi perfecto. Solamente me falta un detalle que quizás me puedas solucionar:

He hecho un bucle:

Code: Select all

while hCtrl != 0
       hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
       cClassName := Upper(GetClassName(hCtrl))
       ? cClassName, GetWindowText(hCtrl)
end
Con los botones funciona perfecto, o sea, me da el prompt del botón.

Si precargo un Get con un texto: VAR cGet := "Hola"...., también lo detecta bien.

Pero si precargo un Get con cGet := SPACE(20), aunque escriba algo en él me devuelve blanco. Como si faltase un Refresh() o algo así. Hay alguna forma de hacer que lea el texto que he escrito en el Get?

Muchísimas gracias

Rafael
User avatar
Paco Garcia
Posts: 172
Joined: Fri Oct 07, 2005 12:00 pm
Contact:

Post by Paco Garcia »

La verdad es que no se por que puede ser.

:(
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Rafael,

Usas un timer desde la otra aplicación en donde compruebas los valores de los controles ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Antonio:
No; no uso ningún timer. Para las pruebas estoy usando una simple ventana (creada con FWH) con tres botones y dos gets. Un get lo inicializo por programa a "Hola" y el otro, a blancos.

La aplicación que trata de leer esos gets captura perfectamente el "Hola" pero aunque escriba algo en el otro get, lo ignora y siempre devuelve blanco.

Este es el trozo de código que uso:

Code: Select all

        hCtrl := GetWindow( hWnd, GW_CHILD )
        WHILE hCtrl != 0
              cClassName := Upper(GetClassName(hCtrl))
              IF cClassName = "EDIT"
                   ? GetWindowText(hCtrl)
              ENDIF
              hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
        END
Alguna idea?

Rafael
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Rafael,

Prueba a inicializar un GET con "hola" y el otro con "adios" y comprueba que obtengas los dos valores correctamente.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Sí. Inicializando los dos gets, capturo correctamente sus valores pero sus valores INICIALES. Quiero decir: Si antes de capturar cambio algún get (por ejemplo, pongo "Buenos dias" en lugar de "Hola"), sigo capturando el valor original de "Hola".
Rafael
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Post by Antonio Linares »

Es realmente extraño, porque GetWindowText( hWnd ) es una función del API de Windows que debe devolver el texto que muestra el control.
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Rafael Clemente
Posts: 365
Joined: Sat Oct 08, 2005 7:59 pm
Location: Barcelona, Spain

Post by Rafael Clemente »

Antonio:
Lo he probado varias veces y, efectivamente, no los lee. Te envío por privado una muestra
Rafael
Post Reply