Главная » Delphi » Процедура составления списка файлов с картинками

0

Удалим кнопку Buttoni и расставим на форме следующие компоненты: вверху, пониже меню, растянем во всю длину панели компонент staticToxt (staticTextl) — он находится на вкладке Addtional и всем напоминает Label, но дополнительно может быть с рельефной рамкой. У него установим свойство BorderStyle В sbsSuiiken, СВОЙСТВО AutoSize В False. Он будет Служить для отображения текущей папки. Теперь скопируем в буфер обмена этот компонент и размножим его внизу формы четыре раза (разумеется, каждый раз подгоняя размеры), получив компоненты, которые назовем StaticTextName (ИМЯ файла), StaticTextSize (размеры картинки), StaticTextl." (номер картинки в списке) и staticTextNFile (всего картинок в списке). У этих компонентов установим свойство Alignment в tacenter (выравнивание текста по центру). Левее последнего поставим обычный Label с надписью Всего, а левее предпоследнего — также Label с надписью Рис. №.

Теперь решим проблему с красивыми кнопками. Поместим на форму две кнопки типа BtnBtn (BtnBtnL и BtnBtnR) — они будут служить для перелистывания картинок по списку вправо и влево. Им хочется задать картинки в виде стрелочек, но по какой-то причине в Delphi 7 нет типовой библиотеки BitMap для кнопок (возможно, она поставляется отдельно— просто не знаю). Я заимствовал стрелочки из библиотеки Delphi 3, и расположил их в папке с проектом под названиями arrL.bmp и arrR.bmp. Кнопки расположим справа внизу, очистим в них заголовки и через свойство Glyph загрузим указанные BitMap в виде стрелочек. Сразу перенесем текст из обработчика несуществующей теперь кнопки Buttoni в обработчик щелчка на кнопке BtnBtnR. Наконец, самой последней поставим обычную кнопку под названием Buttonr с надписью Предпросмотр (вообще-то можно было и переименовать Buttonl, но так надежнее) — она у нас будет служить для запуска окна "превьюшек".

Эти компоненты надо "заякорить", чтобы они не разбежались при распахивании окна. У всех нижних StaticText И Label В свойстве Anchors В True ДОЛЖНЫ быть установлены пункты akLeft И akBottom. а у КНОПОК — пункты akRight И akBottom. Поверх же верхнего staticTexti мы установим компонент ProgressBar (ProgressBarl), причем растянем его так, чтобы ОН ПОЛНОСТЬЮ вписался в staticTexti. Имейте в виду, что StaticText, в отличие от Label, имеет собственное окно и может служить "родителем", что значительно облегчает дело. У ProgressBarl установим свойство step в I, а свойство visible в False. После всей этой возни главная форма на этапе конструирования должна приобрести вид, показанный на рис. I5.1.

Рис. 15.1. Главная форма SlideShow

Теперь, наконец, возьмемся за алгоритм. Для начала отредактируем в OpenDialogl фильтр (свойство Filter), теперь он должен выглядеть, как Картинки jpeg и bmpl*. jpg; *.jpeg; *.bmp. Внесем в тексте модуля Slide следующие переменные в секцию public:

Filelist,SizeList :TStringList; {объекты типа StringList для хранения имен и размера файлов) Jpglm: TJpeglmage; /объект типа JPEG) Bmplm: TBitMap; {объект типа BitMap)

А в секции var добавим такие:

nfiles: integer; fname: string;

buffer : array[0..255] of char,

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

В процедуру FormCreate добавим в самом конце такие строки:

Filelist:»TStringList.Create; {создаем экземпляр списка имен) Filelist.Sorted:=False; {пока сортировать не будем) SizeList:=TStringList.Create; {создаем экземпляр списка размеров) Sizelist.Sorted:=False; (здесь сортировка не нужна) DragAcceptFiles(Forml.Handle,True); (сообщаем, что готовы к приему файлов)

Самая последняя строка— заготовка для последующей реализации Drag&Drop.

Создадим обработчик события onDestroy формы, в котором будем уничтожать наши списки:

procedure TForml.FormDestroytSender: TObject); begin

FileList.Destroy; {уничтожаем списки)

Sizelist.Destroy;

end;

Наконец, напишем функцию для предварительного пересчета файлов, расположив ее в самом верху текста модуля Slide, сразу под процедурой

CreateMyicon".

function NumFiies:boolean;

begin {пересчет файлов с картинками в заданном каталоге!

result.: =True ;

nfiles:=0;

if FindFirst ( " . " ,faAnyFile,srf)=C then

begin (просматриваем все файлы и пересчитываем те, что jpg н bmpl repeat

if (ExtractFileExt (AnslLowerCflse(srf .Name) ) = ‘ .b.np’) or

(ExtractFileExt(AnsiLowerCase(srf.Name))=’.jpg’) or (ExtractFileExt(AnsiLowerCase(srf.Name))=’.ipeg’) then nfiles:=nfiles+l; until (FindNext: (srf)<>0) ; end;

FindClose (srf) ;

if nfiles^O then result:=False else Forml.ProgressEarl.Max:=nfiies;

(если нашли, устанавливаем ползунок)

end;

А ниже ее расположим основную процедуру, которую назовем PictureList. для выявления файлов с картинками и размещения их имен и размеров в списке. В этой процедуре мы сначала располагаем имя и размер в одной и той же строке в списке Fiieiist, который сортируется по мере создания, а потом запрещаем сортировку и делим полученные строки на два списка: FiieList с именами и sizeiist с размерами — способ не очень красивый, но зато позволяет надежно привязать имя к размеру, иначе после сортировки установить соответствие было бы весьма сложно2. По ходу дела мы будем также определять и выводить размер уже загруженного файла (сели имеется его имя ), а в самом начале процедуры устанавливать папку по умолчанию для всех диалогов, выводить ее в INI-файл. а также очищать окна для последующего вывода информации. В результате процедура получится довольно навороченной:

procedure PictureList; (составление списка файлов с картинкам!)

var st:string;

begin

if not NumFiies then exit; (если ни одного, то выход) Form3.DirectoryListRoxl.Directory:=stpath;

{на следующее открытие папки)

with Forml do begin

OpenDialogl.InitialDir:=stPath; Iна следующее открытие файла) ChDir(stpath); /устанавливаем текучею папку) IniFile:=TIniFile.Create(ChangeFileExt(ParamStr(0),1.ini’));

/открываем iniI IniFile.WriteString(‘Main’,•Path’,stpath); IniFile.Destroy;

StaticTextl.Caption:=stPath; {выводим путь и имя) if fnaraeo” then

Sta ticTextName. Capt ion: =Extract FileName (fname) ; StaticTextSize.Caption:=’ ‘; {очистили размер} StaticTextN.Caption:="'; {очистили номер) StaticTextNFile.Caption:=”; {очистили количество) Application.ProcessMessages; {показали, что загрузили) ProgressBarl.Visible:=True; {показали ползунок) ProgressBarl.Position:=0; {установили в 0) FileList.Clear; {очистили список) Filelist.Sorted:=Тrue;

{это чтобы файлы сортировались по алфавиту) Jpglm : = TJpeglmage.Create; {создаем JPEG) Bmplm := TBitMap.Create; (создаем BitMap) if FindFirst(‘*.*’,faAnyFile,srf)=0 then

begin {проематриваем все файлы, и проверяем те, что jpg и bmp) repeat

if (ExtractFileExt(AnsiLowerCase(srf.Name))=’.bmp’) then begin try

Bmplm.LoadFromFile(srf.Hame);

{пробуем загрузить картинку с диска) except {если ничего не вышло – это вовсе не BitMap)

continue; (продолжаем цикл) end;

Filelist.Add(srf.Name+’*’+IntToStr(Bmplm.Width)+

‘x’+IntToStr(Bmplm.Height)) ; {добавляем шля найденного файла и его размеры к списку/ if fnameo” then

if srf.Name = ExtractFileName(fname) then begin

StaticTextSize.Caption:=IntToStr(Bmplm.Width)+

•x’+IntToStr(Bmplm.Height) ; Application.ProcessMessages;

(показываем размеры открытого файла) end;

ProgressBarl.Steplt; end;

if (ExtractFileExt (AnsiLovierCase (srf .Name) ) =’ . jpg’) or

(ExtractFileExt(AnsiLowerCase (srJ: .Name))=’. jpeg’) then begin try

Jpglm.LoadFromFile(srf.Name);

(пробуем загрузить картинку с лиска! except (если ничего не вышло – это вовсе не JPEC}

continue; (продолжаем цикл} end;

Filelist.Add(srf.Name+•*?+IntTo3tr(Jpglm.Width)+

‘x’+IntToStr(Jpglm.Height)) ; (добавляем имя найденного файла и его размеры к списку) if f nameo” then

if srf.Name = ExtractFileName(fname) then begin

StaticTextSize.Caption:=IntToStr(Jpglm.Width)+

‘x’+IntToStr(Jpglm.Height); Application.ProcessMessages;

(показываем размеры открытого файла) end;

ProgressBarl.Steplt; end;

until (FindNext (srf) <>0) ; end;

Bmplm.Destroy; (уничтожаем BitMap) Jpglm.Destroy; {уничтожаем JPEG)

Filelist.Sorted:=False; {больше сортировать не будем)

for nfiles:=0 to Filelist.Count-1 do {делим имя и размер) begin

st:=Filelist[nfiles];

Filelist[nfiles]:=copy(st,1,pos(‘*’, st)-1); SizeList .Add (copy (st, pos (‘ *st) 1, length (st))) ; end; {теперь в Filelist – имена, а в SizeList – размеры)

n:=0;

for nfiles:=0 to Filelist.Count-1 do

{показываем номер открытого файла – до этого он не известен) if Filelist[nfiles1 = ExtractFileName(fname) then begin StaticTextN.Caption;=IntToStr(nfiles+1) ;

n:=nfiles; break end; (если файл открыт, то в л - его номер в списке, иначе п-0)

nfiles:=Filelist.Count;

Stat ic’L’extNFi le. Caption: =1ntToS tr(nfiles);

Iпоказываем сколько файлов) ProgressBarl.Visible:=False; (убрали ползунок) end;

end (PictuceList);

Теперь нам нужно внести эту процедуру в четыре места, по числу перечисленных ранее возможных действий: открыть файл, открыть папку, загрузить файл через Drag&Drop и загрузить файл через командную строку. Первые два действия у нас уже реализованы. Внесем в конец процедуры openciick изменения: удалим оператор г.:=о,- и добавим формирование имени файла и папки, а также вызов нашей процедуры:

procedure TForml.OpenClick(Sender: TObject); (открытие файла) begin

Panel2.Visible:=False; (закрываем панель) If OpenDialog1.Execute then

(если диалог открытия файла завершился удачно) Imagel.Picture.LoadFromFile(OpenDialogl.FileName)

(загружаем картинку в Imagel) else exit; (иначе, если диалог завершился неудачно, то выходим из процедуры) fname:=OpenDialogl.FileName; (запоминаем имя загруженного файла) stpath:=ExtractFileDir(fname);

(запоминаем папку без последнего "\") PictureList; (составление списка файлов с картинками) end;

Теперь внесем изменения в вызов диалога установки папки. В тексте модуля Рарка удалим из процедуры Button3ciick все, что относится к INI-файлу и к установке директории по умолчанию, в результате процедура упростится:

procedure TForm3.Button3Click(Sender: TObject); begin (Ok лля выбора папки) stpath:=DirectoryListBoxl.GetItemPath

(DirectoryListBoxl.Itemlndex) ; ChDir(stpath); (устанавливаем текущую папку) Form3.Close; end;

А процедура openFoiderCiick в модуле Slide, в которой стоял единственный вызов Fora3. showModai, наоборот, усложнится:

procedure TForml.OpenFoiderCiick(Sender: TObject); begin (открыть папку)

Form3.ShowModal; fname: = *'; (пустое имя}

PictureList; (составление списка файлов с картинками( if Fi 1е 1 i.st.CounL=0 then exit; StaticTextl.Caption:=stPath; (загружаем первую картинку по списку:) S tat icTextN.Capt ion: =11′; fname:=stpath+’\’+Filelist[0];

StaticTextName.Caption:=ExtractFileName(fname); Imagel.Picture.LoadFromFile(fname) ; StaticTextSize.Caption:=Sizelist [0] ; end;

Теперь остальные действия. Процедуру по загрузке файла в командной строке (она же при "бросании" файла с картинкой на иконку программы в Проводнике) мы реализуем через обработчик события onActivate формы:

procedure TForml.FormAct ivate(Sender: TObj ect); begin

if paramcountoO then (если есть параметр загрузки) begin try

Imagel.Picture.LoadFromFile(paramstr(1)); (пробуем загрузить картинку) except exit ; end;

fname:=paramstr (1); stpath:=ExtractFileDir(fname);

(запоминаем папку без последнего "\") PictureList; fсоставление списка файлов с картинками} end; end;

Наконец, реализуем Drag&Drop, для чего внесем в секцию private нашу процедуру из главы 13\

procedure DropPicture(var Massage: TWMDROPFILES); message WM_DROPFILES;

Сама процедура будет выглядеть так:

procedure TForml.DropPicture(var Message: TWMDROPFILES); begin (прием файлов, брошенных на форму) DragQueryFile(Massage.Drop,0,Sbuffer,sizeof(buffer)) ; try

Imagel.Picture.LoadFromFile(buffer); (пробуем загрузить)

except

exit; end;

fname:=buffer;

stpath:=ExtractFileDir(fname);

{запоминаем папку без последнего "\"l PictureList; {составление списка файлов с картинками) end;

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

Источник: Ревнч Ю. В.  Нестандартные приемы программирования на Delphi. — СПб.: БХВ-Петербург, 2005. — 560 е.: ил.

По теме:

  • Комментарии