2010-12-13 14 views
5

Estoy trabajando en una aplicación de interfaz gráfica de usuario de Win32 con API simple de Win32 (sin MFC o .NET). El problema que estoy teniendo es hacer que los controles aparezcan transparentes. Yo he llegado con un método que funciona para la mayoría de las cosas, en Windows Vista + hago esto en el WndProc:Controles transparentes de Win32 en todas las versiones de Windows

case WM_CTLCOLORSTATIC: 
{ 
    SetBkMode((HDC)wParam, TRANSPARENT); 
    return (INT_PTR)::GetStockObject(NULL_PEN); 
} 
break; 

En Windows XP, hago esto en el WndProc:

case WM_CTLCOLORSTATIC: 
{ 
    HBRUSH hbr = (HBRUSH)DefWindowProc(hDlg, message, wParam, lParam); 
    ::DeleteObject(hbr); 
    SetBkMode((HDC)wParam, TRANSPARENT); 
    return (LRESULT)(HBRUSH)(COLOR_WINDOW); 
} 

Ahora esto funciona para la mayoría de los controles, sin embargo obtengo un fondo transparente en la etiqueta en la parte superior de un control de cuadro de grupo que dibuja la línea del cuadro de grupo a través del texto. Comencé a trabajar en un caso solo para cajas de grupo, pero estoy seguro de que este es un problema que debe haberse resuelto antes y no quiero reinventar la rueda.

¿Existe un método probado para hacer que los controles parezcan transparentes?

Gracias, J

+1

No creo que deba eliminar el pincel así ... – Anders

+0

¿Está seguro de que el canal alfa está disponible en todas las plataformas que desee? ¿Qué pasa con las personas que tienen que usar su aplicación en una PC con Terminal Services, Remote Desktop o Windows Server?¿Qué quiere decir con "Todas las versiones de Windows"? Windows 98? ¡Eso también es Win32! Tal vez podría decir "Todas las versiones de Windows desde Windows XP y más nuevas" si eso es lo que quiere decir. –

+0

Probablemente tenga razón al respecto, funciona ya sea que elimine el pincel o no. No recuerdo dónde obtuve ese código a partir de ahora, pero había una explicación de por qué el pincel estaba siendo eliminado así. – JWood

Respuesta

6

Para lograr controles transparentes que se va a tener que tener en cuenta que:

  • Realmente no se puede. Los controles estándar de Windows simplemente no admiten la pintura "transparente".
  • Incluso cuando lo hace bien, el cuadro de diálogo parpadeará mal si lo cambia de tamaño.
  • Los 'hacks' para obtener una pintura transparente de los controles que funcionan tienden a ser diferentes si el tema está activado o desactivado, y cambian entre versiones de Windows.

Por lo general, el objetivo de hacer que los controles sean "transparentes" es que se vea una máscara de mapa de bits debajo de los controles. La forma de lograr este tipo de transparencia es crear un mapa de bits para el fondo del control. Luego use CreatePatternBrush desde el mapa de bits.

Este trozo de código DialogProc implementa el método de aplicación de aspectos más simple posible y luego tomar el cuidado de la pintura tanto en el fondo del cuadro de diálogo, y la mayoría de los controles que apoyan esta forma de pintura:

// _hwnd is the dialogs handle 
    // _hbrSkin is a pattern brush handle 
    HWND hwndCtl; 
    POINT pt; 
    HDC hdc; 
case WM_CTLCOLORDLG: 
    return (INT_PTR)_hbrSkin; 
case WM_CTLCOLORSTATIC: 
case WM_CTLCOLORBTN: 
    hdc = (HDC)wParam; 
    SetBkMode(hdc,TRANSPARENT); // Ensure that "static" text doesn't use a solid fill 
    pt.x = 0; pt.y = 0; 
    MapWindowPoints(hwndCtl,_hwnd,&pt,1); 
    SetBrushOrgEx(hdc,-pt.x,-pt.y,NULL); 
    return (INT_PTR)_hbrSkin; 

Los controles que la superposición se dibujará incorrectamente ya que uno pintará su fondo "transparente" sobre el otro. Puede reducir el parpadeo por:

  • No se permite cambiar el tamaño del cuadro de diálogo.
  • configurando el estilo WS_EX_COMPOSITED en el diálogo, pero como el Windows NT 6 DWM no lo admite, es esencialmente inútil desde Vista en.
  • Configuración del estilo WS_CLIPCHILDREN en el cuadro de diálogo & o WS_CLIPSIBLINGS: estos estilos evitan el uso de cuadros de grupo y controles de pestaña, ya que dependen de la superposición de controles.
  • subclasesando todos los controles, usando el mensaje WM_PRINTCLIENT para pintarlos en un backbuffer, luego ajustando el backbuffer preparado en una sola pasada. El trabajo arduo y no todos los controles admiten WM_PRINTCLIENT.
+0

+1, resumen excelente e incluye la llamada SetBrushOrgEx que es fácil pasar por alto si se prueba con un fondo sólido. –

Cuestiones relacionadas