Tratando de leer un get de una ventana desde otra ventana...
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Tratando de leer un get de una ventana desde otra ventana...
Estoy intentando leer el contenido de un Get de una ventana desde otra ventana independiente. Efectivamente, leo el valor inicial del Get pero aunque escriba en él algo diferente, siempre leo el valor inicial.
Alguien podría mirarse estos dos prgs y decirme qué estoy haciendo mal? (ambos se compilan con Buildh.bat)
El programa que captura:
Code:
//----------------------------------------------------------------------------//
// Capt.prg - Prueba de captura de otra ventana
//----------------------------------------------------------------------------//
#include "FiveWin.ch"
#define GW_CHILD 5
#define GW_HWNDNEXT 2
FUNCTION Main()
LOCAL oWnd, hWnd, hCtrl, cClassName, cTitle
cTitle := PADR("TEST", 200)
IF MsgGet( "Entre titulo de una ventana abierta", "Titulo:", @cTitle)
hWnd := FindWindow( 0, ALLTRIM(cTitle))
IF hWnd <= 0
MsgInfo("No puedo capturar esa ventana")
ELSE
hCtrl := GetWindow( hWnd, GW_CHILD )
WHILE hCtrl != 0
cClassName := Upper(GetClassName(hCtrl))
IF cClassName = "EDIT"
? cClassName+" "+GetWindowText(hCtrl)
ENDIF
hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
END
ENDIF
ENDIF
RETURN NIL
y el programa cuyos gets quiero capturar:
Code:
// Test.prg
#include 'FIVEWIN.CH'
FUNCTION Main()
LOCAL oWnd, oGet1, oGet2, cGet1, cGet2
DEFINE WINDOW oWnd FROM 0,0 TO 12,35 TITLE 'Test'
cGet1 := "Hola "
cGet2 := "Bye "
@ 10,10 BUTTON "Button 01" SIZE 100,20 PIXEL OF oWnd ACTION MsgInfo("Button 01")
@ 40,10 GET oGet1 VAR cGet1 SIZE 100,20 PIXEL OF oWnd
@ 70,10 GET oGet2 VAR cGet2 SIZE 100,20 PIXEL OF oWnd
ACTIVATE WINDOW oWnd
RETURN NIL
Gracias,
Rafael
Alguien podría mirarse estos dos prgs y decirme qué estoy haciendo mal? (ambos se compilan con Buildh.bat)
El programa que captura:
Code:
//----------------------------------------------------------------------------//
// Capt.prg - Prueba de captura de otra ventana
//----------------------------------------------------------------------------//
#include "FiveWin.ch"
#define GW_CHILD 5
#define GW_HWNDNEXT 2
FUNCTION Main()
LOCAL oWnd, hWnd, hCtrl, cClassName, cTitle
cTitle := PADR("TEST", 200)
IF MsgGet( "Entre titulo de una ventana abierta", "Titulo:", @cTitle)
hWnd := FindWindow( 0, ALLTRIM(cTitle))
IF hWnd <= 0
MsgInfo("No puedo capturar esa ventana")
ELSE
hCtrl := GetWindow( hWnd, GW_CHILD )
WHILE hCtrl != 0
cClassName := Upper(GetClassName(hCtrl))
IF cClassName = "EDIT"
? cClassName+" "+GetWindowText(hCtrl)
ENDIF
hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
END
ENDIF
ENDIF
RETURN NIL
y el programa cuyos gets quiero capturar:
Code:
// Test.prg
#include 'FIVEWIN.CH'
FUNCTION Main()
LOCAL oWnd, oGet1, oGet2, cGet1, cGet2
DEFINE WINDOW oWnd FROM 0,0 TO 12,35 TITLE 'Test'
cGet1 := "Hola "
cGet2 := "Bye "
@ 10,10 BUTTON "Button 01" SIZE 100,20 PIXEL OF oWnd ACTION MsgInfo("Button 01")
@ 40,10 GET oGet1 VAR cGet1 SIZE 100,20 PIXEL OF oWnd
@ 70,10 GET oGet2 VAR cGet2 SIZE 100,20 PIXEL OF oWnd
ACTIVATE WINDOW oWnd
RETURN NIL
Gracias,
Rafael
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Lo siento: Aquí está el fuente de los dos programas anteriores, formateado como código:
Code: Select all
//----------------------------------------------------------------------------/
// Capt.prg - Prueba de captura de otra ventana
//----------------------------------------------------------------------------/
#include "FiveWin.ch"
#define GW_CHILD 5
#define GW_HWNDNEXT 2
FUNCTION Main()
LOCAL oWnd, hWnd, hCtrl, cClassName, cTitle
cTitle := PADR("TEST", 200)
IF MsgGet( "Entre titulo de una ventana abierta", "Titulo:", @cTitle)
hWnd := FindWindow( 0, ALLTRIM(cTitle))
IF hWnd <= 0
MsgInfo("No puedo capturar esa ventana")
ELSE
hCtrl := GetWindow( hWnd, GW_CHILD )
WHILE hCtrl != 0
cClassName := Upper(GetClassName(hCtrl))
IF cClassName = "EDIT"
? cClassName+" "+GetWindowText(hCtrl)
ENDIF
hCtrl = GetWindow( hCtrl, GW_HWNDNEXT )
END
ENDIF
ENDIF
RETURN NIL
Code: Select all
// Test.prg
#include 'FIVEWIN.CH'
FUNCTION Main()
LOCAL oWnd, oGet1, oGet2, cGet1, cGet2
DEFINE WINDOW oWnd FROM 0,0 TO 12,35 TITLE 'Test'
cGet1 := "Hola "
cGet2 := "Bye "
@ 10,10 BUTTON "Button 01" SIZE 100,20 PIXEL OF oWnd ACTION MsgInfo("Button 01")
@ 40,10 GET oGet1 VAR cGet1 SIZE 100,20 PIXEL OF oWnd
@ 70,10 GET oGet2 VAR cGet2 SIZE 100,20 PIXEL OF oWnd
ACTIVATE WINDOW oWnd
RETURN NIL
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Rafael,
Es bastante extraño, es como si Windows guardase esa información en un buffer interno, porque si cambias esta línea en test.prg:
@ 10,10 BUTTON "Button 01" SIZE 100,20 PIXEL OF oWnd ACTION MsgInfo(GetWindowText( oGet2:hWnd ))
verás que muestra el texto del GET correctamente.
Vas a tener que intentar capturar los datos usando otro sistema: el mensaje WM_COPYDATA. Tienes un ejemplo en samples\copy_16_32\fwcopy16.prg. El ejemplo es para 16 bits y habría que adaptarlo un poco para 32 bits.
Es bastante extraño, es como si Windows guardase esa información en un buffer interno, porque si cambias esta línea en test.prg:
@ 10,10 BUTTON "Button 01" SIZE 100,20 PIXEL OF oWnd ACTION MsgInfo(GetWindowText( oGet2:hWnd ))
verás que muestra el texto del GET correctamente.
Vas a tener que intentar capturar los datos usando otro sistema: el mensaje WM_COPYDATA. Tienes un ejemplo en samples\copy_16_32\fwcopy16.prg. El ejemplo es para 16 bits y habría que adaptarlo un poco para 32 bits.
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain
Antonio:
Me he mirado fwcopy16 pero me temo que ese nivel de C supera lo que yo me atrevo a hacer. Además, ese ejemplo parece que es para copiar datos de mi aplicación a otra ventana y yo necesito justo lo contrario: "Leer" de la otra ventana
Seguiremos dándole vueltas, porque tengo un cliente esperando que le diga algo... Saludos,
Rafael
Me he mirado fwcopy16 pero me temo que ese nivel de C supera lo que yo me atrevo a hacer. Además, ese ejemplo parece que es para copiar datos de mi aplicación a otra ventana y yo necesito justo lo contrario: "Leer" de la otra ventana
Seguiremos dándole vueltas, porque tengo un cliente esperando que le diga algo... Saludos,
Rafael
- Paco Garcia
- Posts: 172
- Joined: Fri Oct 07, 2005 12:00 pm
- Contact:
WM_COPYDATA
Hola Rafael
Existen varias formas de comuncar dos aplicaciones. Una de ellas es utilizando la capacidad de las ventanas de recibir mensajes. Ya sabes que nuestros prorgramas a bajo nivel estan sembrados de SendMessage( hWnd,.... ) que son descifrados en el bucle de mensajes de Windows y mas concretamente en nuestras aplicaciones en el método HandleEvent.
Cuando tu inspeccionas el get estas utilizando en hWnd de un control obtenido de alguna forma. Ahora lo haremos mas o menos igual.
Paso a exponer el código y luego explico
1ª parte
Esta sería la aplicación que solicita datos a otra aplicación (ventana)
2ª Parte
La aplicación que recibe el mensaje y que lo procesa
Con un poco de ingenio puedes hacer que las dos aplicaciones sean capaces de "hablarse" y contarse las cosas que necesites.
Observa que en la segunda aplicación he redefinido el Método HandleEvent de la nueva clase ventana para poder evaluar el mensaje WM_COPYDATA.
http://www.google.es/search?hl=es&q=wm_ ... ogle&meta=
Un saludo
[/code]
Existen varias formas de comuncar dos aplicaciones. Una de ellas es utilizando la capacidad de las ventanas de recibir mensajes. Ya sabes que nuestros prorgramas a bajo nivel estan sembrados de SendMessage( hWnd,.... ) que son descifrados en el bucle de mensajes de Windows y mas concretamente en nuestras aplicaciones en el método HandleEvent.
Cuando tu inspeccionas el get estas utilizando en hWnd de un control obtenido de alguna forma. Ahora lo haremos mas o menos igual.
Paso a exponer el código y luego explico
1ª parte
Code: Select all
#include "FIVEWIN.CH"
static oWnd
#define WM_COPYDATA 74
function MAIN()
LOCAL oBtn, oBtn2, oGet, nVar1 := 1
LOCAL oGet2, nVar2 := 1
LOCAL oGet3, cVar := "Pulsa el boton Send y busca un alert"
DEFINE WINDOW oWnd TITLE "Prueba WM_COPYDATA"
@ 10, 10 GET oGet VAR nVar1 SIZE 50, 18 PIXEL OF oWnd
@ 30, 10 GET oGet2 VAR nVar2 SIZE 50, 18 PIXEL OF oWnd
@ 50, 10 GET oGet3 VAR cVar SIZE 250, 18 PIXEL OF oWnd
@ 80, 10 BUTTON oBtn PROMPT "Send" SIZE 50, 24 PIXEL OF oWnd ACTION SendInfo( nVar1, nVar2, cVar )
@ 110, 10 BUTTON oBtn2 PROMPT "Fin" SIZE 50, 24 PIXEL OF oWnd ACTION oWnd:End()
ACTIVATE WINDOW oWnd
RETURN nil
function SendInfo( nVar, nVar2, cVar )
local hWnd := FindWindow(0,"Escuchando" )
// BUSCAS EL HANDLE DE LA VENTANA CON EL NOMBRE
DEFAULT nVar := 1
DEFAULT nVar2 := 1
DEFAULT cVar := ""
if hWnd != 0
if cVar == ""
Enviar( oWnd:hWnd, hWnd, 101, nVar, nVar2, cVar )
else
Enviar( oWnd:hWnd, hWnd, 100, nVar, nVar2, cVar )
endif
else
MsgInfo( "No encontre la ventana" )
endif
return nil
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
// AQUI TE CREAS LA ESTRUCTURA QUE QUIERAS CON LOS DATOS QUE QUIERAS PASAR
typedef struct tagMYREC
{
HWND hWndOrigen;
char s1[250];
int nFila;
int nColumna;
} MYREC;
HB_FUNC( ENVIAR )
{
HWND hWndOrigen = ( HWND ) hb_parnl( 1 );
HWND hWndDestino = ( HWND ) hb_parnl( 2 );
int nMsg = hb_parni( 3 ); // <<< IDENTIFICADOR DEL MENSAJE PARA QUE DESDE
// LA VENTANA DESTINO DECIDAS LO QUE HACER EN ESTE CASO
COPYDATASTRUCT MyCDS;
MYREC MyRec;
// AQUI LE DAS VALOR A LOS DATOS DE LA ESTRUCTURA
MyRec.hWndOrigen = hWndOrigen;
MyRec.nFila = hb_parni( 4 );
MyRec.nColumna = hb_parni( 5 );
strcpy( MyRec.s1, hb_parc( 6 ) );
//
// Fill the COPYDATA structure
//
MyCDS.dwData = nMsg;
MyCDS.cbData = sizeof( MyRec ); // size of data
MyCDS.lpData = &MyRec;
// SE LO ENVIAS A LA VENTANA DESTINO SIEMPRE DE ESTA FORMA
SendMessage( hWndDestino, WM_COPYDATA,(WPARAM)(HWND) hWndOrigen,(LPARAM) (LPVOID) &MyCDS );
hb_ret();
}
HB_FUNC( RECIBIR )
{
PCOPYDATASTRUCT pMyCDS;
pMyCDS = (PCOPYDATASTRUCT) hb_parnl( 1 );
// RECIBES LOS DATOS Y LOS DEVUELVES AL HANDLEEVENT DE LA VENTANA
// SI QUIERES QUE LA COMUNICACIÓN SEA EN LOS DOS SENTIDOS
// TENDRIAS QUE TENER AQUI TAMBIEN EL HANDLEEVENT REDEFINIDO
hb_reta( 5 );
hb_stornl( (long)((MYREC *)(pMyCDS->lpData))->hWndOrigen, -1, 1 );
hb_storni( pMyCDS->dwData, -1, 2 );
hb_storni( ((MYREC *)(pMyCDS->lpData))->nFila, -1, 3 );
hb_storni( ((MYREC *)(pMyCDS->lpData))->nColumna, -1, 4 );
hb_storc ( ((MYREC *)(pMyCDS->lpData))->s1, -1, 5 );
}
#pragma ENDDUMP
2ª Parte
La aplicación que recibe el mensaje y que lo procesa
Code: Select all
#include "FIVEWIN.CH"
#define WM_COPYDATA 74
static aDatos := {}
PROCEDURE MAIN()
LOCAL oWnd, oMenu
oWnd := TWindow2():New(0,0,20,20,"Escuchando",,oMenu,,,,,,,,,,!.F.,!.F.,!.F.,!.F.,.F. )
ACTIVATE WINDOW oWnd ON INIT WndCenter( oWnd:hWnd )
RETURN
//--------------------------------------------------------------------
CLASS TWindow2 FROM TWindow
CLASSDATA lRegistered AS LOGICAL
METHOD New( nTop, nLeft, nBottom, nRight, cTitle, nStyle, oMenu,;
oBrush, oIcon, oParent, lVScroll, lHScroll,;
nClrFore, nClrBack, oCursor, cBorder, lSysMenu, lCaption,;
lMin, lMax, lPixel ) CONSTRUCTOR
METHOD HandleEvent( nMsg, nWParam, nLParam )
ENDCLASS
METHOD New( nTop, nLeft, nBottom, nRight, cTitle, nStyle, oMenu,;
oBrush, oIcon, oParent, lVScroll, lHScroll,;
nClrFore, nClrBack, oCursor, cBorder, lSysMenu, lCaption,;
lMin, lMax, lPixel ) CLASS TWindow2
return super:New( nTop, nLeft, nBottom, nRight, cTitle, nStyle, oMenu,;
oBrush, oIcon, oParent, lVScroll, lHScroll,;
nClrFore, nClrBack, oCursor, cBorder, lSysMenu, lCaption,;
lMin, lMax, lPixel )
METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TWindow2
local aReturn
local hWndOrigen
local nCDMsg
local nFila, nColumna, cText
if nMsg == WM_COPYDATA
aReturn := Recibir( nLParam )
hWndOrigen := aReturn[1]
nCDMsg := aReturn[2]
nFila := aReturn[3]
nColumna := aReturn[4]
cText := aReturn[5]
do case
case nCDMsg == 100
? "Mensaje " + str( nCDMsg ), nFila, nColumna, cText,"El titulo de la ventana que ha pintado esto es",::cTitle
return 0
case nCDMsg == 101
? "Mensaje " + str( nCDMsg ), nFila, nColumna, cText,"El titulo de la ventana que ha pintado esto es",::cTitle
return 0
// case nCDMsg == ... lo que se quiera y cuantos se quieran
endcase
endif
return super:HandleEvent( nMsg, nWParam, nLParam )
*****************************************************************************
******************************************************************************
******************************************************************************
******************************************************************************
#pragma BEGINDUMP
#include "windows.h"
#include "hbapi.h"
// AQUI TE CREAS LA ESTRUCTURA QUE QUIERAS CON LOS DATOS QUE QUIERAS PASAR
typedef struct tagMYREC
{
HWND hWndOrigen;
char s1[250];
int nFila;
int nColumna;
} MYREC;
HB_FUNC( ENVIAR )
{
HWND hWndOrigen = ( HWND ) hb_parnl( 1 );
HWND hWndDestino = ( HWND ) hb_parnl( 2 );
int nMsg = hb_parni( 3 ); // <<< IDENTIFICADOR DEL MENSAJE PARA QUE DESDE
// LA VENTANA DESTINO DECIDAS LO QUE HACER EN ESTE CASO
COPYDATASTRUCT MyCDS;
MYREC MyRec;
// AQUI LE DAS VALOR A LOS DATOS DE LA ESTRUCTURA
MyRec.hWndOrigen = hWndOrigen;
MyRec.nFila = hb_parni( 4 );
MyRec.nColumna = hb_parni( 5 );
strcpy( MyRec.s1, hb_parc( 6 ) );
//
// Fill the COPYDATA structure
//
MyCDS.dwData = nMsg;
MyCDS.cbData = sizeof( MyRec ); // size of data
MyCDS.lpData = &MyRec;
// SE LO ENVIAS A LA VENTANA DESTINO SIEMPRE DE ESTA FORMA
SendMessage( hWndDestino, WM_COPYDATA,(WPARAM)(HWND) hWndOrigen,(LPARAM) (LPVOID) &MyCDS );
hb_ret();
}
HB_FUNC( RECIBIR )
{
PCOPYDATASTRUCT pMyCDS;
pMyCDS = (PCOPYDATASTRUCT) hb_parnl( 1 );
// RECIBES LOS DATOS Y LOS DEVUELVES AL HANDLEEVENT DE LA VENTANA
// SI QUIERES QUE LA COMUNICACIÓN SEA EN LOS DOS SENTIDOS
// TENDRIAS QUE TENER AQUI TAMBIEN EL HANDLEEVENT REDEFINIDO
hb_reta( 5 );
hb_stornl( (long)((MYREC *)(pMyCDS->lpData))->hWndOrigen, -1, 1 );
hb_storni( pMyCDS->dwData, -1, 2 );
hb_storni( ((MYREC *)(pMyCDS->lpData))->nFila, -1, 3 );
hb_storni( ((MYREC *)(pMyCDS->lpData))->nColumna, -1, 4 );
hb_storc ( ((MYREC *)(pMyCDS->lpData))->s1, -1, 5 );
}
#pragma ENDDUMP
Observa que en la segunda aplicación he redefinido el Método HandleEvent de la nueva clase ventana para poder evaluar el mensaje WM_COPYDATA.
http://www.google.es/search?hl=es&q=wm_ ... ogle&meta=
Un saludo
[/code]
- Rafael Clemente
- Posts: 365
- Joined: Sat Oct 08, 2005 7:59 pm
- Location: Barcelona, Spain