본문 바로가기

MFC

MFC HotKey 등록법

Ctrl + I 핫키 키로 등록할 경우

전역변수 int m_HotkeyWsChangeID; 선언


시작시 정의
//핫키 등록m_HotkeyWsChangeID  = ::GlobalAddAtom(_T("TopMonitorkey"));	
if(!::RegisterHotKey(GetSafeHwnd(), m_HotkeyWsChangeID , MOD_CONTROL, 'P'))		
AfxMessageBox(_T("핫키 등록 실패!"));



메시지맵에 ON_MESSAGE(WM_HOTKEY, OnHotKey)

한다. 이 때 //}}AFX_MSG_MAP 바깥에 한다.


//메세지 받는 프로시져
afx_msg LONG OnHotKey(WPARAM wParam, LPARAM lParam);
LONG CMainFrame::OnHotKey(WPARAM wParam, LPARAM lParam)
{
if((int)wParam == m_nHotKeyID) {
}
return 0;

}







종료시 반드시 해체!!
//해체
::UnregisterHotKey(GetSafeHwnd(), m_HotkeyWsChangeID);




침고

핫키란 프로그래머의 관점에서 보자면 윈도우에서 관리해주는 단축키 시스템입니다. 매우 편리하죠. RegisterHotkey라는 함수로 등록하고, UnregisterHotKey로 해제합니다. 그 외에도 다른 핫키가 있는데 이건 끝에서 얘기하겠습니다.

BOOL RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk);
hWnd : 등록된 핫키가 눌려졌을 때 그 메시지(WM_HOTKEY)를 받을 윈도우입니다.
id : 핫키의 아이디입니다. 윈도우와의 조합으로 인식할 수 있기 때문에 자신의 프로그램에서만 구별할 수 있는 값이면 충분합니다.
fsModifiers : 구별자... CONTROL, ALT, SHIFT등을 의미합니다.
vk : 실제 키입니다.

예를 들어 ALT+SHIFT+K가 눌렸을 때 hWnd에 3을 받으려면
RegisterHotKey(hWnd, 3, MOD_ALT | MOD_SHIFT, 'k');
이렇게 호출하면 되겠죠.
이미 같은 조합의 핫키가 등록되어 있다면 이 함수는 실패합니다.

WM_HOTKEY 메시지는 다음과 같습니다.
WM_HOTKEY
idHotKey = (int) wParam;              // 아이디. 위의 예에서는 3.
fuModifiers = (UINT) LOWORD(lParam);  // MOD_...의 조합
uVirtKey = (UINT) HIWORD(lParam);     // 버추얼 키 코드

더 이상 핫키를 사용할 일이 없을 때는 UnregisterHotKey를 사용합니다.
UnregisterHotKey(hWnd, 3); 등록한 윈도우와 아이디를 사용하면 됩니다.

핫키를 등록할 때 참고사항은 다음과 같습니다.
. WM_HOTKEY는 클래스 위자드에서 지원하지 않습니다. 핸들러는 손으로 직접 써주세요.
. hWnd는 NULL일 수 있습니다. 이 때 WM_HOTKEY는 RegisterHotKey를 호출한 스레드에서 처리해야 합니다.
. id는 어플리케이션에서 호출할 때는 0x0000에서 0xBFFF사이의 값이어야 합니다. 공유 DLL에서 호출할 때는 GlobalAddAtom함수를 호출해서 유일한 아이디를 받아서 사용해야 합니다. (설마 그럴 일이 있을라고요. 설마...)

---------------------------------------------------------------------

핫키를 사용자가 정의하게 하자.

핫키를 사용자가 정의하게 할 때 가장 편한 방법은 핫키 컨트롤을 사용하는 겁니다.
(헉! 그런 컨트롤도 있냐고요? 있더군요... -_-;)
바탕 화면에 있는 적당한 단축아이콘을 골라 등록 정보를 보면 [바로가는키]라는 항목이 보입니다. 그리고 아마도 '없음'이라고 표시되어 있겠죠? 이게 핫키 컨트롤입니다. 없음에 포커스를 준 다음에 아무 키나 눌러보세요.

입력하는 대로 화면에 나타날 것이라고 예상하셨겠지만... 그렇지 않습니다. 뭘 입력해도 CTRL+ALT+의 조합과 나타나죠. SHIFT는 적어도 CTRL이나 ALT중 하나와 함께 누르지 않으면 무시됩니다. 사실 E를 단축키로 지정한다거나 하면 무슨 일을 하다가도 지정한 프로그램이 실행되겠죠. 따라서 좀 복잡한 키 조합이 되도록 하는 것이 좋습니다. 핫키 컨트롤이 좋은 것은 그런 일을 쉽게 할 수 있기 때문이죠.

제 맘대로 MFC의 CHotKeyCtrl만 설명하겠습니다.
중요한 멤버 함수는 3개입니다.
SetHotKey : 핫키를 지정합니다.
GetHotKey : 입력된 핫키를 얻습니다.
SetRules : 핫키를 입력하는 규칙을 지정합니다.

SetRules는 Alt, Ctrl, Shift의 조합에 대한 규칙을 정의합니다. SetRules에서 잘못된 조합을 설정하고, 그 때의 기본 조합을 지정합니다. 바탕화면의 경우는 아마도 SetRules(HKCOMB_A|HKCOMB_C|HKCOMB_NONE|HKCOMB_S, HOTKEYF_ALT|HOTKEYF_CONTROL); 이렇게 지정했겠죠.

SetHotKey로 기본값을 정하고, 사용자가 입력한 결과를 GetHotKey로 얻으면 됩니다.
GetHotKey는 두가지 버전이 있습니다. 두개의 WORD를 레퍼런스로 전달하는 버전이 더 편하겠죠. 원래 리턴값이 하나인 것을 내부에서 두개로 분리해주는 버전입니다.

그러면 GetHotKey의 결과를 이용해서 RegisterHotKey를 불러줍니다.

WORD key, mod;
int mod2; // 변수 이름은 멋난걸로 바꾸세요.
m_ctlHotKey1.GetHotKey(key, mod);
mod2 = ((mod & HOTKEYF_ALT) ? MOD_ALT : 0) |
    ((mod & HOTKEYF_CONTROL) ? MOD_CONTROL : 0) |
    ((mod & HOTKEYF_SHIFT) ? MOD_SHIFT : 0);
RegisterHotKey(hWnd, id, mod2, key);

핫키 컨트롤의 modifier flag과 RegisterHotKey에서 사용하는 flag이 다르기 때문에 위와 같이 변환해줄 필요가 있습니다.

---------------------------------------------------------------------

위에서 보면 서로 flag이 다르기 때문에 변환해줄 필요가 있었는데 왜 그렇게 되어있을까요? 저는 잘 모르죠. -_-;

다만 이제부터 얘기할 WM_SETHOTKEY는 핫키 컨트롤과 flag이 같습니다.
원래 핫키 컨트롤이 이 메시지와 연동하게 되어있을지도 모르죠.

WM_SETHOTKEY 를 사용하면 윈도우에 하나뿐인 핫키를 정의하게 됩니다. 이 핫키가 눌려지면 WM_SYSCOMMAND에 SC_HOTKEY가 오게 됩니다. 해당 윈도우를 활성화하는 일을 정의하는 거죠. 자세한 내용은 MSDN을 참조하세요.
이 메시지는 RegisterHotKey나 WM_HOTKEY와는 관련이 없습니다.

. WM_SETHOTKEY는 child window에는 사용할 수 없습니다.
. 하나의 윈도우에 하나밖에 정의할 수 없습니다. 이미 핫키가 정의되어 있다면 새로운 핫키가 이전의 핫키를 대체합니다.
. 리턴값은 -1, 0, 1, 2중 하나입니다. 1일 때만 제대로 등록된 겁니다.
. 현재 정의된 핫키를 얻으려면 WM_GETHOTKEY를 사용합니다.

'MFC' 카테고리의 다른 글

[MFC] ListCtrl 팁..  (1) 2012.02.23
STL 설명 인터넷 링크  (0) 2011.12.29
MFC HotKey 등록법  (0) 2011.07.13
공유세그먼트  (0) 2011.06.30
DWORD IP to CString, CString IP to DWORD  (0) 2011.05.17
MFC 창 Dialog 최소화 메시지  (0) 2011.05.01