MFC의 메시지맵을 구현하는 매크로를 보면 VS6.0 에선 일단 정상적인 syntax를 갖추고 있다.
#define ON_BN_CLICKED(id, memberFxn) \
ON_CONTROL(BN_CLICKED, id, memberFxn)
#define ON_CONTROL(wNotifyCode, id, memberFxn) \
{ WM_COMMAND, (WORD)wNotifyCode, (WORD)id, (WORD)id, AfxSig_vv, \
(AFX_PMSG)&memberFxn }, // &memberFxn
그러나 VS2008 이상의 버젼에서 부터는 (2005이하는 테스트 해보지 못하였지만 결과는 다르지 않으리라 생각한다) 기본적인 syntax를 아래에서 처럼 무시한다.
#define ON_BN_CLICKED(id, memberFxn) \
ON_CONTROL(BN_CLICKED, id, memberFxn)
#define ON_CONTROL(wNotifyCode, id, memberFxn) \
{ WM_COMMAND, (WORD)wNotifyCode, (WORD)id, (WORD)id, AfxSigCmd_v, \
(static_cast< AFX_PMSG > (memberFxn)) }, // memberFxn여기 까지의 내용은 & 연산자만 관련해서의 내용이었고, Class Qualifier까지 더 생각해본다면 사실 6.0 도 정확한 syntax를 고수하고 있는 것은 아니다.
MFC에서 dialog 방식으로 임의의 버튼 윈도우를 만든 후, 해당 버튼 윈도우에 메시지 핸들러를 하나 등록했다. 다음은 VS6.0에서의 상황
BEGIN_MESSAGE_MAP(CMFC60Dlg, CDialog)
//{{AFX_MSG_MAP(CMFC60Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, OnButton1) // Class Qualifier
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
다음은 VS2008의 경우인데, 이번에는 2008이 제대로 Class Qualifier을 정확히 붙여주고 있다.
BEGIN_MESSAGE_MAP(CMyMFC2Dlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CMyMFC2Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()
해당 내용은 분명 비문법적이므로 관련 내용을 유명한 개발자 커뮤니티에 올리고 답변글을 받아봤다. 몇몇 내용을 발췌하면,
- The only correct way to form a pointer to member in C++ is with & and the class qualifier (in this case CSingleApp::).
The Visual C++ compiler has always been more relaxed and has allowed things not normally permitted in the language such as leaving of the qualifier when forming the pointer from inside the class' context and not needing to use & when it is strictly required.
- Most likely there are #pragmas in the MFC headers or something that suppresses the errors, for backwards compatibility reasons. Older versions of VC++ were much less conforming than the newer compilers.
마지막으로, 2008에서 해당 예외적 기능을 구현하고 있는 방법좀 누군가가 가르쳐주시면 감사하겠습니다.





