Problema con controles y UpdateLayeredWindow

Iniciado por ThunderCls, 16 Agosto 2010, 21:35 PM

0 Miembros y 1 Visitante están viendo este tema.

ThunderCls

Un saludo a todos los del foro.
Bueno, aqui traigo una duda que me ha surgido usando la API UpdateLayeredWindow en un pequeño estudio de transparencias. Veran, estoy usando ULW para cargar una imagen png con alpha blending effects y crear una splash screen con ella, ahora, realmente se ve genial gracias a las cualidades del formato PNG, muy linda, todo bien, pero la cosa se complica de la siguiente forma: Todos los demas controles estandares(Botones, Edits, etc) en el formulario se hacen invisibles una vez corro la aplicacion, por lo que no consigo interactuar con ninguno de ellos ni aun mostrarlos encima de la imagen.
He buscado algo en la web y he visto muchas respuestas diciendo que algo como eso no se puede, que una vez que se utiliza esa API en una ventana, los CHILDS controls no se veran al no ser por otros metodos poco convencionales como crear una "fake" window "encima" de la original y asignarle algunas propiedades con SetLayeredWindowAttributes para de esta forma dar una perspectiva de como si tuvieramos los controles justo encima de nuestra splash. Bueno, eso fue lo que entendi de todo lo que encontre en la web, pero en realidad no capto muy bien todo esto.

Mi pregunta es la siguiente:
Alguien sabe como lograr esto de lo que he estado hablando???...alguien sabe como lograr hacer visibles los controles en una layered window con ULW, o por lo menos sabe de algun otro metodo que pueda servir para esto???

Saludos y gracias x su tiempo en leer este post
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/

Littlehorse

Si efectivamente lo que encontraste en las busquedas es correcto, ya que no podes tener una opacidad en la ventana padre distinta a la de los hijos, por lo menos no de la forma convencional.

Lo de la ventana falsa no es mala idea, de hecho es la opción mas simple que se me ocurre en este momento. El problema es que quizás lleva un poco mas de trabajo para que quede bien.

La idea es que quede algo así:

-----------------------
Ventana falsa         | Presentación
-----------------------
Controles hijos
-----------------------
Ventana real          |Inputs, mensajes, etc

Entonces luego pintas todos los controles en la ventana falsa, y actualizas cuando haya un cambio. Utilizando por supuesto SetWindowLongPtr con GWLP_WNDPROC.

No es muy fácil de entender, y de seguro no es la mejor forma de hacerlo, pero en estos momentos no se me ocurre otra cosa. Si luego se me ocurre una forma mas sencilla de hacerlo, te aviso.
Ayudaría una representación de lo que seria la interfaz (hecha en Photoshop, por ejemplo) y una breve descripción de los contenidos como para tener una idea mas clara de cual es el objetivo final y como seria la interacción con el usuario.

Saludos
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

ThunderCls

Hola Littlehorse, muchas gracias por responder  ;)
Veras, siguiendo en mi busqueda para lograr este objetivo que comento, he visto varios foros y paginas, en alguno de ellos, me parece que en Expert Exchange he leido algunas ideas como estas que corroboran lo que hablabamos anteriormente:

Per-pixel opacity is an entirely different painting model than the standard Win32 mechanism.  There is no WM_PAINT anymore.  Instead, the top-level window composes a bitmap and sends it to the OS to use as the visual representation of the window on screen.  Child windows are not drawn into this bitmap, and so they are not shown on the screen.  This is a general limitation of a WS_EX_LAYERED window when used via UpdateLayeredWindow().

You may have some luck by using a top-level window with the WS_EX_LAYERED style (instead of child windows), and then positioning the window over its location in the WPF application.  Keeping the app window and this "fake" top-level aligned on the screen may be difficult.

I confirmed this with our expert, Dwayne Need and here's what he had to say:

This is a limitation of using WS_EX_LAYERED and UpdateLayeredWindow().  This form of layered windows does not support child windows.  This is a Win32 limitation, not a WPF limitation.  Child windows could be used with constant opacity (WS_EX_LAYERED and SetLayeredWindowAttributes) but WPF does not support that mode, as it is more restrictive (constant versus per-pixel opacity).

Anyways, there are various ways to try and work around the limitation.  None are great.  Limitations like these are part of the motivation for a new generation of presentation APIs such as WPF.

Possible solutions (various degrees of hackery):

1)     Don't host legacy child HWND controls.  Try to find a WPF equivalent.

2)     Write a WPF equivalent of the HWND control (HTML content seems to be a popular request)

3)     Don't use per-pixel alpha.  Consider applying a HREGION instead.

4)     Place your HWND control in a regular top-level window that has the app window as its owner.  Position the control window where you want it.

5)     Use a timer and call Win32's PrintWindow (or send a WM_PRINT) to capture the HWND control to a bitmap, and display that bitmap in WPF.

6)     Try to wrap the containing window in a WS_EX_COMPOSITED window and respond to WM_PAINT to capture a bitmap and display the bitmap in WPF.

7)     Hook the HWND control's window proc and respond to WM_PAINT by capturing the bitmap and displaying it in WPF


Ahora, para que tengas una idea un poco mas clara de lo que tengo y lo que quiero lograr, puedes visitar este enlace: http://www.codeproject.com/KB/dialog/SemiTranDlgWithCtrls.aspx.
En las imagenes se puede ver claramante como se ha logrado el objetivo de insertar controles estandares en layered windows y eso justamente es lo que quiero lograr. He bajado las fuentes pero no me entero de nada, ademas que es .NET  :(
Por eso pido un poco de ayuda por aqui, para ver si al final se puede sacar algun code en C++ que cumpla este cometido.
Saludos y gracias una vez mas por tu tiempo en responder
-[ "...I can only show you the door. You're the one that has to walk through it." – Morpheus (The Matrix) ]-
http://reversec0de.wordpress.com
https://github.com/ThunderCls/