In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.

Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.

Capturar todos los mensajes windows

Foro público de Xailer en español
Responder
jvaimetal
Mensajes: 5
Registrado: Vie Feb 22, 2008 9:10 am

Capturar todos los mensajes windows

Mensaje por jvaimetal »

Hola, muy buenas...
Espero que alguien pueda ayudarme.
He mirado muchos mensajes en los foros y hay bastante código
de ejemplo de cómo capturar algunos mensajes de windows que
le llegan a nuestro programa: WM_KEYDOWN y cosas así... En
principio todo va bien, puedes sobreescribir algunos métodos de las clases
TEdit o lo que quieras y capturas esos eventos.
Incluso también he visto ejemplos de cómo cargar dinámicamente una DLL
y coger la dirección de la función que
nos interese en "inline C", y también me funciona de maravilla.
Mi problema es el siguiente: quiero acceder a un scanner. Para
ello he estado leyendo bastante documentación en TWAIN.ORG, y
es bastante completa. Ya he conseguido que mi aplicación Xailer
cargue el "twain_32.dll", busque la única función que hace de interfaz y
la llame para inicializar. Hasta aquí todo correcto:
pregunto por el DSM (Data Source Manager), lo abro, selecciono
el origen de datos (DS) que puede ser un escáner, una webcam
o lo que sea.
El gran problema es que a partir de ahora (y siguiendo las
indicaciones del manual del estándar TWAIN) nuestro bucle de WinProc hay
que reconfigurarlo y cada vez que hace un GetMessage y coge los mensajes
de windows hay que redirigirlos TODOS al Origen de datos, y preguntarle si
está listo, si no es así, podemos procesar ese mensaje como nuestro. Es el
Origen de datos el que toma el control y avisa a nuestro programa de que
está listo para enviar datos. Pero, ¿como hacer esto en Xailer? Que yo sepa
no tenemos acceso al procedimiento WindProc... esto lo generará Xailer/xHarbour
o yo qué sé... estoy un poco perdido la verdad.
Supongo que si no es posible o es muy complejo de hacer, tendré que hacerme
un interfaz en C++ y llamarlo desde mi programa Xailer. Pero es mucho más
tedioso y tendré que inventarme un "protocolo" para comunicarme entre los
programas. Sería mucho más sencillo y práctico tenerlo todo desde Xailer.
Muchas gracias de antemano,
Javier Jiménez
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5718
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Capturar todos los mensajes windows

Mensaje por jfgimenez »

Javier,
he echado un vistazo rápido a la documentación de twain.org, y ahí viene un
ejemplo de bucle de mensajes. No es perfecto, pero te puede servir. Eso sí,
te aconsejo encarecidamente que deshabilites todas las ventanas de tu
aplicación mientras está corriendo twain para evitar problemas mayores.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
jvaimetal
Mensajes: 5
Registrado: Vie Feb 22, 2008 9:10 am

Capturar todos los mensajes windows

Mensaje por jvaimetal »

Hola de nuevo,
Efectivamente en la documentación de twain.org viene un ejemplo
de bucle de mensajes, pero ¿como se codifica eso en Xailer?. Si
tenemos un programa directamente en C++, dentro de la función
WindProc recibimos todos los mensajes de windows y los podemos
redirigir al Origen de TWAIN, pero en Xailer ¿donde se hace eso?
Esa era mi pregunta originalmente, supongo que no me he
expresado con claridad.
Gracias de antemano.
"Jose F. Gimenez" <jfgimenez@wanadoo.es> wrote:
>Javier,
>
>he echado un vistazo rápido a la documentación de twain.org, y ahí viene
un
>ejemplo de bucle de mensajes. No es perfecto, pero te puede servir. Eso
sí,
>te aconsejo encarecidamente que deshabilites todas las ventanas de tu
>aplicación mientras está corriendo twain para evitar problemas mayores.
>
>--
>Un saludo,
>
>José F. Giménez
>http://www.xailer.com
>http://www.xailer.info
>
>
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5718
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Capturar todos los mensajes windows

Mensaje por jfgimenez »

Javier,
> Efectivamente en la documentación de twain.org viene un ejemplo
> de bucle de mensajes, pero ¿como se codifica eso en Xailer?. Si
> tenemos un programa directamente en C++, dentro de la función
> WindProc recibimos todos los mensajes de windows y los podemos
> redirigir al Origen de TWAIN, pero en Xailer ¿donde se hace eso?
> Esa era mi pregunta originalmente, supongo que no me he
> expresado con claridad.
Tienes que codificarla en C. Lo puedes hacer dentro de un prg usando las
directivas #pragma BEGINDUMP y #pragma ENDDUMP. P.ej.:
#pragma BEGINDUMP
#include "windows.h"
#include "xailer.h"
XA_FUNC( CAPTURAR )
{
while( [este activa la captura] )
{
// este es el bucle de mensajes
}
}
#pragma ENDDUMP
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
jvaimetal
Mensajes: 5
Registrado: Vie Feb 22, 2008 9:10 am

Capturar todos los mensajes windows

Mensaje por jvaimetal »

Buenas tardes,
Ante todo muchas gracias por responder tan rápido.
He intentado hacer lo que me indicas en el mensaje, escribir
una función que mientras el origen esté activo haga un bucle
intentando cazar los mensajes con GetMessage tal y como pone
en la ayuda de TWAIN y si no es un mensaje del origen, lo
"despachamos" nosotros con:
// Source didn’t process it, so we will
if (rc == TWRC_NOTDSEVENT) {
TranslateMessage( (LPMSG) &msg);
DispatchMessage( (LPMSG) &msg);
}
Pero sigue sin funcionar. Me sale la pantalla de "User Interface"
definida por el Origen (en mi caso una webcam) pero tal y
como yo me temía, la pantalla se queda sin recibir ningún mensaje,
y por tanto no puedo pinchar en ningún botón ni cerrarla.
El caso es que tal y como yo tengo entendido, los programas
hechos en C++ (puedes verlo en http://msdn2.microsoft.com/en-us/library/bb384843.aspx),
para win32, tienen que tener definidas
las funciones: WinMain, WndProc y registrar la clase con la función RegisterClassEx.
No soy un experto en programación Win32, pero entiendo que
windows cuando recibe un evento (teclado, ratón, E/S de cualquier
tipo...) u otra notificación (cierre, apagado...) se lo envía
a todos los programas o sólo al que corresponda, según el
evento; y llama al procedimiento WndProc (o el que hayamos
registrado en la clase, puede tener otro nombre).
Vamos al grano: que si yo trato de cazar mensajes con
GetMessage, seguramente ya lo ha cazado el WndProc y entonces
me quedo a dos velas. Y sigo con el mismo problema: ¿Como
redirecciono todos los mensajes y eventos de windows a
una función en Xailer? ¿Se puede hacer? ¿Hay que sobrecargar
algún método? ¿o reasignarlo de alguna manera?
Supongo que el compilador se encargará de generar funciones
genéricas de WinMain y WndProc y de realizar todas estas tareas
de registro de la clase de manera automática, pero para algunos
casos como el mío, estaría bien poder "puentear" o redirigir
a una función propia este comportamiento.
Gracias
"Jose F. Gimenez" <jfgimenez@wanadoo.es> wrote:
>Javier,
>
>> Efectivamente en la documentación de twain.org viene un ejemplo
>> de bucle de mensajes, pero ¿como se codifica eso en Xailer?. Si
>> tenemos un programa directamente en C++, dentro de la función
>> WindProc recibimos todos los mensajes de windows y los podemos
>> redirigir al Origen de TWAIN, pero en Xailer ¿donde se hace eso?
>> Esa era mi pregunta originalmente, supongo que no me he
>> expresado con claridad.
>
>Tienes que codificarla en C. Lo puedes hacer dentro de un prg usando las
>directivas #pragma BEGINDUMP y #pragma ENDDUMP. P.ej.:
>
> #pragma BEGINDUMP
>
> #include "windows.h"
> #include "xailer.h"
>
> XA_FUNC( CAPTURAR )
> {
> while( [este activa la captura] )
> {
> // este es el bucle de mensajes
> }
> }
>
> #pragma ENDDUMP
>
>
>--
>Un saludo,
>
>José F. Giménez
>http://www.xailer.com
>http://www.xailer.info
>
>
jvaimetal
Mensajes: 5
Registrado: Vie Feb 22, 2008 9:10 am

Capturar todos los mensajes windows

Mensaje por jvaimetal »

Buenas tardes,
Espero no haberos hecho perder mucho tiempo en esto.
Ya me respondo yo mismo: no sé si directamente en Xailer se puede
hacer, pero creo que he encontrado la forma de hacerlo.
Aún no lo he probado, pero he encontrado en las ayudas de msdn
algunas funciones interesantes: GetClassInfo(), que a partir
del manejador de la ventana, nos da información útil, a saber,
la estructura WNDCLASS, que contiene un puntero lpfnWndProc a la
función WndProc con la que se registró la clase. Y con la
función SetWindowLong podemos asignar una nueva función para
hacer lo que queramos con los mensajes y los que no procesemos
tendremos que llamar a la antigua función con CallWindowProc.
Con esto creo que está resuelto el problema. En la propia ayuda
de Microsoft nos dice que así se pueden "encadenar" sucesivos
procedimientos WndProc para proceso de mensajes en las clases
y subclases de nuestros programas.
Muchas gracias.
"Javier Jiménez" <jvaimetal@yahoo.es> wrote:
>
>Buenas tardes,
>Ante todo muchas gracias por responder tan rápido.
>He intentado hacer lo que me indicas en el mensaje, escribir
>una función que mientras el origen esté activo haga un bucle
>intentando cazar los mensajes con GetMessage tal y como pone
>en la ayuda de TWAIN y si no es un mensaje del origen, lo
>"despachamos" nosotros con:
> // Source didn’t process it, so we will
> if (rc == TWRC_NOTDSEVENT) {
> TranslateMessage( (LPMSG) &msg);
> DispatchMessage( (LPMSG) &msg);
> }
>
>Pero sigue sin funcionar. Me sale la pantalla de "User Interface"
>definida por el Origen (en mi caso una webcam) pero tal y
>como yo me temía, la pantalla se queda sin recibir ningún mensaje,
>y por tanto no puedo pinchar en ningún botón ni cerrarla.
>El caso es que tal y como yo tengo entendido, los programas
>hechos en C++ (puedes verlo en http://msdn2.microsoft.com/en-us/library/bb384843.aspx),
>para win32, tienen que tener definidas
>las funciones: WinMain, WndProc y registrar la clase con la función RegisterClassEx.
>
>No soy un experto en programación Win32, pero entiendo que
>windows cuando recibe un evento (teclado, ratón, E/S de cualquier
>tipo...) u otra notificación (cierre, apagado...) se lo envía
>a todos los programas o sólo al que corresponda, según el
>evento; y llama al procedimiento WndProc (o el que hayamos
>registrado en la clase, puede tener otro nombre).
>
> Vamos al grano: que si yo trato de cazar mensajes con
>GetMessage, seguramente ya lo ha cazado el WndProc y entonces
>me quedo a dos velas. Y sigo con el mismo problema: ¿Como
>redirecciono todos los mensajes y eventos de windows a
>una función en Xailer? ¿Se puede hacer? ¿Hay que sobrecargar
>algún método? ¿o reasignarlo de alguna manera?
>
> Supongo que el compilador se encargará de generar funciones
>genéricas de WinMain y WndProc y de realizar todas estas tareas
>de registro de la clase de manera automática, pero para algunos
>casos como el mío, estaría bien poder "puentear" o redirigir
>a una función propia este comportamiento.
>
>Gracias
>
Avatar de Usuario
jfgimenez
Site Admin
Mensajes: 5718
Registrado: Lun Abr 06, 2015 8:48 pm
Contactar:

Capturar todos los mensajes windows

Mensaje por jfgimenez »

Javier,
> Espero no haberos hecho perder mucho tiempo en esto.
> Ya me respondo yo mismo: no sé si directamente en Xailer se puede
> hacer, pero creo que he encontrado la forma de hacerlo.
> Aún no lo he probado, pero he encontrado en las ayudas de msdn
> algunas funciones interesantes: GetClassInfo(), que a partir
> del manejador de la ventana, nos da información útil, a saber,
> la estructura WNDCLASS, que contiene un puntero lpfnWndProc a la
> función WndProc con la que se registró la clase. Y con la
> función SetWindowLong podemos asignar una nueva función para
> hacer lo que queramos con los mensajes y los que no procesemos
> tendremos que llamar a la antigua función con CallWindowProc.
>
> Con esto creo que está resuelto el problema. En la propia ayuda
> de Microsoft nos dice que así se pueden "encadenar" sucesivos
> procedimientos WndProc para proceso de mensajes en las clases
> y subclases de nuestros programas.
Esta tecnica se conoce como 'subclassing', y es la más habitual para usar
controles de windows o de terceros. Pero no creo que necesites nada de eso.
Lo único que necesitas es montar el bucle de mensajes como explica la
documentación. Dentro del bucle, la llamada a la función del API
DispatchMessage(), hace que se invoque el procedimiento de ventana del
control que tiene que recibir el mensaje, pero tú no tienes que hacer nada
más.
Por cierto, en Xailer existe la función PrevWindowProc(), que lo que hace es
llamar al procedimiento de ventana que tuviera un determinado control antes
de ser cambiado por Xailer. Si revisas los fuentes de Xailer verás unos
cuantos sitios donde se está usando.
--
Un saludo,
José F. Giménez
http://www.xailer.com
http://www.xailer.info
José F. Giménez
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
rafa
Mensajes: 119
Registrado: Vie Ene 16, 2009 9:59 am

Capturar todos los mensajes windows

Mensaje por rafa »

Javier, no se si será de ayuda, pero yo hice una clase para manejar
scanners, el cual usa una dll llamado dosadi WWW.DOSADI.COM, que te
enmascara todo el API de Twain y no tienes que hacer nada de bucles.
Miratela, que vale la pena, te ahorraras montones de horas.
No se si esta por aqui la clase, pero si la quieres te la envio.
Saludos
Rafa Carmona
Responder