2009-07-23 5 views
1

http://www.microsoft.com/windowsxp/using/accessibility/characterrepeatrate.mspx - Il existe une option dans Windows pour le réglage du délai de répétition. Cela signifie le délai entre la première frappe et les autres si l'on continue à appuyer sur la touche. Je crée une sorte de jeu et je dois me débarrasser de cette "fonctionnalité".Comment puis-je me débarrasser du délai de répétition de caractères en C#?

Jusqu'à présent, je suis parvenu à trouver cette méthode:



[DllImport("user32.dll")] 
static extern ushort GetAsyncKeyState(int vKey); 

public static bool IsKeyPushedDown(Keys keyData) 
{ 
    return 0 != (GetAsyncKeyState((int)keyData) & 0x8000); 
} 

Mais la méthode IsKeyPushedDown trouve si la touche est pressée au moment de l'appel de la fonction - donc je besoin d'une boucle pour tester si la clé est éteint. Le problème est que cela n'attrape toujours pas toutes les frappes - j'ai trop lent boucle je suppose.

Deuxième choix est prépondérant de ProcessCmdKey:


protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    // processing keys 
      if (keyData == Keys.Left || keyData == Keys.Right || keyData == Keys.Up || keyData == Keys.Down) 
      { 
       return true; 
      } 
      else 
      { 
       return base.ProcessCmdKey(ref msg, keyData); 
      } 

} 

cela fonctionne vraiment bien, mais elle est affectée avec un retard de répétition et donc le mouvement de mon monstre dans mon jeu est comme:

Y at-il une solution pour mon problème? Merci

EDIT: J'ai résolu le problème en combinant les deux procédures. Mais c'est une solution très laide. J'espère toujours qu'il y a une meilleure solution.

+0

Examinez la solution que j'ai posté. C'est un peu plus élégant que de revenir à un PInvoke et de le pirater avec ProcessCmdKey. –

Répondre

4

Vous devez traiter KeyDown et KeyUp plutôt que ProcessCmdKey si vous voulez un meilleur contrôle sur ce qui se passe entre le moment où une touche est pressée et relâchée.

La chose la plus simple à faire dans votre scénario serait d'avoir un minuteur sur votre formulaire qui déplace le monstre. Activer la minuterie (et définir une sorte de variable ou deltaX et deltaY qui indique comment déplacer le monstre) lorsque KeyDown est tiré, puis arrêter le minuteur lorsque KeyUp est tiré.

Modifier

À titre d'exemple (très barebones)

public class MyForm : Form 
{ 
    private int deltaX; 
    private int deltaY; 

    private const int movementAmount = 10; 

    private Timer movementTimer = new Timer(); 

    public MyForm() 
    { 
     movementTimer.Interval = 100; // make this whatever interval you'd like there to be in between movements 

     movementTimer.Tick += new EventHandler(movementTimer_Tick); 
    } 

    void movementTimer_Tick(object sender, EventArgs e) 
    { 
     myMonster.Location = new Point(myMonster.X + deltaX, myMonster.Y + deltaY); 
    } 

    protected override void OnKeyDown(KeyEventArgs e) 
    { 
     base.OnKeyDown(e); 

     switch (e.KeyCode) 
     { 
      case Keys.Left: 
       { 
        deltaX -=movementAmount; 
       } break; 
      case Keys.Right: 
       { 
        deltaX += movementAmount; 
       } break; 
      case Keys.Up: 
       { 
        deltaY -= movementAmount; 
       } break; 
      case Keys.Down: 
       { 
        deltaY += movementAmount; 
       } break; 
     } 

     UpdateTimer(); 
    } 

    protected override void OnKeyUp(KeyEventArgs e) 
    { 
     base.OnKeyUp(e); 

     switch (e.KeyCode) 
     { 
      case Keys.Left: 
       { 
        deltaX += movementAmount; 
       } break; 
      case Keys.Right: 
       { 
        deltaX -= movementAmount; 
       } break; 
      case Keys.Up: 
       { 
        deltaY += movementAmount; 
       } break; 
      case Keys.Down: 
       { 
        deltaY -= movementAmount; 
       } break; 
     } 

     UpdateTimer(); 
    } 

    private void UpdateTimer() 
    { 
     movementTimer.Enabled = deltaX != 0 || deltaY != 0; 
    } 
} 
+0

En fait, je ne veux pas contrôler ce qui se passe entre le moment où une touche est pressée et relâchée - Je maintiens la touche enfoncée et le résultat est:

+0

Vous souhaitez le contrôler, car vous souhaitez remplacer le comportement Windows par défaut. Vous devez adopter cette approche, car vous vous reposez essentiellement sur la boucle des messages Windows pour faire la même chose pour vous (appels répétés à ProcessCmdKey, plutôt que de répéter plusieurs fois l'événement timer comme je l'ai décrit plus haut). –

+0

Je suis désolé mais je ne vous suis toujours pas. Pourriez-vous s'il vous plaît écrire un exemple comment cela devrait fonctionner? Je vous remercie! –

Questions connexes