#include "stdafx.h"
#include
//声明自定义消息处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
HWND m_hWnd;
//注册原始输入设备
void RegKeyboardRawInput(HWND hWnd)
{
RAWINPUTDEVICE rawInputDevice[1];
rawInputDevice[0].usUsagePage = 0x01;//设备类
rawInputDevice[0].usUsage = 0x06;//设备类内的具体设备
rawInputDevice[0].dwFlags = RIDEV_INPUTSINK;//意味着即使窗口失去焦点位置,仍然会一直接收输入消息
rawInputDevice[0].hwndTarget = hWnd;
if (RegisterRawInputDevices(rawInputDevice, 1, sizeof(rawInputDevice[0])) == FALSE)
{
printf("RegisterRawInputDevices failed");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
//创建一个隐藏窗口
HINSTANCE hInst;
hInst = GetModuleHandle(NULL); //获取一个应用程序或动态链接库的模块句柄
WNDCLASSEX wcx;
wcx.cbSize = sizeof(wcx);
wcx.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_NOCLOSE;//窗口的风格
wcx.lpfnWndProc = WindowProc; //采用自定义消息处理函数
wcx.cbClsExtra = 0; // no extra class memory
wcx.cbWndExtra = 0; // no extra window memory
wcx.hInstance = hInst; //当前应用程序的实例句柄
wcx.hIcon = LoadIcon(NULL,IDI_APPLICATION); //图标风格
wcx.hCursor = LoadCursor(NULL,IDC_ARROW); //鼠标风格
wcx.hbrBackground = (HBRUSH)WHITE_BRUSH; //背景色
wcx.lpszMenuName =NULL; //菜单名
wcx.lpszClassName = _T("ITSMYOSDCLASS"); //窗口类的名称
wcx.hIconSm = NULL;
if (!RegisterClassEx(&wcx))
{
printf("RegisterClassEx failed");
return 1;
}
//窗口在屏幕上的显示位置
int OSDleft = GetSystemMetrics(SM_CXSCREEN) / 2 - 300;
int OSDTop = GetSystemMetrics(SM_CYSCREEN) / 2;
m_hWnd = CreateWindowEx(
WS_EX_LAYERED | WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_TRANSPARENT | WS_EX_NOACTIVATE,//窗口的扩展风格
wcx.lpszClassName,//上面注册的类名lpszClassName,要完全一致
NULL,
WS_VISIBLE | WS_POPUP,//窗口的风格
OSDleft,//窗口相对于父级的X坐标
OSDTop,//窗口相对于父级的Y坐标
300,//窗口的宽度
300,//窗口的高度
(HWND)NULL,//没有父窗口,为(HWND)NULL//GetDesktopWindow(),
(HMENU)NULL,//没有菜单,为NULL
hInst,//当前应用程序的实例句柄
(LPVOID)NULL); //没有附加数据,为NULL
if (!m_hWnd)
{
printf("CreateWindowEx failed");
return 1;
}
RegKeyboardRawInput(m_hWnd);
//消息循环
MSG msg;
while (GetMessage(&msg, (HWND)NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
//LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
// 自定义消息处理函数的实现
LRESULT CALLBACK WindowProc(_In_ HWND hwnd,_In_ UINT uMsg,_In_ WPARAM wParam,_In_ LPARAM lParam)
{
switch (uMsg)
{
case WM_COMMAND:
break;
case WM_PAINT:
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_INPUT:
{
UINT dwSize = 0;
GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));//取数据,第一次调用函数将获取需要的字节大小
LPBYTE lpbBuffer = new BYTE[dwSize];//分配指定的缓冲区大小
GetRawInputData((HRAWINPUT)lParam, (UINT)RID_INPUT, (LPVOID)lpbBuffer, (PUINT)&dwSize, (UINT)sizeof(RAWINPUTHEADER));//第二次调用获取原始输入数据,读入lpbBuffer
RAWINPUT * raw = (RAWINPUT *)lpbBuffer;
if (raw->header.dwType == RIM_TYPEKEYBOARD)//这里可以截获所有键盘信息,如需区分不同的键盘输入信息,可以通过设备句柄判断。
{
if (raw->data.keyboard.Message == WM_KEYUP)
{
//读取键盘名称
UINT bufferSize;//为键盘设备名准备缓冲区大小
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, NULL, &bufferSize);
WCHAR* RawDevName = new WCHAR[bufferSize];
GetRawInputDeviceInfo(raw->header.hDevice, RIDI_DEVICENAME, RawDevName, &bufferSize);//将设备名读入缓冲区RawDevName
printf("dev=%ls\n", RawDevName);
delete[] RawDevName;
//获取键盘输入
char keytext[10] = { 0 };
BYTE state[256] = { 0 };
ToAscii(raw->data.keyboard.VKey, raw->data.keyboard.MakeCode, state, (LPWORD)keytext, 0);//通过虚拟键盘码得到名字
printf("key=%s\n", keytext);
printf("Kbd: make = % 04x Flags : % 04x Reserved : % 04x ExtraInformation : % 08x, msg = % 04x VK = % 04x \n",
raw->data.keyboard.MakeCode,
raw->data.keyboard.Flags,
raw->data.keyboard.Reserved,
raw->data.keyboard.ExtraInformation,
raw->data.keyboard.Message,
raw->data.keyboard.VKey);
}
}
delete[] lpbBuffer;
return 0;
}
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
效果图