Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Как считать одновременное нажатие нескольких клави


Автор: VisualProgrammerNET 12.2.2006, 16:53
Вот у меня такая тема. При нажатии клавиш направления, нарисованный на форме кружочек перемещается в соответствующем направлении на несколько пикселей. А как сделать так, чтобы кружок мог ходить по диагонали? Т.е. при нажатии одновременно двух клавиш.

smile

Автор: andrx 13.2.2006, 15:44
VisualProgrammerNET !
далеко не идеал, но попробуй хотя бы так :

Код

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace move
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.PictureBox pictureBox1;
        private int xx;
        private int yy;


        private System.ComponentModel.Container components = null;

        public Form1()
        {
            InitializeComponent();
            this.xx = 0;
            this.yy = 0;
        }
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.SuspendLayout();
            // pictureBox1
            this.pictureBox1.BackColor = System.Drawing.Color.Blue;
            this.pictureBox1.Location = new System.Drawing.Point(112, 104);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(8, 8);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
            this.ResumeLayout(false);

        }
        #endregion

        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:    { this.yy = -1; break;    }
                case Keys.Down:    { this.yy = 1; break;    }
                case Keys.Left:    { this.xx = -1; break;    }
                case Keys.Right:    { this.xx = 1; break;    }
            }
            this.pictureBox1.Top += this.yy;
            this.pictureBox1.Left += this.xx;
        }
        private void Form1_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            this.xx = 0;
            this.yy = 0;
        }
    }
}

Автор: mr.DUDA 13.2.2006, 16:41
Так не пойдёт, т.к. одновременно обрабатывается только 1 нажатая клавиша. Вроде бы, в WinForms нельзя обработать более чем одну клавишу одновременно.

Автор: Exception 13.2.2006, 16:59
Как вариант - использовать API-функцию GetKeyState вкупе с таймером.

Автор: Ch0bits 13.2.2006, 17:33
Теперь всё работает! smile На основе кода andrx
Код

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace move
{
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.PictureBox pictureBox1;
        private int xx;
        private int yy;
        private System.ComponentModel.Container components = null;
        public Form1()
        {
            InitializeComponent();
            this.xx = 0;
            this.yy = 0;
        }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        private void InitializeComponent()
        {
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.SuspendLayout();
            // pictureBox1
            this.pictureBox1.BackColor = System.Drawing.Color.Blue;
            this.pictureBox1.Location = new System.Drawing.Point(112, 104);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(8, 8);
            this.pictureBox1.TabIndex = 0;
            this.pictureBox1.TabStop = false;
            // Form1
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.pictureBox1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyUp);
            this.ResumeLayout(false);
        }
        #endregion
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        // Максимальный интервал при двойном нажатии, ms
        private const int MaxInterval = 300;

        private DateTime LastPress;
        private Keys LastKey;

        private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            TimeSpan TS = DateTime.Now - LastPress;
            if (TS.TotalMilliseconds <= MaxInterval && LastKey!=e.KeyCode)
            {
                // Обрабатывает двойное нажатие!
                MessageBox.Show("Двойное нажатие обрабатывается тут!");
                return;
            }
            LastKey = e.KeyCode;
            LastPress = DateTime.Now;
            // Классический обработчик
            switch (e.KeyCode)
            {
                case Keys.Up: { this.yy = -1; break; }
                case Keys.Down: { this.yy = 1; break; }
                case Keys.Left: { this.xx = -1; break; }
                case Keys.Right: { this.xx = 1; break; }
            }
            this.pictureBox1.Top += this.yy;
            this.pictureBox1.Left += this.xx;
        }
        private void Form1_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
        {
            this.xx = 0;
            this.yy = 0;
        }
    }
}

Автор: andrx 13.2.2006, 18:41
Цитата(mr.DUDA @ 13.2.2006, 16:41 Найти цитируемый пост)
Так не пойдёт, т.к. одновременно обрабатывается только 1 нажатая клавиша. Вроде бы, в WinForms нельзя обработать более чем одну клавишу одновременно.


mr.DUDA абсолютно и полностью согласен,
я ведь по сути предлагал перевести проблему в другое "русло" !

Ch0bits, повторюсь, что к сожалению, mr.DUDA абсолютно и полностью прав.
Предложенный код оказывается беспомощным если :
1. Нажать и удерживать кнопку вниз
2. Нажать и удерживать кнопку вправо, удерживая при этом кнопку вниз
3. Отпустить кнопку вправо - ВОТ ТУТ И ВСЕ рисунок замрет на месте

Exception предлагает правильный, но более сложный вариант, зато 100%

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)