Для удобства открытия картинок существует пара компонентов-диалогов: TOpenPictureDialog и TSavePictureDialog.
Список форматов открываемых файлов определяется свойством Filter. Можно, как в случае со стандартными диалогами TOpenDiaiog или TSaveDialog, сформировать их вручную с помощью редактора свойства Filter. Можно поступить проще, воспользовавшись готовыми средствами. Для удобства формирования строк графических фильтров существуют три специальные функции:
function GraphicFilter(GraphicClass: TGraphicClass): string;
Формирует строку с полным текстом графического фильтра, позволяющего открывать все файлы, форматы которых являются потомками параметра GraphicClass. Если в качестве параметра этой функции будет передан класс TGraphic, то в строке будут перечислены все форматы:
'Аll (*.jpg;*.jpeg;*.bmp;*.ico;*.emf;*.wmf} I *.jpg;*.jpeg;*.bmp;*.ico; *.emf;*.wmfIJPEG Image File (*.jpg) I *.jpgI JPEG Image File (*.jpeg) I *.jpeg|Bitmaps (*.bmp) I *.bmplIcons (*.ico) I*.ico|Enhanced Metafiles (*.emf) |*.emf[Metafiles (*.wmf) I *.wmf'
Формат JPEG появляется в перечне, если в приложении используется модуль с тем же названием — JPEG. В приводимом ниже примере возникла необходимость совместить фильтры только для классов TBitmap и TJPEGimage, которые не являются предками друг друга. В этом случае получившиеся строки нужно соединить, использовав символ конкатенации "|":
S := GraphicFilter(TBitmap)+'|'+ GraphicFilter(TJpeglmage)
function GraphicExtension(GraphicClass: TGraphicClass): string;
Возвращает расширение файла, формат которого соответствует графическому классу GraphicClass. Так, если передать в качестве параметра класс TBitmap, то функция вернет строку 'BMP';
function GraphicFileMask(GraphicClass: TGraphicClass): string;
Эта функция возвращает перечень расширений файлов с форматами — потомками GraphicClass, перечисленных через точку с запятой.
Для диалогов предусмотрено несколько событий, которые программист может обработать самостоятельно. Первые три — достаточно тривиальные: OnShow, oncanciose и enclose. Нужно предостеречь программиста: по чьему-то недосмотру последние два вызываются только в случае нормального завершения диалога (нажатием кнопки Open или Save), а если завершить диалог нажатием кнопки Cancel или "крестика" на заголовке диалога, то управления они не получат.
Другие три события связаны с изменениями, которые осуществляет пользователь во время выбора нужного файла. Они происходят в момент изменения формата открываемого файла (событие onTypeChange), изменения текущей папки (OnFolderChange) и текущего файла (OnSelectionChange).
Но разработчики диалогов не предусмотрели одну очень нужную возможность. Дело в том, что у разных графических форматов возможны различные опции и варианты. Если вы имеете опыт работы с графическими пакетами вроде Adobe Photoshop или Corel, то знаете, что, в зависимости от выбранного формата сохранения данных, диалог изменяет свой внешний вид — к нему добавляются элементы управления, соответствующие параметрам формата.
Поступим так и мы, предусмотрев настройку при сохранении файлов формата JPEG. Для этого будет использовано событие OnTypeChange компонента TSavePictureDialog. Для события нужно проверить значение свойства Filterindex. Если оно больше 1 (т. е. выбраны файлы формата JPEG), нужно увеличить высоту окна диалога и разместить на нем дополнительные компоненты: флажок, соответствующий свойству ProgressiveEncoding, и редактор свойства compressionQuaiity (рис. 10.2). Если тип файла снова поменялся и стал равным 1, нужно эти компоненты убрать.

Поможет нам в этом внимательное изучение исходных кодов диалогов, находящихся в модуле EXTDLGS.PAS. Программисты Borland пошли по пути модернизации внешнего вида стандартных диалогов, добавив к ним справа панель для отображения внешнего вида открываемых (записываемых) картинок. Можно пойти дальше и добавить таким же образом и свои элементы управления.
Приводимый ниже пример ModifDlg — усовершенствованная программа просмотра и сохранения файлов растровой графики, к которым относятся файлы форматов JPEG и BMP. Чтобы исключить метафайлы и значки (*.wmf, *.emf, *.ico), соответствующим образом настраиваются фильтры в диалогах открытия и сохранения.
Для изменения размеров диалогового окна нужно отыскать среди входящих в его состав компонентов панель picturePanel (так назвали ее разработчики Borland) и увеличить ее высоту. Следует также поменять и размеры родительских окон. Поскольку они не являются компонентами Delphi (стандартные диалоги являются составными частями Windows) для этой цели используются функции API GetWindowRect И SetWindowPos.
Обратите также внимание, что при загрузке используется событие OnProgress класса TGraphic. В его обработчике информация об объеме проделанной работы отображается на компоненте progressBar1. Для маленьких картинок обработчик вызывается только в начале и в конце операции, пользователь ничего не заметит. Зато при загрузке большого изображения он будет спокоен, видя, что процесс загрузки идет и машина не зависла.
Листинг 10.1. Исходный текст главного модуля программы ModifDlg
unit mainUnit; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtDlgs, StdCtrls, ComCtrls, ExtCtrls, Buttons; type TForml = class(TForm) SavePictureDialogl: TSavePictureDialog; OpenPictureDialogl: TOpenPictureDialog; ScrollBoxl: TScrollBox; Imagel: TImage; ProgressBari: TProgressBar; OpenBitBtn: TBitBtn; SaveBitBtn: TBitBtn; procedure SavePictureDialoglTypeChange(Sender: TObject); procedure ImagelProgress(Sender: TObject; Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: String); procedure SavePictureDialoglClose(Sender: TObject); procedure FormCreate(Sender: TObject); procedure SavePictureDialoglShow(Sender: TObject); procedure OpenBitBtnClick(Sender: TObject); procedure SaveBitBtnClick(Sender: TObject); private public end; var Forml: TForml; implementation {$R *.DFM} uses jpeg; const DeltaH : Integer = 80; var Quality : TJpegQualityRange; ProgressiveEnc : Boolean; procedure TForml.OpenBitBtnClick(Sender: TObject); begin if OpenPictureDialogl.Execute then Imagel.Picture.LoadFromFile (OpenPictureDialogl.FileName); end; procedure TForml.SaveBitBtnClick(Sender: TObject); var ji : TJpeglmage; begin if SavePictureDialogl.Execute then begin ji := TJpeglmage.Create; ji.CompressionQuality := Quality; ji.ProgressiveEncoding := ProgressiveEnc; j i.Assign(Imagel.Picture.Bitmap); ji.SaveToFile(SavePictureDialogl.FileName); ji.Free; end; end; procedure TForml.SavePictureDialoglTypeChange(Sender: TObject); var ParentHandle:THandle;wRect:TRect; PicPanel,PaintPanel:TPanel;JEdit : TEdit; Expanded : boolean; begin With Sender as TSavePictureDialog do begin PicPanel := (FindComponent('PicturePanel') as TPanel); if not Assigned(PicPanel) then Exit; ParentHandle:=GetParent(Handle); PaintPanel:=(FindComponent('PaintPanel') as TPanel); PaintPanel.Align := alNone; Expanded := FindComponent('JLabel') <> nil; if Filterlndex >1 then begin if not Expanded then begin GetWindowRect(ParentHandle,WRect); SetWindowPos(ParentHandle,0,0,0, WRect.Right-WRect.Left, WRect.Bottom-WRect.Top+DeltaH, SWP_NOMOVE+SWP_NOZORDER); GetWindowRect(Handle,WRect); SetWindowPos(handle,0,0,0,WRect.Right- WRect.Left, WRect.Bottom-WRect.Top+DeltaH, SWP_NOMOVE+SWP_NOZORDER); Expanded:=True; PicPanel.Height := PicPanel.Height+DeltaH; if FindComponent('JLabel')=nil then with TLabel.Create(Sender as TSavePictureDialog) do begin Parent := PicPanel; Name := 'JLabel'; Caption := 'Quality'; Left := 5; Height := 25; Top := PaintPanel.Top+PaintPanel.Height+5; end; if FindComponent('JEdit')=nil then begin JEdit := TEdit.Create(Sender as TSavePictureDialog); with JEdit do begin Parent := PicPanel; Name:='JEdit'; Text := '75'; Left:-50;Width := 50; Height := 25; Top := PaintPanel.Top+PaintPanel.Height+5; end; end; if FindComponent('JUpDown')=nil then with TUpDown.Create(Sender as TSavePictureDialog) do begin Parent := PicPanel; Name:='JUpDown'; Associate := JEdit; Increment := 5; Min := 1; Max := 100; Position := 75; end; if FindComponent('JCheck')=nil then with TCheckBox.Create(Sender as TSavePictureDialog) do begin Name: = 'JCheck'; Caption:='Progressive Encoding'; Parent:=PicPanel; Left:=5;Width := PicPanel.Width - 10; Height:=25; Top := PaintPanel.Top+PaintPanel.Height+35; end; end; end else SavePictureDialoglClose(Sender); end; end; procedure TForml.ImagelProgress(Sender: TObject; Stage: TProgressStage; PercentDone: Byte; RedrawNow: Boolean; const R: TRect; const Msg: String); begin case Stage of psStarting: begin Progressbarl.Position := 0; Progressbarl.Max := 100; end; psEnding: begin Progressbarl.Position := 0; end; psRunning: begin Progressbarl.Position := PercentDone; end; end; end; procedure TForml.SavePictureDialoglClose(Sender: TObject); var PicPanel : TPanel; ParentHandle : THandle; WRect : TRect; begin With Sender as TSavePictureDialog do begin PicPanel := (FindComponent('PicturePanel') as TPanel); if not Assigned(PicPanel) then Exit; ParentHandle:=GetParent(Handle); if ParentHandle=0 then Exit; if FindComponent('JLabel')onil then begin FindComponent('JLabel').Free; FindComponent('JEdit').Free; ProgressiveEnc := (FindComponent('JCheck1') as TCheckBox).Checked; FindComponent('JCheck').Free; Quality := (FindComponent('JUpDown') as TUpDown).Position; FindComponent('JUpDown').Free; PicPanel.Height:=PicPanel.Height-DeltaH; GetWindowRect(Handle,WRect); SetWindowPos(Handle,0,0,0,WRect.Right-WRect.Left, WRect.Bottom-WRect.Top-DeltaH, SWP_NOMOVE+SWP_NOZORDER); GetWindowRect(ParentHandle,WRect); SetWindowPos(ParentHandle,0,0,0, WRect.Right-WRect.Left, WRect.Bottom-WRect.Top-DeltaH, SWP_NOMOVE+SWP_NOZORDER); Filterlndex := 1; end; end; end; procedure TForml.FormCreate(Sender: TObject); var s: string; begin s :=GraphicFilter(TBitmap)+'|'+ GraphicFilter(TJpeglmage); OpenPictureDialogl.Filter := s; SavePictureDialogl.Filter := s; end; procedure TForml.SavePictureDialoglShow(Sender: TObject); begin with Sender as TSavePictureDialog do begin if FindComponent('JLabel')Onil then begin FilterIndex := 2; SavePictureDialoglTypeChange(Sender) ; end; end; end; end.
Приведенный пример может послужить толчком, во-первых, к углубленному изучению формата JPEG, а во-вторых, — к модификации стандартных диалогов. На его базе можно создать диалоги открытия аудиозаписей, документов и других специализированных видов файлов.
Последние комментарии
5 дней 8 часов назад
1 неделя 1 день назад
2 недели 3 дня назад
4 недели 1 день назад
5 недель 3 дня назад
7 недель 4 дня назад
10 недель 2 дня назад
10 недель 6 дней назад
11 недель 2 дня назад
12 недель 11 минут назад