Trapper un Sendkeys (CTRL+S) sur une form et executer un script [Résolu]

Signaler
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
-
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
-
Hello,

voila mon pb j'ai fait une toolbar qui fait des senkeys(...) en fonction du bouton sur lequel on presse...
par exemple si on presse sur le bouton valider je fais un :

//envoie de control S
sendkeys("^S")


dans mes forms MDi je voudrait utiliser des MessageFilter(suite à une discussion avec coq sur ce forum)
qui permette de trapper si on presse sur UNE touche...
oui mais voila CTRL+S ca fait DEUX touche....
bref je pietine...

voila le code de ma classe message filter :
internal class CTRLS_MessageFilter : IMessageFilter
{
// constructeur, on lui passe le form qui sera concerné par les actions
public CTRLS_MessageFilter(w_CodeLibelle form)
{
this.form = form;
}

private const int WM_KEYDOWN = 0x0100;
private w_CodeLibelle form;

public bool PreFilterMessage(ref Message m)
{
// si le message est une pression sur touche et que la touche est CTRl + Sif ( m.Msg WM_KEYDOWN && m.WParam (IntPtr)Keys.Control)
{
// si le message est destiné a notre form ou un controle qu'il contient, on le fermeif ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
form.Save_Enregistrement();
// blocage du message
return true;
}
}
// le message n'etait pas celui qu'on attendais, on le laisse passer
return false;
}
}


voila si kkun à une idée avec les messagesfilter ou autre je prend...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."

19 réponses

Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
[DllImport("user32")]
private static extern short GetAsyncKeyState(int vKey);

private const int VK_CONTROL = 0x11;

public bool PreFilterMessage(ref Message m)
{
// récupération de l'etat de la touche ctrl
short ctrlState = GetAsyncKeyState(VK_CONTROL);

// si le message est une pression sur touche et que la touche est CTRl + S
if ( m.Msg == WM_KEYDOWN 
&& m.WParam == (IntPtr)Keys.S // touche S
&& (( ctrlState >> 15 ) & 0x1) == 0x1  // ctrl (gauche ou droit) est pressée
)
{
// si le message est destiné a notre form ou un controle qu'il contient, on le fermeif ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
form.Save_Enregistrement();
// blocage du message
return true;
}
}
// le message n'etait pas celui qu'on attendais, on le laisse passer
return false;
}


Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
pourquoi tu n'appelles pas directement le code executé sur un ctrl+s ?

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
j'ai trouver !!!!!!!

voila la classe de messageFilter a utiliser :

internal class CTRLS_MessageFilter : IMessageFilter
{
// constructeur, on lui passe le form qui sera concerné par les actions
public CTRLS_MessageFilter(Form form)
{
this.form = form;
}

[DllImport("user32")]
private static extern short GetAsyncKeyState(int vKey);
private const int WM_KEYDOWN = 0x0100;
private const int VK_CONTROL = 0x11;
private Form form;

public bool PreFilterMessage(ref Message m)
{
// récupération de l'etat de la touche ctrl
short ctrlState = GetAsyncKeyState(VK_CONTROL);

// si le message est une pression sur touche et que la touche est CTRl + S
if ( m.Msg == WM_KEYDOWN 
&& m.WParam == (IntPtr)Keys.S // touche S
&& (( ctrlState >> 15 ) & 0x1) == 0x1 // ctrl (gauche ou droit) est pressée
)
{
// si le message est destiné a notre form ou un controle qu'il contient, on le fermeif ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
w_FormBase f = (w_FormBase) form;
f.f_Valider();
// blocage du message
return true;
}
}
// le message n'etait pas celui qu'on attendais, on le laisse passer
return false;
}
}


fallait forcer le return true qd on appuie sur CTRL+S
et passer une form que l'on cast ensuite en w_FormBase...

merci coq pour ta patience...

jva pouvoir bien dormir...

:o))
Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
merci coq je teste ca demain ...
maintenant rentrer maison :o)))

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
ok :)
par contre je suis en train de me demander si on aurais pas de quoi verifier l'etat d'une touche directement dans le framework...

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
c ok ca roule...
j'avais essayer de concatener les keys...mais forcement ca mlarchait pas...

merci monsieur coq...
y reste plus qu'a verifier mon sendkeys de ma toolbar...
ca marche en faisant mon ctrl+s mais pas en cliquant sur le bouton qui fait le senkeys....

j'va revoir ca ...
merci encore :o)))

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
hum oui : quand tu envoie le message la touche ctrl n'est pas réellement enfoncée donc GetAsynKeyState la donne comme non enfoncée :(

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
ARGHHH....

damned....
je suis fait....

tu connais un moyen de contourner la chose ???
...
c pour ca que mes test avec des senkeys de F1 fonctionnait...
on pasait pas par le GetAsynKeyState...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
effectivement si j'appuie sur ctrl et que je clique sur mon bouton sa marche...

:o(((

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
ben en fait ma toolbar est lie a ma fenetre MDI
et je trouvais plus elegant la technique du sendkeys

si j'appelle la fonction directement dans ma toolbar, je vais être obligée d'avoir une fonction qui existe....

tu me diras je pourrais faire un objet form qui contiendrais toutes les fonctions de mes 15 boutons de la toolbar, duquel j'heriterais toutes mes forms de mon appli...

et roule...

par contre le sendkeys envoi les touches sur la form active du MDI...

Il me reste peut etre la solution de recuperer ACTIVECHILd en le castant avec ma form parent et je devrais pouvoir accéder à mes fonctions directement....
ca devrait se tenir la non ???

par contre je trouvais la methode du sendkeys plus jolie car elle permettait de faire des forms comme on voulait (sans figer des noms de méthodes...)

et surtout pas d'erreur si une form ne contient pas les méthodes qui vont bien...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
en fait je vois pas vraiment ce que tu veux faire lol

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
lol :o))))

c jeudi... j'ai du mal a mettre mes idées a plat :o)))

en fait je suis entrain de creer des objets pour une boite a outils qui nous permettra de developper + vite...

l'idee c'est de faire une form MDI standard dans laquelle j'integre un objet toolbar_Perso herite du Toolbar standard...
dans se toolbar_perso je dois executer du code de mes fenetres mdichild....je passe donc en parametre l'instance de la form Mdi decrite ci dessus...

donc j'ai creer une form w_FormBase : form dans laquelle je met toutes mes fonctions de validation, recherche, etc.... en virtual...
pour pouvoir faire des override plus tard...
prenons le cas de la fonction de validation qui se trouve sur w_FormBase:

/// <summary>
/// Méthode à éxécuter pour lancer la validation des données
/// </summary>
/// <returns>False (par défaut) si la fenêtre doit gérer elle même la combinaison de touche(après notre traitement),
/// true si on veut arreter l'execution après notre traitement</returns>
public virtual bool f_Valider()
{
//On laisse la main à la fenêtre
return false;
}


sur cette meme form j'ai une instance de la classe ImessageFilter :

internal class CTRLS_MessageFilter : IMessageFilter
{
// constructeur, on lui passe le form qui sera concerné par les actions
public CTRLS_MessageFilter(w_FormBase form)
{
this.form = form;
}

[DllImport("user32")]
private static extern short GetAsyncKeyState(int vKey);
private const int WM_KEYDOWN = 0x0100;
private const int VK_CONTROL = 0x11;
private w_FormBase form;

public bool PreFilterMessage(ref Message m)
{
// récupération de l'etat de la touche ctrl
short ctrlState = GetAsyncKeyState(VK_CONTROL);

// si le message est une pression sur touche et que la touche est CTRl + S
if ( m.Msg == WM_KEYDOWN 
&& m.WParam == (IntPtr)Keys.S // touche S
&& (( ctrlState >> 15 ) & 0x1) == 0x1 // ctrl (gauche ou droit) est pressée
)
{
// si le message est destiné a notre form ou un controle qu'il contient, on le fermeif ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
bool ret = form.f_Valider();
// blocage du message
return ret;
}
}
// le message n'etait pas celui qu'on attendais, on le laisse passer
return false;
}
}



donc si tu fais CTRL+S tu dois executer le script de f_valider

de plus sur l'evenement clique du toolbar(a qui j'ai passer la forme mdi en parametre) je fais un :

switch(e.Button.tag.toString())
{
case "VALIDER":
//SendKeys.Send("^S");
f =	(w_FormBase) Form_Mdi.ActiveMdiChild ;
f.f_Valider ();
break;
}


et au final sur la form qui herite de w_FormBase je fais:

public override bool f_Valider()
{
MessageBox.Show("Valider");
 //On bloque le reste de l'execution
return true;
}


maintenant resultat des courses....

si je clique sur la toolbar de ma MDI le message Valider apparait...

par contre si je suis sur l'instance de ma form heritee de w_FormBase et que je fais CTRL + S ...
ben y se passe rien....

ARG HHHHHH

est ce que le fait de faire un heritage m'a fait perdre mes messagefilter...

...ouha ca doit etre mon plus long post....
:o)))

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
pour infos je fais les Appplication.AddMessageFilter sur le constructeur de ma form w_FormBase...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
euhhhhh... joker !!!! :clown)

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
:o))))

je crois avoir une idée de mon pb...
j'ai un null qui traine kkpart ... :o))))

je le piste...

Aurais-je reussi a coller coq ???
;o))))

pour le reste je vais essayer de me debrouiller...

merci beaucoup pour les message filter et autres...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
je reviens qd meme a la charge... :
sur la fenetre qui va me servir de base pour l'heritage de toute les forms de mon applis j'ai défini les messagefilter en passant la fenetre w_formbase dans le constructeur(voir la reponse de coq) j'ai change ca en passant un form et en faisant un cast :

internal class CTRLS_MessageFilter : IMessageFilter
{
// constructeur, on lui passe le form qui sera concerné par les actions
public CTRLS_MessageFilter(Form form)
{
this.form = (w_FormBase) form;
}

[DllImport("user32")]
private static extern short GetAsyncKeyState(int vKey);
private const int WM_KEYDOWN = 0x0100;
private const int VK_CONTROL = 0x11;
private w_FormBase form;

public bool PreFilterMessage(ref Message m)
{
// récupération de l'etat de la touche ctrl
short ctrlState = GetAsyncKeyState(VK_CONTROL);

// si le message est une pression sur touche et que la touche est CTRl + S
if ( m.Msg == WM_KEYDOWN 
&& m.WParam == (IntPtr)Keys.S // touche S
&& (( ctrlState >> 15 ) & 0x1) == 0x1 // ctrl (gauche ou droit) est pressée
)
{
// si le message est destiné a notre form ou un controle qu'il contient, on le fermeif ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
bool ret = form.f_Valider();
// blocage du message
return ret;
}
}
// le message n'etait pas celui qu'on attendais, on le laisse passer
return false;
}
}


et la lorsque j'herite de ma w_formbase qd j'affiche cette form et que je fais CTRL+S ca fonctionne....UNE FOIS....

et pas plus...

tu as deja eu le cas ????

comprend plus rien moi...

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
euh non lol
verifie que la methode PreFilterMessage est appelée lors du 2eme appui pour voir

Cocoricoooooooo !!!!
coq
MVP Visual C#
Messages postés
1183
Date d'inscription
mercredi 21 janvier 2004
Statut
Membre
Dernière intervention
6 septembre 2011
12
Oui il rentre bien plusieurs fois dans mon prefilterMessage mais il ne rentre pas sur ce if :

if ( m.HWnd form.Handle || form.Contains(Control.FromHandle(m.HWnd)) true )
{
//On lance l'enregistrement
bool ret = form.f_Valider();
// blocage du message
return ret;
}


vu que le form est herite ca vient peut etre de la ???

Arthenius

"Ce qui ne me tue pas, me rend plus fort..."
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
ah ok
j'avais pas vu que tu avais modifier le return lol

Cocoricoooooooo !!!!
coq
MVP Visual C#