В чем разница между LPCSTR, LPCTSTR и LPTSTR?
Зачем нам это нужно, чтобы преобразовать строку в структурную переменную LV/_ITEM pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
В чем разница между LPCSTR, LPCTSTR и LPTSTR?
Зачем нам это нужно, чтобы преобразовать строку в структурную переменную LV/_ITEM pszText:
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
Чтобы ответить на первую часть вашего вопроса:
LPCSTR является строкой const
LPCTSTR является строкой const TCHAR, (TCHAR является либо широким char, либо char в зависимости от того, определен ли UNICODE в вашем проекте)
LPTSTR - строка (не const) TCHAR
Это отличная статья статьи кодекса, описывающая строки С++ (см. 2/3 путь вниз для диаграммы, сравнивающей разные типы)
Быстро и грязно:
LP == L ong P ointer. Просто подумайте, указатель или символ *
C= C, в данном случае, я думаю, они означают, что символьная строка является const, а не указателем, являющимся const.
STR это строка
T для широкого символа или символа (TCHAR) в зависимости от параметров компиляции.
char: 8-битный символ - базовый тип данных C/C++CHAR: псевдоним char - тип данных WindowsLPSTR: строка CHAR нулевым символом в CHAR (L ong P ointer)LPCSTR: постоянная строка CHAR нулевым символом в CHAR (L ong P ointer)wchar_t: 16-битный символ - базовый тип данных C/C++WCHAR: псевдоним wchar_t - тип данных WindowsLPWSTR: строка LPWSTR нулевым символом в WCHAR (L ong P ointer)LPCWSTR: постоянная строка WCHAR нулевым символом в WCHAR (L ong P ointer)UNICODE определитьTCHAR: псевдоним WCHAR если определен UNICODE; в противном случае CHARLPTSTR: строка LPTSTR нулевым символом в TCHAR (L ong P ointer)LPCTSTR: константная строка с TCHAR символом в TCHAR (L ong P ointer)Так
| Item | 8-bit | 16-bit | Varies |
|-------------------|--------------|-------------|-----------------|
| character | CHAR | WCHAR | TCHAR |
| string | LPSTR | LPWSTR | LPTSTR |
| string (const) | LPCSTR | LPCWSTR | LPCTSTR |
TCHAR → Text Char (archive.is)
Добавление к Джону и Тиму ответа.
Если вы не кодируете Win98, в вашем приложении должны быть только два из шести типов строк
LPWSTRLPCWSTRОстальные предназначены для поддержки платформ ANSI или двойных компиляций. Сегодня они не так актуальны, как раньше.
Чтобы ответить на вторую часть вашего вопроса, вам нужно сделать что-то вроде
LV_DISPINFO dispinfo;
dispinfo.item.pszText = LPTSTR((LPCTSTR)string);
поскольку MS LVITEM struct имеет LPTSTR, т.е. изменяемый указатель T-строки, а не LPCTSTR. Что вы делаете, это
1) преобразуйте string (a CString при угадывании) в LPCTSTR (что на практике означает получение адреса его символьного буфера в качестве указателя только для чтения)
2) конвертируйте этот указатель только на чтение в записываемый указатель, отбросив его const -ness.
Это зависит от того, что используется dispinfo для того, есть ли вероятность того, что ваш вызов ListView завершится попыткой написать через pszText. Если это так, это очень опасно: в конце концов вы получили указатель только для чтения, а затем решили рассматривать его как записываемый: возможно, есть причина, по которой он был доступен только для чтения!
Если это CString, с которым вы работаете, у вас есть возможность использовать string.GetBuffer() - это намеренно дает вам возможность записи LPTSTR. Затем вам нужно запомнить вызов ReleaseBuffer(), если строка будет изменена. Или вы можете выделить локальный временный буфер и скопировать туда строку.
В 99% случаев это будет лишним, и обработка LPCTSTR как LPTSTR будет работать... но однажды, когда вы меньше всего этого ожидаете...