Step 6: Retrieving Data from the Keyboard

After a device is acquired, your application can start retrieving data from it. The simplest way to do this is to call the IDirectInputDevice8::GetDeviceState method, which takes a snapshot of the device's state at the time of the call.

The IDirectInputDevice8::GetDeviceState method accepts two parameters: the size of a buffer to be filled with device state data, and a pointer to that buffer. For keyboards, always declare a buffer of 256 unsigned bytes.

The following sample attempts to retrieve the state of the keyboard. If this fails, it calls an application-defined sample function to deallocate existing DirectInput objects, if any. For more information, see Tutorial 1 Samples.

After retrieving the keyboard's current state, your application can respond to specific keys that were pressed down at the time of the call. Each element in the buffer represents a key. If an element's high bit is 1, the key was down at the moment of the call; otherwise, the key was up. To check the state of a given key, use the DirectInput Keyboard Device to index the buffer for a given key.

The following skeleton function, called from the main loop of a hypothetical spaceship game, uses the IDirectInputDevice8::GetDeviceState method to poll the keyboard. It then checks to see if the LEFT ARROW, RIGHT ARROW, UP ARROW or DOWN ARROW keys were pressed when the device state was retrieved. This is accomplished with the KEYDOWN macro defined in the body of the function. The macro accepts a buffer's variable name and an index value, and then checks the byte at the specified index to see if the high bit is set and returns TRUE if it is.

void WINAPI ProcessKBInput() 
{ 
    #define KEYDOWN(name, key) (name[key] & 0x80) 

    char     buffer[256]; 
    HRESULT  hr; 
    hr = g_lpDIDevice->GetDeviceState(sizeof(buffer),(LPVOID)&buffer); 
    if FAILED(hr) 
    { 
        // If it failed, the device has probably been lost. 
        // Check for (hr == DIERR_INPUTLOST) 
        // and attempt to reacquire it here. 
        return; 
    } 

    // Turn the spaceship right or left 
    if (KEYDOWN(buffer, DIK_RIGHT)); 
        // Turn right. 
    else if(KEYDOWN(buffer, DIK_LEFT)); 
        // Turn left. 

    // Thrust or stop the spaceship 
    if (KEYDOWN(buffer, DIK_UP)) ; 
        // Move the spaceship forward. 
    else if (KEYDOWN(buffer, DIK_DOWN)); 
        // Stop the spaceship. 
}

Now that your application can retrieve data from the keyboard, go to Step 7: Closing Down the DirectInput System.