2010-12-13 12 views
5

Sto lavorando a un'applicazione GUI Win32 utilizzando l'API Win32 normale (senza MFC o .NET). Il problema che sto riscontrando è che i controlli appaiono trasparenti. Mi è venuta in mente un metodo che funziona per la maggior parte delle cose, in Windows Vista + faccio questo nel WndProc:Controlli Win32 trasparenti su tutte le versioni di Windows

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

In Windows XP, lo faccio nel WndProc:

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

Ora questo funziona per la maggior parte dei controlli, tuttavia ottengo uno sfondo trasparente sull'etichetta sulla parte superiore di un controllo di casella di gruppo che disegna la linea di casella di gruppo attraverso il testo. Ho iniziato a lavorare su un caso per le sole scatole di gruppo, ma sono sicuro che questo è un problema che deve essere stato risolto prima e non voglio reinventare la ruota.

Esiste un metodo collaudato per rendere trasparenti i controlli?

Grazie, J

+1

Non penso che dovresti eliminare il pennello in questo modo ... – Anders

+0

Sei sicuro che il canale alfa sia disponibile su tutte le piattaforme che desideri? Che dire delle persone che devono utilizzare la tua app su un PC con Servizi terminal, Desktop remoto o Windows Server?Cosa intendi con "Tutte le versioni di Windows"? Windows 98? Anche questo è Win32! Forse potresti dire "Tutte le versioni di Windows da Windows XP e successive" se è questo che intendi. –

+0

Probabilmente hai ragione, funziona se cancello il pennello o meno. Non ricordo da che ora ho preso quel codice, ma c'era una spiegazione sul motivo per cui il pennello veniva cancellato in quel modo. – JWood

risposta

6

Per realizzare i controlli trasparenti si sta andando ad avere per essere consapevoli che:

  • non si può davvero. I controlli standard di Windows non supportano semplicemente la pittura "trasparente".
  • Anche se lo si fa correttamente, la finestra di dialogo lampeggerà male se la si ridimensiona.
  • Gli "hack" per ottenere una verniciatura trasparente dei controlli funzionano in modo diverso se i temi sono attivati ​​o disattivati ​​e cambiano tra le versioni di Windows.

Solitamente l'obiettivo di rendere controlli "trasparente" è così che una pelle bitmap sotto i controlli mostra attraverso. Il modo per ottenere questo tipo di trasparenza è creare una bitmap per lo sfondo del controllo. Quindi utilizzare CreatePatternBrush dalla bitmap.

Questo pezzo di codice DialogProc implementa il metodo di spellatura più semplice possibile e quindi si prenderà cura di dipingere sia lo sfondo della finestra di dialogo, e la maggior parte dei controlli che supportano questa forma di pittura:

// _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; 

I controlli che la sovrapposizione si disegna in modo errato poiché uno dipingerà il suo sfondo "trasparente" sull'altro. È possibile ridurre lo sfarfallio di:

  • Non consentire il ridimensionamento della finestra di dialogo.
  • impostazione dello stile WS_EX_COMPOSITED nella finestra di dialogo, ma poiché il DWM di Windows NT 6 non lo supporta, è essenzialmente inutile da Vista in poi.
  • Impostazione dello stile WS_CLIPCHILDREN nella finestra di dialogo & o WS_CLIPSIBLINGS - questi stili impediscono l'utilizzo di caselle di gruppo e controlli di tabulazione poiché si basano su controlli che si sovrappongono.
  • sottoclasse tutti i controlli, utilizzando il messaggio WM_PRINTCLIENT per dipingerli in un backbuffer, quindi blittare il backbuffer preparato in un unico passaggio. Il duro lavoro e non tutti i controlli supportano WM_PRINTCLIENT.
+0

+1, eccellente sommario e include la chiamata SetBrushOrgEx che è facile trascurare se si esegue il test con uno sfondo solido. –

Problemi correlati