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();
 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章