Tooltip en icono la barra de tareas (y casi conseguido)

12/10/2004 - 21:01 por Zephryn Xirdal | Informe spam
Hola otra vez.

Ya casi tengo conseguido lo de mostrar/ocultar el icono en la barra de
tareas a través de una DLL hecha en C con el API nativo del Win32.

El problema viene ahora de que es imposible comunicar a la aplicación los
mensajes WM_USER que me genera windows a la aplicación.

Añadir un filtro de mensajes con Application.AddMessageFilter no funciona,
porque captura algunos mensajes pero en concreto los WM_USER, no, y no es
cuestión de enviarle otro mensaje y procesarlo yo.

¿Solución?

Añadir un hook a nivel de API a la ventana principal y capturar el mensaje
de WM_USER y si tiene los parámetros concretos, enviarle a la aplicación un
mensaje que la despierte de su estado "oculto":

LRESULT CALLBACK m_wndProcFilter(int nCode,WPARAM wParam,LPARAM lParam)

{

if (nCode < 0) // do not process message

return 0;

CWPSTRUCT *p=(CWPSTRUCT *)lParam;

if(p->message==WM_MYNOTIFYICON && p->hwnd==m_hwnd &&
p->lParam==WM_LBUTTONDOWN)

{

PostMessage(m_hwnd,WM_SHOWWINDOW,TRUE,0);

return 1;

}

return 0;

}

El problema es que no sé qué mensaje enviar para que pase de No Visible a
Visible, que pienso sería lo correcto (porque el cambiar la propiedad
Visible de true a false y viceversa debe generar una secuenca de mensajes).
He probado unos cuantos, pero ninguno la despierta...

Me queda enviar un WM_CHAR con la tecla más extraña que se me ocurra y
capturar ese mensaje, cosa que me parece un verdadera barbaridad, teniendo
en cuenta que la DLL y el EXE están en el mismo espacio de direcciones, lo
comparten todo, pero son incapaces de comunicarse entre sí...

También me queda la opción de la ingeniería inversa (completamente legal en
este caso), pero no tengo ganas...

¿Dónde está documentado todo lo que falta del .NET? Porque 1.821.342.490
bytes de texto comprimido dan para mucho...

La verdad es que estoy bastante cansado ya del tema, y me parece que voy a
abandonar por lo menos el C# y el .NET

Saludos a todos, si a alguien se le ocurre algo, pues le agradecería que me
lo dijera, pero pienso que no vale la pena tanto lío para un programa chorra
que lo único que intenta utilizar en una ínfima parte de lo que la
programación windows puede ofrecer...
El mundo no fue hecho en el tiempo, sino con el tiempo.
Powered by zxFortune http://sourceforge.net/projects/zxfortune

Preguntas similare

Leer las respuestas

#1 Guillermo guille
12/10/2004 - 21:13 | Informe spam
Una duda... si estás usando C# (y .NET) ¿por qué no usas lo que el .NET te
ofrece para trabajar con los iconos de la barra de tareas? o es que me he
perdido algo...

Nos vemos.
Guillermo
Microsoft VB MVP desde 1997
Te invito a mi sitio dedicado al VB y más...
http://www.elguille.info/
http://www.mundoprogramacion.com/
(puede que el correo usado sea anti-spam)


"Zephryn Xirdal" wrote in message
news:
Hola otra vez.

Ya casi tengo conseguido lo de mostrar/ocultar el icono en la barra de tareas
a través de una DLL hecha en C con el API nativo del Win32.

El problema viene ahora de que es imposible comunicar a la aplicación los
mensajes WM_USER que me genera windows a la aplicación.

Añadir un filtro de mensajes con Application.AddMessageFilter no funciona,
porque captura algunos mensajes pero en concreto los WM_USER, no, y no es
cuestión de enviarle otro mensaje y procesarlo yo.

¿Solución?

Añadir un hook a nivel de API a la ventana principal y capturar el mensaje de
WM_USER y si tiene los parámetros concretos, enviarle a la aplicación un
mensaje que la despierte de su estado "oculto":

LRESULT CALLBACK m_wndProcFilter(int nCode,WPARAM wParam,LPARAM lParam)

{

if (nCode < 0) // do not process message

return 0;

CWPSTRUCT *p=(CWPSTRUCT *)lParam;

if(p->message==WM_MYNOTIFYICON && p->hwnd==m_hwnd &&
p->lParam==WM_LBUTTONDOWN)

{

PostMessage(m_hwnd,WM_SHOWWINDOW,TRUE,0);

return 1;

}

return 0;

}

El problema es que no sé qué mensaje enviar para que pase de No Visible a
Visible, que pienso sería lo correcto (porque el cambiar la propiedad Visible
de true a false y viceversa debe generar una secuenca de mensajes). He
probado unos cuantos, pero ninguno la despierta...

Me queda enviar un WM_CHAR con la tecla más extraña que se me ocurra y
capturar ese mensaje, cosa que me parece un verdadera barbaridad, teniendo en
cuenta que la DLL y el EXE están en el mismo espacio de direcciones, lo
comparten todo, pero son incapaces de comunicarse entre sí...

También me queda la opción de la ingeniería inversa (completamente legal en
este caso), pero no tengo ganas...

¿Dónde está documentado todo lo que falta del .NET? Porque 1.821.342.490
bytes de texto comprimido dan para mucho...

La verdad es que estoy bastante cansado ya del tema, y me parece que voy a
abandonar por lo menos el C# y el .NET

Saludos a todos, si a alguien se le ocurre algo, pues le agradecería que me
lo dijera, pero pienso que no vale la pena tanto lío para un programa chorra
que lo único que intenta utilizar en una ínfima parte de lo que la
programación windows puede ofrecer...
El mundo no fue hecho en el tiempo, sino con el tiempo.
Powered by zxFortune http://sourceforge.net/projects/zxfortune



Respuesta Responder a este mensaje
#2 Zephryn Xirdal
12/10/2004 - 21:57 | Informe spam
Sigue abajo.

El mundo no fue hecho en el tiempo, sino con el tiempo.
Powered by zxFortune http://sourceforge.net/projects/zxfortune


"Guillermo 'guille'" escribió en el mensaje
news:%23I9tP%
Una duda... si estás usando C# (y .NET) ¿por qué no usas lo que el .NET te
ofrece para trabajar con los iconos de la barra de tareas? o es que me he
perdido algo...




Sip. Mira mis posts anteriores. Intento sacar un tooltip "ala Windows XP",
cosa que el Trayicon del .NET no soporta.

He intentado buscar el ID del icono y el HWND de la ventana que lo controla
(basándome en un ejemplo de codeproject) para enviarle un NIM_MODIFY, pero
no funciona; crea un icono en blanco al lado del del tray.

Si lo hago con el ejemplo de codeproject, sólo puedo mostrarlo/ocultarlo; si
intento enviarle alguna modificación, se crea otro nuevo, aparte de que el
ejemplo es una verdadera chapuza, pues busca el handle de la ventana con un
nombre fijo (que cambia según hagas unas cosas u otras).

He probado a encapsular el API a través de Interop, pero entonces la
aplicación no se entera de los mensajes que el sistema le envía a la
aplicación, incluso añadiendo un hook de mensajes "ala .NET" (con
Application.AddMessageFilter ), pero sí de otros (vamos, que puedo capturar
un montón de mensajes con esa función menos los que me interesan).

He probado la DLL insertada, que funciona bien, pero tengo el mismo problema
que más arriba. Application.AddMessageFilter se pasa por el forro los
mensajes WM_USER, con lo que decido capturar al más bajo nivel mediante un
hook de toda la vida, cosa que funciona (como el ejemplo), pero ahora me
queda qué mensaje enviarle al .NET para que la ficha principal pase de no
visible a visible.

Estoy haciendo una aplicación que me muestre un "fortune" (una cita) al
inicio de la sesión, y que pueda cambiar la firma del OE, pero ya metido en
faena, estoy haciendo que se quede anclada a la barra de iconos, que
periódicamente se abra con una nueva cita, o la muestre como tooltip en la
barra de iconos, o que lo haga pero sólo cambie la firma del OE de modo
silencioso. También puede programar una tarea, se lanza, cambia la cita (o
muestra la ventana), programa una nueva tarea y se va (así no ocupa memoria
y es lo menos intrusiva con el sistema).

Me queda lo del tooltip y lo de las tareas (que tengo claro cómo hacerlo,
aunque me queda pendiente cómo guardar los datos sensibles (usario y
contraseña) de forma segura.

Quizás me equivoque, pero el .NET adolece de una falta de documentación de
bajo nivel grandísima, aparte de que le falta mucho para encapsular todo el
api de win32... ante un envío de un wish en la web del VS 2005 me dicen que
les falta tiempo, pero que lo tienen en cuenta para futuras versiones... o
sea, que nada.

Por lo que veo, el .NET es bastante bueno para aplicaciones multinivel, para
las que MS llama "inteligentes", y para acceso a datos (ya sean multinivel o
no), pero para los programas sencillos de toda la vida deja mucho que
desear, aparte que de apis modernos (windows xp), nasti de plasti.

Bueno, pues esa es mi historia. Un programa que hubiera tardado una semana
por las noches se ha convertido en una bestia con la que llevo más de un mes
(por las noches). Tengo hecho el mismo programa con el C++Builder y tardé un
par de noches, aparte lo del tooltip y lo de programar una tarea.

Nos vemos.
Guillermo
Microsoft VB MVP desde 1997
Te invito a mi sitio dedicado al VB y más...
http://www.elguille.info/
http://www.mundoprogramacion.com/
(puede que el correo usado sea anti-spam)


"Zephryn Xirdal" wrote in message
news:
Hola otra vez.

Ya casi tengo conseguido lo de mostrar/ocultar el icono en la barra de
tareas a través de una DLL hecha en C con el API nativo del Win32.

El problema viene ahora de que es imposible comunicar a la aplicación los
mensajes WM_USER que me genera windows a la aplicación.

Añadir un filtro de mensajes con Application.AddMessageFilter no
funciona, porque captura algunos mensajes pero en concreto los WM_USER,
no, y no es cuestión de enviarle otro mensaje y procesarlo yo.

¿Solución?

Añadir un hook a nivel de API a la ventana principal y capturar el
mensaje de WM_USER y si tiene los parámetros concretos, enviarle a la
aplicación un mensaje que la despierte de su estado "oculto":

LRESULT CALLBACK m_wndProcFilter(int nCode,WPARAM wParam,LPARAM lParam)

{

if (nCode < 0) // do not process message

return 0;

CWPSTRUCT *p=(CWPSTRUCT *)lParam;

if(p->message==WM_MYNOTIFYICON && p->hwnd==m_hwnd &&
p->lParam==WM_LBUTTONDOWN)

{

PostMessage(m_hwnd,WM_SHOWWINDOW,TRUE,0);

return 1;

}

return 0;

}

El problema es que no sé qué mensaje enviar para que pase de No Visible a
Visible, que pienso sería lo correcto (porque el cambiar la propiedad
Visible de true a false y viceversa debe generar una secuenca de
mensajes). He probado unos cuantos, pero ninguno la despierta...

Me queda enviar un WM_CHAR con la tecla más extraña que se me ocurra y
capturar ese mensaje, cosa que me parece un verdadera barbaridad,
teniendo en cuenta que la DLL y el EXE están en el mismo espacio de
direcciones, lo comparten todo, pero son incapaces de comunicarse entre
sí...

También me queda la opción de la ingeniería inversa (completamente legal
en este caso), pero no tengo ganas...

¿Dónde está documentado todo lo que falta del .NET? Porque 1.821.342.490
bytes de texto comprimido dan para mucho...

La verdad es que estoy bastante cansado ya del tema, y me parece que voy
a abandonar por lo menos el C# y el .NET

Saludos a todos, si a alguien se le ocurre algo, pues le agradecería que
me lo dijera, pero pienso que no vale la pena tanto lío para un programa
chorra que lo único que intenta utilizar en una ínfima parte de lo que la
programación windows puede ofrecer...
El mundo no fue hecho en el tiempo, sino con el tiempo.
Powered by zxFortune http://sourceforge.net/projects/zxfortune







Respuesta Responder a este mensaje
#3 Zephryn Xirdal
12/10/2004 - 23:25 | Informe spam
Pues ya está solucionado, gracias a Guillermo por su ayuda indirecta ("¿por
qué no usas lo que el .NET te
ofrece para trabajar con los iconos de la barra de tareas?"), y es que uno a
veces se obceca de una manera que vamos.

Pues me he creado una ventana TopMost, FixedToolWindow, pequeñita, con unos
colores un tanto "sui-generis" con un edit y un timer. La abro a mano y al
hacer click en cualquier lugar de ella o cuando se termine el timer se
cierra y ya está. A quien no le guste que no mire.

No es bueno que todo suceda como deseamos.

"Zephryn Xirdal" escribió en el
mensaje news:
Hola otra vez.

Ya casi tengo conseguido lo de mostrar/ocultar el icono en la barra de
tareas a través de una DLL hecha en C con el API nativo del Win32.

El problema viene ahora de que es imposible comunicar a la aplicación los
mensajes WM_USER que me genera windows a la aplicación.

Añadir un filtro de mensajes con Application.AddMessageFilter no funciona,
porque captura algunos mensajes pero en concreto los WM_USER, no, y no es
cuestión de enviarle otro mensaje y procesarlo yo.

¿Solución?

Añadir un hook a nivel de API a la ventana principal y capturar el mensaje
de WM_USER y si tiene los parámetros concretos, enviarle a la aplicación
un mensaje que la despierte de su estado "oculto":

LRESULT CALLBACK m_wndProcFilter(int nCode,WPARAM wParam,LPARAM lParam)

{

if (nCode < 0) // do not process message

return 0;

CWPSTRUCT *p=(CWPSTRUCT *)lParam;

if(p->message==WM_MYNOTIFYICON && p->hwnd==m_hwnd &&
p->lParam==WM_LBUTTONDOWN)

{

PostMessage(m_hwnd,WM_SHOWWINDOW,TRUE,0);

return 1;

}

return 0;

}

El problema es que no sé qué mensaje enviar para que pase de No Visible a
Visible, que pienso sería lo correcto (porque el cambiar la propiedad
Visible de true a false y viceversa debe generar una secuenca de
mensajes). He probado unos cuantos, pero ninguno la despierta...

Me queda enviar un WM_CHAR con la tecla más extraña que se me ocurra y
capturar ese mensaje, cosa que me parece un verdadera barbaridad, teniendo
en cuenta que la DLL y el EXE están en el mismo espacio de direcciones, lo
comparten todo, pero son incapaces de comunicarse entre sí...

También me queda la opción de la ingeniería inversa (completamente legal
en este caso), pero no tengo ganas...

¿Dónde está documentado todo lo que falta del .NET? Porque 1.821.342.490
bytes de texto comprimido dan para mucho...

La verdad es que estoy bastante cansado ya del tema, y me parece que voy a
abandonar por lo menos el C# y el .NET

Saludos a todos, si a alguien se le ocurre algo, pues le agradecería que
me lo dijera, pero pienso que no vale la pena tanto lío para un programa
chorra que lo único que intenta utilizar en una ínfima parte de lo que la
programación windows puede ofrecer...
El mundo no fue hecho en el tiempo, sino con el tiempo.
Powered by zxFortune http://sourceforge.net/projects/zxfortune



Respuesta Responder a este mensaje
#4 Guillermo guille
13/10/2004 - 00:41 | Informe spam
muchas veces la solución que "funciona" puede que no sea la mejor (o más
otodoxa), pero... mientras haga lo que debe hacer... pues eso... al que no le
guste, que no mire... o lo haga de otra forma... ;-)))

Nos vemos.
Guillermo
Microsoft VB MVP desde 1997
Te invito a mi sitio dedicado al VB y más...
http://www.elguille.info/
http://www.mundoprogramacion.com/
(puede que el correo usado sea anti-spam)


"Zephryn Xirdal" wrote in message
news:
Pues ya está solucionado, gracias a Guillermo por su ayuda indirecta ("¿por
qué no usas lo que el .NET te
ofrece para trabajar con los iconos de la barra de tareas?"), y es que uno a
veces se obceca de una manera que vamos.

Pues me he creado una ventana TopMost, FixedToolWindow, pequeñita, con unos
colores un tanto "sui-generis" con un edit y un timer. La abro a mano y al
hacer click en cualquier lugar de ella o cuando se termine el timer se cierra
y ya está. A quien no le guste que no mire.

No es bueno que todo suceda como deseamos.

Respuesta Responder a este mensaje
#5 Anonimo
13/10/2004 - 09:05 | Informe spam
podría realizar aportación de código ?


muchas veces la solución que "funciona" puede que no sea


la mejor (o más
otodoxa), pero... mientras haga lo que debe hacer...


pues eso... al que no le
guste, que no mire... o lo haga de otra forma... ;-)))

Nos vemos.
Guillermo
Microsoft VB MVP desde 1997
Te invito a mi sitio dedicado al VB y más...
http://www.elguille.info/
http://www.mundoprogramacion.com/
(puede que el correo usado sea anti-spam)


"Zephryn Xirdal"


wrote in message
news:
Pues ya está solucionado, gracias a Guillermo por su




ayuda indirecta ("¿por
qué no usas lo que el .NET te
ofrece para trabajar con los iconos de la barra de




tareas?"), y es que uno a
veces se obceca de una manera que vamos.

Pues me he creado una ventana TopMost,




FixedToolWindow, pequeñita, con unos
colores un tanto "sui-generis" con un edit y un timer.




La abro a mano y al
hacer click en cualquier lugar de ella o cuando se




termine el timer se cierra
y ya está. A quien no le guste que no mire.

No es bueno que todo suceda como deseamos.




francés.





.

Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida