Формирует строку с полным текстом графического фильтра, позволяющего открывать все файлы, форматы которых являются потомками параметра
GraphicClass. Если в качестве параметра этой функции будет передан класс
TGraphic, то в строке будут перечислены все форматы:
Формат JPEG появляется в перечне, если в приложении используется модуль с тем же названием — JPEG. В приводимом ниже примере возникла необходимость совместить фильтры только для классов
TBitmap и TJPEGimage, которые не являются предками друг друга. В этом случае получившиеся строки нужно соединить, использовав символ конкатенации
"|":
Возвращает расширение файла, формат которого соответствует графическому классу
GraphicClass. Так, если передать в качестве параметра класс
TBitmap, то функция вернет строку
'BMP';
Для диалогов предусмотрено несколько событий, которые программист может обработать самостоятельно. Первые три — достаточно тривиальные:
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 пошли
по пути модернизации внешнего вида стандартных диалогов, добавив к ним справа
панель для отображения внешнего вида открываемых (записываемых) картинок. Можно
пойти дальше и добавить таким же образом и свои элементы управления.
Для изменения размеров диалогового окна нужно
отыскать среди входящих в его состав компонентов панель picturePanel
(так назвали ее разработчики Borland) и увеличить ее высоту. Следует также поменять
и размеры родительских окон. Поскольку они не являются компонентами Delphi (стандартные
диалоги являются составными частями Windows) для этой цели используются функции
API GetWindowRect
И SetWindowPos.
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, а во-вторых, — к модификации
стандартных диалогов. На его базе можно создать диалоги открытия аудиозаписей,
документов и других специализированных видов файлов.