📄 gp_input.cpp
字号:
//********************************************
// DirectInput 相关处理函数
//********************************************
#include <windows.h>
#include <stdio.h>
#include <dinput.h>
#include "gp_other.h"
#include "gp_init.h"
#include "gp_input.h"
//全局通用对象
CMouse Mouse; //鼠标
CKey Key; //键盘
CJoystick g_Joystick; //手柄
extern HWND hWnd;
extern HINSTANCE hInst;
extern BOOL bActive;
#if USE_DX8
LPDIRECTINPUT8 lpDI; //DINPUT设备
#else
LPDIRECTINPUT lpDI; //DINPUT设备
#endif
/////////////////////////////////////////////////////////////////
//INPUT
/////////////////////////////////////////////////////////////////
//初始化DIRECTINPUT
bool WINAPI InitInput()
{
HRESULT hr;
#if USE_DX8
hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8,(void**)&lpDI, NULL );
#else
hr = DirectInputCreate( hInst, DIRECTINPUT_VERSION, &lpDI, NULL );
#endif
if ( FAILED(hr) )
{
MessageBox(hWnd,"Create DirectInput","Failed",MB_OK);
return false;
}
return true;
}
//释放DIRECTINPUT
void WINAPI FreeInput()
{
_RELEASE( lpDI );
}
/////////////////////////////////////////////////////////////////
//MOUSE
/////////////////////////////////////////////////////////////////
//初始化鼠标
HRESULT WINAPI CMouse::InitInput_Mouse( HWND hDlg )
{
HRESULT hr;
//创建设备
hr = lpDI->CreateDevice( GUID_SysMouse, &g_pMouse, NULL );
if ( FAILED(hr) )
{
MessageBox(hWnd,"Create Mouse Device","Failed",MB_OK);
return hr;
}
//数据格式
hr = g_pMouse->SetDataFormat( &c_dfDIMouse );
if ( FAILED(hr) )
{
MessageBox(hWnd,"Set Mouse Data Format","Failed",MB_OK);
return hr;
}
//协作级
hr = g_pMouse->SetCooperativeLevel( hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if ( FAILED(hr) )
{
MessageBox(hWnd,"Set Mouse Cooperative Level","Failed",MB_OK);
return hr;
}
//属性
DIPROPDWORD property;
property.diph.dwSize=sizeof(DIPROPDWORD);
property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
property.diph.dwObj=0;
property.diph.dwHow=DIPH_DEVICE;
property.dwData=16;
hr = g_pMouse->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
if (FAILED(hr))
{
MessageBox(hWnd,"Set Mouse Property","Failed",MB_OK);
return hr;
}
//获取
hr = g_pMouse->Acquire();
if FAILED(hr)
{
return hr;
}
return true;
}
//获取设备
HRESULT WINAPI CMouse::SetAcquire( HWND hDlg )
{
if (NULL == g_pMouse)
return S_FALSE;
if (bActive)
{
g_pMouse->Acquire();
}
else
{
g_pMouse->Unacquire();
}
return S_OK;
}
//释放DIRECTINPUT设备MOUSE
void WINAPI CMouse::FreeInput_Mouse()
{
if( g_pMouse )
{
g_pMouse->Unacquire();
g_pMouse->Release();
g_pMouse=NULL;
}
}
//获取缓冲区数据
unsigned char WINAPI CMouse::GetMouseData()
{
if( g_pMouse )
{
_Begin:
DIDEVICEOBJECTDATA data;
DWORD elements=1; //一个元素
HRESULT hr = g_pMouse->GetDeviceData(sizeof(data), &data, &elements, 0);
if FAILED(hr)
{
if(hr == DIERR_INPUTLOST)
{
hr = g_pMouse->Acquire();
}
}
else
{
if(elements == 1)
{
switch(data.dwOfs)
{
case DIMOFS_X: //忽略移动数据
case DIMOFS_Y:
goto _Begin;
break;
case DIMOFS_BUTTON0:
if( data.dwData & 0x80 ) //高位为1:按下
return LB_DOWN;
return LB_UP; //否则释放
break;
case DIMOFS_BUTTON1:
if( data.dwData & 0x80 )
return RB_DOWN;
return RB_UP;
break;
}
}
else
if(elements==0)
return 0;
}
}
return 0;
}
//清空鼠标缓冲区
void WINAPI CMouse::ReleaseMouseBuffer()
{
while(1)
{
if( GetMouseData()== 0 ) break;
}
}
//**************************
//获取鼠标当前状态(经新浪网友wing_of_dream改进)
//没有太多改进,仅仅测试一下是否没有获取过鼠标设备
void WINAPI CMouse::GetMouseState()
{
if (g_pMouse)
{
DIMOUSESTATE dims;
HRESULT hr;
_again:
hr = g_pMouse->GetDeviceState(sizeof(DIMOUSESTATE), &dims);//得到当前状态
if( FAILED(hr) )
{
hr = g_pMouse->Acquire(); //重新获取
if(!( hr== DI_OK))
{
for (int i=0;i<50;i++)
{
if ((hr = g_pMouse->Acquire()) == DI_OK)
break;
}
}
if (SUCCEEDED(hr))
{
goto _again;
}
}
if( hr == DIERR_NOTACQUIRED )
{
return;
}
//获取鼠标按键信息
if( SUCCEEDED( hr ))
{
if( dims.rgbButtons[0] & 0x80 ) //按下
MouseButton[0]=1;
else
MouseButton[0]=0; //没有按下
if( dims.rgbButtons[1] & 0x80 )
MouseButton[1]=1;
else
MouseButton[1]=0;
}
}
}
//等待鼠标输入,程序中断
bool WINAPI CMouse::WaitMouse(char act)
{
char Button=GetMouseData();
while( Button != act )
{
Button=GetMouseData();
}
return true;
}
//某键当前是否按下 0=左 1=右 2=中 4=左右
bool WINAPI CMouse::IsButton( char Button )
{
GetMouseState();
if( Button==4 )
{
if( MouseButton[0] && MouseButton[1] ) //按下
while(1)
{
GetMouseState();
if( GetAsyncKeyState( VK_RETURN ) ) break;
if( !MouseButton[0] || !MouseButton[1] ) //松开
return true;
}
}
else
if( MouseButton[Button] ) //按下
while(1)
{
GetMouseState();
if( GetAsyncKeyState( VK_RETURN ) ) break;
if( !MouseButton[Button] ) //松开
return true;
}
return false;
}
//返回当前按下某键 0=左 1=右 2=中 4=左右 -1=无
char WINAPI CMouse::DownButton()
{
GetMouseState();
if( MouseButton[0] && MouseButton[1] ) //左右
return 4;
if( MouseButton[0] ) //左
return 0;
if( MouseButton[1] ) //右
return 1;
return -1;
}
/////////////////////////////////////////////////////////////////
//KEYBOARD
/////////////////////////////////////////////////////////////////
CKey::CKey()
{
memset( KeyState, 0, 256);
memset( KeyBuffer, 0, KEYBUFFERSIZE );
KeyBuffer_Start = KeyBuffer_End = 0;
}
CKey::~CKey()
{
}
//初始化DIRECTINPUT设备
bool WINAPI CKey::InitInput_Key(HWND hWnd)
{
HRESULT hr;
//返回一个DIRECTINPUT设备的指针
hr=lpDI->CreateDevice(GUID_SysKeyboard, &lpDIKey, NULL);
if( FAILED(hr) )
{
FreeInput_Key();
return false;
}
//设置数据格式
hr=lpDIKey->SetDataFormat(&c_dfDIKeyboard);
if( FAILED(hr) )
{
FreeInput_Key();
return false;
}
//设置协作层
hr=lpDIKey->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
if( FAILED(hr) )
{
FreeInput_Key();
return false;
}
//设置属性
DIPROPDWORD property;
property.diph.dwSize=sizeof(DIPROPDWORD);
property.diph.dwHeaderSize=sizeof(DIPROPHEADER);
property.diph.dwObj=0;
property.diph.dwHow=DIPH_DEVICE;
property.dwData=KEYBUFFERSIZE;
hr = lpDIKey->SetProperty(DIPROP_BUFFERSIZE, &property.diph);
if FAILED(hr)
{
// 设置缓冲区失败
MessageBox(hWnd, "error on set Key Buffer size", "error", MB_OK);
return FALSE;
}
//得到设备通道
hr=lpDIKey->Acquire();
if( FAILED(hr) )
{
FreeInput_Key();
return false;
}
return true;
}
//获取设备
HRESULT WINAPI CKey::SetAcquire( HWND hDlg )
{
if ( NULL == lpDIKey )
return S_FALSE;
if (bActive)
{
lpDIKey->Acquire();
}
else
{
lpDIKey->Unacquire();
}
return S_OK;
}
//释放DIRECTINPUT设备KEY
void WINAPI CKey::FreeInput_Key()
{
if( lpDIKey )
{
lpDIKey->Unacquire();
lpDIKey->Release();
lpDIKey=NULL;
}
}
//获取键盘即时数据
void WINAPI CKey::GetKeyState()
{
HRESULT hr;
hr=lpDIKey->GetDeviceState(256, (LPVOID)&KeyState);
if( FAILED(hr) )
{
lpDIKey->Acquire();
hr=lpDIKey->GetDeviceState(256, (LPVOID)&KeyState);
}
}
//检测一个键当前是否按下
bool WINAPI CKey::KeyDown(unsigned char Key)
{
GetKeyState();
if( KEYDOWN(KeyState, Key))
{
return true;
}
return false;
}
//返回一个键是否按下
bool WINAPI CKey::GetState(unsigned char Key)
{
if( KEYDOWN(KeyState, Key))
{
return true;
}
return false;
}
//***************************
//返回键盘缓冲区数据(附带即时数据)
void WINAPI CKey::GetKeyData()
{
DIDEVICEOBJECTDATA rgdod[KEYBUFFERSIZE];
DWORD dwItems = KEYBUFFERSIZE;
_again:
HRESULT hr = lpDIKey->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
if(hr != DI_OK)
{
for(int i=0; i<256; i++) //清0
KeyState[i] = 0;
if( FAILED(hr) )
{
hr = lpDIKey->Acquire();
if FAILED(hr)
{
return;
}
if SUCCEEDED(hr)
{
goto _again;
}
}
}
if( SUCCEEDED(hr) && dwItems>0 )
{
for(DWORD i=0; i<dwItems; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -