윈도우에서 C를 활용, 'Winuser.h' 파일에 있는 GetMessage 함수와 RegisterHotKey 함수를 이용하여 키보드의 단축키(핫키)를 설정하고 입력받는다.
Winuser.h 파일을 불러오고 GetMessage, RegisterHotKey 함수를 사용하면 컴파일 시 'C1189 : #error "No Target Architecture"' 오류가 발생한다.
이는 위 함수 내부 변수들이 Winuser.h에 없기 때문에 발생하는 문제로, Winuser.h 대신에 Winuser.h, Winnt.h 등 여러 파일을 포함하는 windows.h 파일을 불러오는 것으로 해결한다.
단축키 설정
BOOL RegisterHotKey(
HWND hWnd,
int id,
UINT fsModifiers,
UINT vk
)
RegisterHotKey는 단축키를 설정한다. 이후 단축키를 입력받으면 메시지큐에 단축키 정보인 'WM_HOTKEY'를 넣어준다. 리턴 값은 bool로서 실패 시 'FALSE', 성공 시 'TRUE'를 반환한다.
RegisterHotKey는 시스템 전역에 단축키를 설정하기 때문에 신중하게 사용되어야 한다.
hWnd
윈도우의 각 창은 hWnd라는 고유 아이디를 갖는다. hWnd는 정수형 값이며 운영체제가 직접 생성하고 사용하므로 사용자가 알 필요는 없다. 'NULL'을 입력하면 함수가 호출된 스레드의 메시지큐에 전달된다.
id
단축키의 고유 id
fsModifiers
같이 사용할 단축키를 지정한다. 'MOD_ALT', 'MOD_CONTROL', 'MOD_SHIFT', 'MOD_WIN'이 있으며 성격이 다른 'MOD_NOREPEAT'가 있다. 만약 단축키를 'ALT + A'로 지정하고 싶다면 'MOD_ALT'를 사용한다. 0을 입력하면 같이 사용할 단축키를 지정하지 않는다. 'MOD_NOREPEAT'는 '|'을 통해 'MOD_ALT' 등과 같이 사용될 수 있으며 단축키를 계속 누르고 있어도 한 번만 실행되게 한다.
vk
단축키를 지정.
예제 : 단축키 'ALT + B'가 정상적으로 등록되면 "Hotkey 'ALT+B' registered"를 출력한다.
if (RegisterHotKey(NULL, 1, MOD_ALT | MOD_NOREPEAT, 'B') == TRUE) // 'B' 대신 0x42 입력가능
{
printf("Hotkey 'ALT+B' registered\n");
}
단축키 사용
BOOL GetMessageA(
LPMSG lpMsg,
HWND hWnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax
)
lpMsg
메시지 큐의 포인터
hWnd
창의 고유 아이디
wMsgFilterMin, wMsgFilterMax
메시지를 필터링할 때 사용한다. Min과 Max를 통해 범위를 지정해주면 범위 내의 메시지만 받을 수 있다. 예를 들어 키보드의 숫자 1~9의 범위만 지정해주면 다른 키들은 입력받을 수 없다. Min과 Max를 둘 다 0으로 지정하면 필터링을 하지 않는다.
예제 : 'B', 'C' 단축키를 등록하고 B를 입력받을 시 "B received"를, C를 입력받을 시 "C received"를 출력한다.
// 단축키 등록
RegisterHotKey(NULL, 1, 0, 'B');
RegisterHotKey(NULL, 2, 0, 'C');
// 단축키 사용
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
if (msg.message == WM_HOTKEY)
{
if (msg.wParam == 1) printf("B received \n");
else if (msg.wParam == 2) printf("C received \n");
}
}
단축키 해제
BOOL UnregisterHotKey(
HWND hWnd,
int id
)
hWnd
창의 고유 아이디.
id
등록된 단축키의 고유 아이디.
예제 : 'Alt + B' 단축키가 해제되면 "Hotkey was Unregisterd"를 출력한다.
예제
#include <windows.h>
#include <stdio.h>
int main() {
RegisterHotKey(NULL, 1, 0, 'B');
RegisterHotKey(NULL, 2, 0, 'C');
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
if (msg.message == WM_HOTKEY)
{
if (msg.wParam == 1) printf("B received \n");
else if (msg.wParam == 2) printf("C received \n");
}
}
}
참고
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-msg
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmessagea
https://docs.microsoft.com/en-us/windows/win32/inputdev/wm-hotkey
https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerhotkey
https://docs.microsoft.com/en-us/cpp/mfc/relationship-between-a-cpp-window-object-and-an-hwnd?view=vs-2019
https://www.codeproject.com/Articles/2213/Beginner-s-Tutorial-Using-global-hotkeys
최근댓글