Остановка клавиш от повторения (C #) - PullRequest
1 голос
/ 12 декабря 2010

В этом приложении мне нужно иметь возможность остановить ответ от нажатия клавиши, чтобы предотвратить попадание ненужных данных в вывод.Проблема, с которой я столкнулся, заключается в том, что использование методов, описанных в моем коде ниже, не позволяет клавишам повторяться, но также не позволяет им реагировать достаточно быстро - пользователи очень быстро нажимают на клавиши.Я не уверен, что это мое оборудование, ограничение API или проблема с моим кодом, но приведенные ниже подпрограммы не просто работают достаточно быстро, чтобы работать без возможности использования программы.Способ определения, активно ли удерживается клавиша (и как долго), также поможет другой функции программы и решит эту текущую проблему.

Есть идеи?

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    e.SuppressKeyPress = isKeyDown;
    isKeyDown = true;
}

private void Form1_KeyUp(object sender, KeyEventArgs e)
{
    isKeyDown = false;
}

private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (!isStreamPlaying) return;
    if (e.KeyChar.Equals('d') || e.KeyChar.Equals('j'))
    {
        //red hit
        SoundPlayer hitSounds = new SoundPlayer(taikoLiveMapper.Properties.Resources.normal_hitnormal);
        hitSounds.Play();
        outputlist.Add(string.Format("320,240,{0},1,{1}", ms, 0));
        lastms = ms;
    }
    else if (e.KeyChar.Equals('s') || e.KeyChar.Equals('k'))
    {
        //blue hit
        SoundPlayer hitSounds = new SoundPlayer(taikoLiveMapper.Properties.Resources.normal_hitclap);
        hitSounds.Play();
        outputlist.Add(string.Format("320,240,{0},1,{1}", ms, 8));
        lastms = ms;
    }
}

Ответы [ 3 ]

3 голосов
/ 12 декабря 2010

Вы можете использовать GetKeyState, чтобы узнать, нажата ли клавиша, и использовать ее для отслеживания клавиш:

    [DllImport("user32.dll")]
    static extern short GetKeyState(int key);

    static bool IsKeyPressed(Keys key)
    {
        short state = GetKeyState((int)key);
        return ((state & 128) != 0);
    }

    int i = 0;

    Dictionary<Keys, DateTime> downSince = new Dictionary<Keys, DateTime>();

    private void UpdateKeyStates()
    {
        foreach (var entry in downSince.ToArray())
        {
            if (!IsKeyPressed(entry.Key))
                downSince.Remove(entry.Key);
        }
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        UpdateKeyStates();
        if (!downSince.ContainsKey(e.KeyCode))
        {
            downSince.Add(e.KeyCode, DateTime.UtcNow);
            i++;

        }
        Text = i.ToString() + " " +(int)(DateTime.UtcNow - downSince[e.KeyCode]).TotalMilliseconds;
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        UpdateKeyStates();
    }

В этом примере подсчитывается i каждый раз при нажатии клавиши, и показано, какдолго он был нажат.Он использует GetKeyState вместо отслеживания KeyDown / KeyUp, так как вы можете пропустить эти сообщения, если что-то еще имеет фокус.

0 голосов
/ 31 января 2014

Согласно документации , «[d] дублирующие события KeyDown происходят каждый раз, когда клавиша повторяется, если удерживать клавишу нажатой, но генерируется только одно событие KeyUp, когда пользователь отпускает ключ».

Поэтому самое простое решение - игнорировать повторяющееся событие KeyDown, если его соответствующее событие KeyUp не было замечено.

Просто сработало для меня.

0 голосов
/ 12 декабря 2010

Вместо этого используйте таймеры: инициализируйте таймеры, по одному для каждого «действия» (например, нажимая d / j или s / k), переместите код красного / синего попадания в таймер и вместо текущего кода имейте:*

if (e.KeyChar.Equals('d') || e.KeyChar.Equals('j'))
{
    //red hit
    if (!tmrRedHit.Enabled)
        tmrRedHit.Enabled = true;
}
else if (e.KeyChar.Equals('s') || e.KeyChar.Equals('k'))
{
    //blue hit
    if (!tmrBlueHit.Enabled)
        tmrBlueHit.Enabled = true;
}

А в таймерах события Elpased также устанавливают для их Enabled значение false после выполнения кода.

...