Acquiring Devices

Acquiring a DirectInput device means giving your application access to it. As long as a device is acquired, DirectInput is making its data available to your application. If the device is not acquired, you may manipulate its characteristics but not obtain any data.

Acquisition is not permanent; your application may acquire and unacquire a device many times.

In certain cases, depending on the cooperative level, a device may be unacquired automatically whenever your application moves to the background. The mouse is automatically unacquired when the user clicks on a menu, because at this point Windows takes over the device.

You need to unacquire a device before changing its properties. The only exception is that you may change the gain for a force feedback device while it is in an acquired state.

Why is the acquisition mechanism needed? There are two main reasons.

First, DirectInput has to be able to tell the application when the flow of data from the device has been interrupted by the system. For instance, if the user has switched to another application with ALT+TAB, and used the input device in that application, your application needs to know that the input no longer belongs to it and that the state of the buffers may have changed. Or consider an application with the DISCL_FOREGROUND cooperative level. The user presses the SHIFT key, and while continuing to press it switches to another application. Then the user releases the key and switches back to the first application. As far as the first application is concerned, the SHIFT key is still down. The acquisition mechanism, by telling the application that input was lost, allows it to recover from these conditions.

Second, because your application can alter the properties of the device, without safeguards DirectInput would have to check the properties each time you wanted to get data with the IDirectInputDevice::GetDeviceState or IDirectInputDevice::GetDeviceData methods. Obviously this would be very inefficient. Even worse, potentially disastrous things could happen like a hardware interrupt accessing a data buffer just as you were changing the buffer size. So DirectInput requires your application to unacquire the device before changing properties. When you reacquire it, DirectInput looks at the properties and decides on the optimal way of transferring data from the device to the application. This is done only once, thereby making GetDeviceState and GetDeviceData very fast.

Since the most common cause of losing a device is that your application moves to the background, you may want to reacquire devices whenever your application is activated. However, this mechanism is not going to cover all cases where a device is unacquired, especially for devices other than the standard mouse or keyboard. Because your application may unacquire a device unexpectedly, you need to have a mechanism for checking the acquisition state before attempting to get data from the device. The Scrawl sample application does this in the Scrawl_OnMouseInput function, where a DIERR_INPUTLOST error triggers a message to reacquire the mouse. (See also Tutorial 2: Using the Mouse.)

There's no harm in attempting to reacquire a device that is already acquired. Redundant calls to IDirectInputDevice::Acquire are ignored, and the device can always be unacquired with a single call to IDirectInputDevice::Unacquire.

Remember, Windows doesn't have access to the mouse when your application is using it in exclusive mode. If you want to let Windows have the mouse, you must let it go. There's an example in Scrawl, which responds to a click of the right button by unacquiring the mouse, putting the Windows cursor in the same spot as its own, popping up a context menu, and letting Windows handle the input until a menu choice is made.