Breaking change – OnNcHitTest

Alright, this is a really bad one. This line of code :-

ON_WM_NCHITTEST()

– which was compiling quite okay in VC++ 6 (and VC++ 7.1) suddenly throws this strange error message.

error C2440: 'static_cast' : cannot convert from 'UINT (__thiscall CPocket::* )(CPoint)' to 'LRESULT (__thiscall CWnd::* )(CPoint)'

And it also has a suggestion to fix the error that is even more confusing :-

Cast from base to derived requires dynamic_cast or static_cast

We are already using static_cast, aren’t we?

Guess what? The return type for OnNcHitTest has been changed from UINT to LRESULT (only in the MFC source, the MSDN documentation still says UINT as of Beta 2) to accommodate for negative return values. Crappy part is that this was wizard generated code – we didn’t even write it, damnit! The fix is to change UINT to LRESULT – though if you want to compile the same code for VC++ 6 and 7.1, you’d want to do what I did :-

//In header file

#if _MSC_VER >= 1400
	afx_msg LRESULT OnNcHitTest(CPoint point);
#else
	afx_msg UINT OnNcHitTest(CPoint point);
#endif	
//In cpp file

#if _MSC_VER >= 1400
	LRESULT CPocket::OnNcHitTest(CPoint point)
#else
	UINT CPocket::OnNcHitTest(CPoint point)
#endif
{
#if _MSC_VER >= 1400
	LRESULT nRet=CButton::OnNcHitTest(point);
#else
	UINT nRet=CButton::OnNcHitTest(point);
#endif
//...

Took me a while to figure that one out! It’s not even listed in the Breaking Changes page! :grrr:

Advertisements

14 thoughts on “Breaking change – OnNcHitTest

  1. Hi,
    I am quite sure that you are right in this matter and the blog is excellent. I should not
    be ashemed that I don’t know why if _MSC_VER >= 1400 ?? :->
    If you can elaborate on this, I will be happy.

  2. I hate predprocessor directives in the code – they obstruct the code and make it hard to read. How about this solution:
    In stdafx.h:
    #if _MSC_VER >= 1400 // VS2005 changed result of OnNCHitTest
    #define HITTEST_RET LRESULT
    #else
    #define HITTEST_RET UINT
    #endif

    And everywhere else is
    // Header files
    afx_msg HITTEST_RET OnNcHitTest(CPoint point);

    // Cpp files
    HITTEST_RET CIsconWaveBenchFrame::OnNcHitTest(CPoint point)
    {
    HITTEST_RET lResult = CFrameWnd::OnNcHitTest(point);

  3. Hi,

    i keep getting this error:

    error C2440: ‘static_cast’: ‘LRESULT (__thiscall CMyApp::* )(WPARAM,LPARAM)’ kann nicht in ‘LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)’ konvertiert werden

    telling me that the messagemap is wrong:
    BEGIN_MESSAGE_MAP(CMyApp, CWinApp)
    //{{AFX_MSG_MAP(CMyApp)
    ON_MESSAGE(UM_SETHOOK, OnSetHook)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    is that something similar?

    cheers
    B

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s