DirectInput由三个对象组成:DirectInput, DirectInputDevice, 和DirectInputEffect 。DirectInput是一个高层的对象,通过DirectInput对象可以对相关的输入设备进行基本的初始化和查找。DirectInput对象最终用来创建低层的DirectInputDevice对象。DirectX中的每个主要组件都采用相同的方法,首先创建高层对象,如DirectInput或DirectSound对象,然后创建低层对象与硬件进行实际的通信。
一个简单的DirectInput创建步骤如下:
一,创建DirectInput对象 使用DirectInput8Create函数.
二,有了DirectInput对象,就可以用它来创建DirectInputDevice对象,使用CreateDevice函数.
三,设置格式SetDataFormat.
四,设置协作级别SetCooperativeLeve
五,获取键盘设备,在本例子中,只是取得键盘设备,没有使用枚举函数来枚举各种输入设备.
完整的源代码如下:
//
// File: DirectInput.cpp
// Date: 10/30/2006
// Author: liuyw1982
//
#include <windows.h>
#include <dinput.h>
//
// 全局函数定义
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow);
long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
bool InitApp(HINSTANCE hInst, int nCmdShow);
HRESULT InitDirectInput();
HRESULT ReadKeyboard(HWND hwnd);
// 全局变量定义
BOOL bActive = FALSE;
LPDIRECTINPUT8 g_lpDInput=NULL;
LPDIRECTINPUTDEVICE8 g_pKeyboard=NULL;
HWND g_hwnd=NULL;
// Windows Main Function
int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
if(!InitApp(hInst, nCmdShow)) return FALSE;
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 ))
return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
ReadKeyboard(g_hwnd);
}
else WaitMessage();
}
}
// WinProc
long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_ACTIVATE:
bActive = TRUE;
break;
case WM_SETCURSOR:
SetCursor(NULL);
return TRUE;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Initialize Appliction
bool InitApp(HINSTANCE hInst, int nCmdShow)
{
HWND hWnd;
WNDCLASS WndClass;
WndClass.style = CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc = WinProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInst;
WndClass.hIcon = LoadIcon(hInst, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(hInst, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = "DInput";
RegisterClass(&WndClass);
hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, "DInput", "DirectInput", WS_EX_APPWINDOW|WS_SYSMENU,
112, 84, 800, 600, NULL, NULL, hInst, NULL);
if(!hWnd) return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
g_hwnd=hWnd;
InitDirectInput();
return true;
}
// Initialize DirectInput
HRESULT InitDirectInput()
{
HRESULT hr;
hr=DirectInput8Create(GetModuleHandle(NULL),DIRECTINPUT_VERSION,IID_IDirectInput8,(VOID**)&g_lpDInput,NULL);
if(FAILED(hr))
return hr;
hr=g_lpDInput->CreateDevice(GUID_SysKeyboard,&g_pKeyboard,NULL);
if(FAILED(hr))
return hr;
hr=g_pKeyboard->SetDataFormat(&c_dfDIKeyboard);
if(FAILED(hr))
return hr;
hr=g_pKeyboard->SetCooperativeLevel(g_hwnd,DISCL_FOREGROUND|DISCL_EXCLUSIVE);
if(FAILED(hr))
return hr;
hr=g_pKeyboard->Acquire();
if(FAILED(hr))
return hr;
return S_OK;
}
// ReadKeyBoardData
HRESULT ReadKeyboard(HWND g_hwnd)
{
HRESULT hr;
TCHAR strNewText[256]=TEXT("");
TCHAR strElement[10];
BYTE disk[256];
int i;
if(NULL==g_pKeyboard)
return S_OK;
ZeroMemory(&disk,sizeof(disk));
hr=g_pKeyboard->GetDeviceState(sizeof(disk),&disk);
if(FAILED(hr))
{
hr=g_pKeyboard->Acquire();
while(DIERR_INPUTLOST==hr)
hr=g_pKeyboard->Acquire();
return S_OK;
}
for(i=0;i<256;i++)
{
if(disk[i]&0x80)
{
wsprintf( strElement, TEXT("0x%02x "), i );
}
}
return S_OK;
}
调试的时候,可在wsprintf( strElement, TEXT("0x%02x "), i );这句中设置断点续传,即可知道键盘是否响应输入.