본문 바로가기

Application Dev./C++/MFC

다이얼로그 기반의 프로그램에서 Enter키, Escape키 막기

[출처] [MFC]다이얼로그 기반의 프로그램에서 Enter 키 안 먹히기|작성자 낭만오리

MFC에서 다이얼로그(Dialog) 베이스에서 프로그래밍 할 경우,
프로그램을 실행했을 때, 엔터(Enter) 키를 누르게 되면 CDialog::OnOK() 함수가
자동적으로 호출 되어서 Dialog가 자동적으로 닫히게 된다. 

이런경우를 막기 위해서는 여러방법이 있는데, 그 중에 일반적으로 많이 쓰이는 것이  CDialog::PreTranslateMessage(MSG* pMsg); 함수를 오버라이딩(재정의) 한 후,
엔터키가 눌렸다는 메시지를 가로채서, 실행하지 않게 하면된다.

마찬가지로, ESC 키가 눌렸을 때는 CDialog::OnCancel() 함수가 자동적으로 호출되어서
Dialog가 자동적으로 닫히게 되는데, 막는 방법은 위의 설명과 같다.


예제는 아래와 같다.

1. MFC에서 프로젝트 이름이 Test라는 다이얼로그 베이스 프로젝트를 만들었다고 가정한다.
2. 메뉴의 View --> ClassWizard 선택 또는 단축키 Ctrl+W 키를 눌러 클래스위저드를
  실행 시키고 PreTranslateMessage 함수를 찾아서  오버라이딩 한다.

 

BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
   //키눌린 메시지가 들어올때 esc이거나 return  값이면
   //걍 리턴 시켜준다.
   if(pMsg->message == WM_KEYDOWN)
   {
      switch(pMsg->wParam)
      {
       case VK_ESCAPE:
       case VK_RETURN:
            return TRUE;
       default:
            break;
       }
    }
   //또는 
   /*
       if(pMsg->wParam == VK_ESCAPE)  return TRUE;
       if(pMsg->wParam == VK_RETURN)  return TRUE;
   */
    return CDialog::PreTranslateMessage(pMsg);
}

 

참고로, 위의 방법이 싫다면 아래와 같이 OnOk() , OnCancel() 함수를 직접 오버라이딩 해 주면 된다.

void CTestDlg::OnOK()
{
     // CDialog::OnOK();    << 이 부분을 주석 처리 또는 삭제하면 된다.
}

만일, IDOK 버튼(기본적으로 생성되는 버튼)을 다이얼로그 상에서 이미 지웠다면
클래스위저드를 사용할 때 객체 목록(Object IDs)에 나타나지 않는다.
이럴 경우는 임시로 버튼을 만들어 아이디를 IDOK로 해 주면 된다.
그리고 다시 클래스 위저드를 열고, 위처럼 오버라이딩 해준후 그 버튼을 지우면 된다.
ESC키를 처리하는 방법도 위와 동일하다. 단지,아이디가 IDCANCEL 이다.





문제는 IDCANCEL 을 막으면 ControlBox에 X 버튼이 막힌다는건데...
VK_ESCAPE 캐치 해서 'TRUE'만 넘겨주면 되네 ㅋㅋ

멍청한 짓 할뻔 했군...