제가 제작하고 있는 프로그램은 순수 API 로만 이루어진 프로그램입니다.
대화상자가 ESC 키에 반응 안하게 하려고 구글링을 해봤지만 대부분 MFC Dialog 에 관한 내용만 뜨더군요.
MFC 에서는 PreTranslateMessage 라는 걸로 쉽게 해결이 가능하지만 API 는 아닙니다... 흑.
하지만 역시 구글링은 절 버리지 않는군요...
http://www.williamwilling.com/blog/?p=28
여기 위 주소에 API Dialog 에 관한 해결 방법이 있었네요.
보통 API 로 Dialog 프로시저를 작성할 때
기본 틀은 위의 코딩과 유사할 것입니다.
하지만 위와 같이 코딩 했을 시 ESC 를 눌렀을 때 대화상자가 종료되어 버립니다.
그렇다고 WM_COMMAND 메세지 처리 부분을 없애면 대화상자의 우상단에 있는 X 버튼도 작동하지 않게 됩니다.
그렇다면 어떻게 해야하나...?
링크에 따르면 WM_COMMAND 대신 WM_CLOSE 메세지를 처리하면 된다고 합니다.
이렇게 코딩을 하면 ESC 에 반응하지 않고 종료되지 않습니다.
그런데 우상단 X버튼, 시스템 메뉴의 닫기, ALT + F4, 작업 관리자의 작업 끝내기 등은 여전히 작동이 됩니다. ~_~
매우 간단해 보여도 저에게는 정말 필요한 기능이였습니다~
그런데!
Multiline 속성을 가진 Edit 에서 ESC 를 누르면 WM_CLOSE 메세지가 처리되어 대화상자가 종료되어 버립니다. -_-;
물론 Multiline 속성을 가진 Edit 를 사용하시지 않는 분들은 전혀 상관 없습니다만...
아무튼 이런 문제에 대한 해결법도 적혀 있습니다.
WM_CLOSE 대신 WM_SYSCOMMAND 메세지로 처리 가능하다고 하네요.
이와 같이 처리를 하게 되면 Edit 에서 ESC를 눌러도 대화상자가 종료되지 않습니다.
그런데 또 한가지 문제가 생깁니다. -_-; 바로 작업 관리자에서 작업 끝내기를 할 때 반응을 하지 않습니다.
직접 해보시면 바로 종료되지 않다가 조금 텀을 두고 강제 종료되거나 응답 없음이라는 표시가 뜹니다.
사소한 것 같지만 저는 이런게 매우 거슬려요. ~_~ 친절하게도 링크에서는 이에 대한 대안 솔루션이 적혀 있습니다.
약간 번거로운 방법이지만 서브클래싱을 이용하는 방법인데요.
WM_CLOSE 메세지를 여전히 사용은 하되 Edit control의 서브클래싱을 통해 ESC 키에 대한 처리를 따로 하는겁니다.
이렇게 하면 EDIT 에서도 ESC가 작동하지 않고 나머지도 문제 없이 잘 되는 것 같네요.
저는 Multiline Edit 를 사용해야 되는 터라 서브클래싱을 이용한 해결 방법을 이용할 생각입니다.
적당히 자기에게 맞는 코딩 방법을 선택해서 사용하시면 되겠습니다~
대화상자가 ESC 키에 반응 안하게 하려고 구글링을 해봤지만 대부분 MFC Dialog 에 관한 내용만 뜨더군요.
MFC 에서는 PreTranslateMessage 라는 걸로 쉽게 해결이 가능하지만 API 는 아닙니다... 흑.
하지만 역시 구글링은 절 버리지 않는군요...
http://www.williamwilling.com/blog/?p=28
여기 위 주소에 API Dialog 에 관한 해결 방법이 있었네요.
보통 API 로 Dialog 프로시저를 작성할 때
BOOL
CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) {switch
(iMessage) {case
WM_COMMAND:switch
(LOWORD(wParam)){case
IDCANCEL: EndDialog(hDlg, IDCANCEL);return
TRUE
; }return
FALSE
; }
기본 틀은 위의 코딩과 유사할 것입니다.
하지만 위와 같이 코딩 했을 시 ESC 를 눌렀을 때 대화상자가 종료되어 버립니다.
그렇다고 WM_COMMAND 메세지 처리 부분을 없애면 대화상자의 우상단에 있는 X 버튼도 작동하지 않게 됩니다.
그렇다면 어떻게 해야하나...?
링크에 따르면 WM_COMMAND 대신 WM_CLOSE 메세지를 처리하면 된다고 합니다.
BOOL
CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) {switch
(iMessage) {case
WM_CLOSE: EndDialog(hDlg, IDCANCEL);return
TRUE
; }return
FALSE
; }
이렇게 코딩을 하면 ESC 에 반응하지 않고 종료되지 않습니다.
그런데 우상단 X버튼, 시스템 메뉴의 닫기, ALT + F4, 작업 관리자의 작업 끝내기 등은 여전히 작동이 됩니다. ~_~
매우 간단해 보여도 저에게는 정말 필요한 기능이였습니다~
그런데!
Multiline 속성을 가진 Edit 에서 ESC 를 누르면 WM_CLOSE 메세지가 처리되어 대화상자가 종료되어 버립니다. -_-;
물론 Multiline 속성을 가진 Edit 를 사용하시지 않는 분들은 전혀 상관 없습니다만...
아무튼 이런 문제에 대한 해결법도 적혀 있습니다.
WM_CLOSE 대신 WM_SYSCOMMAND 메세지로 처리 가능하다고 하네요.
BOOL
CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) {switch
(iMessage) {case
WM_SYSCOMMAND:if
(wParam == SC_CLOSE) { EndDialog(hDlg, 0);return
TRUE
; }break
; }return
FALSE
; }
이와 같이 처리를 하게 되면 Edit 에서 ESC를 눌러도 대화상자가 종료되지 않습니다.
그런데 또 한가지 문제가 생깁니다. -_-; 바로 작업 관리자에서 작업 끝내기를 할 때 반응을 하지 않습니다.
직접 해보시면 바로 종료되지 않다가 조금 텀을 두고 강제 종료되거나 응답 없음이라는 표시가 뜹니다.
사소한 것 같지만 저는 이런게 매우 거슬려요. ~_~ 친절하게도 링크에서는 이에 대한 대안 솔루션이 적혀 있습니다.
약간 번거로운 방법이지만 서브클래싱을 이용하는 방법인데요.
WM_CLOSE 메세지를 여전히 사용은 하되 Edit control의 서브클래싱을 통해 ESC 키에 대한 처리를 따로 하는겁니다.
WNDPROC OldControlProc; LRESULT CALLBACK ControlProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {switch
(message) {case
WM_KEYDOWN:if
(LOWORD(wParam) == VK_ESCAPE) {/* 주석 부분은 링크에 포함되어 있었던 부분입니다. 단지 꼭 필요한 것 같지는 않아서 주석 처리 했습니다. 만약 넣어야 된다고 생각하시는 분들은 주석 처리를 빼고 포함해주시면
됩니다.HWND hwnd_parent = GetAncestor(hWnd, GA_PARENT);
SendMessage(hwnd_parent, WM_COMMAND, IDCANCEL, (LPARAM) hWnd);*/
return
0; }break
; }return
CallWindowProc(OldControlProc, hWnd, message,wParam, lParam); }BOOL
CALLBACK MainDlgProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam) {switch
(iMessage) {case
WM_INITDIALOG: { HWND hwnd_edit = GetDlgItem(hDlg, IDC_EDIT1); OldControlProc = (WNDPROC) SetWindowLongPtr(hwnd_edit, GWL_WNDPROC,
(LONG_PTR) ControlProc);return
TRUE
; }case
WM_CLOSE: { EndDialog(hDlg, 0);return
TRUE
; } }return
FALSE
; }
이렇게 하면 EDIT 에서도 ESC가 작동하지 않고 나머지도 문제 없이 잘 되는 것 같네요.
저는 Multiline Edit 를 사용해야 되는 터라 서브클래싱을 이용한 해결 방법을 이용할 생각입니다.
적당히 자기에게 맞는 코딩 방법을 선택해서 사용하시면 되겠습니다~