键盘钩子与WinAPI c++
Keyboard hook with WinAPI C++
我正在尝试创建一个全局键盘钩子,它将用于读取我正在创建的热键程序的按键,我遇到了一些问题。我需要显示消息框时,用户输入关键字(例如"密码")。我如何在这段代码中做到这一点?
#include <fstream>
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>
using namespace std;
bool isCapsLockOn() {
if ((GetKeyState(VK_CAPITAL) & 0x00001) != 0)
return true;
else
return false;
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
if (wParam == WM_KEYDOWN) {
if (p->vkCode >= 0x30 && p->vkCode <= 0x39) // 0~9
{
switch (p->vkCode) {
// 0 ~ 9 with Shift Options.
case 0x30: if (GetAsyncKeyState(VK_SHIFT)) cout << ')'; else cout << '0'; break;
case 0x31: if (GetAsyncKeyState(VK_SHIFT)) cout << '!'; else cout << '1'; break;
case 0x32: if (GetAsyncKeyState(VK_SHIFT)) cout << '@'; else cout << '2'; break;
case 0x33: if (GetAsyncKeyState(VK_SHIFT)) cout << '#'; else cout << '3'; break;
case 0x34: if (GetAsyncKeyState(VK_SHIFT)) cout << '$'; else cout << '4'; break;
case 0x35: if (GetAsyncKeyState(VK_SHIFT)) cout << '%'; else cout << '5'; break;
case 0x36: if (GetAsyncKeyState(VK_SHIFT)) cout << '^'; else cout << '6'; break;
case 0x37: if (GetAsyncKeyState(VK_SHIFT)) cout << '&'; else cout << '7'; break;
case 0x38: if (GetAsyncKeyState(VK_SHIFT)) cout << '*'; else cout << '8'; break;
case 0x39: if (GetAsyncKeyState(VK_SHIFT)) cout << '('; else cout << '9'; break;
}
}
else if (p->vkCode >= 0x41 && p->vkCode <= 0x5A) // a~z
{
if (!(GetAsyncKeyState(VK_SHIFT) ^ isCapsLockOn())) {
cout << char(tolower(p->vkCode));
}
else
cout << (char)p->vkCode;
}
else if (p->vkCode >= 0x70 && p->vkCode <= 0x7B) // F1 ~ F12.
{
cout << "[F" << p->vkCode - 111 << "]";
}
else if (p->vkCode >= 0x70 && p->vkCode <= 0x7B) // F1 ~ F12.
{
cout << "[F" << p->vkCode - 111 << "]";
}
else if (p->vkCode)
{
switch (p->vkCode)
{
case VK_CAPITAL: cout << "<CAPLOCK>"; break;
case VK_LCONTROL: cout << "<LCTRL>"; break;
case VK_RCONTROL: cout << "<RCTRL>"; break;
case VK_INSERT: cout << "<INSERT>"; break;
case VK_END: cout << "<END>"; break;
case VK_PRINT: cout << "<PRINT>"; break;
case VK_DELETE: cout << "<DEL>"; break;
case VK_BACK: cout << "<BK>"; break;
case VK_LEFT: cout << "<LEFT>"; break;
case VK_RIGHT: cout << "<RIGHT>"; break;
case VK_UP: cout << "<UP>"; break;
case VK_DOWN: cout << "<DOWN>"; break;
case VK_SPACE: cout << ' '; break;
case VK_ESCAPE: cout << "<ESC>"; break;
case VK_TAB: cout << "<TAB>"; break;
}
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
int main()
{
HHOOK keyBoard = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, NULL, NULL);
MSG msg;
while (!GetMessage(&msg, NULL, NULL, NULL)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(keyBoard);
}
if (!(GetAsyncKeyState(VK_SHIFT) ^ isCapsLockOn()))
在c++中,^
表示位异或操作
你可能指的是逻辑或的||
要记录字符串,可以使用std::string
声明字符串。向它添加字符,然后在用户按回车键时显示它。您必须为VK_RETURN
添加处理程序,如下面的示例所示。
如果#include "stdafx.h"
不是必需的,那么不要包含它。#include <stdio.h>
是IO的C头文件,这里不需要,你已经有了c++头文件<iostream>
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
...
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)lParam;
static std::string str;
if (wParam == WM_KEYDOWN)
{
...
else if (p->vkCode >= 0x41 && p->vkCode <= 0x5A) // a~z
{
char c = char(p->vkCode);
if (!(GetAsyncKeyState(VK_SHIFT) || isCapsLockOn()))
c = (char)tolower(c);
cout << c;
str += c;
}
...
else if (p->vkCode)
{
switch (p->vkCode)
{
...
case VK_UP: cout << "<UP>"; break;
case VK_DOWN: cout << "<DOWN>"; break;
case VK_SPACE: cout << ' '; break;
case VK_ESCAPE: cout << "<ESC>"; break;
case VK_TAB: cout << "<TAB>"; break;
case VK_RETURN:
{
cout << "<RETURN>n";
if (str.length())
{
std::string msg = str;
str = "";
::MessageBoxA(0, msg.c_str(), 0, 0);
}
break;
}
...
}
}
}
相关文章:
- WinAPI挂钩鼠标
- 将执行、作业和WinAPI相乘
- 如何在桌面C++上使用 WinApi 画线
- WINAPI 注册应用程序重新启动时不清除打开的套接字
- Winapi:屏幕截图未显示在窗口中
- WinAPI 在单击第一个对话框上的按钮控件并销毁第一个对话框后创建第二个对话框
- Qt with WinAPI MouseProc
- 如何在"SUBSYSTEM:WINDOWS"下显示并输出到Windows(C++ WinApi)上的
- WinAPI 无法创建按钮
- 将 Win32/WinAPI 应用程序移植到 wxWidgets
- WinAPI 检查窗口是否具有常规标题栏
- 如何使用带有矢量的 winapi 读取进程内存从另一个进程读取缓冲区?
- 将Qt集成到现有的VS项目中以取代WinAPI
- __stdcall - WINAPI vs STDMETHODCALLTYPE vs APIENTRY
- 如何将'this'指针传递给C++ WinAPI 线程?
- Winapi-WM_CLOSE的替代方案
- Winapi - SetWindowLongPtr in ShutdownBlockReason创建/销毁JNI本机代码
- WinAPI C++如何从 64 位应用程序加载资源
- winapi 中的哪个功能检查按钮是否正在关闭控制台?
- WinAPI 窗口在使用 PrintWindow 截屏后不再更新