Cooperative Levels

The cooperative level of a device determines how the input is shared with other applications and with the Windows system. You set it by using the IDirectInputDevice::SetCooperativeLevel method, as in this example:

lpdiDevice->SetCooperativeLevel(hwnd, 
                                DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) 
 

The parameters are the handle of the top-level window associated with the device (generally the application window) and one or more flags. The valid flag combinations are shown in the following table:

Flags Notes
DISCL_NONEXCLUSIVE | DISCL_BACKGROUND The default setting
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND
DISCL_EXCLUSIVE | DISCL_FOREGROUND Not valid for keyboard
DISCL_EXCLUSIVE | DISC_BACKGROUND Not valid for keyboard or mouse

Note  Although DirectInput provides a default setting, you should still explicitly set the cooperative level, because doing so is the only way to give DirectInput the window handle. Without this handle, DirectInput will not be able to react to situations that involve window messages, such as joystick recalibration.

The cooperative level has two components: whether the device is being used in the foreground or the background, and whether it is being used exclusively or nonexclusively . Both these components require some explanation.

Foreground and Background

A foreground cooperative level means that the input device is available only when the application is in the foreground or, in other words, has the input focus. If the application moves to the background, the device is automatically unacquired, or made unavailable.

A background cooperative level really means "foreground and background." A device with a background cooperative level can be acquired and used by an application at any time.

You will usually want to have foreground access only, since most applications are not interested in input that takes place when another program is in the foreground.

While developing an application, it is useful to have a conditional define that sets the background cooperative level during debugging. This will prevent your application from losing access to the device every time it moves to the background as you switch to a debugging window.

Exclusive and Nonexclusive

The fact that your application is using a device at the exclusive level does not mean that other applications cannot get data from the device. However, it does mean that no other application can also acquire the device exclusively.

Why does it matter? Take the example of a music player that accepts input from a hand-held remote-control device, even when the application is running in the background. Now suppose you run a similar application that plays movies, again in response to signals from the remote control. What happens when the user presses Play? Both programs start playing, which is probably not what the user wants. To prevent this from happening, each application should have the DISCL_EXCLUSIVE flag set, so that only one of them can be running at a time.

In order to use force feedback effects, an application must have exclusive access to the device.

Windows itself requires exclusive access to the mouse and keyboard. The reason is that mouse and keyboard events such as a click on an inactive window or alt+tab could force an application to unacquire the device, with potentially harmful results such as a loss of data from the input buffer.

When an application has exclusive access to the mouse, Windows is not allowed any access at all. No mouse messages are generated. A further side effect is that the cursor disappears.

DirectInput does not allow any application to have exclusive access to the keyboard. If it did, Windows would not have access to the keyboard and the user would not even be able to use ctrl+alt+delete to restart the system.