键盘动态库开发(修改键值映射和键盘灯控制)

  • 开发需求
  • 键盘DLL功能
    • 1. 键盘OPEN
    • 2. 键盘CLOSE
    • 3. 键盘灯控制
    • 4. 键值抓取

开发需求

需求:开发一款9键键盘DLL和演示程序,要求能控制灯亮、将9个键值映射为77001-77009。
固件:USB标准键盘0-9键值。

一些重要知识:

  • 代码是在win10 64位系统下跑的,理应来说int占8个字节(64位),后来我想错了;我建立的工程是win32控制台应用,意味着编译器就是32位的–“int占多少个字节既由编译器决定,也由CPU或虚拟机或操作系统决定,但归根结底是由编译器决定。”
  • char占1字节,short占 2 字节,int 、float、long 都占 4 字节,double 占8 字节,任意类型的指针都占4个字节
  • 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别
  • 动态链接库构建的框架(生成和使用)

键盘DLL功能

1. 键盘OPEN

键盘open,根据键盘固件的PID、VID和版本连接键盘,并建立keyhook抓取键值的线程。功能稍微复杂。

  • 键盘OPEN,即连接键盘,所需参数有VendorID, ProductID, VersionNumber。核对键盘的VID、PID和Version后,建立键盘输入监听线程(StartKeyHook)。
    函数OpenKeyboard:
BOOL OpenKeyboard(USHORT VendorID, USHORT ProductID, USHORT VersionNumber)
{if((hDevHandle != INVALID_HANDLE_VALUE)){return FALSE;}SECURITY_ATTRIBUTES SecurityAttributes;SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);SecurityAttributes.lpSecurityDescriptor = NULL;SecurityAttributes.bInheritHandle = false;DevInterfaceData.cbSize = sizeof(DevInterfaceData);DevAttributes.Size = sizeof(DevAttributes);HidD_GetHidGuid(&HidGuid);hDevInfoSet = SetupDiGetClassDevs(&HidGuid,NULL,NULL,DIGCF_DEVICEINTERFACE|DIGCF_PRESENT);MemberIndex = 0;while(TRUE){Result = SetupDiEnumDeviceInterfaces(hDevInfoSet, NULL, &HidGuid, MemberIndex, &DevInterfaceData);if (Result == FALSE){break;}MemberIndex++;Result = SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, NULL, NULL,&RequiredSize, NULL);pDevDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);if (pDevDetailData == NULL){SetupDiDestroyDeviceInfoList(hDevInfoSet);return FALSE;}pDevDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);Result = SetupDiGetDeviceInterfaceDetail(hDevInfoSet, &DevInterfaceData, pDevDetailData, RequiredSize, NULL, NULL);MyDevPathName = pDevDetailData->DevicePath;free(pDevDetailData);if (Result == FALSE){continue;}hDevHandle = CreateFile(MyDevPathName,0,//GENERIC_WRITE,//GENERIC_READ|,//只有0值时有效FILE_SHARE_READ |FILE_SHARE_WRITE,&SecurityAttributes,OPEN_EXISTING,0,//FILE_FLAG_OVERLAPPED, //只有使用同步模式有效NULL);if (hDevHandle != INVALID_HANDLE_VALUE){DevAttributes.Size = sizeof(DevAttributes);Result = HidD_GetAttributes(hDevHandle, &DevAttributes);PHIDP_PREPARSED_DATA PreparsedData;Result = HidD_GetPreparsedData(hDevHandle, &PreparsedData);HidP_GetCaps(PreparsedData, &Capabilities);HidD_FreePreparsedData(PreparsedData); if (Result == FALSE){continue;}if ((DevAttributes.VendorID == VendorID) && (DevAttributes.ProductID == ProductID) && (DevAttributes.VersionNumber == VersionNumber)){       //创建读线程,开始获取键盘的值存放到队列。//————————————————————————————————————————————StartKeyHook();//————————————————————————————————————————————SetupDiDestroyDeviceInfoList(hDevInfoSet);return TRUE;}}}SetupDiDestroyDeviceInfoList(hDevInfoSet);return FALSE;
}
  • StartKeyHook键盘钩子函数调用了键盘线程函数KeyboardThread:

BOOL StartKeyHook()
{g_hKBHookThread = CreateThread(0, 0, KeyboardThread, 0, 0, &g_nKBHookThreadId);return TRUE;
}
  • KeyboardThread键盘钩子函数调用了键盘Hook回调函数KeyboardProc抓取键值并修改映射:
DWORD CALLBACK KeyboardThread(PVOID param)
{MSG msg;// set low-level keyboard hook//   if (!IsDebuggerPresent())// {// install the hook for *this* thread, even though it is a systemwide/global hookg_hKeyboard = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(0), 0);//   }// pump messages to stop console from locking upwhile (GetMessage(&msg, 0, 0, 0) > 0){TranslateMessage(&msg);DispatchMessage(&msg);}// remove the hook just before we exitUnhookWindowsHookEx(g_hKeyboard);return 0;}
  • KeyboardProc键盘钩子回调函数抓取键值及修改映射关系:
LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam
)
{//CString csMsg;//csMsg.Format(_T("KeyboardPro code=%d"),code);//AfxMessageBox(csMsg);if (code == HC_ACTION){KBDLLHOOKSTRUCT *Key = (KBDLLHOOKSTRUCT *)lParam;if (!(Key->flags & LLKHF_UP))//{switch ((Key->vkCode & 0xff))//{case '1':dwKeyValue = 77001;return TRUE; //屏蔽该值;case '2':dwKeyValue = 77002;return TRUE; //屏蔽该值case '3':dwKeyValue = 77003;return TRUE; //屏蔽该值case '4':dwKeyValue = 77004;return TRUE; //屏蔽该值case '5':dwKeyValue = 77005;return TRUE; //屏蔽该值case '6':dwKeyValue = 77006;return TRUE; //屏蔽该值case '7':dwKeyValue = 77007;return TRUE; //屏蔽该值case '8':dwKeyValue = 77008;return TRUE; //屏蔽该值case '9':dwKeyValue = 77009;return TRUE; //屏蔽该值default:dwKeyValue =0;break;}}}return CallNextHookEx(g_hKeyboard, code, wParam, lParam);
}

2. 键盘CLOSE

键盘close,即关闭键盘,关闭devhandle并结束抓取keyvalue的线程。
函数CloseKeyboard:

BOOL CloseKeyboard()
{if (hDevHandle == INVALID_HANDLE_VALUE){return FALSE;}if (!CloseHandle(hDevHandle)){return FALSE;}else{//结束线程StopKeyHook();hDevHandle = INVALID_HANDLE_VALUE;return TRUE;}
}

3. 键盘灯控制

键盘灯控制,设一个变量dwSettings[unsigned long int(DWORD)],其中每一比特位0/1对应着灭/亮。用一个字节,2个8位。

9
1 2 3 4 5 6 7 8

函数SetKeyLight:

MYLIBDLL BOOL SetKeyLight(DWORD dwSettings)
{USHORT usFeatureReportByteLength;BYTE CommandBuffer[100];if (hDevHandle == INVALID_HANDLE_VALUE){return FALSE;}usFeatureReportByteLength = Capabilities.FeatureReportByteLength;CommandBuffer[0] = 0x00;CommandBuffer[1] = BYTE(0xFF&dwSettings);CommandBuffer[2] = BYTE((0x0100&dwSettings)>>8);CommandBuffer[3] = CommandBuffer[1]+CommandBuffer[2];return  HidD_SetFeature(hDevHandle, CommandBuffer, usFeatureReportByteLength);}

4. 键值抓取

键值抓取,设一个参数dwTimeout[unsigned long int(DWORD)],执行抓取动作直到过时,返回tempKeyValue作为转换后的值。

函数SetKeyLight:

MYLIBDLL DWORD GetKeyValue(DWORD dwTimeout)
{DWORD tempKeyValue=0;DWORD i;DWORD timeOut=0;timeOut = dwTimeout / 10;if (hDevHandle == INVALID_HANDLE_VALUE){return 0;}for (i = 0; i < timeOut; i++){if (dwKeyValue == 0){Sleep(10);}else{tempKeyValue = dwKeyValue;dwKeyValue = 0;break;}}return tempKeyValue;
}

这个函数非常简单,即等到timeout后将获取到的最后一个键值(dwKeyValue)返回。
其中dwKeyValue是在键盘open到键盘close的整个过程不断获取的。
在外面做一个简单的调用demo就可以使用了。
打开键盘:

读取键值如下:

点亮键灯如下:(键盘变黄色表示点亮)

最后关闭点击CLOSE即可。

键盘动态库开发(修改键值映射和键盘灯控制)相关推荐

  1. Unity中的输入事件总结与数字电视遥控器键值映射

    版权声明:欢迎批评指正,转载请务必注明原文链接:欢迎文章下公开讨论. https://blog.csdn.net/cordova/article/details/51036547 一.Unity的基本 ...

  2. 【快乐水题】677. 键值映射

    原题: 力扣链接:677. 键值映射 题目简述: 实现一个 MapSum 类,支持两个方法,insert 和 sum: MapSum() 初始化 MapSum 对象 void insert(Strin ...

  3. php数组修改键值,php数组中子数组如何修改键值

    php数组中子数组修改键值的方法:使用函数[array_slice()]在数组中根据条件取出一段值,并返回,语法为[array_slice(array,offset,length,preserve)] ...

  4. 字典树/Trie/前缀树-LeetCode总结:720词典中最长的单词;127. 单词接龙;677. 键值映射;面试题 17.17. 多次搜索;648. 单词替换

    MyTrie结构体和相关操作函数 typedef struct MyTrie {bool is_word;vector<MyTrie*> next;MyTrie():is_word(fal ...

  5. C# 调用其他的动态库开发应注意的问题

    1.背景 程序开发语言可以说是五花八门,这就引出了一个新问题 ,不同语言开发的系统进行对接时相关调用的问题. 下面我主要说一下我自己在做接口开发时遇到的问题及解决方法仅供参考,我使用的C#开发进行对接 ...

  6. 安卓按键键值映射关系

    1.vendor或者device 目录或者framework下有一些.kl文件定义键值 2.kl文件命名为规则为Vendor_2717_Product_32b0.kl 其中2717 和32b0可以通过 ...

  7. usb 键盘码表_键盘鼠标对应码表-delphi键值

    在操作API的时候很多时候需要用到我们键盘上的按键,这里是对照的 常数名称 十六进制值 十进制值 对应按键 VK_LBUTTON 01 1 鼠标的左键 VK_RBUTTON 02 2 鼠标的右键 VK ...

  8. 键盘VK键值(java键盘监听)

    键盘VK键值列表 /* Virtual Keys, Standard Set*/ VK_LBUTTON                                      0x01 VK_RBU ...

  9. LeetCode677. 键值映射(Trie树)

    1. 题目 实现一个 MapSum 类里的两个方法,insert 和 sum. 对于方法 insert,你将得到一对(字符串,整数)的键值对.字符串表示键,整数表示值.如果键已经存在,那么原来的键值对 ...

最新文章

  1. 苹果手机怎么投屏 如何操作
  2. 美团点评稳定价格措施及稳定价格期结束 超额配股权失效
  3. 序列化和反序列化的对单例破坏的防止及其原理
  4. 03 | 高可用保证:Nacos 如何有效构建注册中心集群
  5. 洛谷 P1596 [USACO10OCT]Lake Counting S-dfs
  6. pmp中ram和raci的区别_【PMP知识点总结】采购流程、采购合同的类型、采购合同的条款...
  7. Java反射修改返回值_java反射调用时如果返回值是整型数组怎么处理?
  8. java五层架构_Web五层架构
  9. java翻译数字串并打印_如何使用Java翻译字符串?
  10. HDU 3420 Bus Fair [补]
  11. 程序员同事被包工头坑了,这社会很魔幻
  12. oracle新建定时任务,创建 Oracle 定时任务
  13. arcgis python实例_科学网—ArcGIS,Python,网络数据集中查询两点最短路径 - 余露的博文...
  14. WeChat 微信防撤回的方法 plus
  15. 英语四六级听力真题模拟题
  16. 我的世界租赁服务器重置,《我的世界》租赁服自动砍树命令教程 命令方块介绍...
  17. 王唯佳被南开计算机学院录取,被南开录取!沈阳庞贝病少年王唯佳,祝贺你!辽宁日报 昨天辽宁...
  18. jenkins邮件配置和邮件发送
  19. python后台操作炒股软件下载_GitHub - lipq525/stock-1: stock,股票系统。使用python进行开发。...
  20. EOJ3054-波兰式求值(递归法)

热门文章

  1. chroot() 函数
  2. 不能不看!美貌与智慧并重苹果iPhone手机解析
  3. 消息摘要、数字指纹、数字签名、数字时间戳技术
  4. SSM框架实战详细教程(三)IDEA+Maven搭建项目
  5. SpringBootWebSocket出现No mapping found for HTTP request
  6. 角色架構安全性與 Web Services Enhancements 2.0 的相互應用
  7. C语言:跨平台环境下使用snprintf,vsnprintf系列函数要注意返回值的问题
  8. Navicat 一款数据库开发软件
  9. Graylog 日志监控系统介绍
  10. Matlab生成Word文件(含表格和图片插入)