samedi, octobre 06, 2007

Shell transparente via JNA

Dans un précédent billet, j'avais présenté JNA. Je vous propose ici un petit exemple permettant de rendre transparent une Shell SWT tout en utilisant JNA.

Capture d'écran : sans transparence

Capture d'écran : avec transparence


Il faut cependant passer par un appel natif. Pour simplifier les choses je me limiterai à la plateforme Windows. Sous WIN32, un appel aux fonctions suivantes est nécessaire :
  • int getWindowLong(int hWnd, int nIndex)
  • int setWindowLong(int hWnd, int nIndex, int dwNewLong)
  • boolean setLayeredWindowAttributes(int hWnd, int crKey, byte bAlpha, int dwFlags)
Par l'intermédiaire de JNA, l'appel aux fonctions natives se fait très facilement, adieu code C ... Ci-dessous vous trouverez l'interface qui contiendra les définitions des fonctions natives.
public interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class, DEFAULT_OPTIONS);
int GWL_EXSTYLE = -20;
int WS_EX_LAYERED = 0x80000;

int LWA_COLORKEY = 1;
int LWA_ALPHA = 2;

int GetWindowLong(int hWnd, int nIndex);
int SetWindowLong(int hWnd, int nIndex, int dwNewLong);

boolean SetLayeredWindowAttributes(int hwnd, int crKey, byte bAlpha, int dwFlags);
}
La transparence est gérée par setLayeredWindowAttributes. hWnd correspond au handle window de la Shell, nIndex désigne la couleur transparente, bAlpha précise le niveau de transparence et enfin dwFlags permet d'indiquer le type de transparence : soit par une couleur, soit au niveau globale, soit un mixte des deux (utilisation d'un pipe).
myButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
User32 lib = User32.INSTANCE;
int flags = lib.GetWindowLong(myShell.handle, User32.GWL_EXSTYLE);
flags |= User32.WS_EX_LAYERED;
lib.SetWindowLong(myShell.handle, User32.GWL_EXSTYLE, flags);
Color myColor = Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);
lib.SetLayeredWindowAttributes(myShell.handle, myColor.handle, (byte)200, User32.LWA_COLORKEY | User32.LWA_ALPHA);
}
});
Dans cet exemple, je réalise à la fois une transparence de la fenêtre globale et une transparence de la couleur (DARK_BLUE).

Je ne vais pas m'attarder à expliquer le code, vous trouverez l'exemple ici.

A noter que je me suis basé sur le code fournit par le projet JNA.

Je profite de la discussion autour de JNA pour vous donner un lien sur un billet très intéressant à ce sujet (présentation JNI puis JNA) : blog Developpez.com

9 commentaires:

  1. Depuis la 3.4M3 toute fraîche, SWT permet d'utiliser une transparence alpha sur les Shell, pour les OS qui supportent cette fonctionnalité ;-)

    Voir : http://download.eclipse.org/eclipse/downloads/drops/S-3.4M3-200711012000/eclipse-news-M3.html#Platform

    RépondreSupprimer
  2. Salut,

    Merci beaucoup pour l'info toute fraiche. Va falloir que je regarde ça de près.

    Mickaël

    RépondreSupprimer
  3. Bonjour Mr,
    Moi aussi je cherche une solution au problém de la transparence
    enfin j'ai trouver un truk, mais je sait pas comment l'utilisé :( pouvez vous me montrez que doit-je faire ???

    et merci d'avence :)

    RépondreSupprimer
  4. Cette fonctionnalité est disponible depuis Eclipse 3.4

    RépondreSupprimer
  5. ok merci , grace a vous maintenant je sait que j'ai l'eclipse 3.0.0 ^^

    je vai télécharger une version récente, et j'essayeré avec JNA, si j'auré des problémes je vais pas hisiter ^^

    GOD bluss you ;)

    RépondreSupprimer
  6. JNA ne servira plus à rien puisque une Shell depuis Eclipse 3.4 peut être transparente

    RépondreSupprimer
  7. maintenant je suis avec la version 3.6.2 et ni le JNA ni le shell sont reconu avec ecplipse !!!

    import org.eclipse.swt.widgets.Shell;

    The import org.eclipse cannot be resolved

    si vous pouvez me dire que doi-je faire pour y arriver

    merci.

    RépondreSupprimer
  8. Soit il faut faire un plugin Eclipse soit il faut faire un projet Java en incluant la bibliothèque SWT qui se trouve dans le répertoire d'Eclipse.

    JNA ne fait pas partie d'Eclipse il faut le télécharger en plus d'Eclipse.

    RépondreSupprimer
  9. merci beaucoup Mr mickael, je vous emrpi pour votre aide précisuese ça m'a été tré utile

    RépondreSupprimer