Alpha utils

Description

Bonjour !

Comme vous le savez, tout objet interactif dans Windows (boîtes de saisie, boutons, liste déroulante, etc ...) possède un Handle - c'est à dire un descripteur de fenêtre, qui peut être utilisé dans des API telles que SendMessage, Set/GetWindowLong, etc ...
Parlons de Set/GetWindowLong, qui permet de récupérer et de définir tout un tas de trucs pour une fenêtre (qui désigne tout objet interactif dessiné dans Windows) donnée, en spécifiant son handle (descripteur de fenêtre). Il est possible de définir un style de fenêtre, qui peut être une combinaison de multiples constantes. Définissons par exemple ... la constante WS_EX_LAYERED [$00080000] - non déclarée dans Windows, il faut la définir soi-même. Elle permet d'activer le style "layered", et permet à la fenêtre d'être utilisée dans des API telles que GetLayeredWindowAttributes et SetLayeredWindowAttributes (non déclarées dans Windows encore une fois, il faut les appeller soi-même depuis User32.dll), qui permettent de définir les "layered attributs" de la fenêtre passée en paramètre.
Nous arrivons au vif du sujet : qu'est-ce que les "layered attributes" ? Eh bien c'est un certain nombre de paramètres qui définissent la façon dont Windows doit gérer une fenêtre "layered" et son "environnement graphique" (les fenêtres qui sont probablement derrière la fenêtre "layered"). En gros, c'est un AlphaBlend. Windows regarde si telle ou telle fenêtre possède un style incluant WS_EX_LAYERED, et si c'est le cas, il la dessine en alphablend, selon le paramètre LWA_ALPHA [$00000002] (non définie dans Windows, oh la la quel travail de porc cette unité ^^ ...). Pour ceux qui ne le savent pas, l'alphablend est le principe de mélanger deux couleurs entre elles pour obtenir un fondu (exemple : du bleu sur du vert donne du jaune). Néanmoins, pour pouvoir gérer sa propre fenêtre "layered" (qui peut ne pas vous appartenir bien sûr !), il faut d'abord faire un certain nombre de choses.
C'est pourquoi je vous ai concocté une unité Alpha Utils qui permet de gérer très facilement une fenêtre "layered", en vous offrant toutes les routines nécessaires à la gestion d'une telle fenêtre, ainsi que quelques outils pour retrouver facilement quelques descripteurs de fenêtres.
Je vais vous résumer rapidement les étapes de la gestion d'une fenêtre "layered", de façon très générale :

1) On cherche un descripteur de fenêtre parmi le fouillis indescriptible de notre mémoire vive => allez, appellons-le HANDLE ^^.

2) On prépare la fenêtre identifiée par HANDLE à accepter les layered attributes en utilisant PrepareLayering (notez qu'il est possible de spécifier si l'on veut forcer la fenêtre à passer en layering - ça ne marchera pas toujours).

3) On va faire joujou avec le paramètre LWA_ALPHA de notre fenêtre. On va modifier, à notre gré, la valeur alpha de ce paramètre, pour définir avec quelle intensité Windows va appliquer le fondu (0 = totalement invisible (ne répond même plus aux évènements utilisateur), 255 = opaque). On peut même récupérer son état à n'importe-quel moment avec GetWindowAlpha, et le définir avec SetWindowAlpha.

4) Une fois qu'on en a assez, on appelle ReleaseLayering. Cette fonction aura pour effet de rétablir le style initial de la fenêtre.

Remarque : on peut eventuellement utiliser la fonction SupportsLayering, qui permet de savoir si la fenêtre choisie supporte déjà le layering (évite un appel inutile à PrepareLayering si SupportsLayering renvoie True).

Quelques routines utiles pour récupérer divers descripteurs de fenêtre :

- GetTrayHWnd, récupère le descripteur de fenêtre de la barre des tâches
- GetDesktopHWnd, récupère le descripteur de fenêtre du bureau
- GetHWndByWindowName, récupère le descripteur de fenêtre d'une fenêtre si l'on connaît son nom
- GetHWndByWindowClassName, récupère le descripteur de fenêtre d'une fenêtre si l'on connaît son nom de classe
- SearchHWnds, récupère dans un TList les handles de toutes les fenêtres de votre système ! [EnumWindows]

J'ai fourni un petit exemple, qui permet de rendre la barre des tâches transparente, ainsi qu'un petit bonus, pour rendre votre fiche transparente SANS l'utilisation des propriétés AlphaBlend et AlphaBlendValue.
J'ai également mis une option pour lister soit toutes les fenêtres, soit seulement la barre des tâches et notre fiche ...
J'ai mis une capture, que j'ai prises au moment de mettre ma source sur DelphiFr. Notez que j'ai mis en fond d'écran un dégradé, pour bien faire ressortir la transparence de la barre.
__________________________________

NOUVEAU [SAMEDI 17 JANVIER 2009] :

Ajout d'une classe TLayeredWindow pour gérer d'une façon extrêmement simple une fenêtre "layered". Il suffit de créer la classe TLayeredWindow avec un descripteur de fenêtre en paramètre (ainsi que quelques autres paramètres utiles), et elle fera tout pour vous. Elle s'occupera même de la destruction de l'objet et du retour à l'ancien style. Une fois que vous aurez créé l'objet (pensez à le détruire par Free), vous aurez accès à un certain nombre d'informations sur la fenêtre. Voici ce que contient TLayeredWindow :

- Accès au descripteur de fenêtre, possibilité de le modifier sans recréer soi-même une classe TLayeredWindow
- Accès au nom de classe de la fenêtre (dans mon exemple, on aura "Shell_TrayWnd" et "TMainForm")
- Accès au descripteur de fenêtre du parent (lecture seule)
- Accès au nom de classe du parent (lecture seule)
- Accès en lecture seule à l'ancien style de la fenêtre (si vous voulez faire quelque chose avec ??)
- Accès à une propriété qui indique si la fenêtre supportait le layering avant de la forcer à le supporter
- Accès à la valeur alpha de la fenêtre (modification en temps réel)
- Accès à une propriété qui indique si la fenêtre est capable de modifier sa transparence, même en forçant le layering
- Accès à une propriété qui indique si le descripteur de fenêtre pointe bien vers une fenêtre visible
- Accès à une propriété (que vous pouvez modifier) qui indique si l'on doit rétablir l'état initial de la fenêtre une fois la manipulation terminée)
- Accès à une propriété qui indique l'état de la fenêtre (répond/ne répond pas), lecture seule, cela va de soi ^^'.
- Possibilité de choisir si cette classe sert juste pour récupérer des informations sur la fenêtre (on ne touchera pas aux layered attributes - évitera un sale clignotement noir, et eventuellement des problèmes de redessinement)), ou alors si elle sert bien à modifier la transparence de la fenêtre.

Je vous ai même mis un pointeur typé TLayeredWindow, mais il est inutile pour l'instant (peut-être plus tard ??).

Bien sûr, il est possible de contourner cette classe et d'utiliser directement les fonctions PrepareLayering, GetWindowAlpha, etc ... Mais votre code sera considérablement allégé si vous utilisez la classe TLayeredWindow.

Une documentation très complète sous forme de HTML est fournie dans le zip. Lisez-là si vous n'êtes pas à l'aise avec les descripteurs de fenêtres et tout ça ...
Une DLL est fournie pour la compatibilité avec les autres langages (l'unité réservée à la DLL - AlphaUtilsUnit.pas - a été spécialement optimisée pour la DLL).
__________________________________

J'ai probablement oublié des trucs dans la description, merci de me le rappeller :)
Bon amusement ! (cette unité Alpha Utils est tout à fait libre, je voudrais juste que vous gardiez le header (le paquet de texte en commentaire avec la déclaration de l'unité), et que vous m'informiez avant de distribuer une application la contenant. Il en va de même pour l'unité réservée à la DLL).

Merci à tous :)

Source / Exemple :


// In the Zip

Conclusion :


Tous critiques, commentaires, remarques, conseils, etc ... ici :)

Cordialement, Bacterius !

PS : Codé sous Delphi 6 Personal Edition.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.