Методические указания для проведения практических и лабораторных занятий по дисциплине "Программирование на языке высокого уровня" для студентов специальностей 220200 Автоматизированные системы обработки информации и управления

Вид материалаМетодические указания

Содержание


Объект Application
Компонент TScreen
Подобный материал:
1   2   3   4   5   6   7   8   9   10   11

Объект Application

TApplication = class(TComponent)

На уровне методов и свойств этого компонента осуществляется управление выполняемым приложением. Он отсутствует в Палитре компонентов, и все его свойства должны изменяться из программы.

Поводов для обращения к TApplication может быть два. Во-первых, это полу­чение информации о приложении, общей для всех ее форм. Во-вторых, это управление процессом выполнения приложения и входящими в него формами. Эти методы тесно связаны с Windows, и работа с многими из них требует определенного опыта.

К информационным могут быть отнесены следующие свойства:

property Title: string;

Имя приложения. Под этим именем оно отображается в TaskManager, TaskBar и т. п. По умолчанию равно имени проекта.

(Ro) property ExeName: string;

Имя файла с расширением .ЕХЕ, содержащего приложение (то же самое имя возвращает функция ParamStr(0)).

property Icon: TIcon;

Значок приложения. Первоначально, при за­пуске, значок загружается из ресурса с именем MAINICON в файле ресурсов проекта.


Теперь рассмотрим методы и свойства в последовательности, соответствующей "жизненному циклу" приложения. При запуске на выполнение Application сна­чала создает и инициализирует формы приложения при помощи метода:

procedure CreateForm(FormClass: TFormClass; var Reference);

Параметр Reference будет указывать на созданный экземпляр формы класса FormClass.

С обращений к этому методу начинается код, содержащийся в файле с расширением .DPR; при этом в нем создаются только те формы, которые содержатся в списке Auto-Create Forms в опциях проекта. Метод работает таким образом, что в случае, если указатель на главную форму равен nil, то созданная форма становится главной. Из этого следует, что главной всегда будет первая из создаваемых форм. Указатель на нее описан в свойстве:

(Ro) property MainForm: TForm;

Здесь нужно сделать специальную оговорку. Помимо главной и других форм у приложения есть еще одно — невидимое — окно. Именно оно является по-настоящему главным и именно в нем обрабатываются все сообщения Windows, управляющие состоянием приложения. Его дескриптор доступен в свойстве:

property Handle: HWnd;

После создания всех форм метод

procedure Run;

запускает цикл обработки сообщений главной формы приложения. Его код очень прост и выглядит следующим образом:

procedure TApplication.Runt-begin

AddExitProc(DoneApplication);

if FMainForm о nil then begin

FMainForm.Visible := True;

repeat

HandleMessage until Terminated;

end;

end;

Вызываемый в нем метод

procedure HandleMessage;

извлекает следующее сообщение из очереди и передает его на обработку сле­дующим образом:

procedure TApplication.HandleMessage;

begin

if not ProcessMessage then Idle;

end;

Метод ProcessMessage ищет нужный обработчик сообщения и передает ему управление. Назначение метода Idle поясняется ниже.

О поступлении сообщения оповещает вызов обработчика события:

property OnMessage: TMessageEvent;

TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object;

Используя обработку OnMessage, программист может переопределить обра­ботку любого (или любых) сообщений (кроме WM_QUIT и сообщений системы оперативной подсказки). Для этого, выполнив внутри метода необходимые действия, в параметре Handled нужно вернуть True. Тогда сообщение не поступит в функцию окна приложения. Необходимо быть крайне осторожным, подменяя системные обработчики сообщений.

Существует другой способ перехвата сообщений. Для этого нужно написать метод, имеющий следующий rim

TWindowHook = function (var Message: TMessage): Boolean of object;

и зарегистрировать его в качестве перехватчика сообщений приложения с помощью метода:

procedure HookMainWindowfHook: TWindowHook);

Если одна из процедур-перехватчиков типа TWindowHook в цепочке вернет True, это будет означать, что сообщение обработано.

Когда необходимость в перехвате сообщений отпадет, созданный вами метод нужно исключить из списка при помощи вызова метода:

procedure UnhookMainWindow(Hook: TWindowHook);

Если сообщений в очереди нет, то может быть выполнена "фоновая" работа, предусмотренная программистом. Для этого нужен обработчик события, ко­торое генерируется в этой ситуации внутри метода Idle в HandleMessage:

property Onldle: TIdleEvent;

TIdleEvent = procedure (Sender: TObject; var Done: Boolean) of object;

Обработчик должен вернуть признак потребности в последующих событиях Onldle в булевом параметре Done. Если "все сделано" и он присваивает Done значение True, то приложение переходит в режим ожидания сообщения и обработчик не вызывается до возникновения следующей ситуации отсутствия сообщений в очереди. Если возвращается значение False, метод будет вызы­ваться все время при отсутствии сообщений.

Пример обработки сообщений OnMessage и Onldle имеется на дискете (название проекта MOVLINES). Их использует программа сохранения экрана, которая вызывается системой по истечении некоторого времени, в обработчике Onldle она рисует на экране линии и прекращает работу, когда обработчик OnMessage получает сообщение от мыши или клавиатуры.

Как видно из приведенного кода метода Run, сообщения обрабатываются вплоть до установки флага:

(Ro) property Terminated: Boolean;

Такой флаг устанавливается при получении собщения WM_QUIT. Используя его, можно вставить свои действия на завершающем этапе (после окончания обработки сообщений перед вызовом деструктора Application). Свойство это доступно только для чтения, поэтому завершить приложение можно, вызвав метод

procedure Terminate;

который и посылает сообщение WM_QUIT. Для обработки сообщений пред­назначен также метод

procedure ProcessMessages;

который возвращает управление тогда, когда обработаны все сообщения в очереди. Пример:

procedure TApplication.ProcessMessages;

begin

while ProcessMessage do;

end;

Одна или более форм приложения могут иметь статус fsStayOnTop, то есть постоянно находятся поверх других форм (не имеющих этого статуса). Для того, чтобы на время отключить его действие, применяется пара методов:

procedure NormalizeTopMosts;

— отключает статус;

procedure RestoreTopMosts;

— восстанавливает его.

Эти методы могут быть полезными, когда необходимо вывести информацию поверх формы со статусом fsStayOnTop. В самом объекте Application они вызываются соответственно при деактивизации/актнвизации приложения, сво-рачивании/разворачивании главной формы.

Активизация и деактивизация происходят тогда, когда пользователь или приложение осуществляют переключение между задачами Windows. Приложение способно отслеживать эти моменты. При активизации и деактивизации приложения возникают события:

property OnActivate: TNotifyEvent;

property OnDeactivate: TNotifyEvent;

Текущее состояние активности можно узнать в свойстве:

property Active: Boolean;

События, возникающие соответственно при сворачивании и восстановлении главной формы приложения, также относятся к объекту Application:

property OnMinimize: TNotifyEvent;

property OnRestore: TNotifyEvent;

Для программного выполнения таких операций есть два метода:

procedure Minimize;

procedure Restore;

У Application есть метод:

procedure BringToFront;

У формы также есть метод с этим названием, который показывает форму поверх остальных и активизирует ее. Отличие этих методов в том, что Form. BringToFront активизирует вызвавшую его форму, а метод Application.BringToFront — ту форму, которая была активна последней.

Во время выполнения приложения могут возникать исключительные ситуации. При их возникновении обработку осуществляет метод:

procedure HandleException(Sender: TObject);

Стандартная обработка подразумевает вызов метода

procedure ShowException(E: Exception);

который отображает диалоговое окно с именем приложения в заголовке и сообщением об ошибке (содержащемся в параметре — объекте Е класса Exception).

Стандартную обработку можно перекрыть (во всех случаях, кроме обработки исключительной ситуации EAbort), определив обработчик события:

property OnException: TExceptionEvent;

TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;

Целый ряд методов управляет системой помощи. Для ее нормального функционирования в первую очередь необходимо, чтобы было определено имя файла помощи в свойстве:

property HelpPile: string;

Если оно определено, то вызов помощи можно осуществить тремя видами запросов, которьм соответствуют методы:

function HelpContext(Context:

Осуществляет вызов помощи по заданному контексту.

function HelpJump(const JumpID: string): Boolean-

Осуществляет вызов помощи для контекстной строки JumpID. Например, вызов Application.HelpJump('HelpJump ') даст подсказку по этой функции.

function HelpConunand (Command: Word; Data: Longint): Boolean;

Посылает системе помощи команду Command с параметром Data. Для описания типов команд см. справку по процедурам WinHelp API Windows.


Все функции возвращают True, если файл Help определен, и произошел вызов приложения WinHelp.

Если вы хотите перехватить обращение к справочной системе, то необходимо написать обработчик события:

property OnHelp: THelpEvent;

THelpEvent = funcс ion(Command: Word; Data: Longint;

var CallHelp: Boolean):Boolean of object;

В нем вы можете предусмотреть предоставление собственной помощи пользо­вателю. Результат True функции означает успех (помощь предоставлена). Если после обработки события по-прежнему нужно вызвать систему помощи Windows (через WinHelp), то в параметре CallHelp нужно вернуть True.

Метод

function MessageBox(Text, Caption: PChar; Flags: Word): Integer;

содержит вызов стандартного диалогового окна с тем же названием и назна­чением.

Если вы хотите использовать в составе Delphi и вызывать из форм приложения диалог, созданный с помощью других средств программирования, то дескриптор такого диалога должен быть присвоен свойству:

property DialogHandle: HWnd;

Подробные правила работы с этим свойством описаны в документации раз­работчика компонентов Delphi.

Наконец, упомянем о системе оперативной подсказки. У приложения имеется собственный текст подсказки, определяемый свойством:

property Hint: string;

В отличие от подсказок для других компонентов, он не отображается при остановке мыши. Его содержимое обычно передается строке состояния.

Целый ряд методов и свойств объекта, отвечающих за реализацию системы оперативной подсказки, подробно описан в соответствующем разделе. Поэтому они здесь только перечисляются:

property OnHint: TNotifyEvent;

property ShowHint: Boolean;

property HintPause: Integer;

property OnShowHint: TShowHintEvent ;

property HintColor: TColor;

procedure CancelHint;


3.12. Системные объекты - TClipboard и TSreen

TClipboard = class(TPersistent)

Объект TClipboard представляет программисту интерфейс с буфером обмена (Clipboard) Windows. При включении в проект модуля CLIPBRD этот гло­бальный объект создается автоматически и доступен приложению в течение всего цикла.

Методы открытия и закрытия буфера обмена

procedure Open;

procedure Close;

вызываются во всех остальных методах TClipboard, поэтому программист редко нуждается в обращении к ним. В объекте ведется счетчик числа обращений к этим функциям, так что соответствующие функции API Windows вызываются только при первом открытии и последнем закрытии.

Очистка содержимого буфера (для всех форматов) производится вызовом ме­тода:

procedure Clear;

О доступных форматах можно узнать, пользуясь следующими свойствами и методами:

(Ro) property FormatCount: Integer;

— содержит число форматов в буфере на данный момент;

(Ro) property Formats[Index: Integer]: Word;

— содержит их полный список. Функция

function HasFormat(Format: Word): Boolean;

проверяет, содержится ли в данный момент формат Format.

Волею разработчиков различаются способы обмена графической и текстовой информацией через буфер обмена. Рассмотрим их независимо.

Через вызов метода

procedure Assign(Source: TPersistent);

в буфер обмена помещаются данные классов TGraphic, точнее, его потомков — классов TBitmap (формат CF.BITMAP) и TMetaffle (CF.METAFILEPICT). Данные класса TIcon не имеют своего формата и с TClipboard несовместимы.

Допустимо и обратное: в TClipboard есть специальные (скрытые) методы для присваивания содержимого объектам классов TPicture, TBitmap и TMetafile. Допустимы выражения вида:

My Image.Picture.Assign(Clipboard) ;

Для работы с текстом предназначены методы:

function GetTextBuf(Buffer: PChar; BufSize: Integer): Integer;

— читает текст из буфера обмена в буфер Buffer, длина которого ограничена значением BufSize. Функция возвращает истинную длину прочитанного текста;

procedure SetTextBuf(Buffer: PChar);

— помещает текст из Buffer в буфер обмена в формате CF_TEXT;

Свойство

property AsText: string;

соответствует содержимому буфера обмена в текстовом формате CF_TEXT

(приведенному к типу string). При отстутствии там данных этого формата возвращается пустая строка.

Методы

function GetAsHandle(Format: Word): THandle;

procedure SetAsHandle(Format: Word; Value: THandle);

соответственно читают и пишут данные в буфер в заданном формате Format. При чтении возвращается дескриптор находящихся в буфере данных (или О при отсутствии). Для дальнейшего использования эти данные должны быть скопированы. При записи данные, передаваемые в параметре Value, в даль­нейшем должны быть уничтожены системой (а не программой пользователя).

Два метода предназначены для обмена компонентами через буфер обмена (в специально зарегистрированном формате CF_COMPONENT):

function GetComponent(Owner, Parent: TComponent): TComponent;

procedure SetComponent(Component: TComponent);

Они используются составными частями среды Delphi.


Компонент TScreen

TScreen = class(TComponent);

Этот компонент представляет свойства дисплея, на котором выполняется приложение. Поскольку экземпляр данного класса только один (он создается системой при запуске приложения), то большинство методов и свойств имеют информационный характер и недоступны для записи.

Курсор приложения, общий для всех форм, доступен через свойство:

property Cursor: TCursor;

Часто приходится включать "песочные часы" на время выполнения длительной операции. Лучше всего это сделать следующим образом:

Screen.Cursor := crHourglass;

try

(Calculations...} finally

Screen.Cursor := crDefault;

end;

Возвращает дескриптор курсора с индексом Index свойство:

property Cursors[Index: Integer]: HCURSOR;

Няпомшм, что шщексы зарегистрированных курсоров лежат в диапазоне от -17 (crSQLWait) до 0 (crDefault).

Рассмотренный ниже фрагмент кода при инициализации формы заносит имена всех зарегистрированных в системе курсоров в список ListBoxl. Затем, при выборе элемента списка, устанавливается соответствующий ему курсор.

procedure TFormI.FormCreate(Sender: TObject);

type

TGetStrPunc = function(const Value: string): Integer of object;

var

CursorNames: TStringList;

AddValue: TGetStrPunc;

begin

CursorNames := TStringList.Create;

AddValue := CursorNames.Add;

GetCursorValues(TGetStrProc(AddValue));

ListBoxl.Items.Assign(CursorNames) ;

end;

procedure TFormI-ListBoxlClick(Sender: TObject);

begin Screen.Cursor :=

StringToCursor(ListBoxl.Items[ListBoxl.Itemlndex]);

end;

Имена всех установленных в системе шрифтов помещаются в список, опреде-ленньш в свойстве:

(Ro\ property Fonts: TStrings;

Компонент сообщает неизменяемые свойства экрана (в данном видеорежиме). Его размеры в пикселах определены в свойствах:

(ro) property Height: Integer;

(Ro) property Width: Integer;

Число точек на дюйм дисплея содержится в свойстве:

(Ro) property PixelsPerInch: Integer;

При появлении каждая форма заносит себя в список форм глобального объекта Screen. Два (доступных только для чтения) свойства дают информацию об этом списке:

J property Forms[Index: Integer]: TForm;

property FormCount: Integer;

Нужно иметь в виду, что в списке указаны только формы, открытые приложением, а не все окна системы.

Следующие два свойства указывают на активную в данный момент форму и ее активный элемент управления:

(Ro) property ActiveControl: TWinControl;

(ro) property ActiveForm: TForm;

При их изменении генерируются соответственно события:

property OnActiveControlChange: TNotifyEvent;

property OnActiveFormChange: TNotifyEvent;


3.13. Файлы инициализации

TIniFile = class(TObject)

Этот класс — надстройка над файлом инициализации (его расширение .INI) и процедурами чтения и записи в него значений разных типов. Обратите внимание, что все читаемые и записываемые строки имеют тип string (а не pChar, как в стандартном API Windows).

Конструктор класса

constructor Create(const FileName: string);

создает объект, соответствующий файлу инициализации с именем FileName. В дальнейшем оно доступно через свойство:

(Ro) property FileName: string;

Файл инициализации состоит из строк вида "параметр=значение". Такие строки сведены в секции; имена секций заключаются в квадратные скобки.

Методы класса, посредством которых осуществляется работа с файлом, приве­дены в таблице:

function ReadStringfconst Section, Ident, Default: string): string;

procedure WriteString(const

Возвращает строку из секции Section, являющуюся значением параметра Ident. При отсутствии секции или параметра возвращается строка Default.

Записывает (или перезаписывает) в секцию Section строку Ident=Value.

function Readlnteger(const Section, Ident: string; Default: Longint): Longint;




Возвращает значение параметра Ident из секции Section, преобразованное в целое число. В случае любых ошибок возвра­щается значение Default.

Преобразует Value в строку и записывает его в качестве значения Ident в секции Section.

Работает как Readlnteger, но преобразует значение параметра в булеву переменную.

procedure Writelnteger(const Section, Ident: string; Value: Longint);

function ReadBool(const Section, Ident: string; Default: Boolean): Boolean;

procedure WriteBool(const Section, Ident: string; Value: Boolean);

procedure ReadSection(const Section: string; Strings: TStrings) ;

procedure ReadSectionValues(const Section: string; Strings: TSCrings) ;

Работает, как Writelnteger, но преобразует булево значение Value к виду '0'/"Г.

Считывает в набор строк Strings секцию с именем Section. Максимальная длина секции — 8191 байт.

Считывает из секции Section в набор строк Strings только значения параметров.

procedure EraseSection(const Section: string);

Удаляет всю секцию с именем Section.


3.14. Печать данных из приложения

Практически каждое приложение, работающее в Windows, имеет набор воз­можностей, позволяющих печатать те или иные данные. В состав Delphi вклю­чен специальный модуль — PRINTERS, в котором описан класс TPrinter, инкап­сулирующий интерфейс печати Windows.

TPrinter = class(TObject)

Свойства и методы этого класса позволяют разработчику реализовать доста­точно широкий набор возможностей для печати из приложения. Экземпляр объекта TPrinter с именем Printer создается автоматически при запуске приложения, если в его состав включен соответствующий модуль.

Обычно перед началом печати какого-либо документа из приложения необ­ходимо проверить и при необходимости переустановить стандартные парамет­ры. Этот процесс может быть как автоматическим (проверка и переопределение по умолчанию из программы), так и интерактивным (при помощи стандартных диалоговых окон PrintDialog и PrintSetupDialog).

Информацию обо всех инсталлированных в системе принтерах содержит список свойства:

(Ro) property Printers: TStrings;

Свойство доступно только при вьшолнении приложения. Информация о том, какой принтер из списка является текущим, содержится в свойстве:

property Printerlndex: Integer;

Оно возвращает порядковый номер принтера в списке. Значение -1 использу­ется для идентификации принтера, установленного по умолчанию.

Метод

procedure GetPrinter(ADevice, ADriver, APort: PChar;

var ADeviceMode: THandle);

возвращает параметры текущего принтера, используя для его идентификации значение свойства Printerlndex.

Метод

procedure SetPrinter(ADevice, ADriver, APort: PChar;

ADeviceMode: THandle);

проверяет, инсталлирован ли в системе принтер с заданными параметрами. В случае успеха этот принтер становится текущим, в случае неудачи инсталлируется новый принтер. Использование этих двух методов не рекомен­дуется справочным руководством, так как по мнению разработчиков вполне достаточно свойств Printers и Printerlndex. Авторы также рекомендуют приме­нять эти методы только подготовленньм разработчикам, если им необходимо работать с драйверами принтеров.

Свойство

(Ro) property Fonts: TStrings;

содержит список шрифтов, поддерживаемых текущим принтером. Свойство доступно только при вьшолнении приложения.

Расположение листа бумаги определяется свойством:

property Orientation: TPrinterOrientation;

TPrinterOrientation = (poPortrait, poLandscape) ;

Свойство доступно только при выполнении приложения. Высоту и ширину листа бумаги содержат свойства:

(Ro) property PageHeight: Integer;

(R property PageWidth: Integer;

Свойство

property Title: string;