C++:將C++工程從VC6.0工程升級到VS2017所遇到的程式碼不相容問題集合
阿新 • • 發佈:2018-11-16
一、errorC2440:訊息相應函式型別不能轉化
- 問題描述
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 *)”
- 解決方法
- 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
- 問題描述
VS2017編譯報錯如下:
E0140: 函式呼叫中的引數太多
C2660: “CWind::HtmlHelpA:”函式不接受4個引數
E0167: "LPCSTR"型別的實參與“UINT”型別的形參不相容
程式是這麼寫的:
#include "htmlhelp.h"
...
//通過HtmlHelp呼叫幫助檔案(.chm)的程式程式碼如下:
HtmlHelp(NULL, (LPCSTR)helpFile, HH_DISPLAY_TOPIC, 0);
- 問題分析
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”的成員
- 問題描述
在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();
}
- 問題分析
原因是VC++2005及後續VC版本中的CFile沒有ReadHuge和WriteHuge成員函式,只在VC6中的CFile才有,不過ReadHuge()函式已被Read()函式代替,WriteHuge()函式已被Write()函式代替。 - 解決方法
遇到這種情況的解決方法把程式碼中的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();
}