我是天心飞仙 - 2006-8-16 12:53:00
获取外部设备的状态是游戏中必不可少的部分,但是看到很多初学者并不能很好的组织DirectInput,以至于被那些复杂的接口搞得晕头转向。故有此文。
封装要做的工作就是,把那些复杂的接口,做成你自己“看得惯”的东西:)
DI的封装主要有以下几个部分:
[1]Initialize 初始化DI控制组件
[2]GetDevices 获取输入设备状态
[3]SetMousePos 设置鼠标位置
[4]Release 释放DI控制组件
我是天心飞仙 - 2006-8-16 12:54:00
先来看看封装的头文件 MyDirectInput.h
///////////////////////////////////////////////////////////////////////////////
//MyDirectInput.h
//DirectInput封装
///////////////////////////////////////////////////////////////////////////////
#pragma once
#pragma message("MyDirectInput.h --> Linking with dinput8.lib")
#pragma comment(lib,"dinput8.lib")
#include <windows.h>
#include <windowsx.h>
#include <dinput.h>
//DI对象
extern LPDIRECTINPUT8 lpDInput = NULL;
extern LPDIRECTINPUTDEVICE8 lpDIKey = NULL;
extern LPDIRECTINPUTDEVICE8 lpDIMouse = NULL;
//数据缓冲
extern UCHAR key[256];
extern DIMOUSESTATE mouse_state;
//封装接口
extern BOOL Initialize(void ); //初始化
extern BOOL GetDevices(void ); //获取设备
extern BOOL SetMousePos(POINT ); //设置鼠标位置
extern BOOL SetMousePos(long ,long );
extern BOOL Release(void ); //释放
//封装变量
extern BOOL mleft,mright,mcenter; //鼠标按键状态
extern POINT mpt; //鼠标指针位置
我是天心飞仙 - 2006-8-16 12:55:00
再来看实现部分 MyDirectInput.cpp :
///////////////////////////////////////////////////////////////////////////////
//MyDirectInput.cpp
///////////////////////////////////////////////////////////////////////////////
#include "MyDirectInput.h"
#include <windows.h>
#include <windowsx.h>
#include <dinput.h>
///////////////////////////////////////////////////////////////////////////////
extern HWND hWnd;
extern HINSTANCE hInstance;
extern char buffer[80];
//DI对象
LPDIRECTINPUT8 lpDInput = NULL;
LPDIRECTINPUTDEVICE8 lpDIKey = NULL;
LPDIRECTINPUTDEVICE8 lpDIMouse = NULL;
//数据缓冲
UCHAR key[256];
DIMOUSESTATE mouse_state;
BOOL mleft,mright,mcenter;
POINT mpt;
///////////////////////////////////////////////////////////////////////////////
//[1]Initialize 初始化DI控制组件
//分析:游戏中最常用的两个输入设备就是鼠标和键盘,我们的这个封装就是要完成这对两个设备状态的操作。
// 初始化部分,首先要创建DirectInput对象,再创建设备对象。
///////////////////////////////////////////////////////////////////////////////
BOOL Initialize(void )
{
//DirectInput Interface
if(FAILED(DirectInput8Create(hInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,(VOID**)&lpDInput,NULL)))
{
ShowError("DirectInput8Create ERROR");
return FALSE;
}
//Keyboard
if(lpDI->CreateDevice(GUID_SysKeyboard,&lpDIKey,NULL)!=DI_OK)
{
ShowError("lpDI->CreateDevice Keyboard ERROR");
return FALSE;
}
if(lpDIKey->SetCooperativeLevel(hWnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE|DISCL_NOWINKEY)!==DI_OK)
{
ShowError("lpDIKeyboard->SetCooperativeLevel ERROR");
return False;
}
if(lpDIKey->SetDataFormat(&c_dfDIKeyboard)!=DI_OK)
{
ShowError("lpDIKeyboard->SetDataFormat ERROR");
return False;
}
if(lpDIKey->Aquire()!=DI_OK)
{
ShowError("lpDIKeyboard->Acquire ERROR");
return False;
}
//Mouse
if(lpDI->CreateDevice(GUID_SysKeyboard,&lpDIMouse,NULL)!=DI_OK)
{
ShowError("lpDI->CreateDevice Mouse ERROR");
return FALSE;
}
if(lpDIMouse->SetCooperativeLevel(hWnd,DISCL_BACKGROUND|DISCL_EXCLUSIVE|DISCL_NOWINKEY)!==DI_OK)
{
ShowError("lpDIMouse->SetCooperativeLevel ERROR");
return False;
}
if(lpDIMouse->SetDataFormat(&c_dfDIMouse)!=DI_OK)
{
ShowError("lpDIMouse->SetDataFormat ERROR");
return False;
}
if(lpDIMouse->Aquire()!=DI_OK)
{
ShowError("lpDIMouse->Acquire ERROR");
return False;
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//[2]GetDevices 获取输入设备状态
//分析:未经封装的设备状态使用十分不便,这个函数统一获取了有用的状态,以便集中调用
///////////////////////////////////////////////////////////////////////////////
BOOL GetDevices(void )
{
//获取设备信息
lpDIKey->GetDeviceState(256,(LPVOID)key);
lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE)),(LPVOID)&mouse);
//调整按键状态
if(mouse.rgbButtons[0]&0x80) mleft = TRUE; //左键
if(mouse.rgbButtons[1]&0x80) mright = TRUE; //右键
if(mouse.rgbButtons[2]&0x80) mcenter = TRUE; //中键
//调整鼠标位置
//注意,mouse.lX 和 mouse.lY 都是相对于上一次的偏移量!
mpt.x += mouse.lX;
mpt.y += mouse.lY;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//[3]SetMousePos 设置鼠标位置
//分析:由于mouse状态中的lX和lY都是偏移量,所以可以通过直接修改mpt的方法设置鼠标位置
//注意:这个函数有多态性
///////////////////////////////////////////////////////////////////////////////
BOOL SetMousePos(POINT pt )
{
mpt = pt;
return TRUE;
}
BOOL SetMousePos(long x ,long y )
{
mpt.x = x;
mpt.y = y;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
//[4]Release 释放DI控制组件
//注意:由于初始化时创建的顺序不同,所以要相对应的一次释放对象
///////////////////////////////////////////////////////////////////////////////
BOOL Release(void )
{
if(lpDIMouse){
lpDIMouse->Unacquire();
lpDIMouse->Release();
}
if(lpDIKey){
lpDIKeyboardboard->Unacquire();
lpDIKeyboardboard->Release();
}
if(lpDInput){
lpDI->Release();
}
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
我是天心飞仙 - 2006-8-16 12:59:00
注意:实现部分的错误处理我用了 ShowError这个函数,它不是标准的函数,只是我自己创建的一个便于输入的函数。内容如下:
void ShowError(const char * msg)
{
MessageBox(NULL,msg,"Error!",MB_OK);
}
(本文结)
我是天心飞仙 - 2006-8-17 12:06:00
无人区?
郁闷ing...
© 2000 - 2026 Rising Corp. Ltd.