📄 dinput.cpp
字号:
#include "graphics.h"
LPDIRECTINPUT lpDI = NULL;
LPDIRECTINPUTDEVICE lpDIKeyboard;
LPDIRECTINPUTDEVICE lpDIMouse;
BYTE KEY_INPUT[256];
BOOL mouse_button1, mouse_button2,
mouse_button3, mouse_button4;
int mouse_speed = 1;
MOUSE_CURSOR *cursor = NULL;
HANDLE DI_Thread = NULL;
DWORD DI_Thread_ID;
BOOL show_cursor = FALSE;
int mouse_nt, mouse_ot = 0;
int mouse_x = SCREEN_WIDTH / 2, mouse_y = SCREEN_HEIGHT / 2, mouse_z = 0; // 鼠标的坐标
// 初始化DirectInput
BOOL init_directinput()
{
// 建立DirectInput对象
if (DirectInputCreate(app_hInst, DIRECTINPUT_VERSION, &lpDI, NULL) != DI_OK)
return FALSE;
// 建立键盘输入设备
if (lpDI->CreateDevice(GUID_SysKeyboard, &lpDIKeyboard, NULL) != DI_OK)
return FALSE;
if (lpDIKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
return FALSE;
if (lpDIKeyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
return FALSE;
DIPROPDWORD dipdw;
dipdw.diph.dwSize = sizeof(DIPROPDWORD);
dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = 10;
if (lpDIKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph) != DI_OK)
return FALSE;
if (lpDIKeyboard->Acquire() != DI_OK)
return FALSE;
// 建立鼠标输入设备
if (lpDI->CreateDevice(GUID_SysMouse, &lpDIMouse, NULL) != DI_OK)
return FALSE;
if (lpDIMouse->SetDataFormat(&c_dfDIMouse) != DI_OK)
return FALSE;
if (lpDIMouse->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
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 = 64;
if (lpDIMouse->SetProperty(DIPROP_BUFFERSIZE, &property.diph) != DI_OK)
return FALSE;
if (lpDIMouse->Acquire() != DI_OK)
return FALSE;
if (!(DI_Thread = CreateThread(NULL, 0, DirectInputThread, NULL, 0, &DI_Thread_ID)))
return FALSE;
return TRUE;
}
// 取得按键状态
BOOL key_down(BYTE scancode)
{
if (0x80 & KEY_INPUT[scancode])
return TRUE;
return FALSE;
}
// 获取鼠标位置
BOOL get_mouse_pos()
{
#ifndef OFF_MOUSE_DIRECTINPUT
DIMOUSESTATE mouse_stat;
if (lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouse_stat) != DI_OK)
return FALSE;
mouse_x += mouse_stat.lX * mouse_speed;
mouse_x = mouse_x > screen_right ? screen_right : mouse_x;
mouse_x = mouse_x < screen_left ? screen_left : mouse_x;
mouse_y += mouse_stat.lY * mouse_speed;
mouse_y = mouse_y > screen_bottom ? screen_bottom : mouse_y;
mouse_y = mouse_y < screen_top ? screen_top : mouse_y;
mouse_z += mouse_stat.lZ * mouse_speed;
#else
POINT pos;
GetCursorPos(&pos);
mouse_x = pos.x * mouse_speed;
mouse_x = mouse_x > screen_right ? screen_right : mouse_x;
mouse_x = mouse_x < screen_left ? screen_left : mouse_x;
mouse_y = pos.y * mouse_speed;
mouse_y = mouse_y > screen_bottom ? screen_bottom : mouse_y;
mouse_y = mouse_y < screen_top ? screen_top : mouse_y;
#endif
return TRUE;
}
// 获取鼠标按键的状态
BOOL get_button_down()
{
DIMOUSESTATE mouse_stat;
if (lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouse_stat) != DI_OK)
return FALSE;
if (mouse_stat.rgbButtons[0] & 0x80)
mouse_button1 = TRUE;
else
mouse_button1 = FALSE;
if (mouse_stat.rgbButtons[1] & 0x80)
mouse_button2 = TRUE;
else
mouse_button2 = FALSE;
if (mouse_stat.rgbButtons[2] & 0x80)
mouse_button3 = TRUE;
else
mouse_button3 = FALSE;
if (mouse_stat.rgbButtons[3] & 0x80)
mouse_button4 = TRUE;
else
mouse_button4 = FALSE;
return TRUE;
}
// 设置鼠标的灵活度
int set_mouse_speed(int s)
{
int old = mouse_speed;
mouse_speed = s;
return old;
}
// 激活DirectInput对象
void active_directinput(BOOL active)
{
if (active)
{
if (lpDIMouse != NULL)
lpDIMouse->Acquire();
if (lpDIKeyboard != NULL)
lpDIKeyboard->Acquire();
}
else
{
if (lpDIMouse != NULL)
lpDIMouse->Unacquire();
if (lpDIKeyboard != NULL)
lpDIKeyboard->Unacquire();
}
}
// 释放DirectInput对象
void free_directinput()
{
free_mousecursor(&cursor);
if(DI_Thread)
{
TerminateThread(DI_Thread, 0);
Sleep(200);
}
if (lpDIKeyboard != NULL)
{
lpDIKeyboard->Unacquire();
lpDIKeyboard->Release();
lpDIKeyboard = NULL;
}
if (lpDIMouse != NULL)
{
lpDIMouse->Unacquire();
lpDIMouse->Release();
lpDIMouse = NULL;
}
}
// 等待一个键
void wait_key(BYTE scan_code)
{
while(!key_down(scan_code));
}
// 建立鼠标光标
void create_cursor(int count, BMP *bmp, WORD tc, int hx, int hy, int delay)
{
free_mousecursor(&cursor);
if (bmp->width % count == 0)
{
cursor = new MOUSE_CURSOR;
put_message(cursor == NULL, "错误,没有足够的内存。");
cursor->count = count;
cursor->entry = 0;
cursor->width = bmp->width / count;
cursor->height = bmp->height;
cursor->hot_x = hx;
cursor->hot_y = hy;
cursor->delay = delay;
cursor->cur = create_mirror_bitmap(bmp);
put_message(cursor->cur == NULL, "错误,建立鼠标光标失败。");
// 建立存放背景的位图
}
}
// 释放鼠标光标所占的空间
void free_mousecursor(MOUSE_CURSOR **cur)
{
MOUSE_CURSOR *c = *cur;
if (c == NULL)
return;
if (c->cur != NULL)
free(c->cur);
free(c);
*cur = NULL;
}
// 开启鼠标光标
void show_mouse()
{
if (cursor != NULL)
show_cursor = TRUE;
}
// 关闭鼠标光标
void close_mouse()
{
if (cursor != NULL)
show_cursor = FALSE;
}
// DirectInput线程
static DWORD WINAPI DirectInputThread(LPVOID p)
{
while(TRUE)
{
// 获取键盘状态
lpDIKeyboard->GetDeviceState(sizeof(KEY_INPUT), KEY_INPUT);
// 获取鼠标位置状态
DIMOUSESTATE mouse_stat;
#ifndef OFF_MOUSE_DIRECTINPUT
lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouse_stat);
mouse_x += mouse_stat.lX * mouse_speed;
mouse_x = mouse_x > screen_right ? screen_right : mouse_x;
mouse_x = mouse_x < screen_left ? screen_left : mouse_x;
mouse_y += mouse_stat.lY * mouse_speed;
mouse_y = mouse_y > screen_bottom ? screen_bottom : mouse_y;
mouse_y = mouse_y < screen_top ? screen_top : mouse_y;
mouse_z += mouse_stat.lZ * mouse_speed;
#else
POINT pos;
GetCursorPos(&pos);
mouse_x = pos.x * mouse_speed;
mouse_x = mouse_x > screen_right ? screen_right : mouse_x;
mouse_x = mouse_x < screen_left ? screen_left : mouse_x;
mouse_y = pos.y * mouse_speed;
mouse_y = mouse_y > screen_bottom ? screen_bottom : mouse_y;
mouse_y = mouse_y < screen_top ? screen_top : mouse_y;
#endif
lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE), &mouse_stat);
if (mouse_stat.rgbButtons[0] & 0x80)
mouse_button1 = TRUE;
else
mouse_button1 = FALSE;
if (mouse_stat.rgbButtons[1] & 0x80)
mouse_button2 = TRUE;
else
mouse_button2 = FALSE;
if (mouse_stat.rgbButtons[2] & 0x80)
mouse_button3 = TRUE;
else
mouse_button3 = FALSE;
if (mouse_stat.rgbButtons[3] & 0x80)
mouse_button4 = TRUE;
else
mouse_button4 = FALSE;
Sleep(1);
}
return 0;
}
// 用普通方式绘制鼠标光标
void paint_mouse_normal(MOUSE_CURSOR *cur)
{
mask_bitblt_bitmap(screen, mouse_x - cursor->hot_x, mouse_y - cursor->hot_y, cursor->cur, cursor->entry * cursor->width, 0, cursor->width, cursor->height);
mouse_nt = GetTickCount();
if (mouse_nt > mouse_ot + cur->delay)
{
mouse_ot = mouse_nt;
cursor->entry++;
if (cursor->entry >= cursor->count)
cursor->entry = 0;
}
}
// 用Additive方式绘制鼠标光标
void paint_mouse_additive(MOUSE_CURSOR *cur)
{
additive_bitblt_bitmap(screen, mouse_x - cursor->hot_x, mouse_y - cursor->hot_y, cursor->cur, cursor->entry * cursor->width, 0, cursor->width, cursor->height);
mouse_nt = GetTickCount();
if (mouse_nt > mouse_ot + cur->delay)
{
mouse_ot = mouse_nt;
cursor->entry++;
if (cursor->entry >= cursor->count)
cursor->entry = 0;
}
}
// 等待一个键按下,并返回扫描码
int get_key()
{
DIDEVICEOBJECTDATA rgdod;
DWORD item = 1;
lpDIKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &rgdod, &item, 0);
if (item == 0)
return 0;
if (rgdod.dwData & 0x80)
return rgdod.dwOfs;
else
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -