var
dwRet : Integer;
pszText: WideString;
//
dwRet := SendMessageW(GetDlgItem(hWnd, IDC_LANG_LIST), CB_GETCURSEL,
0, 0);
if (dwRet <> CB_ERR) then
begin
pszText := LPWSTR(SendMessageW(GetDlgItem(hWnd, IDC_LANG_LIST),
CB_GETITEMDATA, dwRet, 0));
end;
Неужто надо объявить этот массив глобальным? Не хочу лишних глобальных переменных, тем более под 2000 и XP корректно извлекается текст с каждого элемента. Рассматриваю как вариант SetWindowLongPtrW + GWL_USERDATA для массива, должно сработать. Что можно придумать?
Здравствуйте, fuyant, Вы писали:
F>Ээээ.... ты ожидаешь, что CB_SETITEMDATA скопирует твою строку в какой-то свой внутренний буфер?
Ну конечно же. Правда глупо ожидать такого если в MSDN чётко указано DWORD значение. Есть ли вариант попроще? Хочу хранить дополнительно строку в каждом элементе.
А всё же интересно, почему на XP x64, виртуальных 2000 и XP строка "достаётся" корректно?
Здравствуйте, Maks1509, Вы писали:
M>Здравствуйте, fuyant, Вы писали:
F>>Ээээ.... ты ожидаешь, что CB_SETITEMDATA скопирует твою строку в какой-то свой внутренний буфер?
M>Ну конечно же. Правда глупо ожидать такого если в MSDN чётко указано DWORD значение.
во-во, совсем глупо
M>Есть ли вариант попроще? Хочу хранить дополнительно строку в каждом элементе.
два варианта:
1. хранить свой массив, например, где-нить полем класса, и подсовывать указатели на эти строки в CB_SETITEMDATA
2. создавать строки в куче и в CB_SETITEMDATA запихивать указатели на эти строки. При этом перед разрушением комбобокса обязательно пройтись по всем элементам комбобокса и удалить созданные строки. И не забывать очищать также и перед удалением айтемов из комбобокса.
M>А всё же интересно, почему на XP x64, виртуальных 2000 и XP строка "достаётся" корректно?
Здравствуйте, fuyant, Вы писали:
F>Здравствуйте, fuyant, Вы писали:
F>>Тупо везение. Вообще то это UB
F>Неправильно выразился. Никакой тут не UB — это четкий крэш. А не падает потому что тупо везет. Может из-за дебаг-версии, может из-за виртуалки.
Да мне самому очень интересно, я некоторым тестерам скидывал приложение, всё отлично работало (на семёрке никто не тестировал из них). Это не отладочная сборка точно. Соответсвенно для меня было удивлением такое поведение программы.
Код в инициализации диалога:
var
pszData: Array of Array [0..MAX_PATH-1] of WideChar;
// заполняем здесь массив.
SetWindowLongPtrW(GetDlgItem(hWnd, IDC_LANG_LIST), GWL_USERDATA, Longint(pszData));
Код при завершении диалога:
pszData := Pointer(GetWindowLongPtrW(GetDlgItem(hWnd, IDC_LANG_LIST), GWL_USERDATA));
if (pszData <> nil) then
begin
SetLength(pszData, 0);
SetWindowLongPtrW(GetDlgItem(hWnd, IDC_LANG_LIST), GWL_USERDATA, 0);
end;
Здравствуйте, Maks1509, Вы писали:
M>Здравствуйте, fuyant, Вы писали:
F>>Здравствуйте, fuyant, Вы писали:
F>>>Тупо везение. Вообще то это UB
F>>Неправильно выразился. Никакой тут не UB — это четкий крэш. А не падает потому что тупо везет. Может из-за дебаг-версии, может из-за виртуалки.
M>Да мне самому очень интересно, я некоторым тестерам скидывал приложение, всё отлично работало (на семёрке никто не тестировал из них). Это не отладочная сборка точно. Соответсвенно для меня было удивлением такое поведение программы.
M>Код в инициализации диалога: M>
M>var
M> pszData: Array of Array [0..MAX_PATH-1] of WideChar;
M> // заполняем здесь массив.
M> SetWindowLongPtrW(GetDlgItem(hWnd, IDC_LANG_LIST), GWL_USERDATA, Longint(pszData));
M>
Если все работает и не падает, то могу предположить следующее.
Элементы массива — искомые строки — создаются в куче. Указатели на созданные строки помещаются в USERDATA, потому они и нормально функциклюют.
Зато присутствуют утечки памяти — если эти строки создались в куче, память, выделенную под них, нужно освободить после использования, т.е. delete [] pszData. Ну или как там на делфи это делается, я не знаю....