Estamos desarrollando una aplicación de piel 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.Uso de ventanas en capas para crear bordes de ventana lisos
He encontrado una solución para esto usando ventanas en capas, pero queremos asegurarnos de que funcione (y que funcione bien) en una variedad de sistemas, y quiero ver si alguien tiene mejores ideas , o formas de optimizar lo que estoy haciendo. Sé que las ventanas en capas requieren win2000 o posterior, y eso está bien, ya que eso ya es un requisito por otras razones. A partir de 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 lo que sea que comprenda 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 A y se dibuja sobre los controles de A. La ventana B también tiene el estilo WS_EX_LAYERED, y en la inicialización, llamo al UpdateLayeredWindow con el indicador ULW_ALPHA y un DC fuente 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 la fuente DC para la ventana B es más o menos los píxeles alrededor del borde de la ventana que quiero combinar sin problemas desde el fondo de la ventana a la transparencia total. Me saltaría todo el enfoque de dos ventanas y solo usaría una sola ventana en capas, excepto que cuando estás usando UpdateLayeredWindow, se extrae de un buffer guardado en la memoria, en lugar de los típicos mensajes WM_PAINT y todo eso, y tratando de obtener Los controles interactivos para niños (y las ventanas hijas) para que funcionen bien con eso suena como una molestia notable (y probablemente ni siquiera funcionaría para todo).
Por lo tanto, básicamente se trata de la ventana A con todos los controles secundarios y lo que sea, con la ventana B flotando directamente sobre ella, dibujando un bonito borde liso. Respondo a los mensajes de WM_MOVE y demás moviendo la ventana B junto con él, y tengo la ventana B deshabilitada para que nunca pueda obtener el foco o la entrada (los clics ya se han procesado, ya que partes de él son de opacidad cero, como la mayoría de sus partes internas, ya están excluidas de la selección).
Para las patadas, así es como se ven las piezas, para mostrar lo que quiero decir un poco mejor.
- Window A's background, con cian se utiliza para enmascarar píxeles completamente transparentes.
- Window B's bitmap, con un canal alfa (no representado, por supuesto, es un jpg) que combinaría los píxeles no negros en transparencia.
- Combined result
Por lo tanto, funciona, pero no puedo estar seguro de que es realmente la mejor manera de hacer esto. Tengo dos preguntas:
- ¿Suena aceptable, o hay algo terriblemente terrible al respecto?
- Como funciona actualmente, parece que está utilizando un búfer fuera de la pantalla del tamaño de la ventana (que puede ser de hasta 1024x768) a pesar de que muy pocos píxeles tienen datos de opacidad distintos de cero. ¿Vale la pena la sobrecarga y la complejidad adicional de cortarlo en pedazos de borde separados y componerlos juntos?
Doug, sería genial si puedes compartir el código para esto. Gracias por adelantado. –