Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

как организовать Имя = Значение в CheckListBox [D7]


Страницы:   1 2

Neket ©   (2009-06-29 16:33:00) 

Добрый день. Подскажите как организовать в CheckListBox что-то типа Имя = значение. А именно, к примеру есть CheckListBox1 такого плана
_
|_| Имя1
_
|_| Имя2
_
|_| Имя3

И если я ставлю галочку на любом из этих имен у меня выскакивает OpenDialog и мне нужно организовать присвоение пути к файлу выбранному имени... Т.е. Имя2 = С:\KillAll.bat


Neket   (2009-06-30 12:01:00) [1]

Спасибо.... Может просто неумею сразу корректно объяснить проблему )))


sniknik   (2009-06-30 11:59:00) [2]

> тебя я изначально не считал
я вообще изначально никого не считаю... разве что если с первого же поста начинают нести "неадекват".


sniknik   (2009-06-30 11:58:00) [3]

> как всегда концовка радует... "ВСЕ В САД" )))) Всеравно спасибо
ну, это в общем то  не тебе, это продолжение ответа для Jungle.

тебя я изначально не считал неспособным разобраться, хотя меня и остерегали, что надо писать как для начинающих.
(вот если бы ты не привел код, и/или начал бы в ответ нести что-то неадекватное, то тогда что-то подобное [31] было бы лично для тебя, а так нет)


Neket   (2009-06-30 11:43:00) [4]

как всегда концовка радует... "ВСЕ В САД" )))) Всеравно спасибо


sniknik   (2009-06-30 11:36:00) [5]

> так это самое то для понимания...
а если человек не разделяет создание объекта с изменением его свойств, и не может самостоятельно вынести изменение из условия создания...
ну скажите об этом сразу. и не стоит мне тогда больше с этим человеком разговаривать, даже в начинающих. надо делать раздел "ясли" на форуме и посылать таких туда.


brother   (2009-06-30 11:35:00) [6]

> но я впринципе являюсь сторонником универсальности и корректности.
> Поэтому из принципа внесу изменения.

не из принцыпа, а так правильно


Neket   (2009-06-30 11:34:00) [7]

Хмм... Интресно... Спасибо. впитал. Бум исправляться. Хотя в моем случае можно былобы и остановиться на том что есть ибо так глубоко я лезть не буду, но я впринципе являюсь сторонником универсальности и корректности. Поэтому из принципа внесу изменения. Ещё раз все спасибо.


sniknik   (2009-06-30 11:31:00) [8]

> В твоём примере действие
это не мой пример, это, еще раз повторю, исправленный пример самого автора вопроса. "оригинал" можешь найти немного выше, частями в [17] и [19].

> А судя по условиям задачи оно должно меняться при каждом "чеке"
и в чем проблема? в том, что рассматриваемый пример не есть готовое для копи пасте решение? так это самое то для понимания...

> Но в этом случае нужно ещё быть уверенным, что Objects[N] является объектом типа TMyObject.
с проектом работает несколько человек, и один не ведает что туда вносит другой? какая еще нужна уверенность?


Jungle   (2009-06-30 11:21:00) [9]

sniknik
В твоём примере действие
s:='lalala'+inttostr(c1.ItemIndex);
выполняется только один раз. А судя по условиям задачи оно должно меняться при каждом "чеке", когда выбирается имя файла.
Но в этом случае нужно ещё быть уверенным, что Objects[N] является объектом типа TMyObject.


sniknik   (2009-06-30 11:12:00) [10]

> CheckListBox1.Items.Objects[0]:= TObject(PChar('doError'));
вот это лучше заменить на это -
PInteger(CheckListBox1.Items.Objects[0])^:= 1234;

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


sniknik   (2009-06-30 10:59:00) [11]

> Ок... Ваш варинт.
это не мой вариант, это твой только поправленный. я бы в данном случае вообще не делал созданий/уничтожений в процессе работы программы, а создал бы все обьекты списка при старте проги. (не такие уж они "напряжные" чтобы на них экономить)

procedure TForm1.c1ClickCheck(Sender: TObject);
begin
 with CheckListBox1 do
   if not Assigned(Items.Objects[ItemIndex]) then begin  
     Items.Objects[ItemIndex]:= TMyObject.Create;
     with Items.Objects[ItemIndex] as TMyObject do
       s:='lalala'+inttostr(c1.ItemIndex);
   end;
end;


а ошибку в твоем коде можно увидеть так -
к примеру у тебя есть/будут "общие" кнопки, как иногда делают, "очистить все", "установить все", ну вот пример установки для одного пункта (на нем пробуем), гденибудь по кнопке например делаешь  
CheckListBox1.Checked[0]:= true;
допустим ты уже нажимал пункт отдельно, и установил/снял галку с этого пункта, т.е. объект создавался, был освобожден, но ссылка на него осталась (само собой, ты же не обнуляешь ссылку)
объект может разрушится по естественным причинам, делаем эмуляцию этого, чтоб не ждать, там же по кнопке
CheckListBox1.Items.Objects[0]:= TObject(PChar('doError'));
следующее нажатие вызовет AV, т.к. проверка chek у тебя сбилась из-за "ручного" изменения, а Assigned не сработал.

причем ошибка будет редкой, трудноуловимой, непонятно от каких действий (ни один юзер тебе последовательность не запомнит), и возникнет только тогда когда программа "разрастется" там появятся дополнительные пункты (типа "отметить все"), будет использоваться много памяти, и станет трудной в отладке, т.к. в отладке те же действия повторенные сразу (обьект может еще не разрушится) AV не дадут...


{RASkov}   (2009-06-30 10:35:00) [12]

> [21] Neket   (30.06.09 09:50)
> Поставили галку создали объект, убрали галку уничтожили объект

Это логически не верно. Т.е. со стороны логике программы - верно, а со стороны программиста - нет.
Через месяц внесешь изменения в код и всё.... прощай логика..... нифика не работает, а почему? Потому что программист писал по принципу: Работает сейчас ну и пусть работает, а что там не так мне покакать.


> [23] Neket   (30.06.09 10:23)
> Ок... Ваш варинт. Правильный. Прошу в "Студию" Интересно

Неужели из сказанного выше нет соображений на верный код??? :)


Neket   (2009-06-30 10:23:00) [13]

Ок... Ваш варинт. Правильный. Прошу в "Студию" Интересно


sniknik   (2009-06-30 10:11:00) [14]

> Поставили галку создали объект, убрали галку уничтожили объект. Подругому быть не может.
тогда проверка на Assigned лишняя. т.к. она во первых здесь не работает, во вторых здесь от нее ничего не зависит.

> Ну и как показывает практика, все прекрасно работает
практика без теории приводит к печальным результатам. вот как здесь например. якобы правильно работает но почему не понял, а стоит такую же конструкцию в другом месте использовать, где проверка на Assigned будет значима (от нее будет что-то зависеть), и будет новый вопрос на форуме типа "в одном месте работает в другом нет хотя код одинаковый... почему?".


Neket   (2009-06-30 09:50:00) [15]

Что значит несколько раз?  В моем случае одно исключает другое.
Поставили галку создали объект, убрали галку уничтожили объект. Подругому быть не может.
Ну и как показывает практика, все прекрасно работает


sniknik   (2009-06-30 09:47:00) [16]

1 Assigned работает только если переменная "пустая", т.е. по твоему коду 1 раз.
а нажатий например 10. и ???
2 Free, да и любой другой метод вызванный у разрушенного обьекта приводит к AV. если обьект освобожден но в памяти еще не перезаписан другими данными. то AV может и не быть, что даст иллюзию нормальной работоспособности, но ???

гораздо проще и надежнее создавать обьект 1 раз, предварительно проверив есть он там или нет. и все.


Neket   (2009-06-30 09:34:00) [17]

Не ну эт я предусмотрел.
если галку ставят то идет CREATE если галку снимают то идет FREE

If (CheckListBox1.Checked[CheckListBox1.ItemIndex]=false) Then
                                                         begin
                                                         if Assigned(CheckListBox1.Items.Objects[CheckListBox1.ItemIndex]) then CheckListBox1.Items.Objects[CheckListBox1.ItemIndex].Free;
                                                         end;


sniknik   (2009-06-30 09:30:00) [18]

procedure TForm1.c1ClickCheck(Sender: TObject);
begin
 c1.Items.Objects[c1.ItemIndex]:=TMyObject.Create;
 with c1.Items.Objects[c1.ItemIndex] as TMyObject do
   begin
     s:='lalala'+inttostr(c1.ItemIndex);
   end;
end;

что будет если на "чекбар" в c1 нажмут 2 раза, 3, 10, и т.д. ?


Neket   (2009-06-30 09:12:00) [19]

В данном случае я воспользовался свойством Objects Так как на мой взягляд это очень практично преминимо моего случая.

Код для тех кому вдруг понадобиться (Такимже нубам как и я :-)  )
type
TMyObject = class (TObject)
public
 s:string;
end;

procedure TForm1.c1ClickCheck(Sender: TObject);
begin
 c1.Items.Objects[c1.ItemIndex]:=TMyObject.Create;
 with c1.Items.Objects[c1.ItemIndex] as TMyObject do
   begin
    s:='lalala'+inttostr(c1.ItemIndex);
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
begin
 for i:=0 to c1.Items.Count-1 do
   if c1.Checked[i] then
    ShowMessage(TMyObject(c1.Items.Objects[i]).s);
end;

соответсвенно очистка осуществляется c1.Items.Objects[c1.ItemIndex].Free;

На мой взгляд удобно и понятно.


Германн   (2009-06-30 01:55:00) [20]


> sniknik ©   (30.06.09 01:31) [15]

Коль, В "Начинающих" никто не думает о добавлении/уничтожении в рантайме, если это не сказано явно в сабже или в пояснении сабжа.
Было бы раньше и не в "Начинающим" я бы тоже дал такой совет.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо