Reputation: 257
I want to make some custom hot keys where in any program I can bring up different programs with certain key combinations. I researched how to do hooks and was given this example.
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;
}
Rather than a message box, as I want this to run in the background, I tried using loops but nothing I have tried successfully behaves like the messagebox. Any ideas?
Upvotes: 4
Views: 7098
Reputation: 8587
This good code below is a Hotkey app that sits in the background listening for the CTRL-y
key combination, and you can modify or add any more key combinations to the app. Use CTRL-q
to exit the app when hidden.
If you wish to fully hide the console window, then un-comment this line in main() : //ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false)
. Enjoy.
if (CTRL_key !=0 && key == 'y' )
{
MessageBox(NULL, "CTRL-y was pressed\nLaunch your app here", "H O T K E Y", MB_OK);
CTRL_key=0;
}
Full code listing:
#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 pressed\nLaunch 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 = %c\n", key);
SHIFT_key = 0;
CTRL_key = 0;
ALT_key = 0;
}
printf("lpszKeyName = %s\n", 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;
}
Upvotes: 7
Reputation: 4237
"This hook is called in the context of the thread that installed it. The call is made by sending a message to the thread that installed the hook. Therefore, the thread that installed the hook must have a message loop." - LowLevelKeyboardProc MSDN
You need to create an invisible window.
Upvotes: 1
Reputation: 409166
I'm not sure, but instead of a normal empty infinite loop, you might need to have a complete message loop. Especially if you use the RegisterHotKey function as suggested by ybungalobill.
Upvotes: 0
Reputation: 72469
Don't use windows hooks unless you absolutely need to. In your case you can install a hotkey by calling the RegisterHotKey
function, which is much simpler since you don't need to develop interprocess communication (that is between your DLL with the hook procedure and your main app).
Upvotes: 3