이 팁은 담비님(천리안 FREKBS)님이 1999년 04월 15일에 천리안 프로그래머포럼에 올리신 것입니다.
담비님으로부터는 전제하여 올리는 데 대해 허락을 받았습니다.
좋은 정보를 공유하도록 허락해주신 담비님께 감사드립니다.
───────────────────────────────────────
안녕하세요! 담비입니다.
출처 :
http://www.bcbdev.com/faqs/faq78.htm
콘트롤의 OnKeyPress 핸들러를 작성하여 TAB 키에 반응하도록 했던 경험이 있나요?
아마, 적어도 대부분의 콘트롤들에서는 그렇게 작동하지 않는다는 것을 깨달았을
것이다. 문제는 windows가 focus를 가진 콘트롤이 요청한 경우에만 TAB 키를 위한
키보드 이벤트를 보낸다는 것이다. 화살표 키도 마찬가지이다.
그럼 어떻게 OS가 TAB 키를 위한 키보드 이벤트들을 받고자 하는 포커스를 가진
콘트롤임을 알게할 수 있을까? OS는 받고자 하는 키를 콘트롤에 요청하기 위하여
WM_GETDLGCODE 메세지를 초점을 가진 콘트롤에 보낸다. 이 메세지의 리턴 값은
콘트롤에게 보내지게될 keystroke이 무엇인가를 결정한다. WM_GETDLGCODE는
다음 값들의 조합이다.
* DLGC_BUTTON
* DLGC_DEFPUSHBUTTON
* DLGC_HASSETSEL
* DLGC_RADIOBUTTON
* DLGC_STATIC
* DLGC_UNDEFPUSHBUTTON
* DLGC_WANTALLKEYS
* DLGC_WANTARROWS
* DLGC_WANTCHARS
* DLGC_WANTMESSAGE
* DLGC_WANTTAB
TAB 키에 대한 키 이벤트를 받기 위해 초점을 가진 콘트롤은 DLGC_WANTTAB을 리턴
해야만 한다. 화살표 키에 대한 키 이벤트를 받기 위해서는 DLGC_WANTARROWS를 리턴
한다. 만일 TAB 키와 화살표 키 모두의 키 이벤트들을 받고자 한다면
DLGC_WANTARROWS와 DLGC_WANTTAB를 OR로 bitwise연산하고 그 값을 리턴한다.
만일 모든 키들에 대한 키 이벤트들을 받으려면 DLGC_WANTALLKEYS를 리턴한다.
VCL은 WM_GETDLGCODE 메세지를 사용하는 방법에 관한 몇몇 좋은 예제들을 가지고
있다. TToolBar는 화살표 키들에 대한 이벤트를 받도록 WM_GETDLGCODE에 응답하며,
TCustomGrid는 TAB 키와 화살표 키 모두를 요청하도록 WM_GETDLGCODE를 사용한다.
여기 약간의 코드는 WM_GETDLGCODE 메세지에 그들이 어떻게 응답하는가를 보여주기
위해 VCL에서 발췌해온것이다. 읽기 쉽도록 파스칼에서 C++ 코드로 변환하였다.
void __fastcall TToolBar::WMGetDlgCode(TMessage & Message)
{
// only want the arrow keys in some situations
if(FInMenuLoop)
Message.Result = DLGC_WANTARROWS;
}
void __fastcall TCustomGrid::WMGetDlgCode(TMessage & Message)
{
// always want the arrow keys
Msg.Result := DLGC_WANTARROWS;
...
// sometimes want the tab key
if (Options.Contains(goTabs))
Msg.Result := DLGC_WANTTAB;
// sometimes want WM_CHAR messages
if (Options.Contains(goEditing))
Msg.Result := DLGC_WANTCHARS;
}
void __fastcall TMediaPlayer::WMGetDlgCode(TMessage &Message)
{
Message.Result = DLGC_WANTARROWS;
}
Note : Form에서 WM_GETDLGCODE 핸들러를 작성하지 말라. WM_GETDLGCODE 핸들러는
콘트롤 레벨에서 작성되어져야만 한다.
Note : VCL 프로그램에서, 운영체제는 WM_GETDLGCODE 메세지의 실질적인 creator가
아니다. VCL은 그 메세지를 종합한다. 다행히 이것은 무시할 수있는 세부적인
실행이다. 단순히 OS가 메세지의 creator였던것처럼 WM_GETDLGCODE 핸들러
를 작성한다.