作为标准的输入设备,鼠标在应用程序中也不可或缺。进入Windows时代后,有些工作没有鼠标基本上就无法完成。在游戏中也可以看到不少人左手键盘,右手鼠标,共同冲锋陷阵。DirectInput对鼠标的支持和对键盘的支持相同,使用鼠标的过程也和使用键盘的过程一样。
首先是初始化DirectInput,需要对DXInit进行修改。
#include <dinput.h>
LPDIRECTINPUT8 g_DI;
LPDIRECTINPUTDEVICE8 g_KDIDev;
LPDIRECTINPUTDEVICE8 g_MDIDev; //鼠标输入设备
int DXInit()
{
//先创建DirectInput对象
if ( DirectInput8Create(hInst, // 应用程序实例句柄
DIRECTINPUT_VERSION, // Direct Input版本
IID_IDirectInput8,
(void**)&g_DI, // Direct Input对象
NULL ) ) // 指向IUnknown接口的指针,通常取NULL
{
return FALSE; // 初始化失败就返回FALSE
}
// 创建键盘设备
...
//开始创建鼠标输入设备
hr= g_DI->CreateDevice(GUID_SysMouse, &g_MDIDev, NULL);
if(FAILED(hr))
{
return FALSE;
}
//设置鼠标的数据格式
hr= g_MDIDev->SetDataFormat(&c_dfDIMouse);
if(FAILED(hr))
{
return FALSE;
}
//设置鼠标工作的协作等级
hr= g_MDIDev->SetCooperativeLevel(g_hWnd, DISCL_FOREGROUND |
DISCL_NONEXCLUSIVE);
if(FAILED(hr))
{
return FALSE;
}
//获得鼠标设备
hr= g_MDIDev->Acquire();
if(FAILED(hr))
{
return FALSE;
}
return TRUE;
}
在关闭DirectInput的函数DXShutdown中也增加有关鼠标设备的部分。
void DXShutdown()
{
if (g_DI)
{
...
//增加释放鼠标设备的部分
//注意,鼠标设备和键盘设备都属于同一个DirectInput对象
if(g_MDIDev!=NULL)
{
g_MDIDev->Unacquire();
g_MDIDev->Release();
g_MDIDev= NULL;
}
g_DI->Release();
g_DI = NULL;
}
}
当应用程序切换到后台时,程序会失去输入设备,因此在WndProc中也需要增加对鼠标设备的重新获取处理。
LRESULT CALLBACK WndProc(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_ACTIVATE: //程序处于活动状态
{
if (!HIWORD(wParam))
{
active=TRUE;
}
else
{
active=FALSE;
}
// 如果键盘设备或者鼠标设备为空,就直接返回
if (NULL == g_KDIDev || NULL == g_MDIDev)
return S_FALSE;
if (active)
{
// 获得键盘和鼠标输入设备
g_KDIDev->Acquire();
g_MDIDev->Acquire();
}
else
{
// 失去输入设备,增加鼠标设备
g_KDIDev->Unacquire();
g_MDIDev->Unacquire();
}
return 0;
}
……
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
在glMain中增加对鼠标数据的接收。
int glMain(GLvoid)
{
HRESULT hr;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//获取键盘输入设备的数据,保存在buffer中
hr= g_KDIDev->GetDeviceState(sizeof(buffer), &buffer);
//获取鼠标输入数据,保存在mouseState中
hr= (g_MDIDev->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouseState));
//对键盘和鼠标输入进行处理
if(!KeyPressed())
return FALSE;
……
return TRUE;
}
同样在KeyPressed中也要增加对鼠标数据的处理,
int KeyPressed()
{
……
if(buffer[DIK_RIGHT]) //向右转
{
g_Camera.RotateView(-kSpeed, 0, 1, 0);
}
//前面是对键盘输入的处理,后面是对鼠标输入的处理
//按鼠标左键表示视点向上方移动
if(mouseState.rgbButtons[MOUSE_LEFT] & 0x80)
{
g_Camera.m_vPosition.y +=kSpeed;
g_Camera.m_vView.y +=kSpeed; }
//按鼠标右键表示视点向下方移动
if(mouseState.rgbButtons[MOUSE_RIGHT] & 0x80)
{
g_Camera.m_vPosition.y -=kSpeed;
g_Camera.m_vView.y -=kSpeed;
}
return TRUE;
}