Fond transparent du contrôle sur le thème de xp

J’ai quelques contrôles de fenêtre dessinés sur un bitmap ainsi que sur un fond coloré dans une boîte de dialog. Y aurait-il un moyen possible de rendre l’arrière-plan des contrôles de fenêtre transparent? Actuellement, ils affichent l’arrière-plan coloré par défaut d’une boîte de dialog.

Exemple – J’ai essayé de coller un bitmap bleu uni et les deux contrôles de bouton ont un arrière-plan coloré par défaut, le rectangle coloré.

Fenêtre de dialogue contenant deux boutons d’interface utilisateur au milieu: «OK» et «Annuler». Bien que les boutons soient blanc cassé par défaut, la plupart de la zone intérieure de la boîte de dialogue présente un arrière-plan bleu vif choquant.

Ceci est facilement résolu en fournissant à Windows une poignée pour le pinceau que vous souhaitez utiliser pour peindre l’arrière-plan de votre bouton. Vous faites cela chaque fois que vous recevez le message WM_CTLCOLORBTN dans le gestionnaire de messages de la fenêtre parent du bouton.

J’ai imaginé une petite application de démonstration comparant deux boutons différents côte à côte. Les deux sont des contrôles Win32 BUTTON standard, mais celui de gauche gère le message WM_CTLCOLORBTN et spécifie un pinceau de la même couleur que l’arrière-plan de la fenêtre. Vous pouvez voir immédiatement la différence – les franges gris clair (ou, plus précisément, la couleur par défaut pour les commandes 3D, COLOR_3DFACE ) entourant le rectangle du bouton ont disparu et le bouton est nettement plus COLOR_3DFACE rapport à la couleur d’arrière-plan personnalisée:

Exemple de boutons transparents dans Windows Vista

L’effet fonctionne également dans Windows XP avec les thèmes visuels activés. Voici une capture d’écran de la même application:

Exemple de boutons transparents dans Windows XP

Et le code que j’ai utilisé pour créer l’effet ci-dessus est d’une simplicité presque ridicule. Ajoutez ceci à la procédure de la fenêtre principale de votre application ( MainWndProc ), comme décrit ci-dessus. Vous n’avez pas besoin de toucher vos boutons.

 HBRUSH hButtonBackColor = NULL; LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CTLCOLORBTN: { if (!hButtonBackColor) { // Create the brush, if it hasn't already been created. // (You can use any type of brush here; this is just an example.) hButtonBackColor = GetSysColorBrush(COLOR_3DDKSHADOW); } return (LRESULT)hButtonBackColor; } // ... } } 

Cependant, assurez-vous que le pinceau que vous spécifiez représente exactement la même couleur que la couleur d’arrière-plan de votre fenêtre: un pinceau transparent risque de ne pas fonctionner correctement. De la même manière, pour un pinceau à motifs (personne ne les utilise-t-il plus?), L’origine du pinceau doit être définie pour correspondre à l’arrière-plan.

Assurez-vous toujours de libérer tous les pinceaux que vous créez en appelant DeleteObject !! En C ++, vous pouvez faire cela en faisant d’un object CBrush (ou équivalent) un membre de votre classe de dialog afin qu’il soit automatiquement détruit. En C, vous devez gérer le message WM_NCDESTROY et supprimer le pinceau manuellement.

Notez également qu’il n’est pas nécessaire de spécifier le style BS_OWNERDRAW pour que cette astuce fonctionne. L’exemple ci-dessus utilise deux contrôles de bouton standard, créés à l’aide des indicateurs de style de fenêtre suivants: WS_CHILD , WS_VISIBLE et BS_PUSHBUTTON .

Bien entendu, si votre conception est plus complexe que l’exemple ci-dessus (par exemple, vos boutons chevauchent plusieurs arrière-plans), vous devrez probablement suivre la route indiquée par le propriétaire. Je pense simplement que c’est exagéré pour une tâche aussi simple que celle que vous semblez décrire.

Je ne sais pas si vous pouvez créer un arrière-plan vraiment transparent, mais ma solution peut néanmoins vous aider. Je l’ai toujours résolu en utilisant le message WM_CTLCOLORBTN dans la procédure de la fenêtre principale.
Supposons que nous ayons un switch dans lequel nous traitons les messages reçus par la fenêtre principale.

 case WM_CTLCOLORBTN: return (LRESULT)hBgColor; break; 

hBgColor est un HBRUSH , par exemple:

 HBRUSH hBgColor=CreateSolidBrush(RGB(0, 0, 255)); 

Comme je l’ai dit précédemment, cela ne rend pas vraiment l’arrière-plan du contrôle transparent, mais le définit simplement sur la couleur spécifiée.
EDIT: Je suis désolé, j’ai déjà fait une erreur. J’ai écrit LPARAM au lieu de LRESULT . Maintenant c’est correct.