![]() |
#2
secondsen2011-03-29 14:40
|
DIDEVICEOBJECTDATA是存放键盘缓冲数据的结构体,我讲这个类型的数组变量置零,然后做判断,希望messagebox能把DIDEVICEOBJECTDATA每个成员的值都显示出来,为什么这个程序没有反应呢??

#include <windows.h>
#include <dinput.h>
#include <string.h>
#include <stdio.h>
using namespace std;
#define DINPUT_BUFFERSIZE 4
HWND hwnd;
LPDIRECTINPUT lpDirectInput; // DirectInput object
LPDIRECTINPUTDEVICE lpKeyboard; // DirectInput device
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void ReleaseDInput()
{
if (lpKeyboard!=NULL)
{
lpKeyboard->Unacquire();
lpKeyboard->Release();
lpKeyboard = NULL;
}
if (lpDirectInput!=NULL)
{
lpDirectInput->Release();
lpDirectInput = NULL;
}
}
BOOL InitDInput(HWND hWnd,HINSTANCE hInstance)
{
HRESULT hr;
// 创建一个 DIRECTINPUT 对象
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&lpDirectInput, NULL);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 创建一个 DIRECTINPUTDEVICE 界面
hr = lpDirectInput->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定为通过一个 256 字节的数组返回查询状态值
hr = lpKeyboard->SetDataFormat(&c_dfDIKeyboard);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定协作模式
hr = lpKeyboard->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定缓冲区大小
// 如果不设定,缓冲区大小默认值为 0,程序就只能按立即模式工作
// 如果要用缓冲模式工作,必须使缓冲区大小超过 0
DIPROPDWORD prop;
prop.diph.dwSize = sizeof(DIPROPDWORD);
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
prop.diph.dwObj = 0;
prop.diph.dwHow = DIPH_DEVICE;
prop.dwData = DINPUT_BUFFERSIZE;
hr = lpKeyboard->SetProperty(DIPROP_BUFFERSIZE, &prop.diph);
if FAILED(hr)
{
// 失败
return FALSE;
}
hr = lpKeyboard->Acquire();
if FAILED(hr)
{
// 失败
return FALSE;
}
return TRUE;
}
HRESULT UpdateInputState(void)
{
if(lpKeyboard != NULL)
{
DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data
DWORD dwElements;
HRESULT hr;
ZeroMemory(didod, sizeof(DIDEVICEOBJECTDATA)*DINPUT_BUFFERSIZE);
hr = DIERR_INPUTLOST;
while(hr != DI_OK)
{
dwElements = DINPUT_BUFFERSIZE;
hr = lpKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
if (hr != DI_OK)
{
hr = lpKeyboard->Acquire();
if(FAILED(hr))
return hr;
}
}
if(FAILED(hr))
return hr;
for(int i=0; i<DINPUT_BUFFERSIZE; i++)
{
if (didod[i].dwOfs == 0)
return S_OK;
// 此处放入处理代码
// didod[i].dwOfs 表示那个键被按下或松开
// didod[i].dwData 记录此键的状态,低字节最高位是 1 表示按下,0 表示松开
// 一般用 didod[i].dwData&0x80 来测试}
}
DWORD tmp[20];
VOID* pDest,*pSrc;
pDest = &tmp;
pSrc = &didod;
memcpy( pDest, pSrc, 80 );
string strResult("test:\n");
for (int i=0;i<20;i++)
{
strResult+=tmp[i];
strResult+="\n";
}
MessageBox( NULL, strResult.c_str(),"提示!", MB_OK) ;
}
return S_OK;
}
int _stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
HWND hwnd;
MSG msg;
WNDCLASS WindowClass;
if(!hPrevInstance){
//not first run, to set the windows class
WindowClass.style=NULL;
WindowClass.cbClsExtra=0;
WindowClass.cbWndExtra=0;
WindowClass.hbrBackground = HBRUSH(GetStockObject(BLACK_BRUSH));
WindowClass.hCursor=LoadCursor(hInstance,IDC_ARROW);
WindowClass.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
WindowClass.hInstance=hInstance;
WindowClass.lpfnWndProc=WndProc;
WindowClass.lpszClassName="DInput_Test";
WindowClass.lpszMenuName=NULL;
RegisterClass(&WindowClass);
}
// start to create the window when registed the window class
hwnd=CreateWindow("DInput_Test","DirectInput_Test",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
if FAILED(InitDInput(hwnd,hInstance))
{
MessageBox( NULL, "创建DInput设备出错!","Error!", MB_OK) ;
ReleaseDInput();
PostQuitMessage( 0 );
return 0;
}
GetMessage(&msg,NULL,NULL,NULL);
//process the message quenue
while(msg.message != WM_QUIT)
{
UpdateInputState();
if( GetMessage(&msg,NULL,0,0) )
{
//解析消息
TranslateMessage(&msg);
//分派消息
DispatchMessage(&msg);
}
}
ReleaseDInput();
UnregisterClass( "DInput_Test", hInstance);
return msg.wParam;
}
//window message process function
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
//关闭窗口消息的处理
case WM_CLOSE:
DestroyWindow( hwnd );
break;
//销毁窗口消息的处理
case WM_DESTROY:
//退出当前进程
PostQuitMessage( 0 );
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
return NULL;
}
#include <dinput.h>
#include <string.h>
#include <stdio.h>
using namespace std;
#define DINPUT_BUFFERSIZE 4
HWND hwnd;
LPDIRECTINPUT lpDirectInput; // DirectInput object
LPDIRECTINPUTDEVICE lpKeyboard; // DirectInput device
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
void ReleaseDInput()
{
if (lpKeyboard!=NULL)
{
lpKeyboard->Unacquire();
lpKeyboard->Release();
lpKeyboard = NULL;
}
if (lpDirectInput!=NULL)
{
lpDirectInput->Release();
lpDirectInput = NULL;
}
}
BOOL InitDInput(HWND hWnd,HINSTANCE hInstance)
{
HRESULT hr;
// 创建一个 DIRECTINPUT 对象
hr = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&lpDirectInput, NULL);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 创建一个 DIRECTINPUTDEVICE 界面
hr = lpDirectInput->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定为通过一个 256 字节的数组返回查询状态值
hr = lpKeyboard->SetDataFormat(&c_dfDIKeyboard);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定协作模式
hr = lpKeyboard->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if FAILED(hr)
{
// 失败
return FALSE;
}
// 设定缓冲区大小
// 如果不设定,缓冲区大小默认值为 0,程序就只能按立即模式工作
// 如果要用缓冲模式工作,必须使缓冲区大小超过 0
DIPROPDWORD prop;
prop.diph.dwSize = sizeof(DIPROPDWORD);
prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
prop.diph.dwObj = 0;
prop.diph.dwHow = DIPH_DEVICE;
prop.dwData = DINPUT_BUFFERSIZE;
hr = lpKeyboard->SetProperty(DIPROP_BUFFERSIZE, &prop.diph);
if FAILED(hr)
{
// 失败
return FALSE;
}
hr = lpKeyboard->Acquire();
if FAILED(hr)
{
// 失败
return FALSE;
}
return TRUE;
}
HRESULT UpdateInputState(void)
{
if(lpKeyboard != NULL)
{
DIDEVICEOBJECTDATA didod[DINPUT_BUFFERSIZE]; // Receives buffered data
DWORD dwElements;
HRESULT hr;
ZeroMemory(didod, sizeof(DIDEVICEOBJECTDATA)*DINPUT_BUFFERSIZE);
hr = DIERR_INPUTLOST;
while(hr != DI_OK)
{
dwElements = DINPUT_BUFFERSIZE;
hr = lpKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), didod, &dwElements, 0);
if (hr != DI_OK)
{
hr = lpKeyboard->Acquire();
if(FAILED(hr))
return hr;
}
}
if(FAILED(hr))
return hr;
for(int i=0; i<DINPUT_BUFFERSIZE; i++)
{
if (didod[i].dwOfs == 0)
return S_OK;
// 此处放入处理代码
// didod[i].dwOfs 表示那个键被按下或松开
// didod[i].dwData 记录此键的状态,低字节最高位是 1 表示按下,0 表示松开
// 一般用 didod[i].dwData&0x80 来测试}
}
DWORD tmp[20];
VOID* pDest,*pSrc;
pDest = &tmp;
pSrc = &didod;
memcpy( pDest, pSrc, 80 );
string strResult("test:\n");
for (int i=0;i<20;i++)
{
strResult+=tmp[i];
strResult+="\n";
}
MessageBox( NULL, strResult.c_str(),"提示!", MB_OK) ;
}
return S_OK;
}
int _stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
HWND hwnd;
MSG msg;
WNDCLASS WindowClass;
if(!hPrevInstance){
//not first run, to set the windows class
WindowClass.style=NULL;
WindowClass.cbClsExtra=0;
WindowClass.cbWndExtra=0;
WindowClass.hbrBackground = HBRUSH(GetStockObject(BLACK_BRUSH));
WindowClass.hCursor=LoadCursor(hInstance,IDC_ARROW);
WindowClass.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
WindowClass.hInstance=hInstance;
WindowClass.lpfnWndProc=WndProc;
WindowClass.lpszClassName="DInput_Test";
WindowClass.lpszMenuName=NULL;
RegisterClass(&WindowClass);
}
// start to create the window when registed the window class
hwnd=CreateWindow("DInput_Test","DirectInput_Test",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,nShowCmd);
UpdateWindow(hwnd);
if FAILED(InitDInput(hwnd,hInstance))
{
MessageBox( NULL, "创建DInput设备出错!","Error!", MB_OK) ;
ReleaseDInput();
PostQuitMessage( 0 );
return 0;
}
GetMessage(&msg,NULL,NULL,NULL);
//process the message quenue
while(msg.message != WM_QUIT)
{
UpdateInputState();
if( GetMessage(&msg,NULL,0,0) )
{
//解析消息
TranslateMessage(&msg);
//分派消息
DispatchMessage(&msg);
}
}
ReleaseDInput();
UnregisterClass( "DInput_Test", hInstance);
return msg.wParam;
}
//window message process function
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
//关闭窗口消息的处理
case WM_CLOSE:
DestroyWindow( hwnd );
break;
//销毁窗口消息的处理
case WM_DESTROY:
//退出当前进程
PostQuitMessage( 0 );
break;
default:
return DefWindowProc(hwnd,msg,wparam,lparam);
}
return NULL;
}