Delphi 6 JPGViewer

Delphi 6 JPGViewer

Доброе время суток, господа. Снес себе я окна "ХАПЭ", поставил 2000. Вроде все ОК, но вот беда: нет просмотрщика графических файлов:-(... Пошарив по дискам, я пришел в разочарование... К знакомым идти лень, да и холодно на улице... Как быть? Эх... так ведь у меня Delphi есть! Там все это дело замутить просто, а значит, быстро.

Приступим-с. Запускай дельфина. Вот перед тобой среда разработки, а значит, кидай следующие компоненты:
TImage со страницы Additional.
Три TBitBnt также со страницы Additional.
Одну TPanel со страницы Standard.
TDirectoryListBox, TDriveComboBox с закладки Win 3.1.
Постарайся расположить компоненты, как показано на рисунке. Теперь выставь свойства компонентов, для примера, так:
Для TPanel (на панели у меня все, кроме Image'а:-D)
Align alRight
Color clNavy
Caption '' (удали оттуда все)
Для TImage
Name imView
Align alClient
Center True
Для TForm
Name fmMain
Color clBlack
WindowState wsMaximized
Для TBitBtn
Одна пимпа будет ОК'шная (Name btOk). Две другие управляют просмотром (name btnBack, btnNext соответственно). Так как при старте программы пользователь еще не укажет каталог, где искать картинки, то необходимо запретить нажимать на кнопки управления, поэтому для этих двух пимп свойство Enabled поставь в False.
Более подробно рассмотрим компоненты TDirectoryListBox и TDriveComboBox. DirectoreListBox создает список для отображения структуры папок диска, а DriveComboBox создает выпадающий список всех доступных дисков. Эти компоненты можно связать между собой: в свойстве DirList для DriveComboBox укажи на DirectoryListBox. Теперь дай толковые имена для этих компонентов. Для DirectoryListBox — lbDir, а для DriveComboBox — cbDrive. Вот и все! Разработка интерфейса закончена. Итак, теперь давай научим прогу искать jpg-файлы в заданном каталоге. Для работы нам нужны различные переменные. В разделе Var необходимо сделать изменения:

var
fmMain: TfmMain;//собственно форма
FileFind:TsearchRec; //это необходимо для поиска файлов
FileList:TStringList; //это тоже
hFindFile:THandle; //и это
k:Integer=-1; //надо для управления

Также необходимо добавить модуль jpeg (ведь мы будет юзать jpg-файлы).

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, FileCtrl, ExtCtrls, Buttons, jpeg;

Создай обработчик OnClick для btOk. Я туда написал вот что:

procedure TfmMain.bbOkClick(Sender: TObject);
begin
btnBack.Enabled:=False;
btnNext.Enabled:=False;
FileList:=TStringList.Create; //создаю объект для работы со строками
hFindFile:= FindFirst(lbDir.Directory+'\*.jpg',
faAnyFile,FileFind); //задаю маску поиска и начинаю оный
if hFindFile <> INVALID_HANDLE_VALUE then// если все пучком, то
repeat
if FileExists(FileFind.Name) then// проверяю существование файла (на всякий случай)
FileList.Add(lbDir.Directory+'\'+FileFind. Name); //добавляю в список полный путь к файлу
until FindNext(FileFind)<> 0; //если файлов не найдено, то ухожу из цикла (или если ошибка)
FindClose(FileFind); //закрываю поиск
if FileList.Count<> 0 then
begin
btnNext.Enabled:=true;
btnBack.Enabled:=true;//если число картинок больше 0, то разрешаю просмотр
k:=0;//обнуление счетчика
imView.Picture.LoadFromFile(FileList.Strings [k]); //читаю картинку с файла
end;
end;

Здесь ничего сложного нет. Поначалу блокирую доступ к кнопкам управы (вдруг пользователь сменил каталог на тот, где нет jpg-файлов). Потом создаю лист строк (это типа массива строк).
function FindFirst(path:String, Attr:Integer, F:TSearchRec):Integer — функция начинает поиск файла по заданной маске в указанном каталоге. Если чего случилось нехорошее, то ф-ция возвратит код ошибки. Результат поиска записывается в переменную F (если не было ошибки). Теперь про маску поиска: у каждого файла есть атрибуты. Они могут быть такими:
faReadOnly — $00000001 — Только для чтения
faHidden — $00000002 — Скрытый файл
faSysFile — $00000004 — Системный файл
faVolumeID — $00000008 — Идентификатор
faDirectory — $00000010 — Папка
faArchive — $00000020 — Архивный файл
faAnyFile — $0000003F — Любой файл

У меня lbDir.Directory+'\*.jpg', faAnyFile,FileFind, это значит, что я ищу все jpg-файлы в директории, указанной в lbDir. Далее, если нет ошибки, я создаю цикл, где ищу все файлы, соответствующие маске.

type
TSearchRec = record
Time: Integer;
Size: Integer;
Attr: Integer;//атрибуты
Name: TFileName;//имя файла
ExcludeAttr: Integer;
FindHandle: THandle;
FindData: TWin32FindData;
end;

Function FindNext(F:TSearchRec) — продолжает поиск, который начался ф-ей FindFirst. По мере нахождения графических файлов я формирую список. Когда файлы закончились, я останавливаю поиск. Проверяю количество строк в FileList (if FileList.Count<> 0 then). Если ничего нет (ни одного файла не найдено), я ничего не делаю, а вот если в списке имеется хоть одна запись, то я разрешаю управление и загружаю картинку с файла.
Осталось реализовать управление. Для этого вставь следующий программный код в обработчики onClick для btnBack и btnNext соответственно:

procedure TfmMain.btnBackClick(Sender: TObject);
begin
if k=0 then k:=FileList.Count-1 else//если счетчик на нуле, то необходимо вновь поставить максимальное значение
Dec(k);//уменьшаю на 1 значение k
imView.Picture.LoadFromFile(FileList.Strings[k]);
end;

procedure TfmMain.btnNextClick(Sender: TObject);
begin
if k=FileList.Count-1 then k:=0 else//тут все наоборот: ставлю счетчик на ноль
Inc(k);//увеличиваю на 1 значение k
imView.Picture.LoadFromFile(FileList.Strings[k]);
end;

Вроде все хорошо, все работает... Ан нет, необходимо запоминать каталог, где работала программа в последний раз, а при запуске сразу работать с этим каталогом. Меня очень раздражало по n раз за день переходить в один и тот же каталог. Поэтому нужно реализовать возможность сохранять/читать полный путь к папке, в которой приложение работало при прошлом запуске. Добавь в uses модуль registry и в исходный программный текст две процедуры:

procedure TfmMain.FormClose(Sender: TObject; var Action: TCloseAction);
var
Reg:TRegIniFile;
begin
Reg:=TRegIniFile.Create('Software');
Reg.OpenKey('Viewer', true);
Reg.WriteString('Setting', 'Dir', lbdir.Directory);
Reg.Free;
end;

procedure TfmMain.FormCreate(Sender: TObject);
var
Reg:TRegIniFile;
begin
Reg:=TRegIniFile.Create('Software');// создаю объект для работы с реестром
Reg.OpenKey('Viewer', true);//открываю ключ
lbdir.Directory:=(Reg.readString('Setting', 'Dir', lbdir.Directory));
{читаю значение, а если его нет, то будет lbdir.Directory}
Reg.Free;//освобождаю ресурсы
end;

Работу с реестром я уже объяснял, но если непонятно совсем, то читай комментарии. Вот и все. Теперь действительно все. Удачи и хороших сновидений:-D (у меня сейчас 1:06).

Margo, MargoTut@hotmail.com


Компьютерная газета. Статья была опубликована в номере 07 за 2003 год в рубрике программирование :: delphi

©1997-2024 Компьютерная газета