Pregunta

Estamos desarrollando una aplicación con varios bordes redondeados en la mayoría de sus ventanas.Estoy usando regiones de ventana para definir formas no rectangulares, pero casi todos se oponen al alias irregular que esto causa, porque los píxeles solo pueden ser completamente opacos o completamente transparentes.

Se me ocurrió una solución para esto usando ventanas en capas, pero queremos asegurarnos de que funcione (y esperemos que funcione bien) en una variedad de sistemas, y quiero ver si alguien tiene mejores ideas o formas de hacerlo. optimizar lo que estoy haciendo.Sé que las ventanas en capas requieren win2000 o posterior, y eso está bien, ya que ya es un requisito por otras razones.Según algunas pruebas básicas, se ve bien en Vista, pero eso no es garantía todavía.

Esto es lo que hago:Tengo una ventana, llámala A, con controles y texto y todo lo que compone esa ventana.Tengo la ventana B como hija de la ventana A, excepto que tiene el estilo WS_POPUP en lugar de WS_CHILD, por lo que puede posicionarse fuera de la región de A y se dibuja encima de los controles de A.La ventana B también tiene el estilo WS_EX_LAYERED y, durante la inicialización, llamo Actualizar ventana en capas con el indicador ULW_ALPHA y un DC de origen con un mapa de bits de 32 bits con un canal alfa, para que dibuje con alfa por píxel.

El mapa de bits utilizado en el DC de origen para la ventana B son prácticamente solo los píxeles alrededor del borde de la ventana que quiero combinar suavemente desde el fondo de la ventana hasta lograr una transparencia total.Me saltaría todo el enfoque de dos ventanas y solo usaría una ventana de una sola capa, excepto que cuando usas UpdateLayeredWindow, se extrae de un búfer guardado en la memoria, en lugar de los típicos mensajes WM_PAINT y todo eso, y trato de obtener controles infantiles interactivos (y ventanas secundarias) para que funcionen bien, eso suena como una molestia notable (y probablemente ni siquiera funcionaría para todo).

Entonces, es básicamente la ventana A con todos los controles secundarios y lo que sea, con la ventana B flotando directamente encima de ella, dibujando un bonito borde suave.Respondo a los mensajes WM_MOVE y demás moviendo la ventana B junto con ella, y tengo la ventana B deshabilitada para que nunca pueda recibir foco o entrada (los clics ya pasan, ya que partes de ella que tienen opacidad cero, como la mayoría de sus partes interiores, ya están excluidas de la recogida).

Por diversión, así es como se ven las piezas, para mostrar un poco mejor lo que quiero decir.

Entonces funciona, pero no puedo estar seguro de que sea realmente la mejor manera de hacerlo.Tengo dos preguntas:

  • ¿Suena esto aceptable o hay algo notoriamente terrible en ello?
  • Tal como funciona actualmente, parece que está usando un búfer fuera de la pantalla del tamaño de la ventana (que puede ser de hasta 1024x768), aunque muy pocos píxeles tienen datos de opacidad distintos de cero. ¿Valdría la pena la sobrecarga? ¿Y la complejidad adicional de cortarlo en pedazos de borde separados y componerlos juntos?
¿Fue útil?

Solución

Mi producto utiliza ventanas en capas para dibujar las pequeñas pestañas que adjunto a cada ventana.Utilicé ventanas en capas para conseguir un redondeo suave sin alias.El único problema desagradable con el que me he topado hasta ahora es que algunas ventanas OpenGL se garabatean encima de ventanas en capas en Windows XP y Vista sin DWM.Es un problema de bajo nivel y Microsoft no ha sido de gran ayuda.Puedes reproducirlo abriendo Google Earth y arrastrando tu aplicación sobre la ventana principal de renderizado; tu ventana en capas desaparecerá.

Otros consejos

He descubierto una cosa: tener piezas del marco por separado puede hacer significativamente más rápido que tener una sola ventana de marco gigante, con una gran extensión de píxeles vacíos en el medio. No tengo ningún número real, pero sólo de una prueba rápida de tratar tanto, había una latencia perceptible cuando varias ventanas con ventanas de cuadro completo se superponen entre sí, pero cuando sus marcos, se cortaron en componentes más pequeños, era mucho más ágil . Cualquiera que sea sobrecarga de tener múltiples ventanas superpuestas con sus propios contextos de dispositivo no contribuye mucho, y tener grandes extensiones de píxeles en blanco (o no!) Sigue contribuyendo mucho más carga.

  1. No se olvide de probar bajo RDP y VM (Hyper-V y VMware)
  2. Intente varias tarjetas gfx y en netbooks y portátiles (si es aplicable).
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top