Форум: "Основная";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
ВнизСкорость добавления Найти похожие ветки
← →
Fuel (2006-03-06 08:59) [0]Здравствуйте! Скажите, с помощью чего (как???) в WinAmp происходит практически моментальное добавление файлов?? Я хотел бы добиться такого же результата по скорости в Listview, точнее в Virtual Listview, если это возможно. Я думаю, что нужно сначала добавить в первую колонку полные адреса, а после уже по порядку из неё считывать необходимую информацию о файлах. Но у меня этого сделать не получается. Хотелось бы услышать предложения по ускорению. Кстати, при добавлении сканируются также и подпапки. Может, нужет какой-нибудь сверхбыстрый сканер папок?
← →
API © (2006-03-06 09:06) [1]Я думаю, что нужно сначала добавить в первую колонку полные адреса, а после уже по порядку из неё считывать необходимую информацию о файлах. Но у меня этого сделать не получается.
Правильно думаете.
А почему не получается - судить трудно.
Ибо кода Вы не привели.
Кроме того, получать вторичную вспомогательную информацию (а, впрочем, и пути к файлам - тоже) лучше в отдельном потоке, или, в крайнем случае (но уже только для дополнительной информации) - на Application.OnIdle.
Может, нужет какой-нибудь сверхбыстрый сканер папок?
Ага. Рулонный, с автоподачей... ;)
← →
Fuel (2006-03-11 04:08) [2]Попытался ещё сам, но, видимо, мне нужна помощь.
uses.....
.
.
.
type
PShellItem = ^TShellItem;
TShellItem = record
Location,FileName,Time: string;
end;
type
TPlayListForm = class(TForm)
.
.
.
procedure FormCreate(Sender: TObject);
procedure pmAddFilesClick(Sender: TObject);
procedure spPlayListViewData(Sender: TObject; Item: TListItem);
public
function ShItem(Index: Integer): PShellItem;
procedure ReadFiles(Location, FileExt: String);
.
.
.
var
Form: TForm;
FIDList: TList;
FIShellFolder: IShellFolder;
procedure TForm.FormCreate(Sender: TObject);
begin
FIDList:=TList.Create;
end;
function TPlayListForm.ShItem(Index: Integer): PShellItem;
begin
Result := PShellItem(FIDList[Index]);
end;
//щелчок по контекстному меню
procedure TForm.pmAddFilesClick(Sender: TObject);
var i: Integer;
begin
while i<odAddFiles.Files.Count-1 do
begin
ShellItem := New(PShellItem);
s1:=Trim(ExpandFileName(OpenDialog.Files[i]));
ShellItem.Location := s1;
FIDList.Add(ShellItem) else
ListView.Items.Count := FIDList.Count;
ShellItem.FileName := ExtractFileName(s1);
s2:=LowerCase(Trim(ExtractFileExt(s1)));
ReadFiles(s1,s2); //считывание происходит на лету, а хотелось бы
//для большей скорости, чтобы считывание
//происходило, как в WinAmp"е, после добавления
end;
end;
procedure TPlayListForm.ListViewData(Sender: TObject;
Item: TListItem);
var s1,s2: String;
i: Integer;
begin
if (Item.Index > FIDList.Count) then Exit;
with ShItem(Item.Index)^ do
begin
Item.Caption := Location;
Item.SubItems.Add(FileName);
Item.SubItems.Add(Time);
end;
end;
// в этой процедуре и происходит считывание информации
procedure TPlayListForm.ReadFiles(Location, FileExt: String);
var FileName,Time: String;
begin
.
.
.
ShellItem.FileName:=FileName;
ShellItem.Time:=Time;
Form.Repaint;
end;
← →
API © (2006-03-11 09:43) [3]Хотите ускорения работы процедуры сканирования папок, а как раз текст ее не приводите. Смешно.
← →
Handle (2006-03-11 10:24) [4]
> API © (06.03.06 09:06) [1]
>
> Ага. Рулонный, с автоподачей... ;)
Мне понравилось.
← →
IceBeerg © (2006-03-11 12:09) [5]API © (06.03.06 9:06) [1]
Ага. Рулонный, с автоподачей... ;)
А где РЕКУРСИЯ и МНОГОПОТОЧНОСТЬ?!?
← →
antonn © (2006-03-11 13:01) [6]IceBeerg © (11.03.06 12:09) [5]
А где РЕКУРСИЯ и МНОГОПОТОЧНОСТЬ?!?
рекурсия - склеиваем концы ленты в заправленном состоянии:))
← →
Fuel (2006-03-12 02:57) [7]API
Меня больше интересует другое. Куда поместить ReadFiles, чтобы она начала работать только после добавления? Процедуру сканирования можно и не изменять. Я потому код и не привел.
Пробовал ReadFiles поставить после цикла, но в этом случае считывание происходит только для последнего элемента.
В общем, мне нужно, чтобы при pmAddFiles добавление происходило только в первый столбец, а после начиналось заполнение 2-го и 3-его столбцов.
А вопрос про сканирование мне вообще не стоило задавать. Извините.
А именно сам смысл добавления, т.е. как у меня это происходит, я думаю, привел. Можно дописать:
procedure TPlayListForm.ReadFiles(Location, FileExt: String);
var FileName,Time: String;
begin
FileName:="kfkfkfkf";
Time:="5454";
ShellItem.FileName:=FileName;
ShellItem.Time:=Time;
Form.Repaint;
end;
← →
API © (2006-03-12 03:26) [8]Извините, но алгоритм у Вас какой-то "запутанный". Плюс обилие глобальных переменных, которые, по сути, следовало бы сделать внутренними полями данных формы. И компонентов, которые лежат на форме, но объявления которых Вы зачем-то удалили - даже класс определить порой невозможно (odAddFiles, pmAddFiles и многие другие). Плюс необъявленные переменные - те же s1 и s2 в методе procedure TForm.pmAddFilesClick; (тип понятен из контекста, но смысл их вводить - мне не ясен).
Лично я не вижу возможности разобраться с Вашим кодом, возможно, у кого-то другого телепатор работает лучше.
Кроме того, самого получения списка файлов и их атрибутов я так и не узрел. Приведенный метод ReadFiles,- вообще ничего и не "читает".
Ваша программа вообще - компилирутеся?
То есть, у меня возникает ощущуение, что вы сильно намудрили с кодом.
А чем Вам не подходит пример из Help"а?procedure TForm1.Button1Click(Sender: TObject);
var
sr: TSearchRec;
FileAttrs: Integer;
begin
StringGrid1.RowCount := 1;
if CheckBox1.Checked then
FileAttrs := faReadOnly
else
FileAttrs := 0;
if CheckBox2.Checked then
FileAttrs := FileAttrs + faHidden;
if CheckBox3.Checked then
FileAttrs := FileAttrs + faSysFile;
if CheckBox4.Checked then
FileAttrs := FileAttrs + faVolumeID;
if CheckBox5.Checked then
FileAttrs := FileAttrs + faDirectory;
if CheckBox6.Checked then
FileAttrs := FileAttrs + faArchive;
if CheckBox7.Checked then
FileAttrs := FileAttrs + faAnyFile;
with StringGrid1 do
begin
RowCount := 0;
if FindFirst(Edit1.Text, FileAttrs, sr) = 0 then
begin
repeat
if (sr.Attr and FileAttrs) = sr.Attr then
begin
RowCount := RowCount + 1;
Cells[1,RowCount-1] := sr.Name;
Cells[2,RowCount-1] := IntToStr(sr.Size);
end;
until FindNext(sr) <> 0;
FindClose(sr);
end;
end;
end;
← →
Fuel (2006-03-13 03:03) [9]pmAddFiles - это пункт контекстного меню (изначально назван был N1), odAddFiles - это OpenDialog1. ReadFiles у меня довольно громоздкая, поэтому я её и не приводил. Вижу теперь, что действительно нужно, но учитывая, что смысл кода для разных файлов один и тот же, то приведу только для *.mp3:
procedure TPlayListForm.ReadMediaFiles(Location, FileExt: String);
var FileName: String;
begin
if (FileExt=".mp3") then
begin
MPEGaudio.ReadFromFile(Location);
ID3V2Tag.ReadFromFile(Location);
if (ID3V2Tag.Title="")or (ID3V2Tag.Artist="") then
begin
ID3V1Tag.ReadFromFile(Location);
ID3V2Tag.Title:=ID3V1Tag.Title;
ID3V2Tag.Artist:=ID3V1Tag.Artist
end;
if (ID3V2Tag.Title="") or (ID3V2Tag.Artist="") then
begin
FileName:=ExtractFileName(Location);
Delete(FileName,Length(FileName)-Length(FileExt)+1,Length(FileExt)+1);
ShellItem.FileName:=FileName;
ShellItem.Time:=FormatFileTime(MPEGaudio.Duration);
end
else
begin
ShellItem.FileName:=ID3V2Tag.Artist+" - "+ID3V2Tag.Title;
ShellItem.Time:=FormatFileTime(MPEGaudio.Duration);
end;
end;
А теперь поясню. Переменные Location служит для того, чтобы процедура знала, из какого файла считывать информацию (т.е. полный адрес файла), FileExt содержит в себе расширение файла. Значения этим двум переменным присваиваются до выполнения процедуры, например:
s1:=полный адрес, по которому находится файл;
s2:=расширение этого файла;
После выполнение процедуры ReadFiles(s1,s2).
MPEGAudio, ID3V1, ID3V2 - это уже компоненты, которые считывают, что надо.
FormatFileTime - это функция, которая представляет время (MPEGaudio.Duration) в минутах и секундах, т.е. в привычный нам вид.
И ещё я должен извинится, что не уточнил, какая именно информация считывается.
Что касается кода, то нет, я с ним особо сильно не намудрил, но он большой. И всё компилируется превосходно. Единственное, что хочу осуществить, это:
открываю папку, файлы (*.mp3) из которой добавляются в Virtual ListView. Добавляются только полные адреса в первый столбец, больше ничего. Вот они полностью добавились, и уже после этого происходит считывание времени и имени файлов. Эта информация соответственно добавляется во 2-ой и 3-ий столбцы.
И вопрос не по теме: где достать информацию по перетаскиванию элементов внутри Virtual ListView? Если кто знает, дайте ссылочку, или ещё что-нибудь, что будет.
← →
Defunct © (2006-03-13 04:33) [10]Попытайтесь полный список хранить в StringList, а видимые строки отображать в StringGrid. Количество RowCount задайте равным количеству видимых строк, ScrollBar поставьте свой. Вы будете ошеломлены скоростью.
← →
Alex Konshin © (2006-03-13 07:38) [11]Еще раз порекомендуюсвой ArrayGrid, он как раз подоходит для таких задач намного лучше, чем ListView.
← →
Fuel (2006-03-18 04:16) [12]Долго я молчал, всё времени не было.
Похоже, мой вопрос не совсем понятен.
Чтобы лучше воспринималось, спрошу так:
как заполнить первый столбец ListView, не заполняя остальные.
Например, не такItem.Caption := Location;
,
Item.SubItems.Add(FileName);
Item.SubItems.Add(Time)
а такItem.Caption := Location;
Просто убрав две строки. В этом случае возникает ошибка.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.04.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.013 c