+ Reply to Thread
Results 1 to 8 of 8

Thread: Вопрос про контролы windows и std::string .

  1. #1

    Default Вопрос про контролы windows и std::string .

    Может кто подскажет по типам данных .
    Читаю я csv фаил в vector <wstring> . Потом хотел вывести в ListView через SendMessage . Думал все на мази , а вот хрен .

    Code:
    LV_ITEM lvitem;
    ...
    lvitem.mask = LVIF_TEXT;
    lvitem.iItem = n;
    lvitem.iSubItem = 0;
    lvitem.pszText = wdat->phone.c_str();     // Ошибка с типами данных
    SendMessage(hListView,LVM_INSERTITEM,0,(LPARAM) &lvitem);
    Проблема в том что структура lvitem в pszText хочет получить lpwstr . А wstring методом c_str() отдает lpcwstr . Т е константу .
    И что делать я как-то недогоняю . Как корректно получить от std::wstring нужный неконстантный тип ? Или как конвертировать . Или , если никак , то в каком формате тогда хранить данные и как это обычно решают ?
    Нагуглил пару вариантов , но они такие уродские . Должен же быть стандартный кошерный способ .
    Last edited by Debug; 20-04-2013 at 08:49.

  2. #2
    root's Avatar

    Default Re: Вопрос про контролы windows и std::string .

    Ну, можно сделать, например, так:

    Code:
    LPCTSTR test = _T("Hello, World!");
    LPTSTR pszText = (LPTSTR) test;
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  3. #3

    Default Re: Вопрос про контролы windows и std::string .

    _T это макрос . Препроцессор просто добавляет L к строке "Hello, World!" .

    Code:
    #if defined(_UNICODE)
    #define _T(x) L ##x
    #else
    #define _T(x) x
    #endif
    Он не может обрабатывать переменные . Препроцессор их не видит .

    Code:
    string str("hello world");
    cout << _T(str.c_str());
    Этот код не соберется с ошибкой Error:идентификатор "Lstr" не определен .

    Но в целом мысль понятна . Да , я могу сделать что-то типа

    Code:
    string str("hello world");
    string str2(str);
    cout << (LPSTR)str2.c_str();
    Т е явно привести тип . Наверно это лучшее, что я сейчас могу . Хотя придется добавлять + 1 строку при каждом получении данных . А у меня их сейчас 12 полей в ст-ре . А если не копировать , то вообще нет гарантии , что контролы не модифицируют данные в векторе .
    Меня больше другое пузырит . Неужели нет строчного типа данных , который предусмотрено использовать с контролами по дефолту . Т е когда microsoft создавала api они же должны были понимать , что люди врядли будут хранить свои данные в char * ?

  4. #4
    root's Avatar

    Default Re: Вопрос про контролы windows и std::string .

    _T это макрос . Препроцессор просто добавляет L к строке "Hello, World!".
    ...
    Этот код не соберется с ошибкой Error:идентификатор "Lstr" не определен.
    Мде... А кто сказал, что его надо как-то применять? Тем более в таком виде:

    Code:
    string str("hello world");
    cout << _T(str.c_str());
    _Т() - применяется только к литералам, т.е. к строкам.

    В моем примере, строка кода:

    Code:
    LPCTSTR test = _T("Hello, World!");
    Предназначена всего-лишь для НАГЛЯДНОГО создания переменной "test" типа LPCTSTR. Я бы мог выдать, что-то в этом роде:

    Code:
    LPCTSTR test = ptsHelloWorld;
    Но, если кому-то вздумается проверить работу примера, все равно придется как-то создавать ptsHelloWorld.

    Т е явно привести тип . Наверно это лучшее, что я сейчас могу . Хотя придется добавлять + 1 строку при каждом получении данных.
    Ну зачем добавлять еще одну строку?

    А если не копировать , то вообще нет гарантии , что контролы не модифицируют данные в векторе.
    Это само собой разумеется...

    Меня больше другое пузырит . Неужели нет строчного типа данных , который предусмотрено использовать с контролами по дефолту . Т е когда microsoft создавала api они же должны были понимать , что люди врядли будут хранить свои данные в char * ?
    Все есть. Надо только больше думать и меньше бездумно копировать. Используемый тобой тип wstring вполне себе годится для твоих целей.

    Вернемся к твоему вопросу:

    Проблема в том что структура lvitem в pszText хочет получить lpwstr . А wstring методом c_str() отдает lpcwstr . Т е константу .
    LPWSTR тоже самое что и LPTSTR, а LPCWSTR тоже самое что LPCTSTR. Так как в MSDN, параметр pszText, в стуктуре LV_ITEM, задан как LPTSTR, то я составил следующий пример:

    Code:
    LPCTSTR test = _T("Hello, World!");
    LPTSTR pszText = (LPTSTR) test;
    Все что тебе нужно было сделать, это просто добавить "(LPTSTR)" в месте где происходила ошибка:

    Code:
    lvitem.pszText = (LPTSTR) wdat->phone.c_str();
    И все должно работать.
    Last edited by root; 21-04-2013 at 14:16.
    Успех – это путь от провала до провала без потери энтузиазма. (В. Черчиль)

    Не бойся идти медленно, бойся остановиться. (Китайская пословица)

    When you lose fun and start doing things only for the payback, you're dead. (c) TCLH (Phrack 65, Intro)

  5. #5

    Default Re: Вопрос про контролы windows и std::string .

    LPCTSTR test = _T("Hello, World!");
    Предназначена всего-лишь для НАГЛЯДНОГО создания переменной "test"
    Наверно я слишком буквально тебя понял .
    Все что тебе нужно было сделать, это просто добавить "(LPTSTR)" в месте где происходила ошибка
    Согласен . Но , как я понимаю , предварительно все-таки нужно переменную копировать .
    Code:
    string str("hello world");
    string str2(str);
    cout << (LPSTR)str2.c_str();
    Ибо если привести тип оригинальной строки в неконстантный и отдать контролу , есть шанс что в дальнейшем она будет испорчена .

  6. #6
    ARCHANGEL's Avatar

    Default Re: Вопрос про контролы windows и std::string .

    Не нужно ничего копировать. Конкретно для таких целей (убрать спецификатор const) есть конструкция const_cast. Описание на MSDN

    Ну а вам надо сделать как-то так:

    lvitem.pszText = const_cast< lpwstr > wdat->phone.c_str();

    Преобразования в стиле С также работают здесь. Т.е. lvitem.pszText = (lpwstr) wdat->phone.c_str(); тоже даст желаемый результат, но первый вариант - более наглядный и правильный с точки зрения ООП.
    Добрым быть просто - достаточно обратить свой гнев на негодяев...

  7. #7

    Default Re: Вопрос про контролы windows и std::string .

    lvitem.pszText = &(wdat->phone[0]);

    UPD оффтоп:
    блин ща скажут что археолог. =)
    Last edited by knt; 12-03-2014 at 10:23.

  8. #8
    500mhz's Avatar

    Default Re: Вопрос про контролы windows и std::string .

    некрофил

  9. Пользователь сказал cпасибо:
    Dark Koder (15-03-2014)
+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
All times are GMT. The time now is 01:33
vBulletin® Copyright ©2000 - 2018
www.reverse4you.org