簡體   English   中英

“錯誤'SetWindowTextA':不是'CStatic'的成員,並且char * fgets(char *,int,FILE *):無法將參數1從'TCHAR'轉換為'char *'

[英]"Error 'SetWindowTextA': is not a member of 'CStatic' and char *fgets(char*, int, FILE*): can not convert argument 1 from 'TCHAR' to 'char*'

我將C ++項目從Visual Studio 2005遷移到了Visual Studio 2017 Professional,並且在以調試和發布模式進行構建時遇到以下錯誤:

1。

在調試版本中,當我如下圖所示使用SetWindowTextA時,出現錯誤“錯誤C2039'SetWindowTextA':不是'CStatic'的成員

m_status_text.SetWindowTextA(theStr);

m_status_text聲明為CStatic,如下所示:

CStatic m_status_text;

如果我使用SetWindowTextW,它將在發布版本中引發錯誤。

m_status_text.SetWindowTextW(theStr);

當我將其更改為“ SetWindowText”(如下所示)時,它既適用於調試版本也適用於發布版本。 這是正確的方法嗎?

m_status_text.SetWindowText(theStr);

據我所知,當我們使用“ SetWindowText”時,以Unicode格式將其視為“ SetWindowTextW”,對於多字節字符集格式,則將其視為“ SetWindowTextA”。

但是SetWindowText如何用於Debug和Release版本?

2。

如果我使用“ fgets”,也可以像在調試版本中那樣使用“ _fgetts”代替“ fgets”(對於發行版本)“ fgetws”(對於調試版本),我得到以下錯誤:

char fgets(char ,int,FILE *):無法將參數1從'TCHAR [260]'轉換為'char *'

fgets(currDir,MAX_PATH,f);    // For release build
fgetws(currDir, MAX_PATH, f); // For Debug build
  1. 我可以使用“ _tfopen”代替“ fopen”(對於發行版)和“ _wfopen”(對於調試版)

    f = _tfopen(fileName,_T(“ r”));

代替

f = fopen(fileName,"r");  // For release build
f = _wfopen(fileName, L"r"); // For Debug build

請幫我。

Windows API為每個處理或允許將字符串作為參數的函數提供2種變體:

  • UNICODE,通常函數名稱以W結尾
  • ANSI:函數名稱將以A結尾

然后,Windows API將為所有這些函數提供一個通用的變體,而沒有尾隨的A或W字母,這將取決於是否定義了UNICODE映射到上述(A或W)之一。

例:

SetWindowText

映射到:
-如果未定義UNICODE,則設置SetWindowTextA (=> ANSI)
-SetWindowTextW(如果定義了UNICODE)

UNICODE變量將字符串作為wchar_t *處理,而ANSI變量將字符串作為char *處理。

TCHAR是宏定義的字符類型,根據是否定義了UNICODE映射到char或wchar_t:
-如果未定義UNICODE,則TCHAR = char
-如果定義了UNICODE,則TCHAR = wchar_t

對於“現代” Windows應用程序,VS2017默認情況下使用UNICODE模式(這是VC ++項目文件的選項),我建議您堅持使用該模式,除非您絕對必須支持Windows的較早版本(即98)。
使用UNICODE模式,將使用SetWindowTextW()函數變體(或僅使用SetWindowText()),並將其傳遞給wchar_t *(或TCHAR *)字符串。

如果您需要同時以ANSI和UNICODE模式支持或編譯項目,則可能需要使用TCHAR類型,但是如今很少使用了。

在您的問題中,您似乎將兩個相互正交的軸混合在一起:ANSI與Uni​​code構建以及Debug與發行版本。

RE#1 ANSI vs. Unicode函數調用,當您調用MFC類方法時,應僅調用“未修飾的”方法名稱,例如:

// Note the use of the "undecorated" SetWindowText method call:
m_status_text.SetWindowText(theStr);

// This gave you an error:
// m_status_text.SetWindowTextA(theStr);

這與Debug vs. Release版本無關 ,后者會影響其他方面,例如運行時性能。 實際上,通常在調試版本中,有更多的代碼可以編譯並檢查不變量和其他安全方面,例如確保索引不會越過安全數組邊界,或確保STL容器正確使用迭代器等。
所有這些其他調試構建檢查通常會產生效率較低的代碼,但是這些相同的調試檢查可以幫助您檢測各種錯誤,您可以在交付更有效的應用程序發布版本之前對其進行修復。

但是,這又獨立於ANSI vs. Unicode構建模式方面。


RE#2在Release版本和Debug版本中使用不同的文件功能:如果確實需要(確定嗎?您實際上要實現什么?),可以使用以下#ifdef

#ifdef _DEBUG
   // Debug-build specific code
   // ...
#else 
   // Release-build specific code
   // ...
#endif

當然,您可以在Debug和Release版本中使用fopen_wfopen_tfopen :同樣,這些Unicode / MBCS和Debug / Release版本是正交的。

PS通常,我鼓勵您將代碼庫移至Unicode,並僅以Unicode模式構建(Debug-Uni​​code和Release-Unicode)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM