Detecting when the user is pressing the shift key

942 Views Asked by At

Currently I am working on a Piano in Windows Form Application. What I did is when you press a certain key on the keyboard it plays a sound (technically it force a press of button). Now what I want to do is add that when the user is pressing a key as well as pressing the shift key, it will play a longer sound. For example if the A key is pressed it will play sound of the C chord, and if the A is pressed + the shift key is pressed it will play a longer version of the sound. This is the code for the key pressing and an example of one of the sounds playing:

private bool shiftPressed = false;
const int NOTE_LENGTH = 500;

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    switch (keyData)
    {
        case Keys.A://C
            C_Low.BackColor = Color.Gray;
            C_Low.PerformClick();
            break;
        case Keys.S://D
            D_Low.BackColor = Color.Gray;
            D_Low.PerformClick();
            break;
        case Keys.D://E
            E_Low.BackColor = Color.Gray;
            E_Low.PerformClick();
            break;
        case Keys.F://F
            F_Low.BackColor = Color.Gray;
            F_Low.PerformClick();
            break;
        case Keys.G://F
            G_Low.BackColor = Color.Gray;
            G_Low.PerformClick();
            break;
        case Keys.H://A
            A_Low.BackColor = Color.Gray;
            A_Low.PerformClick();
            break;
        case Keys.J://B
            B_Low.BackColor = Color.Gray;
            B_Low.PerformClick();
            break;
        case Keys.W://C#
            C_Diez_Low.BackColor = Color.Gray;
            C_Diez_Low.PerformClick();
            break;
        case Keys.E://D#
            D_Diez_Low.BackColor = Color.Gray;
            D_Diez_Low.PerformClick();
            break;
        case Keys.T://F#
            F_Diez_Low.BackColor = Color.Gray;
            F_Diez_Low.PerformClick();
            break;
        case Keys.Y://G#
            G_Diez_Low.BackColor = Color.Gray;
            G_Diez_Low.PerformClick();
            break;
        case Keys.U://A#
            A_Diez_Low.BackColor = Color.Gray;
            A_Diez_Low.PerformClick();
            break;
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

As example the C_Low_Click_1 event:

private void C_Low_Click_1(object sender, EventArgs e) //Play C low
{
    if (shiftPressed)
    {
        C_Low.BackColor = Color.White;
        if (Low.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Low_Long);
            player.Load();
            player.PlaySync();
        }
        if (Med.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Medium_Long);
            player.Load();
            player.PlaySync();
        }
        if (High.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_High_Long);
            player.Load();
            player.PlaySync();
        }
    }
    else
    {
        C_Low.BackColor = Color.White;
        if (Low.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Low);
            player.Load();
            player.PlaySync();
        }
        if (Med.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_Medium);
            player.Load();
            player.PlaySync();
        }
        if (High.Checked)
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer(Properties.Resources.C_High);
            player.Load();
            player.PlaySync();
        }
    }
}

Any help will be appreciated, and if I did not provide any information please tell me :D

2

There are 2 best solutions below

0
On

You should consider to use the KeyEvents of your form, especially the KeyDown and KeyUp events. Important: to use the event properly, you must set the KeyPreview attribute to true first!

Then use following code within the KeyDown event:

shiftPressed = e.Shift;

and in the KeyUp event:

shiftPressed = false;
// also possible, although I won't recommend using the code below,
// as there could be some incorrect handling if shift is pressed
// shiftPressed = e.Shift;
0
On

Keys is a flags enum, so you would test for the shift key using:

var shiftPressed = keyData.HasFlag(Keys.Shift);

When shift is pressed your switch statement won't work (as the value isn't Keys.A, for example, it's Keys.Shift|Keys.A). You can remove the shift first so your switch statement will work:

var keyWithoutShift = keyData & ~Keys.Shift;

switch (keyWithoutShift) 
{ 
    // handle keys as normal
}