Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Компонент TCheckListBox в BCB6, Кто-нибудь разбирался с ним, помогите 
:(
    Опции темы
avalon
  Дата 14.3.2003, 03:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 13.2.2003

Репутация: нет
Всего: нет



Подскажите, плз, как они "выкусывают" свой TCheckListBoxDataWrapper (объект для хранения состояния итема - cbChecked, cbUnchecked, cbGrayed и т.д.) при таком доступе к ассоциированному объекту:

j = *(long*)TestBox->Items->Objects[0];

В TCheckListBoxDataWrapper'е есть поле для хранения адреса ассоциированных данных пользователя.


TCheckListBox *TestBox;
long *i, j;
i = new long;
*i = 9999;

TestBox->Items->AddObject("test sg", (TObject*)i);
TestBox->Checked[0] = 1;
TestBox->State[0] = cbGrayed;
j = *(long*)TestBox->Items->Objects[0];

j == *i // confused.gifconfused.gif

Оно в принципе правильно работает, но я не могу понять, как они это делают?
Перелопатил весь checklst.pas, не нашел.
Пожалуйста, помогите !


PM MAIL ICQ   Вверх
Vyacheslav
Дата 17.3.2003, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Ничего не понял. Причем здесь ассоциированые объекты? Эти объекты используются только, если у программиста возникла необходимость хранить наряду с текстовой строкой дополнительную информацию. Если такой необходимости нет, его можно просто не использовать. В твоем примере просто дополнительно хранится число 9999. До состояния можно добраться через State или Checked
Код

TCheckListBox *TestBox;
long *i, j;
i = new long;
*i = 9999;

// добавляем пункт "test sg" и ассоциируем с ним число 9999
TestBox->Items->AddObject("test sg", (TObject*)i);
// устанавливаем Checked
TestBox->Checked[0] =  true;
//сбрасываем Checked и  устанавливаем cbGrayed
//а хотели наверное TestBox->ItemEnabled[0] = false
TestBox->State[0] = cbGrayed;
// обратно получаем ассоцироавнный объект  9999
j = *(long*)TestBox->Items->Objects[0];

j == *i //



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
avalon
Дата 17.3.2003, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 13.2.2003

Репутация: нет
Всего: нет



Мне надо написать компонент типа TComboBox, только с возможностью множественного выбора. Я ковырял исходники TCheckListBox, чтобы понять как и где они хранят состояние итемов. Оказалось, они вставляют объект TCheckListBoxDataWrapper(хранящий состояние итемов) между итемом и ассоц. данными, то есть итем указывает не на ассоц. данные, а на TCheckListBoxDataWrapper, а он, в свою очередь, на ассоц. данные. При доступе к асс. данным методами TCheckListBox TCheckListBoxDataWrapper явно выкусывается (видно в исх. коде), но при доступе методами TStrings и TStringList выкусывания в коде нет!!! А ведь при доступе к асс. данным методами TStrings я получаю нормальные асс. данные, как в моем примере. Тем не менее, в TStrings не имеют представления о том, что между итемом и асс. данными может что-то быть, но методы TStrings корректно работают. (confused.gif!!! Ж8-О)
PM MAIL ICQ   Вверх
Vyacheslav
Дата 17.3.2003, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Состояние итемов они хранят, как ты правильно заметил в TCheckListBoxDataWrapper.
Что здесь непонятно, я лично не понял. Во первых, надо учитывать, что в TCustomListBox используется не просто TStringList, а TListBoxStrings. У него переопределены GetObject и SetObject. Они для получения ассоциированного объекта используют методы своего владельца, в данном случае CheckListBox. ( учти метод GetItemData - DYNAMIC)

Код

function TListBoxStrings.GetObject(Index: Integer): TObject;
begin
 if ListBox.Style in [lbVirtual, lbVirtualOwnerDraw] then
   Result := ListBox.DoGetDataObject(Index)
 else
 begin
   Result := TObject(ListBox.GetItemData(Index));
   if Longint(Result) = LB_ERR then Error(SListIndexError, Index);
 end;
end;

Ну а TCheckListBox::GetItemData и выполняет "выкусывание"
Код

function TCheckListBox.GetItemData(Index: Integer): LongInt;
begin
 Result := 0;
 if HaveWrapper(Index) then
   Result := TCheckListBoxDataWrapper(GetWrapper(Index)).FData;
end;



--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
avalon
Дата 18.3.2003, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 13.2.2003

Репутация: нет
Всего: нет



Vyacheslav, спасибо smile.gif
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0434 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.