主窗口和DirectInput的封装
注:GE是GameEngine的缩写。
GE_APP类解决应用程序的窗口创建问题,为了突出消息处理,这个类并没有更抽象地将窗口程序的消息循环体代码进行封装。因此,这里的应用程序架构是创建窗口(包括注册窗口类,创建窗口,显示窗口,设置窗口回调函数的默认处理),然后继续使用消息循环体,读取键盘和鼠标的输入等,进行一帧的渲染或其他处理。
命名约定:
(1)类采用大写和下划线,如 GE_APP。
(2)类里面的成员变量如果是private或者protected类型,采用下划线开始,紧接着小写字母,如 _data。
(3)类里面的成员变量如果是public类型,采用m_开始, 紧接着小写字母,如m_data。
(4)类里面的方法如果是private或者protected类型,采用下划线开始,紧接着大写字母,如 _Func()。
(5)类里面的方法如果是public类型,采用大写字母开始,如 Func()。
(6)不管是变量还是函数都不采用大小写混合命名,而采用下划线,以更有利于阅读。
(7)目前编译器的及时信提示功能已经十分强大,这里将不采用匈牙利命名法,以免影响代码阅读。
由于本人水平有限,代码中可能有错误,如若发现,敬请指出。
源码下载
需要在工程中设置链接dxguid.lib和dinput8.lib。
首先定义1个头文件GE_COMMON.h,来包含公用的头文件。
GE_COMMON.h
接着定义GE_APP.h
GE_APP.cpp
现在封装DirectInput。
GE_INPUT.h
GE_INPUT.cpp
测试程序,由于身边没有游戏手柄,所以无法测试关于Joystick的代码,这个测试程序存在一些BUG,但大体能用。
GE_APP类解决应用程序的窗口创建问题,为了突出消息处理,这个类并没有更抽象地将窗口程序的消息循环体代码进行封装。因此,这里的应用程序架构是创建窗口(包括注册窗口类,创建窗口,显示窗口,设置窗口回调函数的默认处理),然后继续使用消息循环体,读取键盘和鼠标的输入等,进行一帧的渲染或其他处理。
命名约定:
(1)类采用大写和下划线,如 GE_APP。
(2)类里面的成员变量如果是private或者protected类型,采用下划线开始,紧接着小写字母,如 _data。
(3)类里面的成员变量如果是public类型,采用m_开始, 紧接着小写字母,如m_data。
(4)类里面的方法如果是private或者protected类型,采用下划线开始,紧接着大写字母,如 _Func()。
(5)类里面的方法如果是public类型,采用大写字母开始,如 Func()。
(6)不管是变量还是函数都不采用大小写混合命名,而采用下划线,以更有利于阅读。
(7)目前编译器的及时信提示功能已经十分强大,这里将不采用匈牙利命名法,以免影响代码阅读。
由于本人水平有限,代码中可能有错误,如若发现,敬请指出。
源码下载
需要在工程中设置链接dxguid.lib和dinput8.lib。
首先定义1个头文件GE_COMMON.h,来包含公用的头文件。
GE_COMMON.h
/*
************************************************************************************
[Include File]
PURPOSE:
Include Common header files.
************************************************************************************ */
#ifndef GAME_ENGINE_COMMON_H
#define GAME_ENGINE_COMMON_H
#define DIRECTINPUT_VERSION 0x0800 // let compile shut up
#include < windows.h >
#include < tchar.h >
#include < string .h >
#include < stdio.h >
#include < d3d9.h >
#include < d3dx9.h >
#include < dinput.h >
#include < dsound.h >
#define Safe_Release(object) if((object) != NULL) { (object)->Release(); (object)=NULL; }
#endif
[Include File]
PURPOSE:
Include Common header files.
************************************************************************************ */
#ifndef GAME_ENGINE_COMMON_H
#define GAME_ENGINE_COMMON_H
#define DIRECTINPUT_VERSION 0x0800 // let compile shut up
#include < windows.h >
#include < tchar.h >
#include < string .h >
#include < stdio.h >
#include < d3d9.h >
#include < d3dx9.h >
#include < dinput.h >
#include < dsound.h >
#define Safe_Release(object) if((object) != NULL) { (object)->Release(); (object)=NULL; }
#endif
接着定义GE_APP.h
/*
************************************************************************************
[Include File]
PURPOSE:
Create Game Main Window Framework.
************************************************************************************ */
#ifndef GAME_ENGINE_APP_H
#define GAME_ENGINE_APP_H
#include " GE_COMMON.h "
#define WINDOW_CLASS_NAME "MY_GAME"
class GE_APP
{
private :
HWND _wnd;
WNDCLASSEX _wnd_class;
public :
GE_APP() {};
~ GE_APP() {};
WNDCLASSEX Get_Window_Class() { return _wnd_class; }
HWND Get_Window_Handle() { return _wnd; }
bool Create_Window(LPCTSTR win_title, HINSTANCE instance, int cmd_show);
static LRESULT CALLBACK Window_Proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
private :
ATOM _Reg_Window_Class(HINSTANCE instance);
};
#endif
[Include File]
PURPOSE:
Create Game Main Window Framework.
************************************************************************************ */
#ifndef GAME_ENGINE_APP_H
#define GAME_ENGINE_APP_H
#include " GE_COMMON.h "
#define WINDOW_CLASS_NAME "MY_GAME"
class GE_APP
{
private :
HWND _wnd;
WNDCLASSEX _wnd_class;
public :
GE_APP() {};
~ GE_APP() {};
WNDCLASSEX Get_Window_Class() { return _wnd_class; }
HWND Get_Window_Handle() { return _wnd; }
bool Create_Window(LPCTSTR win_title, HINSTANCE instance, int cmd_show);
static LRESULT CALLBACK Window_Proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
private :
ATOM _Reg_Window_Class(HINSTANCE instance);
};
#endif
GE_APP.cpp
/*
************************************************************************************
[Implement File]
PURPOSE:
Create Game Main Window Framework.
************************************************************************************ */
#include " GE_COMMON.h "
#include " GE_APP.h "
// ------------------------------------------------------------------------------------
// Create a window by specified title and show type.
// ------------------------------------------------------------------------------------
bool GE_APP::Create_Window(LPCTSTR win_title, HINSTANCE instance, int cmd_show)
{
// regiter window class
_Reg_Window_Class(instance);
// create a window
_wnd = CreateWindow(WINDOW_CLASS_NAME, win_title, WS_SYSMENU | WS_CAPTION | WS_VISIBLE,
CW_USEDEFAULT, 0 , CW_USEDEFAULT, 0 , NULL, NULL, instance, NULL);
if (_wnd == NULL)
// create failed
return false ;
// sets the specified window's show state
ShowWindow(_wnd, cmd_show);
// updates the client area of the specified window
UpdateWindow(_wnd);
return true ;
}
// ------------------------------------------------------------------------------------
// Registers a window class for subsequent use in calls to the CreateWindow
// or CreateWindowEx function.
//
// If the function succeeds, the return value is a class atom that uniquely
// identifies the class being registered.
// If the function fails, the return value is zero.
// ------------------------------------------------------------------------------------
ATOM GE_APP::_Reg_Window_Class(HINSTANCE instance)
{
_wnd_class.cbSize = sizeof (WNDCLASSEX);
_wnd_class.style = CS_HREDRAW | CS_VREDRAW;
_wnd_class.lpfnWndProc = (WNDPROC) Window_Proc;
_wnd_class.cbClsExtra = 0 ;
_wnd_class.cbWndExtra = 0 ;
_wnd_class.hInstance = instance;
_wnd_class.hIcon = 0 ;
_wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
_wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
_wnd_class.lpszMenuName = 0 ;
_wnd_class.lpszClassName = WINDOW_CLASS_NAME;
_wnd_class.hIconSm = NULL;
return RegisterClassEx( & _wnd_class);
}
// --------------------------------------------------------------------------
// Callback function, handle message return by windows.
// --------------------------------------------------------------------------
LRESULT CALLBACK GE_APP::Window_Proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage( 0 );
break ;
}
return DefWindowProc(wnd, msg, wParam, lParam);
}
[Implement File]
PURPOSE:
Create Game Main Window Framework.
************************************************************************************ */
#include " GE_COMMON.h "
#include " GE_APP.h "
// ------------------------------------------------------------------------------------
// Create a window by specified title and show type.
// ------------------------------------------------------------------------------------
bool GE_APP::Create_Window(LPCTSTR win_title, HINSTANCE instance, int cmd_show)
{
// regiter window class
_Reg_Window_Class(instance);
// create a window
_wnd = CreateWindow(WINDOW_CLASS_NAME, win_title, WS_SYSMENU | WS_CAPTION | WS_VISIBLE,
CW_USEDEFAULT, 0 , CW_USEDEFAULT, 0 , NULL, NULL, instance, NULL);
if (_wnd == NULL)
// create failed
return false ;
// sets the specified window's show state
ShowWindow(_wnd, cmd_show);
// updates the client area of the specified window
UpdateWindow(_wnd);
return true ;
}
// ------------------------------------------------------------------------------------
// Registers a window class for subsequent use in calls to the CreateWindow
// or CreateWindowEx function.
//
// If the function succeeds, the return value is a class atom that uniquely
// identifies the class being registered.
// If the function fails, the return value is zero.
// ------------------------------------------------------------------------------------
ATOM GE_APP::_Reg_Window_Class(HINSTANCE instance)
{
_wnd_class.cbSize = sizeof (WNDCLASSEX);
_wnd_class.style = CS_HREDRAW | CS_VREDRAW;
_wnd_class.lpfnWndProc = (WNDPROC) Window_Proc;
_wnd_class.cbClsExtra = 0 ;
_wnd_class.cbWndExtra = 0 ;
_wnd_class.hInstance = instance;
_wnd_class.hIcon = 0 ;
_wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
_wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
_wnd_class.lpszMenuName = 0 ;
_wnd_class.lpszClassName = WINDOW_CLASS_NAME;
_wnd_class.hIconSm = NULL;
return RegisterClassEx( & _wnd_class);
}
// --------------------------------------------------------------------------
// Callback function, handle message return by windows.
// --------------------------------------------------------------------------
LRESULT CALLBACK GE_APP::Window_Proc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage( 0 );
break ;
}
return DefWindowProc(wnd, msg, wParam, lParam);
}
现在封装DirectInput。
GE_INPUT.h
/*
************************************************************************************
[Include File]
PURPOSE:
Create Game Input handle module.
************************************************************************************ */
#ifndef GAME_ENGINE_INPUT_H
#define GAME_ENGINE_INPUT_H
#include " GE_COMMON.h "
#define ITEMS_NUM 10
static LPDIRECTINPUT8 g_directinput = NULL;
BOOL CALLBACK Enum_Joystick(LPCDIDEVICEINSTANCE device_instance, LPVOID data);
class GE_INPUT
{
private :
bool _use_joystick;
LPDIRECTINPUTDEVICE8 _keyboard;
LPDIRECTINPUTDEVICE8 _mouse;
LPDIRECTINPUTDEVICE8 _joystick;
char _key_buffer[ 256 ]; // keyboad buffer (immediate mode)
DIDEVICEOBJECTDATA _mouse_buffer[ITEMS_NUM]; // mouse data buffer (buffer mode)
DIJOYSTATE2 _joystick_buffer; // joystick buffer (immediate mode)
long _left_mouse_move_x, _left_mouse_move_y; // mouse move coordinate
public :
GE_INPUT();
~ GE_INPUT();
void Create_Input(HINSTANCE instance, HWND hwnd, int min = - 100 , int max = 100 ,
int dead_zone = 20 , bool use_joystick = false );
bool Read_Keyboard();
bool Read_Mouse();
bool Read_Joystick();
bool Is_LButton_Pressed();
bool Is_RButton_Pressed();
bool Is_MButton_Pressed();
// Judge which key user has been pressed
bool Is_Key_Pressed( int key) { return (_key_buffer[key] & 0x80 ? true : false ); }
long Get_Mouse_Move_X() { return _left_mouse_move_x; }
long Get_Mouse_Move_Y() { return _left_mouse_move_y; }
// Judge which joystick button has been pressed
bool Is_JSButton_Pressed( int button)
{
return (_joystick_buffer.rgbButtons[button] & 0x80 ) ? true : false ;
}
private :
bool _Create_Directinput(HINSTANCE instance);
bool _Create_Keyboard(HWND hwnd);
bool _Create_Mouse(HWND hwnd);
bool _Create_Joystick(HWND hwnd, int min, int max, int dead_zone);
void _Release_Input();
};
#endif
[Include File]
PURPOSE:
Create Game Input handle module.
************************************************************************************ */
#ifndef GAME_ENGINE_INPUT_H
#define GAME_ENGINE_INPUT_H
#include " GE_COMMON.h "
#define ITEMS_NUM 10
static LPDIRECTINPUT8 g_directinput = NULL;
BOOL CALLBACK Enum_Joystick(LPCDIDEVICEINSTANCE device_instance, LPVOID data);
class GE_INPUT
{
private :
bool _use_joystick;
LPDIRECTINPUTDEVICE8 _keyboard;
LPDIRECTINPUTDEVICE8 _mouse;
LPDIRECTINPUTDEVICE8 _joystick;
char _key_buffer[ 256 ]; // keyboad buffer (immediate mode)
DIDEVICEOBJECTDATA _mouse_buffer[ITEMS_NUM]; // mouse data buffer (buffer mode)
DIJOYSTATE2 _joystick_buffer; // joystick buffer (immediate mode)
long _left_mouse_move_x, _left_mouse_move_y; // mouse move coordinate
public :
GE_INPUT();
~ GE_INPUT();
void Create_Input(HINSTANCE instance, HWND hwnd, int min = - 100 , int max = 100 ,
int dead_zone = 20 , bool use_joystick = false );
bool Read_Keyboard();
bool Read_Mouse();
bool Read_Joystick();
bool Is_LButton_Pressed();
bool Is_RButton_Pressed();
bool Is_MButton_Pressed();
// Judge which key user has been pressed
bool Is_Key_Pressed( int key) { return (_key_buffer[key] & 0x80 ? true : false ); }
long Get_Mouse_Move_X() { return _left_mouse_move_x; }
long Get_Mouse_Move_Y() { return _left_mouse_move_y; }
// Judge which joystick button has been pressed
bool Is_JSButton_Pressed( int button)
{
return (_joystick_buffer.rgbButtons[button] & 0x80 ) ? true : false ;
}
private :
bool _Create_Directinput(HINSTANCE instance);
bool _Create_Keyboard(HWND hwnd);
bool _Create_Mouse(HWND hwnd);
bool _Create_Joystick(HWND hwnd, int min, int max, int dead_zone);
void _Release_Input();
};
#endif
GE_INPUT.cpp
/*
************************************************************************************
[Implement File]
PURPOSE:
Create Game Input handle module.
************************************************************************************ */
#include " GE_COMMON.h "
#include " GE_INPUT.h "
// ------------------------------------------------------------------------------------
// Constructor, initialize data.
// ------------------------------------------------------------------------------------
GE_INPUT::GE_INPUT()
{
_use_joystick = false ;
_keyboard = NULL;
_mouse = NULL;
_joystick = NULL;
_left_mouse_move_x = 0 ;
_left_mouse_move_y = 0 ;
}
// ------------------------------------------------------------------------------------
// Destructor, Release input resource.
// ------------------------------------------------------------------------------------
GE_INPUT:: ~ GE_INPUT()
{
_Release_Input();
}
// ------------------------------------------------------------------------------------
// Release all input resource.
// ------------------------------------------------------------------------------------
void GE_INPUT::_Release_Input()
{
// Releases access to keyboard
if (_keyboard)
_keyboard -> Unacquire();
// Releases access to mouse
if (_mouse)
_mouse -> Unacquire();
// Releases access to joystick
if (_use_joystick && (_joystick != NULL))
_joystick -> Unacquire();
// release keyboard and mouse
Safe_Release(_keyboard);
Safe_Release(_mouse);
// release joystick
if (_use_joystick)
Safe_Release(_joystick);
Safe_Release(g_directinput);
}
// ------------------------------------------------------------------------------------
// Create directinput, include keybrad, mouse, joystick.
// ------------------------------------------------------------------------------------
void GE_INPUT::Create_Input(HINSTANCE instance, HWND hwnd, int min, int max, int dead_zone, bool use_joystick)
{
_Create_Directinput(instance);
_Create_Keyboard(hwnd);
_Create_Mouse(hwnd);
if (use_joystick)
_Create_Joystick(hwnd, min, max, dead_zone);
}
// ------------------------------------------------------------------------------------
// Creates a Microsoft DirectInput object.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Directinput(HINSTANCE instance)
{
if (FAILED(DirectInput8Create(instance, DIRECTINPUT_VERSION, IID_IDirectInput8, ( void ** ) & g_directinput, NULL)))
{
MessageBox(NULL, " Create Directinput object failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Create keyboard device.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Keyboard(HWND hwnd)
{
// create keyboard device
if (FAILED(g_directinput -> CreateDevice(GUID_SysKeyboard, & _keyboard, NULL)))
{
MessageBox(NULL, " DirectInput interface create failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Sets the data format for the Microsoft DirectInput device.
if (FAILED(_keyboard -> SetDataFormat( & c_dfDIKeyboard)))
{
MessageBox(NULL, " Set data format with keyboard read mode failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Establishes the cooperative level for this instance of the device.
// The cooperative level determines how this instance of the device interacts with other instances
// of the device and the rest of the system.
if (FAILED(_keyboard -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set cooperative Leve failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Obtains access to the keyboard device
if (FAILED(_keyboard -> Acquire()))
{
MessageBox(NULL, " Acquire keyboard access failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// zero keyboard buffer
ZeroMemory(_key_buffer, sizeof ( char ) * 256 );
return true ;
}
// ------------------------------------------------------------------------------------
// Read keyboard data from buffer.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Keyboard()
{
if (DIERR_INPUTLOST == _keyboard -> GetDeviceState( sizeof (_key_buffer), (LPVOID) _key_buffer))
{
// re-acquire access to keyboard
_keyboard -> Acquire();
if (FAILED(_keyboard -> GetDeviceState( sizeof (_key_buffer), (LPVOID) _key_buffer)))
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Create mouse device.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Mouse(HWND hwnd)
{
// create mouse input device
if (FAILED(g_directinput -> CreateDevice(GUID_SysMouse, & _mouse, NULL)))
{
MessageBox(NULL, " Create mouse input device failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set data format for mouse
if (FAILED(_mouse -> SetDataFormat( & c_dfDIMouse)))
{
MessageBox(NULL, " Set mouse data format failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set cooperative level for mouse
if (FAILED(_mouse -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set mouse cooperative level failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set property for mouse
DIPROPDWORD device_prop;
device_prop.diph.dwSize = sizeof (DIPROPDWORD);
device_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
device_prop.diph.dwObj = 0 ;
device_prop.diph.dwHow = DIPH_DEVICE;
device_prop.dwData = ITEMS_NUM;
if (FAILED(_mouse -> SetProperty(DIPROP_BUFFERSIZE, & device_prop.diph)))
{
MessageBox(NULL, " Set property for mouse failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// get access to mouse
if (FAILED(_mouse -> Acquire()))
{
MessageBox(NULL, " Get access to mouse failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Read data from mouse buffer.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Mouse()
{
DWORD read_num = 1 ;
// zero mouse buffer before reading data
ZeroMemory(_mouse_buffer, sizeof (DIDEVICEOBJECTDATA) * ITEMS_NUM);
// read all mouse data from buffer
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if (DIERR_INPUTLOST == _mouse -> GetDeviceData( sizeof (DIDEVICEOBJECTDATA), & _mouse_buffer[i], & read_num, 0 ))
{
_mouse -> Acquire();
if (FAILED(_mouse -> GetDeviceData( sizeof (DIDEVICEOBJECTDATA), & _mouse_buffer[i], & read_num, 0 )))
return false ;
}
if (_mouse_buffer[i].dwOfs == DIMOFS_X)
_left_mouse_move_x += _mouse_buffer[i].dwData;
if (_mouse_buffer[i].dwOfs == DIMOFS_Y)
_left_mouse_move_y += _mouse_buffer[i].dwData;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Judge whether left mouse button has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_LButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON0) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Judge whether right mouse button has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_RButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON1) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Judge whether mouse wheel has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_MButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON2) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Create joystick.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Joystick(HWND hwnd, int min, int max, int dead_zone)
{
// Enumerates all joystick that have been installed successfully
if (FAILED(g_directinput -> EnumDevices(DI8DEVCLASS_GAMECTRL, Enum_Joystick, & _joystick, DIEDFL_ATTACHEDONLY)))
{
MessageBox(NULL, " Enumerate joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
if (_joystick == NULL)
{
MessageBox(NULL, " There is no joystick has been installed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set data format for mouse
if (FAILED(_mouse -> SetDataFormat( & c_dfDIJoystick2)))
{
MessageBox(NULL, " Set joystick data format failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set cooperative level for mouse
if (FAILED(_mouse -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set joystick cooperative level failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set property for mouse
DIPROPRANGE device_prop;
device_prop.diph.dwSize = sizeof (DIPROPRANGE);
device_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
device_prop.diph.dwObj = 0 ;
device_prop.diph.dwHow = DIPH_DEVICE;
device_prop.lMin = min;
device_prop.lMax = max;
if (FAILED(_joystick -> SetProperty(DIPROP_RANGE, & device_prop.diph)))
{
MessageBox(NULL, " Set property range for joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set dead zone for joystick
DIPROPDWORD dead_zone_prop;
dead_zone_prop.diph.dwSize = sizeof (DIPROPDWORD);
dead_zone_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
dead_zone_prop.diph.dwObj = 0 ;
dead_zone_prop.diph.dwHow = DIPH_DEVICE;
dead_zone_prop.dwData = 100 * dead_zone;DIPROP_DEADZONE;
if (FAILED(_joystick -> SetProperty(DIPROP_DEADZONE, & dead_zone_prop.diph)))
{
MessageBox(NULL, " Set dead zone for joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// zero joystick buffer
ZeroMemory( & _joystick, sizeof (DIJOYSTATE2));
return true ;
}
// ------------------------------------------------------------------------------------
// Read data from joystick.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Joystick()
{
// get access to joystick
if (FAILED(_joystick -> Acquire()))
return false ;
// polling joystick to retrieve data
if (FAILED(_joystick -> Poll()))
return false ;
// get joystick current state
if (DIERR_INPUTLOST == _joystick -> GetDeviceState( sizeof (DIJOYSTATE2), & _joystick_buffer))
{
// re-acquire access to joystick
_joystick -> Acquire();
if (FAILED(_joystick -> GetDeviceState( sizeof (DIJOYSTATE2), & _joystick_buffer)))
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Application-defined callback function that receives Microsoft DirectInput devices
// as a result of a call to the IDirectInput8::EnumDevices method.
// ------------------------------------------------------------------------------------
BOOL CALLBACK Enum_Joystick(LPCDIDEVICEINSTANCE device_instance, LPVOID data)
{
LPDIRECTINPUTDEVICE8 * diDevice = (LPDIRECTINPUTDEVICE8 * ) data;
if (FAILED(g_directinput -> CreateDevice(device_instance -> guidInstance, diDevice, NULL)))
return DIENUM_CONTINUE;
return DIENUM_STOP;
}
[Implement File]
PURPOSE:
Create Game Input handle module.
************************************************************************************ */
#include " GE_COMMON.h "
#include " GE_INPUT.h "
// ------------------------------------------------------------------------------------
// Constructor, initialize data.
// ------------------------------------------------------------------------------------
GE_INPUT::GE_INPUT()
{
_use_joystick = false ;
_keyboard = NULL;
_mouse = NULL;
_joystick = NULL;
_left_mouse_move_x = 0 ;
_left_mouse_move_y = 0 ;
}
// ------------------------------------------------------------------------------------
// Destructor, Release input resource.
// ------------------------------------------------------------------------------------
GE_INPUT:: ~ GE_INPUT()
{
_Release_Input();
}
// ------------------------------------------------------------------------------------
// Release all input resource.
// ------------------------------------------------------------------------------------
void GE_INPUT::_Release_Input()
{
// Releases access to keyboard
if (_keyboard)
_keyboard -> Unacquire();
// Releases access to mouse
if (_mouse)
_mouse -> Unacquire();
// Releases access to joystick
if (_use_joystick && (_joystick != NULL))
_joystick -> Unacquire();
// release keyboard and mouse
Safe_Release(_keyboard);
Safe_Release(_mouse);
// release joystick
if (_use_joystick)
Safe_Release(_joystick);
Safe_Release(g_directinput);
}
// ------------------------------------------------------------------------------------
// Create directinput, include keybrad, mouse, joystick.
// ------------------------------------------------------------------------------------
void GE_INPUT::Create_Input(HINSTANCE instance, HWND hwnd, int min, int max, int dead_zone, bool use_joystick)
{
_Create_Directinput(instance);
_Create_Keyboard(hwnd);
_Create_Mouse(hwnd);
if (use_joystick)
_Create_Joystick(hwnd, min, max, dead_zone);
}
// ------------------------------------------------------------------------------------
// Creates a Microsoft DirectInput object.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Directinput(HINSTANCE instance)
{
if (FAILED(DirectInput8Create(instance, DIRECTINPUT_VERSION, IID_IDirectInput8, ( void ** ) & g_directinput, NULL)))
{
MessageBox(NULL, " Create Directinput object failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Create keyboard device.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Keyboard(HWND hwnd)
{
// create keyboard device
if (FAILED(g_directinput -> CreateDevice(GUID_SysKeyboard, & _keyboard, NULL)))
{
MessageBox(NULL, " DirectInput interface create failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Sets the data format for the Microsoft DirectInput device.
if (FAILED(_keyboard -> SetDataFormat( & c_dfDIKeyboard)))
{
MessageBox(NULL, " Set data format with keyboard read mode failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Establishes the cooperative level for this instance of the device.
// The cooperative level determines how this instance of the device interacts with other instances
// of the device and the rest of the system.
if (FAILED(_keyboard -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set cooperative Leve failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// Obtains access to the keyboard device
if (FAILED(_keyboard -> Acquire()))
{
MessageBox(NULL, " Acquire keyboard access failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// zero keyboard buffer
ZeroMemory(_key_buffer, sizeof ( char ) * 256 );
return true ;
}
// ------------------------------------------------------------------------------------
// Read keyboard data from buffer.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Keyboard()
{
if (DIERR_INPUTLOST == _keyboard -> GetDeviceState( sizeof (_key_buffer), (LPVOID) _key_buffer))
{
// re-acquire access to keyboard
_keyboard -> Acquire();
if (FAILED(_keyboard -> GetDeviceState( sizeof (_key_buffer), (LPVOID) _key_buffer)))
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Create mouse device.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Mouse(HWND hwnd)
{
// create mouse input device
if (FAILED(g_directinput -> CreateDevice(GUID_SysMouse, & _mouse, NULL)))
{
MessageBox(NULL, " Create mouse input device failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set data format for mouse
if (FAILED(_mouse -> SetDataFormat( & c_dfDIMouse)))
{
MessageBox(NULL, " Set mouse data format failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set cooperative level for mouse
if (FAILED(_mouse -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set mouse cooperative level failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set property for mouse
DIPROPDWORD device_prop;
device_prop.diph.dwSize = sizeof (DIPROPDWORD);
device_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
device_prop.diph.dwObj = 0 ;
device_prop.diph.dwHow = DIPH_DEVICE;
device_prop.dwData = ITEMS_NUM;
if (FAILED(_mouse -> SetProperty(DIPROP_BUFFERSIZE, & device_prop.diph)))
{
MessageBox(NULL, " Set property for mouse failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// get access to mouse
if (FAILED(_mouse -> Acquire()))
{
MessageBox(NULL, " Get access to mouse failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Read data from mouse buffer.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Mouse()
{
DWORD read_num = 1 ;
// zero mouse buffer before reading data
ZeroMemory(_mouse_buffer, sizeof (DIDEVICEOBJECTDATA) * ITEMS_NUM);
// read all mouse data from buffer
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if (DIERR_INPUTLOST == _mouse -> GetDeviceData( sizeof (DIDEVICEOBJECTDATA), & _mouse_buffer[i], & read_num, 0 ))
{
_mouse -> Acquire();
if (FAILED(_mouse -> GetDeviceData( sizeof (DIDEVICEOBJECTDATA), & _mouse_buffer[i], & read_num, 0 )))
return false ;
}
if (_mouse_buffer[i].dwOfs == DIMOFS_X)
_left_mouse_move_x += _mouse_buffer[i].dwData;
if (_mouse_buffer[i].dwOfs == DIMOFS_Y)
_left_mouse_move_y += _mouse_buffer[i].dwData;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Judge whether left mouse button has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_LButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON0) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Judge whether right mouse button has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_RButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON1) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Judge whether mouse wheel has been pressed.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Is_MButton_Pressed()
{
for ( int i = 0 ; i < ITEMS_NUM; i ++ )
{
if ((_mouse_buffer[i].dwOfs == DIMOFS_BUTTON2) && (_mouse_buffer[i].dwData & 0x80 ))
return true ;
}
return false ;
}
// ------------------------------------------------------------------------------------
// Create joystick.
// ------------------------------------------------------------------------------------
bool GE_INPUT::_Create_Joystick(HWND hwnd, int min, int max, int dead_zone)
{
// Enumerates all joystick that have been installed successfully
if (FAILED(g_directinput -> EnumDevices(DI8DEVCLASS_GAMECTRL, Enum_Joystick, & _joystick, DIEDFL_ATTACHEDONLY)))
{
MessageBox(NULL, " Enumerate joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
if (_joystick == NULL)
{
MessageBox(NULL, " There is no joystick has been installed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set data format for mouse
if (FAILED(_mouse -> SetDataFormat( & c_dfDIJoystick2)))
{
MessageBox(NULL, " Set joystick data format failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set cooperative level for mouse
if (FAILED(_mouse -> SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
{
MessageBox(NULL, " Set joystick cooperative level failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set property for mouse
DIPROPRANGE device_prop;
device_prop.diph.dwSize = sizeof (DIPROPRANGE);
device_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
device_prop.diph.dwObj = 0 ;
device_prop.diph.dwHow = DIPH_DEVICE;
device_prop.lMin = min;
device_prop.lMax = max;
if (FAILED(_joystick -> SetProperty(DIPROP_RANGE, & device_prop.diph)))
{
MessageBox(NULL, " Set property range for joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// set dead zone for joystick
DIPROPDWORD dead_zone_prop;
dead_zone_prop.diph.dwSize = sizeof (DIPROPDWORD);
dead_zone_prop.diph.dwHeaderSize = sizeof (DIPROPHEADER);
dead_zone_prop.diph.dwObj = 0 ;
dead_zone_prop.diph.dwHow = DIPH_DEVICE;
dead_zone_prop.dwData = 100 * dead_zone;DIPROP_DEADZONE;
if (FAILED(_joystick -> SetProperty(DIPROP_DEADZONE, & dead_zone_prop.diph)))
{
MessageBox(NULL, " Set dead zone for joystick failed. " , " ERROR " , MB_OK | MB_ICONINFORMATION);
return false ;
}
// zero joystick buffer
ZeroMemory( & _joystick, sizeof (DIJOYSTATE2));
return true ;
}
// ------------------------------------------------------------------------------------
// Read data from joystick.
// ------------------------------------------------------------------------------------
bool GE_INPUT::Read_Joystick()
{
// get access to joystick
if (FAILED(_joystick -> Acquire()))
return false ;
// polling joystick to retrieve data
if (FAILED(_joystick -> Poll()))
return false ;
// get joystick current state
if (DIERR_INPUTLOST == _joystick -> GetDeviceState( sizeof (DIJOYSTATE2), & _joystick_buffer))
{
// re-acquire access to joystick
_joystick -> Acquire();
if (FAILED(_joystick -> GetDeviceState( sizeof (DIJOYSTATE2), & _joystick_buffer)))
return false ;
}
return true ;
}
// ------------------------------------------------------------------------------------
// Application-defined callback function that receives Microsoft DirectInput devices
// as a result of a call to the IDirectInput8::EnumDevices method.
// ------------------------------------------------------------------------------------
BOOL CALLBACK Enum_Joystick(LPCDIDEVICEINSTANCE device_instance, LPVOID data)
{
LPDIRECTINPUTDEVICE8 * diDevice = (LPDIRECTINPUTDEVICE8 * ) data;
if (FAILED(g_directinput -> CreateDevice(device_instance -> guidInstance, diDevice, NULL)))
return DIENUM_CONTINUE;
return DIENUM_STOP;
}
测试程序,由于身边没有游戏手柄,所以无法测试关于Joystick的代码,这个测试程序存在一些BUG,但大体能用。
/*
************************************************************************************
[Implement File]
PURPOSE:
Test Window Framework.
************************************************************************************ */
#define DIRECTINPUT_VERSION 0x0800
#include < stdio.h >
#include " GE_APP.h "
#include " GE_INPUT.h "
#pragma warning(disable : 4996 )
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
GE_APP ge_app;
GE_INPUT ge_input;
MSG msg = { 0 };
TCHAR temp_text[ 50 ] = { 0 };
POINT curr_pos; // current mouse cursor position
// create window
if ( ! ge_app.Create_Window( " Test Window Frame " , instance, cmd_show))
return false ;
HWND hwnd = ge_app.Get_Window_Handle();
HDC hdc = GetDC(hwnd);
// create directinput
ge_input.Create_Input(instance, hwnd, - 100 , 100 , 20 , true );
SetWindowPos(hwnd, 0 , 0 , 0 , 0 , 0 , SWP_NOSIZE);
SetCursorPos( 0 , 0 );
while (msg.message != WM_QUIT)
{
if (PeekMessage( & msg, NULL, 0 , 0 , PM_REMOVE))
{
TranslateMessage( & msg);
DispatchMessage( & msg);
}
else
{
// read data from keyboard buffer
if (ge_input.Read_Keyboard())
{
if (ge_input.Is_Key_Pressed(DIK_A))
MessageBox(NULL, " Key A is pressed. " , " Hint " , MB_OK | MB_ICONINFORMATION);
if (ge_input.Is_Key_Pressed(DIK_F) && ge_input.Is_Key_Pressed(DIK_LCONTROL))
MessageBox(NULL, " Ctrl+F is pressed. " , " Hint " , MB_OK | MB_ICONINFORMATION);
if (ge_input.Is_Key_Pressed(DIK_ESCAPE))
PostQuitMessage( 0 );
}
// read mouse input
if (ge_input.Read_Mouse())
{
GetCursorPos( & curr_pos);
ScreenToClient(hwnd, & curr_pos);
if (ge_input.Is_LButton_Pressed())
{
sprintf(temp_text, " LEFT(%d, %d) " , ge_input.Get_Mouse_Move_X(), ge_input.Get_Mouse_Move_Y());
TextOut(hdc, curr_pos.x, curr_pos.y, temp_text, lstrlen(temp_text));
}
if (ge_input.Is_RButton_Pressed())
{
sprintf(temp_text, " RIGHT(%d, %d) " , ge_input.Get_Mouse_Move_X(), ge_input.Get_Mouse_Move_Y());
TextOut(hdc, curr_pos.x, curr_pos.y, temp_text, lstrlen(temp_text));
}
}
}
}
UnregisterClass(WINDOW_CLASS_NAME, instance);
return true ;
}
[Implement File]
PURPOSE:
Test Window Framework.
************************************************************************************ */
#define DIRECTINPUT_VERSION 0x0800
#include < stdio.h >
#include " GE_APP.h "
#include " GE_INPUT.h "
#pragma warning(disable : 4996 )
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmd_line, int cmd_show)
{
GE_APP ge_app;
GE_INPUT ge_input;
MSG msg = { 0 };
TCHAR temp_text[ 50 ] = { 0 };
POINT curr_pos; // current mouse cursor position
// create window
if ( ! ge_app.Create_Window( " Test Window Frame " , instance, cmd_show))
return false ;
HWND hwnd = ge_app.Get_Window_Handle();
HDC hdc = GetDC(hwnd);
// create directinput
ge_input.Create_Input(instance, hwnd, - 100 , 100 , 20 , true );
SetWindowPos(hwnd, 0 , 0 , 0 , 0 , 0 , SWP_NOSIZE);
SetCursorPos( 0 , 0 );
while (msg.message != WM_QUIT)
{
if (PeekMessage( & msg, NULL, 0 , 0 , PM_REMOVE))
{
TranslateMessage( & msg);
DispatchMessage( & msg);
}
else
{
// read data from keyboard buffer
if (ge_input.Read_Keyboard())
{
if (ge_input.Is_Key_Pressed(DIK_A))
MessageBox(NULL, " Key A is pressed. " , " Hint " , MB_OK | MB_ICONINFORMATION);
if (ge_input.Is_Key_Pressed(DIK_F) && ge_input.Is_Key_Pressed(DIK_LCONTROL))
MessageBox(NULL, " Ctrl+F is pressed. " , " Hint " , MB_OK | MB_ICONINFORMATION);
if (ge_input.Is_Key_Pressed(DIK_ESCAPE))
PostQuitMessage( 0 );
}
// read mouse input
if (ge_input.Read_Mouse())
{
GetCursorPos( & curr_pos);
ScreenToClient(hwnd, & curr_pos);
if (ge_input.Is_LButton_Pressed())
{
sprintf(temp_text, " LEFT(%d, %d) " , ge_input.Get_Mouse_Move_X(), ge_input.Get_Mouse_Move_Y());
TextOut(hdc, curr_pos.x, curr_pos.y, temp_text, lstrlen(temp_text));
}
if (ge_input.Is_RButton_Pressed())
{
sprintf(temp_text, " RIGHT(%d, %d) " , ge_input.Get_Mouse_Move_X(), ge_input.Get_Mouse_Move_Y());
TextOut(hdc, curr_pos.x, curr_pos.y, temp_text, lstrlen(temp_text));
}
}
}
}
UnregisterClass(WINDOW_CLASS_NAME, instance);
return true ;
}