InterestGroupDirectx/CnetTutorials/DirectInput9/ImmediateFeedbackKeyboard

Written by ThomasWard

This tutorial shows you the basic startup tasks to use the keyboard

using DirectInput version 9 and C#.net. It assumes the following:

If you do not have the DirectX 9 SDK installed on your computer, prior to trying this source code, please download [WWW] The DirectX 9 SDK and install it.

Ok, lets get started. Open up Visual Studio 2003 and start a new C#.net windows application project and name it KeyboardTest.

Once the project appears, you'll see that it has Form1.cs in the solution explorer. We'll be using this form to put all of our code in. Now you have to set a reference to microsoft.DirectX and Microsoft.DirectX.DirectInput prior to programming anything. You do this by going to the project menu, alt+p, then go to add reference... and press enter or press the letter r.

When the new screen appears, in the list of components, down arrow until you get to Microsoft.DirectX. Once on it, press alt+e to activate the select button. It will be added to the list of "selected references". Continue to down arrow until you arive at Microsoft.DirectX.DirectInput. Once on it, press alt+e to activate the select button. Now you have added both references to the "selected components" list. Finally, just tab to the ok button and press enter. Now you have set a reference to Microsoft.DirectX and Microsoft.DirectX.DirectInput. You can now begin to program the keyboard test application.

Your project has form1.cs already added to it. Open up the code editor for form1.cs and add these using statements to the top of form1 above the line namespace KeyboardTest:

using Microsoft.DirectX;
using Microsoft.DirectX.DirectInput;

Now in the form1 class, just under the text "#Region Windows Form Designer generated code" add these variables...

// used for keyboard

private Device kbd = null;

    // used for loop to test for keystrokes
    // in the method TestForKeyPress

private bool blnRunning = false;

    // used to test if we have control of the keyboard
    // or if another application has stolen it from us
    // in the method IsKeyboardAquired 

private bool blnKeyboardAquired = false;

    // used to tell what key we have pressed in the method
 // TestForKeyPress 

private KeyboardState kbdState = null;
   

Now in the InitializeKeyboard method, we are going to setup the keyboard. Here is the code with comments:

                // Initialize Keyboard device
                public void InitializeKeyboard()
                {

                        try
                        {
                                // Create keyboard device
                                kbd = new Device(SystemGuid.Keyboard);

                                // Set the device cooperative level
                                // We will set cooperative level to non-exclusive so
// that other apps can share the keyboard
                
kbd.SetCooperativeLevel(this,CooperativeLevelFlags.Background | CooperativeLevelFlags.NonExclusive);

                                // Aquire the keyboard
                                kbd.Acquire();

// Set this flag so our
                                // loop knows we have the keyboard
                                blnKeyboardAquired = true;

// set this flag so
// our loop can run
blnRunning = true;

// Start our loop
TestForKeyPres();
                        }
                        catch(InputException)
                        {
                                // Display failior message
                                MessageBox.Show("Unable to create keyboard.");

                                // Close down the application.
                                Close();
                        }
                }

A couple of things you'll notice here in the InitializeKeyboard method. We set the keyboards cooperative level to background or nonexclusive. There are other flags you can use to setup the keyboard such as forground and exclusive. All these flags do is tell DirectInput how the keyboard should react to other applications trying to get access to the keyboard or when your application loses focus.

If we try to gain access to the keyboard and get an error, we jump to the catch branch and shut down and exit the application. If we do gain access, we set a boolean variable blnKeyboardAquired to true letting our code know we have access to the keyboard. That is important to know in your source code since you could lose access to the keyboard and if you do, and then try to process keystrokes, you'll get an error. So, in your code, you have to always test to make certain you still have control of the keyboard. I have a method to do this I'll show you in a bit but first, the line

TestForKeyPress(); 

in the InitializeKeyboard method calls a public method in our class that enters an infinite loop and tests for specific keystrokes. I know, infinite loops are normally bad but all games use them as the main loop for any game believe it or not. So, prior to calling our method TestForKeyPress to actually test for keys being pressed, we set a boolean variable blnRunning to true. While that is true, we will always be looping and monitoring for exact key presses in our public method TestForKeyPress. Here is that method. Copy it and place it below the InitializeKeyboard method.

// ***
    // Method name: TestForKeyPress
    // Description: tests for various keys that are pressed on the keyboard
    // Parameters: none
    // returns: none
    // ***

                public void TestForKeyPres()
                {

                        while(blnRunning == true)
                        {

                                // Make certain the app does not lock up
                                // in this loop
                                Application.DoEvents();

                                // Check to see if we have the keyboard
                                // and capture input
                                if(IsKeyboardAquired() == true)
                                {

                                        // What is the state of the 
keyboard
                                        // We will poll the keyboard
                                        // and find out what keys are 
down
                                        kbdState = kbd.GetCurrentKeyboardState();

                                        // Is the control key down
                                        if(kbdState[Key.LeftControl] ||
                                        kbdState[Key.RightControl]
                                        {
                                                

MessageBox.Show("Control was pressed!");
                                        }

                                        // Are we pressing A
                                        if(kbdState[Key.A])
                                        {
                                                MessageBox.Show("The A key was pressed!");
                                        }

                                        // Are we pressing escape
                                        if(kbdState[Key.Escape])
                                        {

                                                // kill the loop
                                                blnRunning = false;

                                                // Close app
                                                Close();
                                        }
                                }
                        }
                }

Notice the line  while(blnRunning == true).  That gets us into our infinite loop and we test for various keystrokes in the code. If we hit one we are looking for, we show a message box on the screen. If we hit escape, we set that boolean to false to exit the loop and then end the application. Note, some screen readers you have to let keys pass through for this to work. I.E for JFW, you have to hit insert+3 to pass a key through and then hit escape to get it to work. I.E for Window Eyes you have to press insert+b and then escape to get it to work.Screen readers interfere with DirectInput while using the keyboard.

Finally, we need a method to call in the infinite loop to always check if we still have control of the keyboard. That line of code is like this in the loop:

if(IsKeyboardAquired() == true);

and that line calls our method name IsKeyboardAquired to see if we still have control of the keyboard. that method looks like this, copy it to the clipboard and then paste it directly after our method TestForKeyPress.

// ***
    // Function name: IsKeyboardAquired
    // Description: tests to see if our application still has control
    //  of the keyboard
    // Parameters: none
    // Returns: true if our application has control of the keyboard
    // false if it does not have control of it any more
    // ***

                public bool IsKeyboardAquired()
                {

                        // If keyboard aquired is false
                        // try to get it back
                        if(blnKeyboardAquired == false)
                        {
        
                                try
                                {
                                        // Lost keyboard
                                        // and try to get it back

                                        kbd.Acquire();
                                        blnKeyboardAquired = true;
                                }
                                catch(InputException)
                                {
                                        // Still no luck
                                        blnKeyboardAquired = false;
                                }
                        }

                        // Return state
                        return blnKeyboardAquired;
                }

So you see that blnKeyboardAquired is set to true if we can gain access to it in this method and then set to false if we cannot. Then in the infinite loop in the method TestForKeyPress, we test this blnKeyboardAquired variable prior to trying to test for keystrokes. If it is true, this means we have access to the keyboard and can test for keystrokes. If it is false, we skip processing keys until we gain access to the keyboard once again.

At this point, there is one more thing we must do to complete this application. We must update the main method to load our InitializeKeyboard Method. You can update Main like this:

static void Main() 
                {
                        using(Form1 form = new Form1())
                        {

                                // Initialize the keyboard
                                form.InitializeKeyboard();

// Start the application.
                                Application.Run(form);
                        }
                }
                

last edited 2005-03-28 15:30:52 by JustinDaubenmire