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:
Same condition apply for widly use ON_MESSAGE macro too..
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.
Indranil, _MSC_VER defines the compiler version, so Nish just decided to change function prototype (CButton::OnNcHitTest) for a Beta2 compiler by using #if #else #endif statements.
Hi Nish, there are some more annoying things. But I’m not sure if they were listed in the breaking changes in 7.1 or 8. I had to fix the COptionTree for a internal test programm.
http://www.codeproject.com/treectrl/coptiontree.asp
Just wanted to say thanks for posting this, probably saved me a lot of time.
I use the following snippet in my global header file:
#if _MFC_VER (OnNcHitTest)) },
#endif
Thank you, I have been searching for the solution for months,almost give up.
This post is very useful.
thanks also from my side!!
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);
…
Thanks, was useful. Can happen in a lot of other context, but can be fixed with a similar solution.
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
What a fix! thanks for that….
Thanks , you really helped me out with that one!!
I love your site. 🙂 Love design!!! I just came across your blog and wanted to say that Ive really enjoyed browsing your blog posts. Sign: ndsam