Когда я отправляю и конвертирую стандартную строку с помощью win32 SendMessage, я получаю странные символы

Мне нужно добавить текст в элемент управления редактирования win32. У меня есть рабочая функция для этого, но текст, который печатается в элементе редактирования, является бредом, почему? пример кода взят из примера Microsoft из здесь

void settext(HWND hDlg,std::string s)
{
    //std::wstring ws; 
    //ws.assign( s.begin(), s.end() );
    //LPWSTR pwst = &ws[0];
    //// get temporary LPCWSTR (pretty safe)
    //LPCWSTR pcwstr = ws.c_str();
    //SetDlgItemText(hWndEdit, IDC_EDIT1,pcwstr);
    HWND hWndEdit = GetDlgItem (hDlg, IDC_EDIT1);
    LPSTR pst = &s[0];
    int ndx = GetWindowTextLength (hWndEdit);
    SetFocus (hWndEdit);
    #ifdef WIN32
      SendMessage (hWndEdit, EM_SETSEL, (WPARAM)ndx, (LPARAM)ndx);
    #else
      SendMessage (hWndEdit, EM_SETSEL, 0, MAKELONG (ndx, ndx));
    #endif
      SendMessage (hWndEdit, EM_REPLACESEL,0,(LPARAM)pst);
    
}

и из вызова DlgProc im:

std::string  ss("wwwwww");
settext(hwnd,ss);

обновить
, даже если я сделаю так, как предлагается здесь:

 SendMessage (hWndEdit, EM_REPLACESEL,0,(LPARAM)s.c_str()); 

которые проходят компиляцию, но все же напечатанные символы являются тарабарскими
и если я это сделаю:

LPSTR pst = s.c_str()

компиляция не проходит ошибка:
ошибка C2440: 'инициализация': невозможно преобразовать из 'const char *' в 'LPSTR'


person user63898    schedule 09.06.2011    source источник
comment
Вы строите в режиме юникода или анси?   -  person bdonlan    schedule 10.06.2011


Ответы (4)


Я предполагаю, что ваше приложение скомпилировано для Unicode, поэтому окно интерпретирует вашу строку ANSI C как строку Unicode C, следовательно, символы из другого языка.

person David Heffernan    schedule 09.06.2011
comment
Приложение скомпилировано в юникоде, я печатаю на английском. может быть, это проблема, так как я могу преодолеть это? - person user63898; 10.06.2011
comment
Передайте LPWSTR в SendMessage. Используйте wstring. Наверняка это ваша проблема! - person David Heffernan; 10.06.2011
comment
Если приложение скомпилировано как Unicode (убедитесь, что определены и UNICODE, и _UNICODE), вам потребуется передать строку Unicode; вместо этого используйте wstring. Чтобы быть уверенным, попробуйте явно вызвать SendMessageW и использовать LPCWSTR pstr = ws.c_str(), передав pstr в качестве указателя на SendMessageW. - person BrendanMcK; 10.06.2011
comment
BrendanMcK вы правы, это ответ, также я должен отправить строку с L - person user63898; 10.06.2011
comment
Префикс L действительно означает, что вы обозначаете широкий строковый литерал - person David Heffernan; 10.06.2011

Проблема в том, что

LPSTR pst = &s[0];

не завершается нулем. Вам нужно использовать

LPCSTR pst = s.c_str();
person grayDad    schedule 09.06.2011
comment
это дает мне ошибку: ошибка C2440: «инициализация»: невозможно преобразовать из «const char *» в «LPSTR» - person user63898; 10.06.2011
comment
Объявите pst как LPCSTR, как говорит вам компилятор - person David Heffernan; 10.06.2011
comment
хорошо сделал это, и он проходит компиляцию, но все же я вижу тарабарщину в элементе управления редактированием - person user63898; 10.06.2011

Нет никакой гарантии, что &s[0] завершается нулем, поэтому вы, вероятно, просто видите любую случайную память, пока после конца вашей строки не появится нуль. Вероятно, в некоторых компиляторах/библиотеках он иногда/все время завершается нулем и, таким образом, до сих пор не появлялся.

Вместо этого вы захотите использовать s.c_str().

person Mark B    schedule 09.06.2011
comment
Используйте LPCSTR. C означает const — вам не разрешено изменять строку, на которую указывает указатель из c_str(). - person bdonlan; 10.06.2011

Вы можете преобразовать свой LPSTR в LPWSTR с помощью ATL, чтобы API-интерфейсы Unicode могли его переварить.

#include <windows.h>
#include <atlbase.h>

void settext(HWND hDlg,std::string s)
{
    USES_CONVERSION;
    LPSTR pst = A2T(s.c_str());

A2T преобразует узкую строку в строку, совместимую с текущими настройками компиляции (Unicode/многобайтовая). Вы также можете использовать A2W, который явно преобразует ANSI в WIDE, но A2T всегда будет поступать правильно, независимо от того, компилируете ли вы в режиме Unicode или нет.

На самом деле A2T выделяет достаточно места в стеке для результирующей строки, поэтому вам не нужно беспокоиться об ее освобождении.

person Ferruccio    schedule 09.06.2011