directinput缓冲模式的疑问,我写的这个代码为什么没有反应呢?
上代码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; }