반응형

윈도우에서 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