Автор: Пользователь скрыл имя, 06 Февраля 2013 в 01:52, аттестационная работа
Класс TList -- универсальный список. Он представляет собой массив нетипированных указателей и поэтому годится для хранения набора любых, в том числе разнотипных, данных и объектов. При добавлении/удалении в список данные не создаются и не уничтожаются -- эта обязанность лежит на программисте. Приведем доступные ему методы и свойства класса.
Работая над приложением в Delphi, вы никогда не будете создавать объекты класса TGraphic, но переменной этого типа вы можете присваивать указатель на любой из классов-потомков. Метод
procedure Assign(Source: TPersistent);
переопределяет одноименный метод предка, позволяя полиморфное присваивание графических объектов (см. ниже).
Загрузку и выгрузку графики в поток осуществляют методы
procedure LoadFromStream(Stream: TStream);
procedure SaveToStream(Stream: TStream);
а загрузку и выгрузку в файл:
procedure LoadFromFile(const Filename: string) ;
procedure SaveToFile(const Filename: string);
Эти методы создают соответствующий файловый поток и затем вызывают методы LoadFromStream/SaveToStream.
Два метода осуществляют взаимодействие с буфером обмена:
procedure LoadFromClipboardFormat(
APalette: HPALETTE);
procedure SaveToCiipboardPormat(var AFormat: Word; var AData:
THandle; var APalette: HPALETTE);
Здесь AFormat -- используемый графический формат; AData и APalette _ данные и палитра (если она требуется). Потомок должен иметь свой формат и уметь обрабатывать данные, представленные в нем. Свойство
(Ro) property Empty: Boolean;
устанавливается в True, если графический объект пуст (в него не загружались данные).
Высота и ширина графического объекта:
property Height: Integer;
property Width: Integer;
Для каждого дочернего типа значения этих свойств вычисляются своим способом. Наконец, свойство
property Modified: Boolean;
показывает, модифицировался ли данный графический объект. Это свойство устанавливается в True внутри обработчика события OnChange.
Класс TPicture
TPicture = class(TPersistent)
Класс-надстройка над TGraphic, точнее -- над его потомками. Он содержит поле Graphic, которое может содержать TBitmap, TIcon и TMetafile. Предназначение TPicture -- управлять вызовами соответствующих методов, скрывая при этом хлопоты с определением типа и детали их реализации.
Кроме того, на уровне TPicture определены возможности по регистрации и использованию других -- определенных пользователем -- классов графических объектов, порожденных от TGraphic. Доступ к графическому объекту осуществляется посредством свойства:
property Graphic: TGraphic;
Если графический объект ilmcct один из трех предопределенных типов, то к нему можно обратиться и как к одному из свойств:
property Bitmap: TBitrr.ap;
property Icon: TIcon ;
property Metafile: TMetafile;
Если в поле Graphic хранился объект одного класса, а затребован -- другого, то прежний объект уничтожается, а вместо него создается пустой объект нужного класса. Если же вы описали свой класс (допустим, TDIB), то к его методам и свойствам следует обращаться так:
(Graphic as TDIB).My Property := MyValue;
Перечислим остальные методы и свойства:
procedure LoadFromFile(const Filename: scring); |
Анализирует расширение имени файла FileName и, если оно известно (зарегистрировано), то создается объект нужного класса и вызывается его метод LoadFromFile. В противном случае возникает исключительная ситуация EInvalidGraphic. Стандартными расширениями являются .ICO, .WMF и .BMP. |
procedure SaveToFile(const Filename: string); |
Сохраняет графику в файле, вызывая соответствующий метод объекта Graphic. |
procedure LoadFromClipboardFor-r.ac iAFcr.T.at: Word; AData: T'Handle; APalette: HPALETTE) ; |
Если формат AFormat найден среди зарегистрированных, то AData и APalette передаются для загрузки одноименному методу соответствующего объекта. Стандартно зарегистрированных форматов два: битовое изображение CF BITMAP и метафайл CFMETAFILEPICT. |
procedure SaveToClipboardFormat(var AFormat: Word; var AData: THar.dle; var APalette: H?ALE"T3!; |
Сохраняет графику в буфере обмена, вызывая метод объекта Graphic. |
procedure Assign(Source: TPersistent) ; |
Метод Assign переписан таким образом, чтобы присваиваемый объект мог быть класса как TPicture, так и TGraphic или любого его потомка. Кроме того, параметр Source может быть равен nil -- в этом случае поле Graphic очищается с удалением прежнего объекта. |
class function SupportsClipboardPormat( |
Метод класса возвращает True, если формат AFormat поддерживается классом TPicture (зарегистрирован в системе). Напомним, что методы класса можно вызывать через ссылку на класс, без создания экземпляра объекта. |
class procedure RegisterFileFormat(const AExtension, ADescription:
string; AGraphicClass: TGraphicClass); class procedure RegisterClipboardFormat( |
Предназначены для создателей новых графических классов. Они позволяют зарегистрировать формат файла и буфера обмена и связать их с созданным классом -- потомком TGraphic, который умеет читать и записывать информацию в этом формате. |
(^) property Width: Integer; (ко) property Height: Integer- |
Ширина и высота картинки. Те же, что и у Graphic. |
property OnChange: TNotifyEvent; |
Это событие вызывается при изменениях графического объекта. |
Все три разновидности графических объектов имеют свои системы кэширования. Это означает, что на один реально существующий в системе (и занимающий долю ресурсов!) дескриптор могут одновременно ссыпаться несколько объектов. Реализуется такое связывание через метод Assign. Выражение
Iconi.Assign(Icon2) ;
означает, что два этих объекта разделяют теперь один значок.
Более простым является кэширование для TIcon и TMetafile, которые умеют только отображать себя и не предназначены для редактирования (создатели Delphi считают, что дескриптор графического объекта дается программисту не для того, чтобы ковыряться в нем на уровне двоичных кодов). Гораздо сложнее устроен механизм кэширования для TBitmap, который имеет свою канву для рисования.
Внутреннее представление информации в графических объектах двоякое -- она может храниться как поток типа TMemoryStream (в него загружается содержимое соответствующего файла), как область памяти с дескриптором (структура которой зависит от типа графического объекта) и одновременно в двух этих видах, содержимое которых автоматически синхронизируется. Поэтому будьте готовы к тому, что загрузка изображения потребует вдвое большего объема памяти -- особенно это актуально для больших картинок.
Кого-то может удивить отсутствие объявленных методов рисования вроде Draw у TIcon, TMetafile и TBitmap. Такие методы есть, но они недоступны. Все
рисование должно осуществляться через вызовы методов Draw и StretchDraw канвы, содержащей графику, ибо канва несет тот контекст, в котором должна осуществляться операция. Рассмотрим предопределенные графические классы.
Класс TMetafile
TMetafile = class(TGraphic)
Инкапсулирует свойства стандартного метафайла Windows. В нем перекрываются методы Assign, LoadFromStream, SaveToStream, LoadFromClipboardFormat, SaveToClipboardFormat. В буфер обмена объект помещает свое содержимое в формате CF_METAFILEPICT. Помимо общих, класс имеет свойства:
г г | |
property Handle: HMETAFILE; |
Дескриптор метафайла. |
property Inch: Word; |
Число точек на дюйм в координатной системе метафайла. Связано с установленным режимом отображения. |
Класс TIcon
TIcon = class(TGraphic)
Инкапсулирует значок Windows.
Не пытайтесь изменить размеры значка -- они постоянны (равны GetSystemMetrics(SM_CXICON) и GetSystemMetrics(SM_CYICON)), и при попытке присвоить новые значения возникает исключительная ситуация EInvalidGraphicOperation. Значок нельзя также читать и писать в буфер обмена, так как в Windows нет соответствующего формата. В этом классе перекрываются методы класса TGraphic: Assign, LoadFromStream и SaveToStream. Дополнительно также определены:
' ^ *"* | |
property Handle: HICON; |
Дескриптор значка. |
function ReleaseHandle: HICON; |
Метод "отдает" дескриптор -- возвращает его значение, обнуляя ссылку на него в объекте. |
Класс TBitmap
TBitmap = class(TGraphic)
Класс соответствует битовой карте, зависимой от устройства (Device -- dependent bitmap, DDB). В нем перекрываются методы Assign, LoadFromClipboardFormat, LoadFromStream, SaveToClipboardFormat, SaveToStream. Объект взаимодействует с буфером обмена в формате CF_BITMAP.
Канва битовой карты доступна через свойство:
(roi property Canvas: TCanvas;
Обратите внимание на то, что другие потомки TGraphic канвы не имеют. С ее помощью можно рисовать на поверхности изображения.
Дескрипторы битовой карты и ее палитры доступны как свойства:
property Handle: HBITMAP;
property Palette: HPALETTE;
Два метода
function ReleaseHandle: HBITMAP;
function ReleasePalette: HPALETTE;
возвращают дескрипторы битовой карты и палитры и после этого обнуляют соответствующие поля, т. е. как бы "отдают" дескрипторы пользователю.
При любом внешнем обращении к дескриптору битовой карты и любой попытке рисовать на ее канве, разделение одной картинки несколькими объектами прерывается, и объект получает свою отдельную копию содержимого дескриптора. Для этого есть методы:
procedure Dormant ;
-- выгружает изображение в поток и уничтожает дескрипторы битовой карты и палитры,
procedure Freelmage;
-- "освобождает" дескриптор битовой карты для дальнейшего использования и внесения изменений. Это означает, что если на данный дескриптор есть ссылки, то он дублируется; поток очищается.
Битовая карта может быть монохромной и цветной, что определено свойством:
property Monochrome: Boolean;
Значение True соответствует монохромной битовой карте. При его изменении происходит преобразование содержимого к требуемому виду.
"Фоновый" цвет битовой карты:
(Ro) property TransparentColor: TColor;
Это тот цвет, который можно отменить в операции BrushCopy, чтобы она выглядела прозрачной. Для монохромной карты этот цвет -- белый.
Функции для работы с графикой
В модуле GRAPHICS сосредоточен целый ряд полезных функций:
function GraphicFilter(GraphicClass: TGraphicClass): string; |
Эту функцию удобно использовать вместе с диалогами открытия и закрытия файла. Для заданного класса GraphicClass она вернет строку, которую сразу можно присвоить свойству Filter диалога. Например, для TBitmap она вернет строку 'Bitmaps (*.BMP)|*.BMP'. |
function GraphicExtensionfGraphicClass: TGraphicClass): string; |
Возвращает строку, содержащую расширение, которое встречается у файлов в формате GraphicClass. Например, GraphicExtension(TIcon) равно строке 'ICO'. |
function ColorToRGB(Color: TColor): Longint; |
Преобразует значение типа TColor в формат RGB. |
function ColorToIdent(Color: Longint; var Ident: string): Boolean; function IdentToColor(const Ident: string; var Color: Longint):Boolean; |
Функции взаимного преобразования цвета в строку с его названием (определенным в модуле GRAPHICS). Например, ColorToIdent(clWhite, AString) присвоит AString значение 'clWhite'. В случае неуспеха возвращается False; |
function ColorToString(Color: Tcolor): string; function StringToColorfS: string): TColor; |
Назначение аналогично двум предыдущим функциям. При отсутствии цвета Color в списке предопределенных цветов возвращается строка с его значением в шестнадцатиричном формате. При отсутствии цвета с именем S (в том же списке) делается попытка преобразовать строку в число, в случае неудачи возникает исключительная ситуация. |
procedure GetColorValues(Proc: TGetStrProc); |
Производит вызов определенной пользователем процедуры Proc для всех имеющихся в списке цветов. В качестве параметра в такую процедуру передается строка с именем цвета. Эта процедура используется в примере MOVLINES на прилагаемой к книге дискете. |
Для преобразования битовой карты из зависимого от устройства формата DDB в независимый (DIB) предназначены две функции:
| |
procedure GetDIBSizes(Bitmap: HBITMAP; var InfoHeaderSize: Integer; var ImageSize: Longint); |
Возвращает размер заголовка изображения и размер самого изображения. Значение InfoHeaderSize равно размеру структуры TBitmapInfoHeader плюс, при необходимости, размеру палитры (каждый элемент которой TRGBQuad занимает 4 байта). В ImageSize возвращается количество байт, которое нужно отвести для получения изображения в формате DIB. |
function GetDIBfBitmap: HBITMAP; Palette: HPALETTE; var Bitmaplnfo; var Bits): Boolean; |
Преобразует DDB (определенную через Bitmap и Palette) в DIB. Заголовок помещается в Bitmaplnfo, а сами данные -- в Bits. |
Описание компонентов VCL
После знакомства с общими принципами работы компонентов перейдем к их предметному рассмотрению. В этом разделе описаны все элементы Палитры компонентов, сгруппированные по функциональному назначению. Вы встретите здесь и компоненты, не входящие в Палитру; как правило, они являются предками других компонентов, важными для понимания.
Для каждого из компонентов приводятся все методы и свойства, которые доступны программисту, работающему с этим компонентом, то есть описанные как public и published (в т. ч. недокументированные). Мы попытались проиллюстрировать некоторые неочевидные вещи хотя бы коротким фрагментом кода. В развернутом виде примеры использования компонентов можно найти на дискете, прилагаемой к книге.
3.2.1. Работа с меню
В приложениях, написанных на Delphi, могут быть реализованы меню двух основных видов:
* Главное меню. Такое меню принадлежит форме и отображается вместе с ней под ее панелью заголовка. Если в приложении несколько форм, то для удобства можно объединять меню всех активных форм в одном.
* Всплывающее меню. Такое меню предусмотрено почти у всех компонентов -- элементов управления Windows. Оно возникает (всплывает) при нажатии правой кнопки мыши на этом компоненте. Предусмотрено такое меню и у формы.
Меню являются иерархическими структурами, состоящими из пунктов меню. Каждый пункт может быть выбран. Это может произойти вследствие щелчка кнопкой мыши, нажатия соответствующих клавиш на клавиатуре или вызова процедуры в программе.
На нижнем уровне лежат команды меню -- пункты, с выбором которых должна быть связана та или иная реакция приложения. Команда! объединяются в подменю. Подменю -- это пункты, выбор которых означает показ или свертывание списка входящих в него команд и подменю.
Принципы создания и работы с меню в Delphi очень просты. Каждому пункту меню соответствует свой компонент класса TMenuItem. Вы добавляете к меню новые пункты (а к форме -- новые компоненты) либо во время разработки (при помощи Конструктора меню), либо во время исполнения. При выборе пункта меню для описывающего его компонента инициируется событие OnClick, в обработчике которого и нужно предусмотреть соответствующие действия.
Компонент TMenuItem
TObject-->TPersistent--"
Модуль MENUS
В Палитру компонентов не входит
Этот компонент, который является основой системы меню в Delphi, вы не встретите в Палитре компонентов -- он входит в состав имеющихся там компонентов TMainMenu и
TPopupMenu.
Текст, содержащийся в пункте меню, определяется свойством:
(Pb) property Caption: string;
Помимо основной, он несет еще две дополнительные нагрузки. Во-первых, если в строке имеется амперсанд ('&'), то он вместе с следующим за ним символом является акселератором. Например, для строки '&File' нажатие <Alt>+<F> означает выбор этого пункта. Во-вторых, если текст состоит из