使用windows钩子自定义热键
C++ Custom hot keys using windows hooks
我想做一些自定义热键,在任何程序中,我可以用某些键组合来调出不同的程序。我研究了如何做挂钩,并给出了这个例子。
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {
// Set windows hook
HHOOK keyboardHook = SetWindowsHookEx(
WH_KEYBOARD_LL,
keyboardHookProc,
hInstance,
0);
MessageBox(NULL, "Press OK to stop hot keys", "Information", MB_OK);
return 0;
}
而不是消息框,因为我希望它在后台运行,我尝试使用循环,但我没有尝试成功的行为像消息框。什么好主意吗?
下面这段好代码是一个热键应用程序,它坐在后台监听CTRL-y
键组合,你可以修改或添加任何更多的键组合到应用程序。使用CTRL-q
隐藏时退出应用程序
如果您希望完全隐藏控制台窗口,那么取消注释main(): //ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false)
中的这一行。享受。
if (CTRL_key !=0 && key == 'y' )
{
MessageBox(NULL, "CTRL-y was pressednLaunch your app here", "H O T K E Y", MB_OK);
CTRL_key=0;
}
完整代码清单:
#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )
#include <windows.h>
#include <stdio.h>
HHOOK hKeyboardHook;
__declspec(dllexport) LRESULT CALLBACK KeyboardEvent (int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD SHIFT_key=0;
DWORD CTRL_key=0;
DWORD ALT_key=0;
if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
{
KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
DWORD dwMsg = 1;
dwMsg += hooked_key.scanCode << 16;
dwMsg += hooked_key.flags << 24;
char lpszKeyName[1024] = {0};
lpszKeyName[0] = '[';
int i = GetKeyNameText(dwMsg, (lpszKeyName+1),0xFF) + 1;
lpszKeyName[i] = ']';
int key = hooked_key.vkCode;
SHIFT_key = GetAsyncKeyState(VK_SHIFT);
CTRL_key = GetAsyncKeyState(VK_CONTROL);
ALT_key = GetAsyncKeyState(VK_MENU);
if (key >= 'A' && key <= 'Z')
{
if (GetAsyncKeyState(VK_SHIFT)>= 0) key +=32;
if (CTRL_key !=0 && key == 'y' )
{
MessageBox(NULL, "CTRL-y was pressednLaunch your app here", "H O T K E Y", MB_OK);
CTRL_key=0;
}
if (CTRL_key !=0 && key == 'q' )
{
MessageBox(NULL, "Shutting down", "H O T K E Y", MB_OK);
PostQuitMessage(0);
}
printf("key = %cn", key);
SHIFT_key = 0;
CTRL_key = 0;
ALT_key = 0;
}
printf("lpszKeyName = %sn", lpszKeyName );
}
return CallNextHookEx(hKeyboardHook, nCode,wParam,lParam);
}
void MessageLoop()
{
MSG message;
while (GetMessage(&message,NULL,0,0))
{
TranslateMessage( &message );
DispatchMessage( &message );
}
}
DWORD WINAPI my_HotKey(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!hInstance) hInstance = LoadLibrary((LPCSTR) lpParm);
if (!hInstance) return 1;
hKeyboardHook = SetWindowsHookEx ( WH_KEYBOARD_LL, (HOOKPROC) KeyboardEvent, hInstance, NULL );
MessageLoop();
UnhookWindowsHookEx(hKeyboardHook);
return 0;
}
int main(int argc, char** argv)
{
HANDLE hThread;
DWORD dwThread;
hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE) my_HotKey, (LPVOID) argv[0], NULL, &dwThread);
//ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
if (hThread) return WaitForSingleObject(hThread,INFINITE);
else return 1;
}
除非绝对需要,否则不要使用windows钩子。在你的情况下,你可以通过调用RegisterHotKey
函数安装一个热键,这是更简单的,因为你不需要开发进程间通信(这是你的DLL与钩子子程和你的主应用程序之间)。
"这个钩子在安装它的线程的上下文中被调用。通过向安装该钩子的线程发送消息来进行调用。因此,安装钩子的线程必须有一个消息循环。"- MSDN
你需要创建一个不可见的窗口
我不确定,但是您可能需要一个完整的消息循环,而不是普通的空无限循环。特别是如果您使用RegisterHotKey函数,如ybungalbill所建议的。
相关文章:
- CMake 在 Windows 上的自定义位置上找不到 Boost
- 在自定义程序中使用本机 Windows 自然顺序排序
- 我们无法在 Windows 10 中设置自定义密码过滤器
- 使用 Windows 功能区框架自定义颜色
- 如何将CString转换为使用WCHAR的Windows API和自定义函数?
- 如何以编程方式自定义Windows Media Player
- 调整大小的大小时,会创建自定义的Windows边框边缘消失
- 在 Code::Blocks 中使用自定义安装目录在 Windows 上链接 SDL-bgi
- 使用64位 自定义窗口形状(ETC平滑的角落不是矩形)在Windows中使用C 创建OpenGL窗口
- 如何在Windows 8中安装自定义凭证提供商
- 自定义Caffe Windows CPP中的卷积层
- 如何在Windows中创建扩展(自定义)文件属性
- 如何使用 Windows API 自定义对话框模板的资源
- Windows安装程序,成功执行后自定义操作出现错误2896
- Win32应用程序,在调用Windows内容之前调用自定义类方法
- Windows安装程序,在C++中访问自定义操作中的自定义属性
- 为windows实现一个自定义的unistd.h来处理VisualStudio问题
- 自定义系统对话框 - Windows Mobile 6.5
- 如何使用V2 CP样本自定义Windows 10凭据提供程序
- 自定义Windows身份验证包