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

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

Вопрос к вам, мастера! [D6, WinXP]


Страницы:   1 2

Anar ©   (2002-09-10 14:15:00) 

Допустим у меня список файлов в ListBoxe:

C:\Anar\Temp\file.txt
C:\Anar\Temp\file2.exe
C:\Anar\Temp\file3.jpg
и т.д.

Создаю Button и к нему обработчик:




begin
Repeat
DeleteFile(ListBox1.Items.Index[i]);
ListBox1.Items.Delete[i];
i:=i+1;
Until ListBox1.Items.Strings="";
end;


Он короче удаляет все файлы и строки из ListBox1, но когда доходит до конца выдаёт ошибку такого рода: ListBox bound Index (точно не помню я не дома и пишу всё по памяти). Как правильно удалять по очереди все элементы из ListBox, пока там не окажется ни один элемент.

И ещё: Как известно, процесс удаления элемента из спика происходит намного быстрее, чем процесс удаления файла с жёсткого диска. Как сделать чтоб следующий элемент(файл) начал удаляться только после того как удалиться предыдущий?


Рыжик   (2002-09-11 11:08:00) [1]

Пробую в отладчике и убеждаюсь: пока не удалится файл, на следующую строку не переходит. Может ты чего-то не договариваешь? Опиши подробней свою ситуацию.


Anar   (2002-09-11 10:17:00) [2]

Нет, нет. Ты сам попробуй, убедишься. Если б можно было бы так как ты раньше сказал, то второй раз я бы не спросил.


Рыжик   (2002-09-11 10:10:00) [3]

Да вроде бы DeleteFile должна закончиться, только когда удаление завершится полностью. А потом уже программа перейдёт на следующую строчку. Или нет?


Anar   (2002-09-11 09:55:00) [4]

Не надо спорить, с удалением из списка строк я разобрался, лучше скажите как сделать так чтобы до того как файл не удалится с HDD следующая запись не начинала удаляться. Например, у меня файлы размером 2-3 Мб, а они не сразу удаляются с диска, в то время как записи из ListBox"а удаляются моментально.


Рыжик   (2002-09-10 15:30:00) [5]

Lord Warlock © (10.09.02 15:19)
А где было мной написано что ListBox.Items.Count не изменится при удалении??? Естественно, изменится. Только это уже никак не повлияет на счётчик в цикле. А сыр-бор из-за того, что вами было сказано:
> Не забывай что при удалении и добавлении ListBox1.Items.Count
> меняется, поэтому в цикле for напрямую его использовать
> нельзя

Однако я говорю, можно ;)


Рыжик   (2002-09-10 15:25:00) [6]

В моём последнем примере в ListBox ничего не удаляется, так что ListBox.Items.Count не меняется. Согласно вашему замечанию
ListBox1.Items.Count вычисляется каждый проход цикла. Это означает, что i тоже не будет меняться и программа зациклится. Однако в действительности i уменьшается с каждым проходом цикла.
Так что цикл for это не аналог цикла while. В последнем счётчик надо изменять ручками, а в первом скётчик уменьшается или увеличивается всегда, какое бы вы ни использовали для него начальное значение.


Lord Warlock   (2002-09-10 15:19:00) [7]

..естественно вместе с ListBox1.Items.Delete, так как весь сыр-бор из-за него.


Lord Warlock   (2002-09-10 15:17:00) [8]

Уважаемый Рыжик ©,

попробуй в отладчике походить по циклу, который ты привел выше и посмотри ListBox1.Items.Count или ShowMessage(IntToStr(ListBox1.Items.Count));в цикле


Рыжик   (2002-09-10 15:12:00) [9]

Уважаемый Lord Warlock ©
А вы просто попробуйте такой цикл
for i:=ListBox1.Count-1 downto 0 do
ShowMessage(IntToStr(i));

и посмотрите, что будет.
Здесь ListBox1.Count не меняется, но цикл идёт благополучно


Lord Warlock   (2002-09-10 15:03:00) [10]

Уважаемый Рыжик ©,
for i:=ListBox1.Items.Count-1 downto 0 do
ListBox1.Items.Delete(i);


ListBox1.Items.Count вычисляется каждый проход цикла

это просто аналог

while ListBox1.Items.Count>0 do
ListBox1.Items.Delete(ListBox1.Items.Count-1)


Рыжик   (2002-09-10 14:55:00) [11]


> Lord Warlock © (10.09.02 14:43)

for i:=ListBox.Items.Count-1 downto 0 do
ListBox.Items.Count вычислится только один раз, а дальше идёт просто уменьшение на единицу. Так что можно


Lord Warlock   (2002-09-10 14:43:00) [12]


> Рыжик © (10.09.02 14:40)
> C for тоже можно, только в обратном порядке


Только так:

Cnt:=ListBox1.Items.Count-1;
for i:=Cnt downto 0 do
....

или
for i:=0 to Cnt do

Не забывай что при удалении и добавлении ListBox1.Items.Count меняется, поэтому в цикле for напрямую его использовать нельзя


Рыжик   (2002-09-10 14:40:00) [13]

C for тоже можно, только в обратном порядке


Lord Warlock   (2002-09-10 14:34:00) [14]

> for i:=0 to ListBox1.Items.Count-1 do
Совсем забыл про эти грабли :))

Разумеется надо делать в цикле while с удалением первого или последнего элемента, как предложил Reindeer Moss Eater


Reindeer Moss Eater   (2002-09-10 14:29:00) [15]

while ListBox.Items.Count > 0 do
begin
DeleteFile(ListBox1.Items.Index[0]);
ListBox1.Items.Delete[0];
end;


Рыжик   (2002-09-10 14:27:00) [16]

А ошибка происходт из-за того, что после первого удаления, второй элемент становится первым. Когда i=1 на самом деле удаляется с индексом 2 в первоначальном списке. Доходит где-то до середины, а дальше эл-тов нет, хотя список не пустой.


Lord Warlock   (2002-09-10 14:27:00) [17]

И что такое ListBox1.Items.Index[i]?
наверное имеется ввиду ListBox1.Items[i];

а написать лучше так

for i:=0 to ListBox1.Items.Count-1 do
begin
DeleteFile(ListBox1.Items[i]);
ListBox1.Items.Delete(i);
end;


Рыжик   (2002-09-10 14:22:00) [18]

for i:=ListBox.Items.Count-1 downto 0 do
begin
DeleteFile(ListBox1.Items.Index[i]);
ListBox1.Items.Delete[i];
end;
В таком варианте пока DeleteFile не закончится, ListBox1.Items.Delete и не начнётся.


Anar   (2002-09-10 14:21:00) [19]

Начальное значение i=0


Anar   (2002-09-10 14:20:00) [20]

Вру!

Код такой:
begin
Repeat
DeleteFile(ListBox1.Items.Strings[i]);
ListBox1.Items.Delete[i];
i:=i+1;
Until ListBox1.Items.Strings="";
end


Страницы:   1 2

Наверх

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