윈도우 운영체에에서 alt 키와 f10 키는 조금 특별한 키로 분류 됩니다. 대부분의 윈도우 응용프로그램이 Alt 키나 f10 키를 누르면 메인 메뉴로 포커스가 이동합니다. 이와 같은 사용자 인터페이스의 일관성을 유지하려고,두 키에 대한 입력이 발생하면 WM_KEYDOWN 과 WM_KEYUP 메시지가 아니다 WM_SYSKEYDOWN 과 WM_SYSKEYUP 메시지가 발생합니다. 메시지의 이름이 달라졌을 뿐 개발자 입장에서 보면 크게 다를것은 없습니다. 그러나 메시지가 발생한 원인에서 차이가 있으므로 작성할 코드의 특징이 달라질 가능성이 큽니다.
다음은 WM_SYSKEYDOWN 메시지 핸들러 함수인 OnSysKeyDown() 함수를 뷰 클래스에 등록한 예제
void CWndProcView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
WORD wResult = GetKeyState(VK_SPACE);
//상위 바이트의 1번 비트가 1이면 키가 눌려진 상태 //같은 방법으로 Caps Lock 키의 상태 검사 AfxMessageBox(strMessage); CView::OnKeyDown(nChar, nRepCnt, nFlags);
OnSysKeyDown() 함수의 인자는 OnKeyDown() 함수와 같습니다. 대부분의 키 입력에서 대해 OnKeyDown() 함수는 Alt키와 조합된 키 입력에 대해 호출됩니다.
HIBYTE() 와 LOBYTE() 매크로는 인자로 주어진 16비트 값에서 각각 상위/하위 바이트 를 잘라내는 매크로 입니다.
VK_SPACE는 토글 키가 아니므로 굳이 하위 바이트 정보를 확인할 이유가 없습니다. 그래서 상위 바이트 정보만 검사하는것이고 1번 비트가 1인지 비트 연산 하여 학인 합니다.
Caps Lock,Number Lock,Scroll Lock 키는 대표적인 토글 키로서 이들 키는 한 번씩 누를 때마다 상태가 On/Off 되는 특성이 잇습니다 .
이런 상태 정보는 GetKeyState()함수 가 반환한 결과의 하위 바이트에 들어 있습니다. On/Off 상태는 앞서와 같이 1번 비트를 확인하면 됩니다. 사용이 빈번하므로 알아 두길 바랍니다.
WM_SYSCHAR 메시지는 Alt 키와 문자키 입력이 조합된 경우에 발생합니다. 덧글 쓰기 엮인글 쓰기 공감 |
MFC 에서도 WM_KEYDOWN 을 사용 할수 있다.
소스를 통해서 알아보자 (SetWindowPos,SetWindowText 등은 기본 API 에서 와 역할이 같다 단지 CWnd 에서 사용하는것)
기초 MFC를 만든뒤에 클래스 뷰에서 View 클래스에 메시지 를 통해 WM_CREATE 인 OnCreate 와 WM_KEYDOWN인 OnKeyDown 을 만들어 두자
// WndProcView.h : CWndProcView 클래스의 인터페이스 부분 에서 CWnd 를 선언해두자 // 작업입니다.
그후 CWndProcView.cpp 의 OnCreate 에 윈도우를 생성하자
int CWndProcView::OnCreate(LPCREATESTRUCT lpCreateStruct) m_wndChild.Create(TEXT("STATIC"),TEXT("KeyMove"), // TODO: 여기에 특수화된 작성 코드를 추가합니다. return 0;
그후 CWndProcView.cpp 안에 추가된 OnKeyDown 에서 키보드 입력을 통해서 윈도우를 조절할수 있다.
void CWndProcView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) m_wndChild.GetWindowRect(&Rect); ptChild.x = Rect.left; //스크린 기준 좌표를 클라이언트 뷰 기준의 좌표로 환산한다. switch(nChar)
CString strText = TEXT("");
//입력한 키가 Enter,Back Space,ESC 키가 아니면 if(nChar != VK_RETURN && nChar != VK_BACK && nChar != VK_ESCAPE)
// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다. CView::OnKeyDown(nChar, nRepCnt, nFlags); 덧글 쓰기 엮인글 쓰기 공감 |
MFC 에서도 WndProc 를 쓸수 있다. 메세지 맵이 있는 CMainFrame 클래스의 에서 WndProc 의 재정의인 WindowProc 가 그것이다.
또한 PreTranslateMessage 함수를 정의하면 윈도우 프로시저 함수나 메세지 핸들러 함수를 호춣기 전에 PreTranslateMessage 는 호출된다. WindowProc() 함수처럼 이 함수를 재정의하여 모든 왼도우 메시지를 처리하는 것도 가능하지만 굳이 이함수를 이용할 필요 없이 WindowProc() 를 이용하면 그만이다
만일 PreTranslateMessage 에서 WM_KEYDOWN 의 메시지를 처리하지 않도록 코드를 작성하면 WM_KEYDOWN은 호출되지 않는다. PreTranslateMessage()은 메시지 큐에서 메시지를 꺼낸직후 사용되기 떄문에 필터링이 가능한 메시지는 메시지 큐를 경유하는 메시지로 한정된다. (SendMessage 함수는 바로 WindowProc() 를 호출하기 떄문에 메시지 큐를 경우 않한다)
PreTranslateMessage 함수의 주된 역할은 메시지 필터링이다. 즉 불필요한 메시지를 걸러 주는것이다.
|
'프로그래밍 > MFC' 카테고리의 다른 글
[MFC] CWinAppEx::CleanState() (0) | 2010.08.25 |
---|---|
CView (0) | 2010.05.24 |
차일드 사용 (0) | 2010.05.20 |
MFC에서 hWnd와 hinst 얻어오기 (0) | 2010.05.20 |
마우스 이벤트 (0) | 2010.05.20 |