Imessagefilter - exemple d'utilisation d'un filtre de messages

Soyez le premier à donner votre avis sur cette source.

Snippet vu 11 603 fois - Téléchargée 29 fois

Contenu du snippet

Suite à question sur le forum (http://www.csharpfr.com/forum.v2.aspx?ID=524275), voici un petit exemple d'implémentation de l'interface IMessageFilter (System.Windows.Forms.IMessageFilter).
Dans cet exemple on s'en sert pour définir un event "TabPressed" afin d'être averti de l'appui sur TAB dont la cible est un formulaire donné ou un de ses enfants.

Source / Exemple :


public class TabMessageFilter : IMessageFilter
{
    #region Constantes

    private const int WM_KEYDOWN = 0x0100;
    private const int VK_TAB = 0x09;

    #endregion Constantes

    #region Constructeur

    /// <summary>
    /// Initialise une nouvelle instance de TabMessageFilter.
    /// </summary>
    /// <param name="form">Instance de Form à surveiller.</param>
    public TabMessageFilter(Form form)
    {
        this._form = form;

        // inscription à l'event qui nous permettra d'être averti 
        // de la destruction du formulaire surveillé
        this._form.Disposed += new EventHandler(_form_Disposed);
    }

    #endregion Constructeur

    #region Champs

    private Form _form; // formulaire a surveiller.

    #endregion Champs

    #region Event TabPressed

    public event EventHandler TabPressed;

    /// <summary>
    /// Déclenche l'évènement TabPressed.
    /// </summary>
    protected virtual void OnTabPressed()
    {
        if ( this.TabPressed != null )
        {
            this.TabPressed(this._form, new EventArgs());
        }
    }

    #endregion Event TabPressed

    #region Membres de IMessageFilter

    public bool PreFilterMessage(ref Message m)
    {
        if ( m.Msg == WM_KEYDOWN && m.WParam == (IntPtr)VK_TAB && IsFormOrChildControl(m.HWnd) )
        {
            // si le message est l'appui sur une touche et qu'il s'agit de TAB 
            // et que la cible est un handle d'une fenetre dont le formulaire 
            // surveillé est parent, on déclenche l'event
            this.OnTabPressed();
        }

        return false;
    }

    #endregion

    #region Méthodes utilitaires

    /// <summary>
    /// Permet de savoir si le handle est celui d'un parent de notre formulaire
    /// </summary>
    /// <param name="hWnd"></param>
    /// <returns></returns>
    private bool IsFormOrChildControl(IntPtr hWnd)
    {
        try
        {
            return  ( Control.FromHandle(hWnd).FindForm() == _form );
        }
        catch
        {
            return false;
        }
    }

    #endregion Méthodes utilitaires

    private void _form_Disposed(object sender, EventArgs e)
    {
        // auto-suppression du filtre de message
        try
        {
            Application.RemoveMessageFilter(this);
        }
        catch
        {
        }
    }
}

///
/// Exemple d'utilisation
/// 
TabMessageFilter filter = new TabMessageFilter(this);
filter.TabPressed += new EventHandler(filter_TabPressed);
Application.AddMessageFilter(filter);

...

private void filter_TabPressed(object sender, EventArgs e)
{
    MessageBox.Show("TAB !!!");
}

Conclusion :


Liens utiles :

MSDN - Interface IMessageFilter :
http://msdn.microsoft.com/fr-fr/library/system.windows.forms.imessagefilter.aspx

A voir également

Ajouter un commentaire Commentaires
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
86
La syntaxe en C# est la même que celle du destructeur en C++, mais ce n'est pas le même concept.
Un peu de lecture sur le sujet : Le guide du Routard du modèle "Dispose" : http://www.dotnetguru.org/articles/dossiers/dispose/article.htm (utiliser FF pour l'affichage, ou peut être IE8 et sup mais pas IE7)
Messages postés
23
Date d'inscription
mardi 22 janvier 2002
Statut
Membre
Dernière intervention
16 novembre 2009

Ma question etait juste pour savoir si il etait necessaire le removefiltermessage? Apparemment oui c'est necessaire !!
Au fait le fait de mettre dans ~lenomdetaclasse (finalizer: c'est pas le detructeur ??) ca n'engendre pas de soucis !!
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
86
Salut,

Si par "destructeur" tu entends le gestionnaire d'évènement attaché à l'event Disposed, ou une surcharge de la méthode Dispose, ça revient au même que ce que j'ai fait.
Si par "destructeur" tu parles d'un finaliseur, je ne crois pas non : tu n'as aucun idée du moment où il sera appelé, et je ne suis pas certaines des effets de bord possibles d'un appel à RemoveMessageFilter avec un objet en cours de finalisation.
Messages postés
23
Date d'inscription
mardi 22 janvier 2002
Statut
Membre
Dernière intervention
16 novembre 2009

Juste une question toute bête ...

Il vaut mieux faire dans le destructeur d'une form "Application.RemoveMessageFilter(this);" quand dans le contructeur on fait "Application.AddMessageFilter(this);" ??
Messages postés
6351
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
86
de rien :-)
Afficher les 7 commentaires

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.