青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當(dāng)自強(qiáng)而不息

使用DirectInput進(jìn)行交互(2)

 

本篇是 使用DirectInput進(jìn)行交互(1)的續(xù)篇。



設(shè)置數(shù)據(jù)格式

每種設(shè)備都有一種用于讀取數(shù)據(jù)的特定數(shù)據(jù)格式,需要考慮的東西也很多,包括鍵、鼠標(biāo)按鍵、軸等。因此要使程序從設(shè)備讀取數(shù)據(jù),首先必須告訴 DirectInput讀取這種數(shù)據(jù)所采用的格式。通過 IDirectInputDevice8::SetDataFormat函數(shù)即可滿足上述要求。

Sets the data format for the DirectInput device.

HRESULT SetDataFormat(
LPCDIDATAFORMAT lpdf
);

Parameters

lpdf
Address of a structure that describes the format of the data that the DirectInputDevice should return. An application can define its own DIDATAFORMAT structure or use one of the following predefined global variables:
  • c_dfDIKeyboard
  • c_dfDIMouse
  • c_dfDIMouse2
  • c_dfDIJoystick
  • c_dfDIJoystick2

Return Values

If the method succeeds, the return value is DI_OK. If the method fails, the return value can be one of the following error values: DIERR_ACQUIRED, DIERR_INVALIDPARAM, DIERR_NOTINITIALIZED.

Remarks

The data format must be set before the device can be acquired by using the IDirectInputDevice8 Interface method. It is necessary to set the data format only once. The data format cannot be changed while the device is acquired.

If the application is using action mapping, the data format is set instead by the call to IDirectInputDevice8::SetActionMap.


SetDataFormat函數(shù)只有一個參數(shù),這個參數(shù)是一個指向DIDATAFORMAT結(jié)構(gòu)體的指針,此結(jié)構(gòu)體的定義如下:

Describes a device's data format. This structure is used with the IDirectInputDevice8::SetDataFormat method.

typedef struct DIDATAFORMAT {
DWORD dwSize;
DWORD dwObjSize;
DWORD dwFlags;
DWORD dwDataSize;
DWORD dwNumObjs;
LPDIOBJECTDATAFORMAT rgodf;
} DIDATAFORMAT, *LPDIDATAFORMAT;

Members

dwSize
Size of this structure, in bytes.
dwObjSize
Size of the DIOBJECTDATAFORMAT structure, in bytes.
dwFlags
Flags describing other attributes of the data format. This value can be one of the following:
DIDF_ABSAXIS
The axes are in absolute mode. Setting this flag in the data format is equivalent to manually setting the axis mode property, using the IDirectInputDevice8::SetProperty method. This cannot be combined with DIDF_RELAXIS flag.
DIDF_RELAXIS
The axes are in relative mode. Setting this flag in the data format is equivalent to manually setting the axis mode property using the IDirectInputDevice8::SetProperty method. This cannot be combined with the DIDF_ABSAXIS flag.
dwDataSize
Size of a data packet returned by the device, in bytes. This value must be a multiple of 4 and must exceed the largest offset value for an object's data within the data packet.
dwNumObjs
Number of objects in the rgodf array.
rgodf
Address to an array of DIOBJECTDATAFORMAT structures. Each structure describes how one object's data should be reported in the device data. Typical errors include placing two pieces of information in the same location and placing one piece of information in more than one location.

Remarks

Applications do not typically need to create a DIDATAFORMAT structure. An application can use one of the predefined global data format variables, c_dfDIMouse, c_dfDIMouse2, c_dfDIKeyboard, c_dfDIJoystick, or c_dfDIJoystick2.

Applications that need to create a DIDATAFORMAT structure must first call IDirectInputDevice8::EnumObjects to determine the available objects for the current device. This is because the IDirectInputDevice8::SetDataFormat method will return DIERR_INVALIDPARAM if an an object is described in the DIDATAFORMAT structure but does not exist on the current device.

The following code example sets a data format for a device that has an X-axis and a Y-axis:

// Suppose an application uses the following 
// structure to read device data. 
    
typedef 
struct MYDATA { 
    LONG  lX;                   
// X-axis goes here. 
    LONG  lY;                   // Y-axis goes here. 
    BYTE  bButtonA;             // One button goes here. 
    BYTE  bButtonB;             // Another button goes here. 
    BYTE  bPadding[2];          // Must be DWORD multiple in size. 
} MYDATA; 
    
// Then, it can use the following data format. 
    
DIOBJECTDATAFORMAT rgodf[ ] = { 
  { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX),
    DIDFT_AXIS | DIDFT_ANYINSTANCE, 0, }, 
  { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), 
    DIDFT_AXIS | DIDFT_ANYINSTANCE, 0, }, 
  { &GUID_Button, FIELD_OFFSET(MYDATA, bButtonA),
    DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, }, 
  { &GUID_Button, FIELD_OFFSET(MYDATA, bButtonB), 
    DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0, }, 
}; 
#define numObjects (sizeof(rgodf) / sizeof(rgodf[0])) 
    
DIDATAFORMAT df = { 
    
sizeof(DIDATAFORMAT),       // Size of this structure 
    sizeof(DIOBJECTDATAFORMAT), // Size of object data format 
    DIDF_ABSAXIS,               // Absolute axis coordinates 
    sizeof(MYDATA),             // Size of device data 
    numObjects,                 // Number of objects 
    rgodf,                      // And here they are 
}; 
 

結(jié)構(gòu)體中的rgodf是一個指向DIOBJECTDATAFORMAT結(jié)構(gòu)體的指針,其定義如下:

Describes a device object's data format for use with the IDirectInputDevice8::SetDataFormat method.

typedef struct DIOBJECTDATAFORMAT {
CONST GUID * pguid;
DWORD dwOfs;
DWORD dwType;
DWORD dwFlags;
} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT;

Members

pguid
Unique identifier for the axis, button, or other input source. When requesting a data format, making this member NULL indicates that any type of object is permissible.
dwOfs
Offset within the data packet where the data for the input source is stored. This value must be a multiple of 4 for DWORD size data, such as axes. It can be byte-aligned for buttons.
dwType
Device type that describes the object. It is a combination of the following flags describing the object type (axis, button, and so forth) and containing the object-instance number in the middle 16 bits. When requesting a data format, the instance portion must be set to DIDFT_ANYINSTANCE to indicate that any instance is permissible, or to DIDFT_MAKEINSTANCE(n) to restrict the request to instance n. See the examples under Remarks.
DIDFT_ABSAXIS
The object selected by the IDirectInputDevice8::SetDataFormat method must be an absolute axis.
DIDFT_AXIS
The object selected by the IDirectInputDevice8::SetDataFormat method must be an absolute or relative axis.
DIDFT_BUTTON
The object selected by the IDirectInputDevice8::SetDataFormat method must be a push button or a toggle button.
DIDFT_FFACTUATOR
The object selected by the IDirectInputDevice8::SetDataFormat method must contain a force-feedback actuator; in other words, it must be possible to apply forces to the object.
DIDFT_FFEFFECTTRIGGER
The object selected by the IDirectInputDevice8::SetDataFormat method must be a valid force-feedback effect trigger.
DIDFT_POV
The object selected by the IDirectInputDevice8::SetDataFormat method must be a point-of-view controller.
DIDFT_PSHBUTTON
The object selected by the IDirectInputDevice8::SetDataFormat method must be a push button.
DIDFT_RELAXIS
The object selected by IDirectInputDevice8::SetDataFormat must be a relative axis.
DIDFT_TGLBUTTON
The object selected by IDirectInputDevice8::SetDataFormat must be a toggle button.
DIDFT_VENDORDEFINED
The object selected by IDirectInputDevice8::SetDataFormat must be of a type defined by the manufacturer.
dwFlags
Zero or more of the following values:
DIDOI_ASPECTACCEL
The object selected by IDirectInputDevice8::SetDataFormat must report acceleration information.
DIDOI_ASPECTFORCE
The object selected by IDirectInputDevice8::SetDataFormat must report force information.
DIDOI_ASPECTPOSITION
The object selected by IDirectInputDevice8::SetDataFormat must report position information.
DIDOI_ASPECTVELOCITY
The object selected by IDirectInputDevice8::SetDataFormat must report velocity information.

Remarks

A data format is made up of several DIOBJECTDATAFORMAT structures, one for each object (axis, button, and so on). An array of these structures is contained in the DIDATAFORMAT structure that is passed to IDirectInputDevice8::SetDataFormat. An application typically does not need to create an array of DIOBJECTDATAFORMAT structures; rather, it can use one of the predefined data formats, c_dfDIMouse, c_dfDIMouse2, c_dfDIKeyboard, c_dfDIJoystick, or c_dfDIJoystick2, which have predefined settings for DIOBJECTDATAFORMAT.

The following object data format specifies that DirectInput should choose the first available axis and report its value in the DWORD at offset 4 in the device data.

DIOBJECTDATAFORMAT dfAnyAxis = { 
    0,                              
// Wildcard 
    4,                              // Offset 
    DIDFT_AXIS | DIDFT_ANYINSTANCE, // Any axis is okay. 
    0,                              // Ignore aspect 
}; 
 

The following object data format specifies that the x-axis of the device should be stored in the DWORD at offset 12 in the device data. If the device has more than one x-axis, the first available one should be selected.

DIOBJECTDATAFORMAT dfAnyXAxis = { 
    &GUID_XAxis,                    
// Must be an x-axis 
    12,                             // Offset 
    DIDFT_AXIS | DIDFT_ANYINSTANCE, // Any x-axis is okay. 
    0,                              // Ignore aspect 
}; 
 

The following object data format specifies that DirectInput should choose the first available button and report its value in the high bit of the byte at offset 16 in the device data.

DIOBJECTDATAFORMAT dfAnyButton = { 
    0,                                
// Wildcard 
    16,                               // Offset 
    DIDFT_BUTTON | DIDFT_ANYINSTANCE, // Any button is okay. 
    0,                                // Ignore aspect 
}; 
 

The following object data format specifies that button 0 of the device should be reported as the high bit of the byte stored at offset 18 in the device data.

If the device does not have a button 0, the attempt to set this data format fails.

DIOBJECTDATAFORMAT dfButton0 = { 
    0,                                    
// Wildcard 
    18,                                   // Offset 
    DIDFT_BUTTON | DIDFT_MAKEINSTANCE(0), // Button zero 
    0,                                    // Ignore aspect 
}; 
 

來看看宏DIOBJECTDATAFORMAT的定義:

The DIDFT_MAKEINSTANCE macro creates an instance identifier of a device object for packing in the dwType member of the DIOBJECTDATAFORMAT structure.

#define DIDFT_MAKEINSTANCE(n) ((WORD)(n) << 8)

Parameters

n
Type is WORD. Instance of the object; for example, 1 for button 1 of a mouse.



設(shè)置協(xié)作級別

首先必須面對一個事實(shí),那就是每個程序都會使用許多輸入設(shè)備。幾乎每個程序都會使用鍵盤和鼠標(biāo),同時某些程序還會使用游戲桿。在處理的時候,必須同其他可能仍在運(yùn)行的應(yīng)用程序共享對這些設(shè)備的訪問,或者應(yīng)用程序獨(dú)占對設(shè)備的所有訪問,這樣除非該應(yīng)用程序結(jié)束了對設(shè)備的訪問,否則就不允許其他應(yīng)用程序控制這些設(shè)備。

設(shè)置協(xié)作級別的函數(shù)是IDirectInputDevice8::SetCooperativeLevel。

Establishes the cooperative level for this instance of the device. The cooperative level determines how this instance of the device interacts with other instances of the device and the rest of the system.

HRESULT SetCooperativeLevel(
HWND hwnd,
DWORD dwFlags
);

Parameters

hwnd
Window handle to be associated with the device. This parameter must be a valid top-level window handle that belongs to the process. The window associated with the device must not be destroyed while it is still active in a DirectInput device.
dwFlags
Flags that describe the cooperative level associated with the device. The following flags are defined:
DISCL_BACKGROUND
The application requires background access. If background access is granted, the device can be acquired at any time, even when the associated window is not the active window.
DISCL_EXCLUSIVE
The application requires exclusive access. If exclusive access is granted, no other instance of the device can obtain exclusive access to the device while it is acquired. However, nonexclusive access to the device is always permitted, even if another application has obtained exclusive access. An application that acquires the mouse or keyboard device in exclusive mode should always unacquire the devices when it receives WM_ENTERSIZEMOVE and WM_ENTERMENULOOP messages. Otherwise, the user cannot manipulate the menu or move and resize the window.
DISCL_FOREGROUND
The application requires foreground access. If foreground access is granted, the device is automatically unacquired when the associated window moves to the background.
DISCL_NONEXCLUSIVE
The application requires nonexclusive access. Access to the device does not interfere with other applications that are accessing the same device.
DISCL_NOWINKEY
Disable the Windows logo key. Setting this flag ensures that the user cannot inadvertently break out of the application. Note, however, that DISCL_NOWINKEY has no effect when the default action mapping user interface (UI) is displayed, and the Windows logo key will operate normally as long as that UI is present.

Return Values

If the method succeeds, the return value is DI_OK. If the method fails, the return value can be one of the following error values: DIERR_INVALIDPARAM, DIERR_NOTINITIALIZED, E_HANDLE.

Remarks

Applications must specify either DISCL_FOREGROUND or DISCL_BACKGROUND; it is an error to specify both or neither. Similarly, applications must specify either DISCL_EXCLUSIVE or DISCL_NONEXCLUSIVE.

If the system mouse is acquired in exclusive mode, the pointer is removed from the screen until the device is unacquired. This applies only to a mouse created by passing GUID_SysMouse to IDirectInput8::CreateDevice.

Applications that select the background exclusive mode cooperative level are not guaranteed to retain access to the device if another application requests exclusive access. When a background exclusive mode application loses access, calls to DirectInput device methods will fail and return DIERR_NOTACQUIRED. The application can regain access to the device by manually unacquiring the device and reaquiring it.

Applications must call this method before acquiring the device by using the IDirectInputDevice8 Interface method.


設(shè)置特殊屬性

設(shè)置設(shè)備的特殊屬性,包括軸模式(axis mode),緩沖區(qū)(buffering)以及最大最小范圍。

對于軸模式,有兩個選擇:相對和絕對。絕對模式基于一個中心坐標(biāo)來報告坐標(biāo)。位于這個點(diǎn)左邊或上面的值都報告成負(fù)值,同時位于這個點(diǎn)右邊或下面的值都報告成正值。相對坐標(biāo)就是當(dāng)前位置同上一個位置之間的距離差。

至于緩沖區(qū),可以設(shè)置緩沖到數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)量。這樣就可以隨意讀取設(shè)備的數(shù)據(jù)而無需擔(dān)心會遺漏數(shù)據(jù)。當(dāng)情況比較簡單的時候,使用緩沖區(qū)的數(shù)據(jù)對游戲開發(fā)而言就沒有多大必要了。

最后一個特殊性屬性是設(shè)備的最小和最大范圍設(shè)置。舉例來說,將游戲桿推動到最左邊就會產(chǎn)生最小值,而推動到最右邊就會產(chǎn)生最大值。這兩邊產(chǎn)生何種值取決于具體的設(shè)置,只有游戲桿才會涉及到最小和最大范圍設(shè)置。

用于設(shè)置特殊屬性的函數(shù)是 IDirectInputDevice8::SetProperty。

Sets properties that define the device behavior. These properties include input buffer size and axis mode.

HRESULT SetProperty(
REFGUID rguidProp,
LPCDIPROPHEADER pdiph
);

Parameters

rguidProp
Reference to (C++) or address of (C) the globally unique identifier (GUID) identifying the property to be set. This can be one of the predefined values, or a pointer to a GUID that identifies the property. The following property values are predefined for an input device:
DIPROP_APPDATA
Sets the application-defined value associated with an in-game action, as a DIPROPPOINTER.
DIPROP_AUTOCENTER
Specifies whether device objects are self centering. This setting applies to the entire device, rather than to any particular object, so the dwHow member of the associated DIPROPDWORD structure must be DIPH_DEVICE.

The dwData member can be one of the following values.

DIPROPAUTOCENTER_OFF: The device should not automatically center when the user releases the device. An application that uses force feedback should disable autocentering before playing effects.

DIPROPAUTOCENTER_ON: The device should automatically center when the user releases the device.

Not all devices support the autocenter property.

DIPROP_AXISMODE
Sets the axis mode. The value being set (DIPROPAXISMODE_ABS or DIPROPAXISMODE_REL) must be specified in the dwData member of the associated DIPROPDWORD structure. See the description of the pdiph parameter for more information. This setting applies to the entire device, so the dwHow member of the associated DIPROPDWORD structure must be set to DIPH_DEVICE.
DIPROP_BUFFERSIZE
Sets the input buffer size. The value being set must be specified in the dwData member of the associated DIPROPDWORD structure. See Remarks. This setting applies to the entire device, so the dwHow member of the associated DIPROPDWORD structure must be set to DIPH_DEVICE.
DIPROP_CALIBRATION
Predefined property that allows the application to access the information that DirectInput uses to manipulate axes that require calibration. This property exists primarily for applications of the control panel type. Normal applications should not need to deal with calibration information.

You can access the calibration mode property for an axis by setting the dwHow member of the DIPROPHEADER structure to DIPH_BYID or to DIPH_BYOFFSET and setting the dwObj member to the object ID or offset, respectively.

Control panel applications that set new calibration data must also invoke the IDirectInputJoyConfig::SendNotify method to notify other applications of the change in calibration. For more information about IDirectInputJoyConfig::SendNotify, see the DirectX Driver Development Kit (DDK).

DIPROP_CALIBRATIONMODE
Enables the application to specify whether DirectInput should retrieve calibrated or uncalibrated data from an axis. By default, DirectInput retrieves calibrated data.

Setting the calibration mode for the entire device is equivalent to setting it for each axis individually.

The dwData member of the DIPROPDWORD structure can be one of the following values:

DIPROPCALIBRATIONMODE_COOKED: DirectInput should return data after applying calibration information. This is the default mode.

DIPROPCALIBRATIONMODE_RAW: DirectInput should return raw, uncalibrated data. This mode is typically used only by applications of the control panel type. Note that raw data might include negative values.

Setting a device into raw mode causes the dead zone, saturation, and range settings to be ignored.

DIPROP_CPOINTS
This property is unsupported. Sets calibration points used for the adjustment of incoming raw data. The values being set must be specified as CPOINT types in the cp array of the associated DIPROPCPOINTS structure. This setting applies to individual device objects, so the dwHow member of the associated DIPROPHEADER structure must be set to either DIPH_BYID or DIPH_BYOFFSET.
DIPROP_DEADZONE
Sets the value for the dead zone of a joystick, in the range from 0 through 10,000, where 0 indicates that there is no dead zone, 5,000 indicates that the dead zone extends over 50 percent of the physical range of the axis on both sides of center, and 10,000 indicates that the entire physical range of the axis is dead. When the axis is within the dead zone, it is reported as being at the center of its range. This setting can be applied to either the entire device or to a specific axis.
DIPROP_FFGAIN
Sets the gain for the device. This setting applies to the entire device, rather than to any particular object, so the dwHow member of the associated DIPROPDWORD structure must be DIPH_DEVICE.

The dwData member contains a gain value that is applied to all effects created on the device. The value is an integer in the range from 0 through 10,000, specifying the amount by which effect magnitudes should be scaled for the device. For example, a value of 10,000 indicates that all effect magnitudes are to be taken at face value. A value of 9,000 indicates that all effect magnitudes are to be reduced to 90 percent of their nominal magnitudes.

DirectInput always checks the gain value before setting the gain property. If the gain is outside of the range (less than zero or greater than 10,000), IDirectInputDevice8::SetProperty will return DIERR_INVALIDPARAM. Otherwise, if successful, it will return DI_OK, even if the device does not support force feedback.

Setting a gain value is useful when an application wants to scale down the strength of all force-feedback effects uniformly, based on user preferences.

Unlike other properties, the gain can be set when the device is in an acquired state.

DIPROP_INSTANCENAME
This property exists for advanced applications that want to change the friendly instance name of a device (as returned in the tszInstanceName member of the DIDEVICEINSTANCE structure) to distinguish it from similar devices that are plugged in simultaneously. Most applications should have no need to change the friendly name.

This setting applies to the entire device, so the dwHow member of the associated DIPROPDWORD structure must be set to DIPH_DEVICE.

The pdiph parameter must be a pointer to the diph member of a DIPROPSTRING structure.

DIPROP_PRODUCTNAME
This property exists for advanced applications that want to change the friendly product name of a device (as returned in the tszProductName member of the DIDEVICEINSTANCE structure) to distinguish it from similar devices which are plugged in simultaneously. Most applications should have no need to change the friendly name.

This setting applies to the entire device, so the dwHow member of the associated DIPROPDWORD structure must be set to DIPH_DEVICE.

The pdiph parameter must be a pointer to the diph member of a DIPROPSTRING structure.

Setting the product name is only useful for changing the user-defined name of an analog joystick on Microsoft Windows 98, Windows 2000, and Windows Millennium Edition (Windows Me) computers. In other cases, attempting to set this property will still return DI_OK. However, the name is not stored in a location used by IDirectInputDevice8::GetProperty.

DIPROP_RANGE
Sets the range of values an object can possibly report. The minimum and maximum values are taken from the lmin and lmax members of the associated DIPROPRANGE structure.

For some devices, this is a read-only property.

You cannot set a reverse range; lmax must be greater than lmin.

DIPROP_SATURATION
Sets the value for the saturation zones of a joystick, in the range from 0 through 10,000. The saturation level is the point at which the axis is considered to be at its most extreme position. For example, if the saturation level is set to 9,500, the axis reaches the extreme of its range when it has moved 95 percent of the physical distance from its center position (or from the dead zone). This setting can be applied to either the entire device or a specific axis.
pdiph
Address of the DIPROPHEADER structure contained within the type-specific property structure.

Return Values

If the method succeeds, the return value is DI_OK or DI_PROPNOEFFECT. If the method fails, the return value can be one of the following error values: DIERR_INVALIDPARAM DIERR_NOTINITIALIZED, DIERR_OBJECTNOTFOUND, DIERR_UNSUPPORTED.

Remarks

The buffer size determines the amount of data that the buffer can hold between calls to the IDirectInputDevice8::GetDeviceData method before data is lost. This value may be set to 0 to indicate that the application does not read buffered data from the device. If the buffer size in the dwData member of the DIPROPDWORD structure is too large for the device to support it, then the largest possible buffer size is set.



在調(diào)用SetProperty函數(shù)時始終要使用的DIPROPHEADER結(jié)構(gòu)體定義如下:

Serves as a header for all property structures.

typedef struct DIPROPHEADER {
DWORD dwSize;
DWORD dwHeaderSize;
DWORD dwObj;
DWORD dwHow;
} DIPROPHEADER, *LPDIPROPHEADER;

Members

dwSize
Size of the enclosing structure. This member must be initialized before the structure is used.
dwHeaderSize
Size of the DIPROPHEADER structure.
dwObj
Object for which the property is to be accessed. The value set for this member depends on the value specified in the dwHow member.
dwHow
Value that specifies how the dwObj member should be interpreted. This value can be one of the following:
DIPH_DEVICE
The dwObj member must be 0.
DIPH_BYOFFSET
The dwObj member is the offset into the current data format of the object whose property is being accessed.
DIPH_BYUSAGE
The dwObj member is the human interface device usage page and usage values in packed form.
DIPH_BYID
The dwObj member is the object type/instance identifier. This identifier is returned in the dwType member of the DIDEVICEOBJECTINSTANCE structure returned from a previous call to the IDirectInputDevice8::EnumObjects member.


獲得設(shè)備

在使用任何設(shè)備之前,首先必須獲得設(shè)備。只有獲得了設(shè)備才能確保程序能夠訪問設(shè)備,以及同其他程序共享訪問還是完全控制設(shè)備。要注意的是其他程序可能會爭奪并搶走對設(shè)備的控制權(quán),要補(bǔ)救這種情況就必須重新獲得設(shè)備。何時必須獲得設(shè)備?第一種情況就是在創(chuàng)建接口的時候,原因在于使用設(shè)備之前必須首先獲得它。另一種情況就是當(dāng)另一個程序搶走了對設(shè)備的控制,同時 DirectInput通知了程序時。

調(diào)用IDirectInputDevice8::Acquire函數(shù)即可獲得設(shè)備。

Obtains access to the input device.

HRESULT Acquire();

Parameters

None.

Return Values

If the method succeeds, the return value is DI_OK, or S_FALSE if the device was already acquired. If the method fails, the return value can be one of the following error values: DIERR_INVALIDPARAM, DIERR_NOTINITIALIZED, DIERR_OTHERAPPHASPRIO.

Remarks

Before a device can be acquired, a data format must be set by using the IDirectInputDevice8::SetDataFormat method or IDirectInputDevice8::SetActionMap method. If the data format has not been set, IDirectInputDevice8 Interface returns DIERR_INVALIDPARAM.

Devices must be acquired before calling the IDirectInputDevice8::GetDeviceState or IDirectInputDevice8::GetDeviceData methods for that device.

Device acquisition does not use a reference count. Therefore, if an application calls the IDirectInputDevice8 Interface method twice, then calls the IDirectInputDevice8 Interface method once, the device is unacquired.

If IDirectInputDevice8::BuildActionMap succeeds but no actions have been mapped, a subsequent call to IDirectInputDevice8::SetActionMap will return DI_OK but a call to IDirectInputDevice8 Interface will fail with DIERR_INVALIDPARAM.


輪詢設(shè)備

輪詢可以準(zhǔn)備設(shè)備并在合適的情況下讀取設(shè)備數(shù)據(jù),因?yàn)閿?shù)據(jù)可能具有臨界時間。游戲桿就是這樣的設(shè)備,要從設(shè)備讀取數(shù)據(jù),計算機(jī)需要發(fā)送一個電子脈沖給它。雖然輪詢對于游戲桿輸入而言是必須的,但是對鍵盤或鼠標(biāo)來說卻并不需要輪詢。

輪詢設(shè)備需要使用IDirectInputDevice8::Poll函數(shù)。

Retrieves data from polled objects on a DirectInput device. If the device does not require polling, calling this method has no effect. If a device that requires polling is not polled periodically, no new data is received from the device. Calling this method causes DirectInput to update the device state, generate input events (if buffered data is enabled), and set notification events (if notification is enabled).

HRESULT Poll();

Parameters

None.

Return Values

If the method succeeds, the return value is DI_OK, or DI_NOEFFECT if the device does not require polling. If the method fails, the return value can be one of the following error values: DIERR_INPUTLOST, DIERR_NOTACQUIRED, DIERR_NOTINITIALIZED.

Remarks

Before a device data can be polled, the data format must be set by using the IDirectInputDevice8::SetDataFormat or IDirectInputDevice8::SetActionMap method, and the device must be acquired by using the IDirectInputDevice8 Interface method.



讀取數(shù)據(jù)

經(jīng)過以上的步驟,就剩下最后一步了,那就是使用 IDirectInputDevice8::GetDeviceState函數(shù)讀取設(shè)備數(shù)據(jù)。為了存儲設(shè)備的信息,必須傳遞一個數(shù)據(jù)緩沖區(qū)給此函數(shù),這樣程序才能使用設(shè)備的信息,每種設(shè)備的數(shù)據(jù)各不相同。

Retrieves immediate data from the device.

HRESULT GetDeviceState(
DWORD cbData,
LPVOID lpvData
);

Parameters

cbData
Size of the buffer in the lpvData parameter, in bytes.
lpvData
Address of a structure that receives the current state of the device. The format of the data is established by a prior call to the IDirectInputDevice8::SetDataFormat method.

Return Values

If the method succeeds, the return value is DI_OK. If the method fails, the return value can be one of the following error values: DIERR_INPUTLOST, DIERR_INVALIDPARAM, DIERR_NOTACQUIRED, DIERR_NOTINITIALIZED, E_PENDING.

Remarks

Before device data can be obtained, set the cooperative level by using the IDirectInputDevice8::SetCooperativeLevel method, then set the data format by using IDirectInputDevice8::SetDataFormat, and acquire the device by using the IDirectInputDevice8 Interface method.

The five predefined data formats require corresponding device state structures according to the following table:

Data format

State structure

c_dfDIMouse DIMOUSESTATE
c_dfDIMouse2 DIMOUSESTATE2
c_dfDIKeyboard array of 256 bytes
c_dfDIJoystick DIJOYSTATE
c_dfDIJoystick2 DIJOYSTATE2

For example, if you passed the c_dfDIMouse format to the IDirectInputDevice8::SetDataFormat method, you must pass a DIMOUSESTATE structure to the IDirectInputDevice8::GetDeviceState method.



無論是哪種設(shè)備,下面的代碼都能讀取其數(shù)據(jù)。它們考慮了丟失設(shè)備并在適當(dāng)?shù)臅r刻重新獲得設(shè)備的情況,必須傳遞一個指向緩沖區(qū)的指針給下面這個函數(shù),緩沖區(qū)的大小要能夠保存設(shè)備信息以及讀取的數(shù)據(jù)量。

BOOL Read_Device(IDirectInputDevice8* directinput_device, void* buffer, long buffer_size)
{
    HRESULT rv;

    
while(1)
    {
        
// poll device
        g_directinput_device->Poll();

        
// read in state
        if(SUCCEEDED(rv = g_directinput_device->GetDeviceState(buffer_size, buffer)))
            
break;

        
// return when an unknown error
        if(rv != DIERR_INPUTLOST || rv != DIERR_NOTACQUIRED)
            
return FALSE;

        
// re-acquire and try again
        if(FAILED(g_directinput_device->Acquire()))
            
return FALSE;
    }

    
return TRUE;
}

使用DirectInput處理鍵盤

如果調(diào)用成功,下面的初始化函數(shù)則返回一個指向新創(chuàng)建的IDirectInputDevice8對象的指針;反之當(dāng)函數(shù)調(diào)用失敗時,返回NULL。只需給此函數(shù)傳遞父窗口的句柄和與定義的DirectInput對象即可。
 
//--------------------------------------------------------------------------------
// Initialize keyboard interface, return a keyboad interface pointer.
//--------------------------------------------------------------------------------
IDirectInputDevice8* Init_Keyboard(HWND hwnd, IDirectInput8* directinput)
{
    IDirectInputDevice8* directinput_device;


  
// create the device object
    if(FAILED(directinput->CreateDevice(GUID_SysKeyboard, &directinput_device, NULL)))
        
return NULL;

    
// set the data format
    if(FAILED(directinput_device->SetDataFormat(&c_dfDIKeyboard)))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// set the coooperative mode
    if(FAILED(directinput_device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// acquire the device for use
    if(FAILED(directinput_device->Acquire()))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// everything well, so return a vaild pointer.
    return directinput_device;
}


要存儲鍵盤數(shù)據(jù),必須使用一個大小為256字節(jié)的數(shù)組,每個字節(jié)存儲一個鍵的狀態(tài),這樣就給出了保存256個鍵的空間。每個字節(jié)存儲鍵當(dāng)前的狀態(tài)信息,即鍵是否被按下。要得到鍵的狀態(tài),就要檢查高位(字節(jié)),如果置位,鍵就被按下;如果清零,鍵就未被按下。在DirectInput 中,每個鍵都有一個屬于自己的宏,這些宏都以DIK_為前綴。A鍵定義為DIK_A,ESC為DIK_ESCAPE等。查閱DX SDK或DInput.h可以得到其他鍵的宏。

點(diǎn)擊下載源碼和工程

完整源碼如下:
 
/***************************************************************************************
PURPOSE:
    Keyboard device Demo
 ***************************************************************************************/


#define DIRECTINPUT_VERSION 0x0800

#include <windows.h>
#include <stdio.h>
#include <dinput.h>
#include "resource.h"

#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")

#define Safe_Release(p) if((p)) (p)->Release();

// window handles, class and caption text.
HWND g_hwnd;
static char g_class_name[] = "KeyboardClass";

IDirectInput8* g_directinput;               
// directinput component
IDirectInputDevice8* g_directinput_device;  // keyboard device

//--------------------------------------------------------------------------------
// Window procedure.
//--------------------------------------------------------------------------------
long WINAPI Window_Proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    
switch(msg)
    {
    
case WM_DESTROY:
        PostQuitMessage(0);
        
return 0;
    }

    
return (long) DefWindowProc(hwnd, msg, wParam, lParam);
}

//--------------------------------------------------------------------------------
// Initialize keyboard interface, return a keyboad interface pointer.
//--------------------------------------------------------------------------------
IDirectInputDevice8* Init_Keyboard(HWND hwnd, IDirectInput8* directinput)
{
    IDirectInputDevice8* directinput_device;

    
// create the device object
    if(FAILED(directinput->CreateDevice(GUID_SysKeyboard, &directinput_device, NULL)))
        
return NULL;

    
// set the data format
    if(FAILED(directinput_device->SetDataFormat(&c_dfDIKeyboard)))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// set the coooperative mode
    if(FAILED(directinput_device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// acquire the device for use
    if(FAILED(directinput_device->Acquire()))
    {
        directinput_device->Release();
        
return NULL;
    }

    
// everything well, so return a vaild pointer.
    return directinput_device;
}

//--------------------------------------------------------------------------------
// Read keyboard buffer.
//--------------------------------------------------------------------------------
BOOL Read_Device(IDirectInputDevice8* directinput_device, void* buffer, long buffer_size)
{
    HRESULT rv;

    
while(1)
    {
        
// poll device
        g_directinput_device->Poll();

        
// read in state
        if(SUCCEEDED(rv = g_directinput_device->GetDeviceState(buffer_size, buffer)))
            
break;

        
// return when an unknown error
        if(rv != DIERR_INPUTLOST || rv != DIERR_NOTACQUIRED)
            
return FALSE;

        
// re-acquire and try again
        if(FAILED(g_directinput_device->Acquire()))
            
return FALSE;
    }

    
return TRUE;
}

//--------------------------------------------------------------------------------
// Main function, routine entry.
//--------------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
    WNDCLASS    win_class;
    MSG         msg;
    
char        key_state_buffer[256];

    
// create window class and register it
    win_class.style         = CS_HREDRAW | CS_VREDRAW;
    win_class.lpfnWndProc   = Window_Proc;
    win_class.cbClsExtra    = 0;
    win_class.cbWndExtra    = DLGWINDOWEXTRA;
    win_class.hInstance     = inst;
    win_class.hIcon         = LoadIcon(inst, IDI_APPLICATION);
    win_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
    win_class.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    win_class.lpszMenuName  = NULL;
    win_class.lpszClassName = g_class_name;    

    
if(! RegisterClass(&win_class))
        
return FALSE;

    
// create the main window
    g_hwnd = CreateDialog(inst, MAKEINTRESOURCE(IDD_KEYBOARD), 0, NULL);

    ShowWindow(g_hwnd, cmd_show);
    UpdateWindow(g_hwnd);

    
// initialize directinput and get keyboard device
    DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **) &g_directinput, NULL);

    
// initialize keyboard
    g_directinput_device = Init_Keyboard(g_hwnd, g_directinput);

    
// start message pump, waiting for signal to quit.
    ZeroMemory(&msg, sizeof(MSG));

    
while(msg.message != WM_QUIT)
    {
        
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        
        
// read in keyboard and break if ESCAPE pressed
        Read_Device(g_directinput_device, key_state_buffer, sizeof(key_state_buffer));

        
if(key_state_buffer[DIK_ESCAPE] & 0x80)
            
break;
    }

    
// release directinput objects
    g_directinput_device->Unacquire();
    g_directinput_device->Release();
    g_directinput->Release();

    UnregisterClass(g_class_name, inst);
    
    
return (int) msg.wParam;
}

 

運(yùn)行效果:



  閱讀下篇: 使用DirectInput進(jìn)行交互(3)

posted on 2007-07-24 21:50 lovedday 閱讀(2246) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


公告

導(dǎo)航

統(tǒng)計

常用鏈接

隨筆分類(178)

3D游戲編程相關(guān)鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区在线视频| 亚洲日本va午夜在线影院| 亚洲天堂偷拍| 欧美91视频| 亚洲欧美一区二区精品久久久| 女生裸体视频一区二区三区| 国内精品伊人久久久久av影院| 欧美一区二区三区电影在线观看| 一个色综合av| 欧美四级在线观看| 亚洲在线视频| 亚洲性线免费观看视频成熟| 国产精品毛片一区二区三区 | 一区二区成人精品| 亚洲国产经典视频| 欧美电影专区| aaa亚洲精品一二三区| 亚洲日本在线视频观看| 欧美日韩国产首页在线观看| 一区二区三区精密机械公司| 99精品国产在热久久婷婷| 欧美日韩在线播放三区四区| 亚洲愉拍自拍另类高清精品| 亚洲主播在线| 狠狠入ady亚洲精品经典电影| 免费视频一区二区三区在线观看| 裸体歌舞表演一区二区| 亚洲理伦电影| 亚洲小说欧美另类婷婷| 国产小视频国产精品| 嫩草伊人久久精品少妇av杨幂| 欧美.com| 香蕉成人伊视频在线观看| 久久国产福利| 99re国产精品| 午夜精品久久久久久久99热浪潮| 伊人久久婷婷| 99精品视频一区| 国产主播一区| 亚洲国产精品一区制服丝袜| 欧美体内she精视频| 久久激情五月丁香伊人| 麻豆精品在线视频| 午夜精品国产精品大乳美女| 久久久久久久性| 欧美日韩性视频在线| 国产精品日日摸夜夜添夜夜av | 亚洲国产精品视频| 国产精品v片在线观看不卡| 久久黄色级2电影| 欧美xart系列高清| 欧美在线观看一二区| 欧美国产在线电影| 欧美一区三区二区在线观看| 欧美顶级大胆免费视频| 久久精品系列| 欧美特黄一级| 欧美激情精品久久久久久免费印度| 欧美三级视频| 欧美激情第五页| 国产欧美日韩在线观看| 最新国产拍偷乱拍精品| 激情91久久| 亚洲一线二线三线久久久| 亚洲欧洲日本国产| 欧美一区二区黄色| 亚洲字幕一区二区| 欧美精品在线极品| 欧美jjzz| 精品成人一区二区| 性欧美videos另类喷潮| 亚洲夜间福利| 欧美日韩二区三区| 亚洲高清色综合| 黄网动漫久久久| 性视频1819p久久| 亚洲在线不卡| 欧美性色aⅴ视频一区日韩精品| 欧美激情一区| 亚洲国产高清在线| 久久亚洲欧美| 欧美.com| 亚洲国产精品一区二区www在线 | 亚洲精品久久久久久久久| 欧美在线免费视屏| 欧美中文在线免费| 国产精品美腿一区在线看 | 欧美日韩和欧美的一区二区| 亚洲国产欧美一区二区三区久久 | 亚洲男女自偷自拍| 欧美色播在线播放| 日韩亚洲欧美成人一区| 一本大道久久a久久精品综合| 欧美激情免费观看| 亚洲精选视频在线| 亚洲一区欧美激情| 国产精品亚洲不卡a| 午夜日韩视频| 久久综合久久综合久久| 尤物在线精品| 欧美黑人国产人伦爽爽爽| 91久久一区二区| 久久久久**毛片大全| 猛男gaygay欧美视频| 国产视频一区在线观看一区免费| 亚洲——在线| 久久久噜噜噜久久久| 韩国三级在线一区| 欧美xx视频| 亚洲图片欧美午夜| 久久精品一区二区国产| 在线精品视频一区二区三四| 欧美成人精品一区二区| 一区二区三区四区蜜桃| 久久精品成人一区二区三区蜜臀| 在线成人小视频| 欧美精品大片| 亚洲欧美成人一区二区在线电影| 久久久夜夜夜| 99国内精品| 国产日韩欧美高清免费| 久久尤物视频| 99国产麻豆精品| 久久久久久网址| aa级大片欧美| 国产一区二区成人| 免费美女久久99| 亚洲一区二区在线看| 欧美大片在线观看| 亚洲欧美三级伦理| 亚洲国产经典视频| 国产精品乱码人人做人人爱| 久久婷婷国产综合国色天香| 99精品免费网| 欧美jizz19性欧美| 欧美在线视频a| 日韩系列欧美系列| 很黄很黄激情成人| 国产精品乱码妇女bbbb| 欧美国产精品va在线观看| 午夜一区二区三区不卡视频| 亚洲人妖在线| 欧美福利一区二区三区| 小黄鸭视频精品导航| 亚洲免费观看在线观看| 一色屋精品亚洲香蕉网站| 国产精品mv在线观看| 欧美国产日韩一区二区| 久久久视频精品| 亚洲嫩草精品久久| 一区二区三区成人| 亚洲人成久久| 亚洲国产高清aⅴ视频| 久久一区二区三区超碰国产精品| 亚洲综合精品| 一本久道综合久久精品| 91久久久久久国产精品| 国内一区二区三区在线视频| 国产精品欧美一区二区三区奶水| 欧美激情在线观看| 美乳少妇欧美精品| 久久久一区二区三区| 久久精品国产欧美激情| 欧美在线精品免播放器视频| 性欧美xxxx视频在线观看| 亚洲欧美国产精品va在线观看| 一区二区日韩免费看| 99成人在线| 宅男噜噜噜66一区二区66| 日韩亚洲视频| 一本到高清视频免费精品| 亚洲免费观看在线观看| 亚洲精品久久嫩草网站秘色| 亚洲国产欧美一区二区三区久久 | 久久精品麻豆| 久久精品99国产精品日本| 亚洲欧美在线aaa| 欧美精品三级在线观看| 欧美日韩精品福利| 欧美日本二区| 欧美日韩综合不卡| 国产精品video| 国产精品视频一区二区三区| 国产精品―色哟哟| 国产日韩欧美不卡在线| 国产中文一区| 亚洲精品国产无天堂网2021| 日韩视频一区二区在线观看 | 蜜桃久久av| 欧美理论电影网| 欧美亚洲成人精品| 国产啪精品视频| 精品动漫3d一区二区三区| 亚洲电影在线看| 亚洲视频成人| 久久爱www.| 欧美激情成人在线| 99re8这里有精品热视频免费 | 欧美在线一级视频| 女人色偷偷aa久久天堂|