- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
注册快捷键与hook监听键盘的区别
快捷键注册是针对某一个窗口的,注册之后当这个窗口收到快捷键,操作系统就会发送 WM_HOTKEY 消息来通知该窗口。所以快捷键注册是没办法监听全局的,比如你要定义一个快捷键 Ctrl + ` 在桌面上也能调出你的窗口,可是这个消息是发给桌面这个程序去了没办法触发你的程序。 快捷键收到消息之后消息会被转发给注册的hwnd 相当于截断了消息,如果要做全局监听的话还是推荐用 hook。
控制台注册快捷键
#include <stdio.h>
#include <Windows.h>
int main()
{
MSG msg = {0};
HWND hConsole = GetActiveWindow(); // 获取当前显示窗口的句柄(即控制台这个窗口的句柄)
RegisterHotKey(
hConsole, // 注册快捷键的窗口句柄
1, // 热键标识符
MOD_CONTROL | MOD_NOREPEAT, // Ctrl 键 No Repeat 不重复发送
'A' // A
); // Ctrl + A
RegisterHotKey(hConsole, 2, MOD_CONTROL | MOD_NOREPEAT,'B');// Ctrl + B
RegisterHotKey(hConsole, 3, MOD_ALT | MOD_NOREPEAT,'A'); // Alt + A
RegisterHotKey(hConsole, 4, MOD_ALT | MOD_NOREPEAT,'B'); // Alt + B
RegisterHotKey(hConsole, 5, MOD_NOREPEAT,'S'); // 直接按 S
// 循环获取操作系统发来的消息
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
// 当收到快捷键消息时
if (msg.message == WM_HOTKEY)
{
switch(msg.wParam)
{
case 1:
printf("Ctrl + A 被按下! \n\n");
break;
case 2:
printf("Ctrl + B 被按下! \n\n");
break;
case 3:
printf("Alt + A 被按下! \n\n");
break;
case 4:
printf("Alt + B 被按下! \n\n");
break;
case 5:
printf("S 被按下! \n\n");
break;
}
}
}
}
hotkey_console
窗口注册快捷键
在window窗体开发中,窗口过程函数中实际上还可以通过 WM_KEYUP WM_KEYDOWN 等消息获取到用户的按键,大家可以通过如下类似的代码来查看窗口收到的消息(其实控制台下也是可以这样拿的)
case WM_KEYDOWN:
wsprintf(text, "wParam : 0x%x lParam : 0x%x", wParam, lParam);
echo(text);
break;
不过这种的缺点也是很明显的,就是复合键等快捷键定义没有使用 WM_HOTKEY 方便
#include <Windows.h>
void echo(LPSTR str)
{
MessageBox(NULL, str, TEXT("提示"), MB_OK);
}
// 5. 窗口过程处理
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CHAR text[50];
switch(msg)
{
// 窗口创建消息
case WM_CREATE:
RegisterHotKey(
hwnd, // 注册快捷键的窗口句柄
1, // 热键标识符避免热键冲突
MOD_CONTROL | MOD_NOREPEAT, // Ctrl 键 No Repeat 不重复发送
'A' // A
); // Ctrl + A
RegisterHotKey(hwnd, 2, MOD_CONTROL | MOD_NOREPEAT,'B');// Ctrl + B
RegisterHotKey(hwnd, 3, MOD_ALT | MOD_NOREPEAT,'A'); // Alt + A
RegisterHotKey(hwnd, 4, MOD_ALT | MOD_NOREPEAT,'B'); // Alt + B
RegisterHotKey(hwnd, 5, MOD_NOREPEAT,'S'); // 直接按 S
break;
// 快捷键消息
case WM_HOTKEY:
switch(wParam)
{
case 1:
printf("Ctrl + A 被按下! \n\n");
break;
case 2:
printf("Ctrl + B 被按下! \n\n");
break;
case 3:
printf("Alt + A 被按下! \n\n");
break;
case 4:
printf("Alt + B 被按下! \n\n");
break;
case 5:
printf("S 被按下! \n\n");
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
char text[30];
const char szClassName[] = "myWindowClass";
// 1. 设置注册窗口结构体
wc.cbSize = sizeof(WNDCLASSEX); // 注册窗口结构体的大小
wc.style = 0; // 窗口的样式
wc.lpfnWndProc = WndProc; // 指向窗口处理过程的函数指针
wc.cbClsExtra = 0; // 指定紧跟在窗口类结构后的附加字节数
wc.cbWndExtra = 0; // 指定紧跟在窗口事例后的附加字节数
wc.hInstance = hInstance; // 本模块的实例句柄
wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); // 图标的句柄
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 光标的句柄
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // 背景画刷的句柄
wc.lpszMenuName = NULL; // 指向菜单的指针
wc.lpszClassName = szClassName; // 指向类名称的指针
wc.hIconSm = LoadIcon(hInstance, IDI_APPLICATION); // 和窗口类关联的小图标
// 2. 使用【窗口结构体】注册窗口
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, TEXT("窗口注册失败!"), TEXT("错误"), MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 3. 创建窗口
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE, // 窗口的扩展风格
szClassName, // 指向注册类名的指针
TEXT("窗口标题"), // 指向窗口名称的指针
WS_OVERLAPPEDWINDOW, // 窗口风格
CW_USEDEFAULT, CW_USEDEFAULT, 350, 200, // 窗口的 x,y 坐标以及宽高
NULL, // 父窗口的句柄
NULL, // 菜单的句柄
hInstance, // 应用程序实例的句柄
NULL // 指向窗口的创建数据
);
if(hwnd == NULL)
{
MessageBox(NULL, TEXT("窗口创建失败"), TEXT("错误"),MB_ICONEXCLAMATION | MB_OK);
return 0;
}
// 4. 显示窗口
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// 6. 消息循环
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
hotkey_window
Ctrl + Alt 等复杂组合键
还是在控制台下编写例子,其实没有差多少
#include <stdio.h>
#include <Windows.h>
int main()
{
MSG msg = {0};
HWND hConsole = GetActiveWindow();
// Ctrl + D
RegisterHotKey(hConsole,1,MOD_CONTROL | MOD_NOREPEAT,'D');
// Win键 + Z
RegisterHotKey(hConsole,2,MOD_WIN | MOD_NOREPEAT,'Z');
// Ctrl + Alt + S
RegisterHotKey(hConsole,3,MOD_CONTROL | MOD_ALT | MOD_NOREPEAT,'S');
// Ctrl + Alt + Shift + A
RegisterHotKey(hConsole,4,MOD_CONTROL | MOD_ALT | MOD_SHIFT | MOD_NOREPEAT,'A');
// 循环获取操作系统发来的消息
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
// 当收到快捷键消息时
if (msg.message == WM_HOTKEY)
{
printf("收到 WM_HOTKEY 快捷键消息\n");
printf("wParam : 0x%x lParam : 0x%x \n", msg.wParam, msg.lParam);
switch(msg.wParam)
{
case 1:
printf("Ctrl + D 被按下! \n\n");
break
case 2:
printf("Win + Z 被按下! \n\n");
break
case 3:
printf("Ctrl + Alt + S 被按下! \n\n");
break
case 4:
printf("Ctrl + Alt + Shift + A 被按下! \n\n");
break
}
}
}
}
|
|