"Ошибка 'SetWindowTextA': не является членом 'CStatic' и char * fgets (char *, int, FILE *): не может преобразовать аргумент 1 из 'TCHAR' в 'char *' - PullRequest
0 голосов
/ 04 декабря 2018

Я перенес свой проект 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, он вызывает ошибку в Release Build.

m_status_text.SetWindowTextW(theStr);

Когда я изменил его на «SetWindowText», как показано ниже, он работает для обоих отладкии выпускает сборки. Это правильный путь?

m_status_text.SetWindowText(theStr);

Насколько мне известно, когда мы используем "SetWindowText", в формате Unicode он обрабатывает его как "SetWindowTextW", а для формата многобайтовых символов он обрабатываеткак "SetWindowTextA".

Но как SetWindowText работает для сборок Debug и Release?

2.

А также можем ли мы использовать "_fgetts" вместо "fgets"(Для сборки выпуска) "fgetws" (Для сборки отладки) Как и в сборке отладки, если я использую "fgets", я получаю следующую ошибку:

char fgets (char , int,ФАЙЛ *): невозможно преобразовать аргумент 1 из 'TCHAR [260]' в 'char *'

fgets(currDir,MAX_PATH,f);    // For release build
fgetws(currDir, MAX_PATH, f); // For Debug build

Могу ли я использовать "_tfopen" вместо "fopen" (для сборки выпуска) и "_wfopen" (для сборки отладки)

f = _tfopen (fileName, _T ("r"));

Вместо

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

Пожалуйста, помогите мне в этом.

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

В вашем вопросе вы, кажется, смешиваете две оси, которые ортогональны друг другу: сборки ANSI против Unicode и сборки Debug против выпуска.

RE # 1 вызовы функций ANSI против 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 против Release, которые влияют на другие аспекты, такие как производительность во время выполнения.На самом деле, как правило, в отладочных сборках есть больше кода, который компилируется и проверяет инварианты и другие аспекты безопасности, такие как проверка того, что индексы не пересекают безопасные границы массива, или правильное использование итератора с контейнерами STL и т. Д.
Все этиДополнительные проверки отладочной сборки приводят к получению менее эффективного кода, но эти же проверки отладки помогают обнаруживать различные ошибки, которые вы можете исправить перед выпуском более эффективной сборки Release вашего приложения.

Но, опять же, это не зависит от аспекта режима построения ANSI и Unicode.


RE # 2 Использование различных файловых функций в Release vsОтладка сборки: если вам действительно это нужно (вы уверены? Чего вы на самом деле пытаетесь достичь?), Вы можете использовать #ifdef, например:

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

OfКонечно, вы можете использовать fopen, _wfopen и _tfopen в сборках Debug и Release: опять эти сборки Unicode / MBCS и Debug / Release ортогональны.

PS InВ общем, я бы посоветовал вам перевести базу кода в Unicode и просто собрать в режиме Unicode (как Debug-Unicode, так и Release-Unicode).

0 голосов
/ 04 декабря 2018

Windows API имеет 2 варианта для каждой функции, которая обрабатывает или допускает строки в качестве параметров:

  • UNICODE, обычно имя функции заканчивается на W
  • ANSI: имя функции заканчивается наA

Windows API затем предоставляет общий вариант для всех этих функций без завершающей буквы A или W, который будет отображаться на одну из вышеуказанных (A или W) в зависимости от того, определен ли UNICODE илиnot.

Пример:

SetWindowText

сопоставлен с:
- SetWindowTextA , если UNICODE НЕ определен (=> ANSI)
- SetWindowTextW , если определен UNICODE

Вариант UNICODE обрабатывает строки как wchar_t *, тогда как вариант ANSI обрабатывает строки как char *.

TCHAR - это макроопределенный символьный тип, который отображается на char или wchar_t в зависимости от того, определен UNICODE или нет:
- TCHAR = char, если UNICODE НЕ определен
- TCHAR = wchar_t, если UNICODE определен

Для «современного» приложения WindowsВ связи с этим VS2017 по умолчанию использует режим UNICODE (это вариант для файла проекта VC ++), и я предлагаю вам придерживаться этого, если только вы абсолютно не должны поддерживать старые версии Windows (т.е. 98).
в режиме UNICODE выиспользуйте варианты функции SetWindowTextW () (или просто SetWindowText ()), и вы передадите ей строку wchar_t * (или TCHAR *).

Использование типа TCHAR может потребоваться, если вам нужно поддерживать или компилироватьпроект в режиме ОБА ANSI И ЮНИКОД, но в настоящее время это редко требуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...