MFC:将工程从VC6.0工程升级到VS2017所遇到的代码不兼容问题集合

一、errorC2440:消息相应函数类型不能转化

  1. 问题描述
    VS2017编译提示以下两个问题:
(1)errorC2440	“static_cast”: 无法从“UINT (__thiscall CSizingControlBar::* )(CPoint)”转换为“LRESULT (__thiscall CWnd::* )(CPoint)”
(2)errorC2440	“static_cast”: 无法从“LRESULT (__thiscall CTextProgressCtrl::* )(UINT,LPTSTR)”转换为“LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)”
(3)errorC2440	“static_cast”: 无法从“BOOL (__thiscall CCJPagerCtrl::* )(NMPGSCROLL *,LRESULT *)”转换为“BOOL (__thiscall CCmdTarget::* )(NMHDR *,LRESULT *)”
  1. 解决方法
  • error(1)解决方法:
    通过提示的消息找到相应的消息相应函数,本次出现的问题是CSizingControlBar::OnNcHitTest,由
    afx_msg UINT OnNcHitTest(CPoint point); //VC6תVS2017-gxy-20181025
    改成
    afx_msg LRESULT OnNcHitTest(CPoint point); //VC6תVS2017-gxy-20181025
    此外函数定义的地方也要由
    UINT CSizingControlBar::OnNcHitTest(CPoint point) //VC6转VS2017-gxy-20181025
    改成
    LRESULT CSizingControlBar::OnNcHitTest(CPoint point) //VC6转VS2017-gxy-20181025
    之所以改返回的数据类型是因为,高版本的VS(好像是从VS2010开始)对消息的检查更为严格,因此这些在VC6下完全正常运行的消息映射在VS上编译不通过。
  • error(2)解决方法:
    同样的error(2)解决也需要将消息相应函数写成LRESULT *(WPARAM,LPARAM)这样的格式,跟error(1)一样直接改变形参数据类型:
    UINT换成WPARAM,LPTSTR换成LPARAM
  • error(3)解决方法:
    error(3)也需要将消息响应函数的形参改成标注的形参类型,但是这里多少有点区别,直接替换之后胡后续函数可能会有问题,我的选择是形参替换之后在函数里在强制转换回来。
    以前是这样子:
BOOL CCJPagerCtrl::OnPagerScroll(NMPGSCROLL *pNMPGScroll, LRESULT *pResult)
{
	*pResult = 0;
	switch (pNMPGScroll->iDir) {
		case PGF_SCROLLLEFT:
		case PGF_SCROLLRIGHT:
		case PGF_SCROLLUP:
		case PGF_SCROLLDOWN:
		break;
	}
	return 0;
}

改完之后是这样子

BOOL CCJPagerCtrl::OnPagerScroll(NMHDR *pNMPGScroll, LRESULT *pResult)
{
    *pResult = 0;
	NMPGSCROLL *pNMPGScroll_ROLL = (NMPGSCROLL *)pNMPGScroll;
    switch (pNMPGScroll_ROLL->iDir) {
  	 	 case PGF_SCROLLLEFT:
    	 case PGF_SCROLLRIGHT:
   		 case PGF_SCROLLUP:
    	 case PGF_SCROLLDOWN:
        break;
    }
    return 0;
}

虽然我发现,写的这个函数无论如何返回的都是0。
PS:原来NMPGCALCSIZE*是一个结构体指针,该结构体的第一个变量的类型又是NMHDR类型的结构体。


二、C2660:VS2017下使用MFC无法调用函数Htmlelp

  1. 问题描述
    VS2017编译报错如下:
E0140: 函数调用中的参数太多
C2660:	“CWind::HtmlHelpA:”函数不接受4个参数
E0167: "LPCSTR"类型的实参与“UINT”类型的形参不兼容

程序是这么写的:

#include "htmlhelp.h"
...
//通过HtmlHelp调用帮助文件(.chm)的程序代码如下:
 HtmlHelp(NULL, (LPCSTR)helpFile, HH_DISPLAY_TOPIC, 0);
  1. 问题分析
    F12进入HtmlHelp(文件位置是:D:\Windows Kits\10\Include\10.0.17134.0\um\HtmlHelp.h)函数定义如下
HtmlHelpA(
    _In_opt_ HWND hwndCaller,
    _In_ LPCSTR pszFile,
    _In_ UINT uCommand,
    _In_ DWORD_PTR dwData
);

但是#include "htmlhelp.h"htmlhelp.h文件应该是在本地文件夹也就是E:\Top7PlusAll\Top7PlusProject\Top7PlusSolution\graphic,感觉HtmlHelp函数所属的h文件(或者说是链接的库)不对导致这个问题的。
3. 解决方法
把上述代码改成一下就可以了
#include “htmlhelp.h”

//通过HtmlHelp调用帮助文件(.chm)的程序代码如下:
 ::HtmlHelp(NULL, (LPCSTR)helpFile, HH_DISPLAY_TOPIC, 0);

就是仅仅在函数前边加上“::”就可以了,很奇怪


三、errorC2039:“WriteHuge”: 不是“CFile”的成员

  1. 问题描述
    在VS2017上编译提示
C2039:"WriteHuge"不是“CFile”的成员
C2039:"WriteHuge"不是“CFile”的成员
C2039:"WriteHuge"不是“CFile”的成员

程序是这样写的

CFile bf;
if (bf.Open(name, CFile::modeCreate | CFile::modeWrite)) {
    bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
    bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
    bf.WriteHuge(lpData, size);
    bf.Close();
 }
  1. 问题分析
    原因是VC++2005及后续VC版本中的CFile没有ReadHuge和WriteHuge成员函数,只在VC6中的CFile才有,不过ReadHuge()函数已被Read()函数代替,WriteHuge()函数已被Write()函数代替。
  2. 解决方法
    遇到这种情况的解决方法把代码中的ReadHuge换成Read、WriteHuge换成Write即可,即上述程序改成如下
CFile bf;
if (bf.Open(name, CFile::modeCreate | CFile::modeWrite)) {
    bf.Write(&bfh, sizeof(BITMAPFILEHEADER));
    bf.Write(&bih, sizeof(BITMAPINFOHEADER));
    bf.Write(lpData, size);
    bf.Close();
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章