Gestion du clavier en C# [problème]

cs_alncool Messages postés 16 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 12 juillet 2005 - 8 févr. 2005 à 09:13
 ronan - 2 mars 2019 à 11:54
Voila j'ai une application à réaliser qui utilise les différents appuis sur des touches définies du clavier pour executer différents traitements. Dans mes recherches j'ai trouvé que je devais utiliser les classes System.Windows.Forms.KeyPressEventHandler ou Windows.Forms.KeyEventHandler pour intercepter les messages. J'ai compris aussi qu'il y avait trois types de message KeyDown (pour le message dès l'appuis de la touche), KeyUp (pour le message quand la touche est relachée) et KeyPress (quand la touche reste appuyée).
[corrigez moi si je me trompe!]
Cependant je n'ai pas trouvé d'exemple concret sur l'utilisation 'un peu avancé' des touche comme la détection d'un appuis long, la double pression sur une touche (comme un double clic). En fait j'ai souvent trouvé des interception dans le genre :

private
void Form1_KeyDown(
object sender, System.Windows.Forms.KeyEventArgs e)


{



if (e.KeyCode.ToString() == "Left") faire() ;



if (e.KeyCode.ToString() == "Right") faire () ;



if (e.KeyCode.ToString() == "Up") faire()
;


}

Donc j'aimerai bien savoir si quelqu'un a déjà utilisé ces méthodes pour m'éclairer un peu car cet exemple est trop limité pour mon application. En fait mon projet tourne autour d'un Pocket PC dont l'utilisation ne s'effectue que par gestion clavier. Je programme sous Visual .Net 2003 avec, bien entendu, le SDK pour pocket PC.
Je vous serai très reconnaissant pour votre aide!

Merci d'avance

Règle du bon codeur:
1) faire compliquer quand on peut faire simple
2) taper sur son PC quand ça ne marche pas
3) profiter de ses erreurs pour les recopiers dans un autre programme
4) je crois qu'avec tout ça j'y arriverai un jour

4 réponses

cs_coq Messages postés 6351 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
8 févr. 2005 à 09:21
Deja le ToString, bof :

private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Left) faire() ;
if (e.KeyCode == Keys.Right) faire () ;
if (e.KeyCode == Keys.Up) faire() ;
}

Cocoricoooooooo !!!!
coq
MVP Visual C#
0
cs_coq Messages postés 6351 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
8 févr. 2005 à 09:23
oups je n'avais pas vu le "PocketPC"
Du coup je ne sais pas si ce que je viens de donner est correct

Cocoricoooooooo !!!!
coq
MVP Visual C#
0
cs_alncool Messages postés 16 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 12 juillet 2005
9 févr. 2005 à 15:37
Le fait que ce soit le Pocket Pc n'influe en rien le code.. le joytick et les bouttons sont considéré comme un clavier ordinaire.
En fait le code que tu ma écris est aussi un autre style de code que j'ai beaucoup trouvé cependant je reste sur le même probleme : comment je fais pour gérer des appuis long sur une touche ou des doubles appuis?
En gros j'aimerai savoir si il existe une classe avec des méthode pour gérer les appuis long, court et aussi double appuis.
Je suis preneur de nimporte quel source et même en VC++ 6, ou VB.NET ou encore VC.NET.

Merci cependant de ta réponse qui a été tres rapide! ;)

Règle du bon codeur:
1) faire compliquer quand on peut faire simple
2) taper sur son PC quand ça ne marche pas
3) profiter de ses erreurs pour les recopiers dans un autre programme
4) je crois qu'avec tout ça j'arriverai un jour
0
cs_alncool Messages postés 16 Date d'inscription jeudi 4 décembre 2003 Statut Membre Dernière intervention 12 juillet 2005
5 mai 2005 à 12:34
Voila étant moi même
l'auteur de ce topic je tiens à mettre à disposition la solution de mon
problème. Je suis sûr que ca aidera pas mal un grnad nombre d'entre
vous qui ont besoin de gérer le clavier. Mon code n'est peut-être pas
très optimisé mais sa peut dépanner. ;)



Voici le code que j'ai réalisé avec l'environnement Visual Studio 2003 plus le SDK Pocket PC 2003




Fichier Form1.cs // en C#



using System;

using System.Drawing;

using System.Collections;

using System.Windows.Forms;

using System.Data;



namespace gestionPad

{

///

/// Description résumée de Form1.

///

public class Form1 : System.Windows.Forms.Form

{

private System.Windows.Forms.ListBox listBox1;

private System.Windows.Forms.MainMenu mainMenu1;

private System.Windows.Forms.Timer timer1;

private System.Windows.Forms.Timer timer2;

private System.Windows.Forms.ListBox listBox2;

private System.Windows.Forms.Label label1;

private System.Windows.Forms.Label label2;

// Définition des variables

private bool isDoublePressed;

private int indexListBoxTouche;

private int indexListBoxType;

private bool isPressed;



public Form1()

{

//

// Requis pour la prise en charge du Concepteur Windows Forms

//

InitializeComponent();

//


// TODO : ajoutez le code du
constructeur après l'appel à InitializeComponent

//



}

///

/// Nettoyage des ressources utilisées.

///

protected override void Dispose( bool disposing )

{

base.Dispose( disposing );

}



#region Code généré par le Concepteur Windows Form

///

/// Méthode requise pour la prise en charge du concepteur - ne modifiez pas

/// le contenu de cette méthode avec l'éditeur de code.

///

private void InitializeComponent()

{

this.mainMenu1 = new System.Windows.Forms.MainMenu();

this.listBox1 = new System.Windows.Forms.ListBox();

this.timer1 = new System.Windows.Forms.Timer();

this.timer2 = new System.Windows.Forms.Timer();

this.listBox2 = new System.Windows.Forms.ListBox();

this.label1 = new System.Windows.Forms.Label();

this.label2 = new System.Windows.Forms.Label();

//

// listBox1

//

this.listBox1.Location = new System.Drawing.Point(8, 40);

this.listBox1.Size = new System.Drawing.Size(224, 80);

//

// timer1

//

this.timer1.Interval = 500;

this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

//

// timer2

//

this.timer2.Interval = 300;

this.timer2.Tick += new System.EventHandler(this.timer2_Tick);

//

// listBox2

//

this.listBox2.Location = new System.Drawing.Point(8, 160);

this.listBox2.Size = new System.Drawing.Size(224, 80);

//

// label1

//

this.label1.Location = new System.Drawing.Point(8, 8);

this.label1.Size = new System.Drawing.Size(224, 20);

this.label1.Text = "Touche détectée :";

//

// label2

//

this.label2.Location = new System.Drawing.Point(8, 128);

this.label2.Size = new System.Drawing.Size(224, 20);

this.label2.Text = "Type d\'appuis détecté :";

//

// Form1

//

this.ClientSize = new System.Drawing.Size(240, 254);

this.Controls.Add(this.label2);

this.Controls.Add(this.label1);

this.Controls.Add(this.listBox2);

this.Controls.Add(this.listBox1);

this.Menu = this.mainMenu1;

this.Text = "Gestion du Pad";

this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.appuis);


this.KeyUp += new
System.Windows.Forms.KeyEventHandler(this.relachement);



}

#endregion



///

/// Point d'entrée principal de l'application.

///



static void Main()

{

Application.Run(new Form1());

}



private void appuis(object sender, System.Windows.Forms.KeyEventArgs e)

{

#region gestion touches directionnelles

if(isPressed==false)

{


//analyse du
message de windows concernant l'évènement KeyDown

switch(e.KeyCode)

{



case Keys.NumPad8: //pour l'émulateur

case Keys.Up :




listBox1.Items.Insert(this.indexListBoxTouche++,"préssé haut");



this.preTraitement();

break;



case Keys.NumPad2: //pour l'émulateur

case Keys.Down :




listBox1.Items.Insert(this.indexListBoxTouche++,"préssé bas");



this.preTraitement();

break;



case Keys.NumPad4: //pour l'émulateur

case Keys.Left :




listBox1.Items.Insert(this.indexListBoxTouche++,"préssé gauche");



this.preTraitement();

break;



case Keys.NumPad6: //pour l'émulateur

case Keys.Right :




listBox1.Items.Insert(this.indexListBoxTouche++,"préssé droite");



this.preTraitement();

break;

case Keys.Return :




listBox1.Items.Insert(this.indexListBoxTouche++,"préssé centrale");



this.preTraitement();

break;

}

this.updateListBox1();



}

#endregion

}

private void preTraitement()

{

// une touche est pressée

isPressed = true;

// Si le timer1 n'est pas actif, on le lance

if(this.timer1.Enabled==false)

{

timer1.Enabled=true;

}

// Sinon le timers est encore actif donc c'est

// un double appuis (deuxième appuis rapide<500ms)

else

{



listBox2.Items.Insert(this.indexListBoxType++,"double appuis");

// On a un double appuis

this.isDoublePressed=true;

// On met a jour la ListBox2

this.updateListBox2();

}



}





private void relachement(object sender, System.Windows.Forms.KeyEventArgs e)

{

#region gestion touches directionnelles

//analyse du message de windows concernant l'évènement KeyUp

switch(e.KeyCode)

{



case Keys.NumPad8: //pour l'émulateur

case Keys.Up :




listBox1.Items.Insert(this.indexListBoxTouche++,"relaché haut");



// La touche n'est plus pressée



isPressed=false;

break;



case Keys.NumPad2: //pour l'émulateur

case Keys.Down :




listBox1.Items.Insert(this.indexListBoxTouche++,"relaché bas");



isPressed=false;

break;



case Keys.NumPad4: //pour l'émulateur

case Keys.Left :




listBox1.Items.Insert(this.indexListBoxTouche++,"relaché gauche");



isPressed=false;

break;



case Keys.NumPad6: //pour l'émulateur

case Keys.Right :




listBox1.Items.Insert(this.indexListBoxTouche++,"relaché droite");



isPressed=false;

break;

case Keys.Return :




listBox1.Items.Insert(this.indexListBoxTouche++,"relaché centrale");



isPressed=false;

break;

}

// On met à jour la ListBox1

this.updateListBox1();



#endregion

}



private void updateListBox1()

{


//Si la ListBox1 contient plus de
5 objets (capacité max = dépend de la taille que vous donnez)

//On fait descendre la scroll bar sur le dernier objet

if(this.indexListBoxTouche>5)

listBox1.TopIndex++;

}

private void updateListBox2()

{


//Si la ListBox2 contient plus de
5 objets (capacité max = dépend de la taille que vous donnez)

//On fait descendre la scroll bar sur le dernier objet

if(this.indexListBoxType>5)

listBox2.TopIndex++;

}





private void timer1_Tick(object sender, System.EventArgs e)

{

// arrête le timer 1 après 500ms (1 tick)

this.timer1.Enabled=false;

// lance le deuxième timer

if(this.isDoublePressed==false)


//Si ilna s'agit pas d'un double appuis

//On lance le deuxième timer2

this.timer2.Enabled=true;

else

//Sinon on remet la variable à false

//pour pouvoir analyser s'il s'agit

//d'un appuis long ou court

this.isDoublePressed=false;

}



private void timer2_Tick(object sender, System.EventArgs e)

{

//Arrêt du timer2 après son premier tick de 300ms

this.timer2.Enabled=false;

//On détermine suivant l'état de la variable isPressed

//si, à la fin du timer2, la touche est toujour appuyée

//(appuis long) ou si la touche a été relachée (appuis court)

if(isPressed==true)

{



listBox2.Items.Insert(this.indexListBoxType++,"appuis long");

}

else

{



listBox2.Items.Insert(this.indexListBoxType++,"appuis court");

}

// On met à jour la ListBox2

this.updateListBox2();

}

}

}















































































































































































































































































Donc pour ne pas vous
embrouiller avec tout mon code superflux pour mettre à jour les
affichage dans les listbox etc je vous donne mon algorithme simplifié
au max :











Evénement on détecte un message de relâchement de touche


Aucune touche pressée


Fin Evénement




Evénement on détecte un message de pression de touche


Si aucune touche n’est appuyée alors


Une touche est enfoncée


Si le Timer1 n’ est pas lancé


Lancement du timer1 // qui s’arrête au bout de 500ms


Sinon


Détection d’un double appuis


Fin Si


Fin Si


Fin Evénement




Evénement Timer1 arrêté


Si l’on a pas détecté un double appuis


On lance le Timer2 // qui s’arrête au bout de 300ms


Sinon


On ne détecte plus de double appuis


Fin Si


Fin Evénement




Evénement Timer2 arrêté


Si on a encore une touche pressée


Détection d’un appui long


Sinon


Détection d’un appuis court


Fin Si


Fin Evénement






Explication supplémentaires :




En gros la détection se base sur une échelle de temps dont la réaction
du programme s'effectue au maximum à 800ms pour ce qui est de la
détection des appuis court et long et d'un peut moins pour ce qui est
du double appuis (dépend de la vitesse de l'utilisateur).



Le programme détecte un appuis court si l'appui dure moins de 800ms, un
appui long si l'appui dure plus de 800ms et double appuis si l'on
appuie deux fois une touche en moins de 500ms d'intervalle.



Vous vous demanderez peut être pourquoi a chaque touche du pad
directionnel j'ai deux 'case', eh bien tout simplement parce que chez
moi l'émulateur utilise les valeur des touches du pavé numérique alors
qu'un vrai pocket pc utilise la valeur des touche directionnelle
(située entre les touches alphanumériques et numériques). Alors une
bonne lesson : ne vous fiez pas à ce que vous dit l'emulateur car des
fois on est loin de la réalité ... testez aussi sur le vrai pocket. Je
suis resté deux semaines sur un probleme de projet à l'école à cause de ça!!





Voila..Si vous avez des remarques ou simplement me remercier parce sa vous a aider :p ...

Règle du bon codeur:
1) faire compliquer quand on peut faire simple
2) taper sur son PC quand ça ne marche pas
3) profiter de ses erreurs pour les recopiers dans un autre programme
4) je crois qu'avec tout ça j'arriverai un jour
0
comment on fais pour faire tourner et cliquer si il vois un truck particulier ???
0
Rejoignez-nous