Ответ 1
Невозможно просто бросить это:
_bstr_t b("Steve");
CString cs;
cs = (LPCTSTR) b;
Я думаю, что это должно работать, когда проект Unicode.
У меня есть переменная _bstr_t
bstrErr
, и у меня есть переменная CString
csError
. Как установить значение, которое входит в bstrErr
в csError
?
Невозможно просто бросить это:
_bstr_t b("Steve");
CString cs;
cs = (LPCTSTR) b;
Я думаю, что это должно работать, когда проект Unicode.
CString имеет конструкторы и операторы присваивания как для LPCSTR, так и для LPCWSTR, поэтому никогда не нужно вызывать WideCharToMultiByte, и вы не можете заставить кастинг ошибочным в режиме Unicode или в режиме unicode.
Вы можете просто назначить строку таким образом:
csError = bstrErr.GetBSTR();
Или используйте конструктор CString csError (bstrErr.GetBSTR());
Я использую GetBSTR. Это то же самое, что лить bstrErr с (LPCWSTR), но я предпочитаю его для удобочитаемости.
Если вы компилируете для Unicode - просто назначьте инкапсулированный BSTR в CString. Если вы компилируете ANSI, вам нужно будет использовать WideCharToMultiByte() для преобразования.
Также следует помнить, что инкапсулированный BSTR может быть нулевым, что соответствует пустой строке. Если вы не позаботились об этом, ваша программа будет работать в undefined.
BSTR myBSTRVal;
CString BSTRasCString("")
char szValue[MAX_PATH] = "";
// This will map the BSTR to a new character string (szValue)
WideCharToMultiByte(CP_ACP, 0, myBSTRVal, -1, szValue, sizeof(szValue), NULL,
NULL);
BSTRasCString.Format("%s", szValue);
BSTRasCString.TrimLeft();
BSTRasCString.TrimRight();
CString
, CStringA
и CStringW
:
Класс CStringT
является классом шаблона, который использует символьный тип TCHAR
. TCHAR
обозначает wchar_t
если установлен макрос UNICODE
, в противном случае он идентичен char
.
Класс CString
является typedef для шаблона шаблона CStringT
. Когда вы объявляете экземпляр CString
, вы фактически создаете экземпляр класса шаблона с именем CStringT
.
Класс CStringA
- это шаблонный класс, который использует внутри себя узкий символьный тип char
.
CStringW
- это шаблонный класс, который внутренне использует тип широких символов wchar_t
. Я никогда не использую CString
или CStringT
в коде, вместо этого я всегда использую явные классы CStringA
или CStringW
. Классы CString*
имеют конструкторы, которые принимают узкие и широкие строки. То же самое верно для _bstr_t
. Строки типа BSTR
должны быть выделены функцией SysAllocString()
которая ожидает строку OLECHAR
, следовательно, в Win32/64 широкая строка. Если вы хотите скопировать _bstr_t
который содержит Unicode, в CStringA
вы должны преобразовать его в UTF8. Я использую классы CW2A
и CA2W
для конвертации.
В следующей функции события надстройки Word я покажу использование этих типов:
STDMETHODIMP CConnect::TestButtonClicked(IDispatch* Command)
{
BSTR smi = SysAllocString(L"Two smileys 😊 in a row: ");
_bstr_t ley = L"😊\U0001F60A";
/* Either using CStringA, UTF16 -> UTF8 conversion needed */
CStringA smiley(CW2A(smi, CP_UTF8));
smiley += CW2A(ley.GetBSTR(), CP_UTF8);
MessageBoxW(NULL, CA2W(smiley, CP_UTF8), L"Example", MB_OK | MB_TASKMODAL);
/* Or using CStringW, use ctor and += operator directly
CStringW smiley = smi;
smiley += ley.GetBSTR();
MessageBoxW(NULL, smiley, L"Example", MB_OK | MB_TASKMODAL);
*/
SysFreeString(smi);
return S_OK;
}