Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_po_OOP_Delphi.docx
Скачиваний:
54
Добавлен:
31.05.2015
Размер:
2.39 Mб
Скачать

11. Построение пользовательского интерфейса

Основные понятия:

VCL (Visual Components Library) – библиотека визуальных компонент.

CLX(Component Library for Cross Platform - библиотека компонентов кроссплатформенного программирования)

Компонент – любой класс, порожденный от класса TComponent. То есть это класс, имеющий опубликованные свойства, объект которого содержится в палитре компонентов. Это так называемые “строительные кирпичики” для создания приложений. TComponent является предком всех компонентов VCL-библиотеки. Владельцем всех компонентов, расположенных в форме, является сама форма. Владельцем всех форм является приложение.

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

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

property Owner: TComponent;

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

Предком класса TComponent служит класс TPersistent: в нем реализован виртуальный метод Assign – основа для копирования объектов VCL.

Элементы управления

Потомком класса TComponent является класс TControl – элемент управления Windows. Все что видит пользователь в клиентской области формы, порождено от класса TControl. Таким образом, потомки TControl являются визуальными компонентами. Этот класс уже обладает “поведением” – в нем предусматривается реакция на основные события. Но объект класса TControl не является окном Windows и не может получить фокус ввода.

Понятие окна Windows инкапсулировано в потомке TControl – классе TWinControl. Такой компонент получает соответствующий атрибут – дескриптор окна.

В библиотеке VCL классы TControl и Twincontrol являются предками всех компонентов, которые должны уметь отображать себя на экране при помощи графических средств операционной системы. В библиотеке CLX(Component Library for Cross Platform - библиотека компонентов кроссплатформенного программирования) аналогичную задачу выполняют классы TControl и TWidgetControl. Они обеспечивают работоспособность компонентов-потомков в качестве экранных объектов widget. Widget —класс, объекты которого должны менять свое поведение в зависимости от состояния. Большинство свойств и методов классов Twincontrol и TWidgetControl совпадают. Однако есть и различия, вызванные особенностями графических интерфейсов операционных систем Windows и Linux.

Благодаря созданию специального варианта библиотеки VCL, которая называется Component Library for Cross Platform (CLX) стала возможной кроссплатформенная разработка приложений в Delphi Большинство свойств и методов компонентов VCL и CLX идентичны. А существующие различия вызваны необходимостью использования специальных объектов - widget и особенностями представления визуальных элементов в Linux.

Каждый визуальный компонент унаследует от класса TControl такие важные свойства как:

1) property BoundsRect: TRect; - определяет прямоугольник, содержащий координаты верхнего левого и правого нижнего углов компонента в системе координат клиентской области родительского элемента. Можно установить положение и размер компонента, изменяя координаты верхнего левого угла, длины и ширины методом:

procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer; virtual;

пример: Button1.SetBounds(150,150,200,80);

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

2) property Left: Integer;

3) property Top: Integer;

4) property Width: Integer;

5) property Height: Integer;

6) property Visible: Boolean; - определяет возможность видимости элемента.

7)property Align: TAlign; - определяет выравнивание компонента относительно границ родителя. Может принимать такие значения как alNone – выравнивание отсутствует, alTop, alLeft, alRight, alBottom – выравнивание происходит по соответствующей стороне родителя. alClient – занимает все пространство клиентской области родителя.

Форма, работа с формами (стр 349)

Приложения, создаваемые в среде Delphi, как, впрочем, и любые другие Windows-программы, сосредоточены вокруг форм – окон приложения.

Форма – контейнер, в котором размещаются другие визуальные и невизуальные компоненты.

К каждой форме в Delphi привязываются 2 файла. Один из них, с типичным для языка Pascal расширением pas, является программным модулем (unit), описывающим класс формы и все ее компоненты. Другой файл, имеющий тип dfm, описывает расположение всех компонент на форме, их свойства, а так же параметры самой формы – т.е. все то, что можно настроить при помощи инспектора объектов.

Пример файла dfm:

object Form1: TForm1

Left = 192

Top = 114

Width = 870

Height = 600

Caption = 'Form1'

Color = clBtnFace

Font.Charset = DEFAULT_CHARSET

Font.Color = clWindowText

Font.Height = -11

Font.Name = 'MS Sans Serif'

Font.Style = []

OldCreateOrder = False

PixelsPerInch = 96

TextHeight = 13

object Button1: TButton

Left = 296

Top = 168

Width = 75

Height = 25

Caption = 'Button1'

TabOrder = 0

end

end

Что касается другой составляющей формы – файла pas, который мы, собственно и видим в паре с ее визуальным представлением, то в нем хранится описание формы как класса, а так же подпрограмм, типов и переменных, не являющихся частью формы как таковой, но по тем или иным соображениям помещенных в данный файл. Применительно к той же самой форме, содержащей лишь одну простую кнопку, pas-файл для нее будет выглядеть так, как представлено на листинге 11.2.

Листинг 11.2. Программный файл формы

unit pro2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

end.

Класс TForm

Итак, ключевую часть в программном модуле, описывающем то или иное окно приложения, является класс, описывающий это самое окно. Для форм в VCL, подобно другим компонентам, определен специальный класс – TForm. Однако следует учитывать, что на самом деле, класс TForm никогда напрямую не используется в приложениях: вместо него мы всегда будем работать с классами, порожденными на его основе.

Hierarchy

TObject

TPersistent

TComponent

TControl

TWidgetControl

TFrameControl

TScrollingWidgetControl

TCustomForm

TForm

Форма (в примере) описывается как класс TForm1, а кнопка (Button1) является свойством этого класса. Если добавить к кнопке обработчик события (например, для OnClick), то этот обработчик автоматически получит имя Button1Click и будет определен как метод класса TForm1.

unit pro2;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

end;

end.

Создаваемый класс, описывающий форму, унаследует все свойства и методы от базового класса TForm, который происходит от класса TCustomForm, добавляя к нему лишь методы, связанные с многооконным интерфейсом (MDI). Класс TCustomForm, в свою очередь, происходит от класса TScrollingWinControl, являющегося прямым потомком уже упоминавшегося ранее класса TWinControl, опять-таки, имеющего по отношению к своему родителю лишь одно глобальное отличие – возможность прокрутки содержимого

Обычно сколько-нибудь сложное приложение содержит несколько форм. Первая из введенных в приложение форм считается главной. Главная форма отличается от прочих рядом свойств. Во-первых, именно этой форме передается управление в начале выполнения приложения. Во-вторых, закрытие пользователем главной формы означает завершение выполнения приложения.

Для каждой автоматически создаваемой формы Delphi добавляет в файл программы соответствующий оператор ее создания методом CreateForm. Это можно увидеть, если выполнить команду Project | View Source и просмотреть появившийся файл проекта .dpr. Он может, например, содержать следующие выполняемые операторы:

Application.CreateForm(TForml, Forml);

Application.CreateForm(TAboutBox, AboutBox);

Application.Run;

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

В нужный момент форму можно сделать видимой методами Show или Show-

Modal. Последний метод открывает форму как модальную. Это означает, что

управление передается этой форме и пользователь не может передать фокус другой форме данного приложения до тех пор, пока он не закроет модальную форму. Методы Show и ShowModal можно применять только к невидимой в данный момент форме. Если нет уверенности, что форма в данный момент видима, то прежде, чем применять эти методы, следует проверить свойство Visible формы. Например:

if (not Form2.Visible) then Form2.ShowModal;

Методом Hide форму в любой момент можно сделать невидимой.

Необходимо помнить, что для выполнения методов CreateForm, Show, ShowModal, Hide и вообще для обмена любой информацией между формами модули соответствующих форм должны использовать друг друга. Например, если форма (Б) модуле "Unitl должна управлять формой (В) модуле Unit2, то в оператор uses модуля Unitl должно быть включено имя второго модуля Unit2. А если к тому же форма в модуле Unit2 должна пользоваться какой-то информацией, содержащейся в модуле Unitl, то в оператор uses модуля Unit2 должно быть включено имя первого модуля Unitl. В этом случае, если операторы uses в обоих модулях расположены в разделах Interface, возникнут проблемы с недопустимыми круговыми ссылками (circuior unit reference) и компилятор выдаст соответствующую ошибку.

От недопустимых круговых ссылок можно избавиться; если разомкнуть их, поместив один или оба оператора uses в раздел implementation. Впрочем, проще не включать имена модулей приложения в операторы uses вручную, а использовать команду File Use Unit, которая автоматизирует этот процесс и гарантирует отсутствие круговых ссылок.

Закрыть форму можно методом Close.

Модальные формы (353)

Открытие форм как модальных используется в большинстве диалоговых окон. Модальная форма приостанавливает выполнение вызвавшей ее процедуры до тех пор, пока пользователь не закроет эту форму. Модальная форма не позволяет также пользователю переключить фокус курсором мыши на другие формы данного приложения, пока форма не будет закрыта. Т.е. пользователь должен выполнить предложенные ему действия прежде, чем продолжить работу. Модальной может быть сделана любая форма, если она делается видимой методом ShowModal. Если та же самая форма делается видимой методом Show, то она не будет модальной.

Поведение модальной формы определяется ее основным свойством ModalResult. Это свойство доступно только во время выполнения приложения. При открытии формы методом ShowModal сначала свойство ModalResult равно нулю. Как только при обработке каких-то событий на форме свойству ModalResult будет присвоено положительное значение, модальная форма закроется. А значение ее свойства ModalResult можно будет прочитать как результат, возвращаемый методом ShowModal. Таким образом, программа, вызвавшая модальную форму, может узнать, что сделал пользователь, работая с этой формой, например, на какой кнопке он щелкнул.

В Delphi предопределены некоторые константы, облегчающие трактовку ре-

зультатов, полученных при закрытии модальной формы:

Все приведенные выше пояснения значений ModalResult (кроме значений О

и 2) носят чисто условный характер. В своем приложении можно трактовать ту или иную величину ModalResult и соответствующие константы как угодно. Требуемые значения ModalResult можно задавать в обработчиках соответствующих событий в компонентах модальной формы.

Пример приложения с модальными формами заставки и запроса пароля:

  1. Создаем новое приложение. 2 формы - главная форма Form1 и форма для ввода пароля Form2.

  2. В форме Form2 разместим окно редактирования Edit1, в котором пользователь будет вводить свой пароль. Задать в свойстве PasswordChar компонента Edit символ *.

В обработчике события OnKeyDown этого компонента запишите:

if Edit1.Text='password'

then ModalResult:=6

else Close

  1. В главной форме напишем обработчик события формы OnShow:

if (Form2.ShowModal <>6)

then Close

else

begin

ShowMessage('Ваш пароль:'+Form2.Edit1.Text);

end;

ФРЕЙМЫ (Frame)

Frame — фрейм – это компонент, который представляет собой нечто среднее между панелью и формой. С формой его роднит то, что он:

  • проектируется отдельно, как самостоятельное окно

  • имеет свой модуль — файл .pas

  • имеет возможности наследования, причем даже более широкие, чем у формы, так как может наследоваться даже внутри одного приложения

  • может включаться в Депозитарий и использоваться так же, как и форма, включая наследование

С панелью фрейм роднит то, что он:

  • не является самостоятельным окном Windows и может отображаться только на форме или другом контейнере

  • имеет свойства, методы, события, подобные панели, а не форме

Таким образом, фрейм — это панель, т.е. некий фрагмент окна приложения, но способный переноситься на разные формы, в разные приложения и допускающий использование преимуществ наследования.

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

Начать проектирование нового фрейма можно командой File | New Frame или командой File | New и выбором пиктограммы Frame на странице New окна Депозитария. В обоих случаях откроется окно фрейма, подобное окну формы, а в Редакторе Кода вы увидите текст заготовки модуля фрейма:

unit Unit2;

Interface // Открытый интерфейс фрейма

{Список подключаемых модулей}

uses Windows, Messages, SysUtils, Classes, Graphics,

Controls, Forms, Dialogs;

{Объявление класса фрейма}

type

TFrame2 = class(TFrame)

{Сюда Delphi помещает объявления компонентов,

размещаемых на фрейме. Не добавляйте сюда ничего вручную}

private // Закрытый раздел класса

{Private declarations}

{Сюда могут помещаться объявления переменных, функций

и процедур, включаемых в класс фрейма, но не доступных

для других модулей}

public // Открытый раздел класса

{Public declarations}

{Сюда могут помещаться объявления переменных, функций

и процедур, включаемых в класс фрейма и доступных для

других модулей}

end;

{Сюда могут помещаться объявления типов, констант,

переменных, функций и процедур, к которым будет

доступ из других модулей, но которые не включаются

в класс фрейма. Они будут едины для всех объектов

фреймов}

implementation // Реализация модуля

{$R *.DFM}

{Сюда могут помещаться предложения uses, объявления

типов, констант, переменных, к которым не будет

доступа из других модулей. Они будут едины для

всех объектов фреймов. Тут же должны быть реализации

всех объявленных в разделе interface функций и

процедур, а также могут быть реализации любых

дополнительных, не объявленных ранее функций и процедур}

end.

ОБЗОР КОМПОНЕНТОВ БИБЛИОТЕКИ VCL DELPHI

КОМПОНЕНТЫ ВВОДА И ОТОБРАЖЕНИЯ ТЕКСТОВОЙ ИНФОРМАЦИИ.

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

К основным компонентам ввода и редактирования текста относятся TEdit, TMemo, TRichEdit.

Компонент TEdit – предназначен для ввода и редактирования однострочных текстов. Его предком является компонент TCustomEdit. Некоторые из его свойств и методов:

property Text: TCaption; - содержит текст компонента

procedure Clear; virtual; - позволяет очистить весь текст в редакторе.

Основное свойство – text. Этот компонент не имеет собственного кода, в нем опубликованы свойства его предка TCustomEdit.

Hierarchy

TObject

TPersistent

TComponent

TControl

TWidgetControl

TCustomEdit

TEdit

Компонент TMemoпредставляет собой многострочный редактор текста. Этот компонент снабжен функциями, свойственными большинству редакторов. В нем предусмотрены типичные комбинации горячих клавиш Ctrl-C — копирование выделенного текста в буфер обмена Clipboard (команда Copy), Ctrl-X - вырезание выделенного текста в буфер Clipboard (команда Cut), Ctrl-V — вставка текста из буфера Clipboard в позицию курсора (команда Paste), Ctrl-Z — отмена последней команды редактирования.

В компоненте Memo формат (шрифт, его атрибуты, выравнивание) одинаков

для всего текста и определяется свойством Font. Если вы сохраните в файле текст, введенный или отредактированный пользователем, то будет создан текстовый файл, содержащий только символы и не содержащий элементов форматирования. При последующем чтении этого файла в Memo формат будет определяться текущим состоянием свойства Font компонента Memo, а не тем, в каком формате ранее вводился текст.

Hierarchy

TObject

TPersistent

TComponent

TControl

TWidgetControl

TFrameControl

TCustomMemo

TMemo

Основное свойство – lines.

property Lines: TStrings;

Содержимое редактора представлено как объект, содержащий текст в виде набора строк, который хранится в свойстве lines.

Загрузка в окно Memol текста из файла может осуществляться командой

Memol.Lines.LoadFromFile('text.txt');

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

Memol.Lines.SaveToFile('text.txt');

Компонент TRichEdit - работает с текстом в обогащенном формате RTF. При желании изменить атрибуты вновь вводимого фрагмента текста вы можете задать свойство SelAttributes. Это свойство типа TTextAttributes, которое в свою очередь имеет подсвойства: Color (цвет), Name (имя шрифта), Size (размер), Style (стиль) и ряд других.

Hierarchy

TObject

TPersistent

TComponent

TControl

TWinControl

TCustomEdit

TCustomMemo

TCustomRichEdit

TRichEdit

Компоненты TListBox и TCheckListBox – отображают списки строк и позволяют пользователю выбрать в них нужную строку. Основное свойство обоих компонентов, содержащее список строк, — Items, имеющее TStrings. Заполнить его во время проектирования можно, нажав кнопку с многоточием около этого свойства (Items) в окне Инспектора Объектов. Во время выполнения работать с этим свойством можно, пользуясь свойствами и методами класса TStrings Clear, Add, Get и другими.

В компоненте TListBox имеется свойство MultiSelect, разрешающее пользователю множественный выбор в списке. Если MultiSelect = false (значение по умолчанию), то пользователь может выбрать только один элемент списка. В этом случае можно узнать индекс выбранной строки из свойства ItemIndex.

Например, следующий код проверяет выбор пользователя.

begin

if ListBox1.ItemIndex < 0

then ShowMessage('Вы не сделали свой выбор')

else ShowMessage('Ваш выбор ' + IntToStr(ListBox1.ItemIndex+1) + ': ' +

ListBox1.Items.Strings[ListBox1.ItemIndex]);

end;

По умолчанию Itemlndex = — 1. Это означает, что ни один элемент списка не выбран.

Если допускается множественный выбор (MultiSelect = true), то значение Itemlndex соответствует тому элементу списка, который находится в фокусе. При множественном выборе проверить, выбран ли данный элемент, можно проверив свойство Selected[Index: Integer] типа Boolean. Например, следующий код отображает сообщения вида «Выбрана строка ...: ...» обо всех выбранных строках.

for i:=0 to ListBox1.Items.Count - 1 do

if (ListBox1.Selected[i])

then

ShowMessage('Выбрана строка ' + IntToStr(i+1) + ': ' +

ListBox1.Items.Strings[i]);

КНОПКИ, ИНДИКАТОРЫ, УПРАВЛЯЮЩИЕ ЭЛЕМЕНТЫ

Управляющие кнопки Button и BitBtn

Простейшей и, пожалуй, наиболее часто используемой кнопкой является кнопка Button, расположенная на странице библиотеки Standard. Реже используется кнопка BitBtn, отличающаяся, прежде всего, возможностью отобразить на ее поверхности изображение. Большинство свойств, методов и событий у этих видов кнопок одинаковы.

Основное с точки зрения внешнего вида свойство кнопки — Caption (надпись). В надписях кнопок можно предусматривать использование клавиш ускоренного доступа, выделяя для этого один из символов надписи. Перед символом, который должен соответствовать клавише ускоренного доступа, ставится символ амперсанда &. Этот символ не появляется в надписи, а следующий за ним символ оказывается подчеркнутым. Тогда пользователь может вместо щелчка на кнопке нажать в любой момент клавишу Alt совместно с клавишей выделенного символа.

Основное событие любой кнопки — OnClick, возникающее при щелчке на ней. Именно в обработчике этого события записываются операторы, которые должны выполняться при щелчке пользователя на кнопке. Свойство Cancel, если его установить в true, определяет, что нажатие пользователем клавиши Esc будет эквивалентно нажатию на данную кнопку. Это свойство целесообразно задавать равным true для кнопок Отменить в различных диалоговых окнах, чтобы можно было выйти из диалога, нажав на эту кнопку или нажав клавишу Еsc. Свойство Default, если его установить в true, определяет, что нажатие пользователем клавиши ввода Enter будет эквивалентно щелчку на данной кнопке, даже если она в этот момент не находится в фокусе.

Все сказанное выше в равной степени относится и к Button, и к BitBtn.

Рассмотрим теперь особенности кнопки с пиктограммой BitBtn. Изображение на этой кнопке задается свойством Glyph - При нажатии кнопки с многоточием в строке свойства Glyph в Инспекторе Объектов вызывается окно открытия файла рисунка .bmp, содержащего желаемое изображение. Расположение изображения и надписи на кнопке определяется свойствами Margin, Layout и Spacing.

Если свойство Margin равно -1 (значение по умолчанию), то изображение и надпись размещаются в центре кнопки. При этом положение изображения по отношению к надписи определяется свойством Layout, которое может принимать значения: blGlyphLeft (слева, это значение принято по умолчанию), blGlyphRight (справа), blGlyphTop (вверху), blGlyphBottom (внизу).

Свойство Spacing задает число пикселов, разделяющих изображение и надпись на поверхности кнопки. По умолчанию Spacing = 4.

Группы радиокнопок — компоненты RadioGroup, RadioButton и GroupBox

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

RadioGroup — панель группы радиокнопок. А надписи кнопок и их количество определяются свойством Items, имеющим тип TStrings.

Определить, какую из кнопок выбрал пользователь, можно по свойству ItemIndex, которое показывает индекс выбранной кнопки. Индексы, как всегда в Delphi, начинаются с 0. По умолчанию Itemlndex = -1, что означает отсутствие выбранной кнопки.

Пример просмотра выбранной альтернативы: Label1.SetTextBuf(PChar(IntToStr(RadioGroup1.ItemIndex)));

Использование группы радиокнопок не всегда удобно. Его хорошо использовать, если надписи кнопок имеют примерно одинаковую длину, иначе кнопки могут быть автоматически размещены не очень красиво.

В этом случае удобно использовать RadioButton, сгруппированные панелью GroupBox. Эта панель сама по себе пустая. Ее назначение — служить контейнером для других управляющих элементов, в частности, для радиокнопок RadioButton.

Индикатор CheckBox

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

Проверять состояние индикатора можно по значению свойства Checked. Если Checked равно true, то индикатор выбран иначе Checked равно false.

Label1.SetTextBuf(PChar(BoolToStr(CheckBox1.Checked)));

КОМПОНЕНТЫ МЕНЮ

В Delphi имеется два компонента, представляющие меню: MainMenu — главное меню, и PopupMenu — всплывающее меню. Оба компонента расположены на странице Standard.

Обычно на форму помещается один компонент MainMenu. Основное свойство компонента — Items. Каждый раздел меню, т.е. каждый элемент свойства Items, является объектом типа TMenuItem, обладающий своими свойствами, методами, событиями. Основное событие раздела меню— OnClick, возникающее при щелчке пользователя на разделе или при нажатии горячих клавиш быстрого доступа. Свойство объекта TMenuItem - Caption обозначает надпись раздела (элемента меню).

ОБРАБОТКА СОБЫТИЙ КЛАВИАТУРЫ И МЫШИ

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

В компонентах Delphi определен ряд событий, связанных с мышью. Это события:

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

• Пользователь выбрал элемент в сетке, дереве, списке, выпадающем списке,

нажав клавишу со стрелкой.

• Пользователь нажал клавишу пробела, когда кнопка или индикатор были

в фокусе.

• Пользователь нажал клавишу Enter, а активная форма имеет кнопку по умолчанию, указанную свойством Default.

• Пользователь нажал клавишу Esc, а активная форма имеет кнопку прерыва-

ния, указанную свойством Cancel.

И некоторых других.

Для формы событие OnClick наступает, если пользователь щелкнул на пустом месте формы или на недоступном компоненте.

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

Во все обработчики событий, связанных с манипуляциями мыши (как и во все другие обработчики) передается параметр Sender типа TObject. Этот параметр содержит указатель на компонент, в котором произошло событие.

procedure TForm1.Button1Click(Sender: TObject);

begin

end;

Методы обработки событий прописываются в файле Unit.dfm

Например:

object Button1: TButton

Left = 200

Top = 168

Width = 75

Height = 25

Caption = 'Button1'

TabOrder = 0

OnClick = Button1Click

OnMouseMove = Button1MouseMove

end

В оконных компонентах Delphi определены три события, связанные с клавиатурой. Это события:

Последовательность событий клавиатуры при нажатии клавиш Shift-н :

(327)

РАБОТА С ПРОЦЕССАМИ И ПОТОКАМИ (стр 445)

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

Запуск из одной программы другой называется порождением дочернего процесса.

В общем случае процесс может включать в себя не один, а несколько потоков. Каждый поток — это некоторая последовательность команд, которой операционная система выделяет определенные кванты времени. Поэтому потоки выполняются как бы параллельно.

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

  1. Запуск внешней программы функцией WinExec

Самый простой способ запустить какую-то программу из своего приложения — использовать функцию WinExec. Эта функция может работать в любых версиях Windows и выполнять любые файлы.

Функция WinExec определяется следующим образом:

function WinExec(CmdLine: PChar; CmdShow: integer): integer;

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

1. Каталог, из которого загружено приложение

2. Текущий каталог

3. Системный каталог Windows, возвращаемый функцией GetSystemDirectory

4. Каталог Windows, возвращаемый функцией GetWindowsDirectory

5. Список каталогов из переменной окружения PATH

Параметр CmdShow определяет форму представления окна запускаемого приложения Windows. Чаще всего используется значение SW_RESTORE, при котором окно запускаемого приложения активизируется и отображается на экране. Если это окно в данный момент свернуто или развернуто, то оно восстанавливается до своих первоначальных размеров и отображается в первоначальной позиции.

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

Приведем примеры применения WinExec.

Оператор

WinExec('file.exe' , SW_RESTORE)-

запускает программу file.exe.

Оператор

WinExec('COMMAND.COM', SW_RESTORE);

Запускает командную строку.

  1. Порождение процесса функцией CreateProcess

Более современной, чем WinExec, является функция API Windows CreateProcess, которая и рекомендуется для 32-разрядных приложений:

function CreateProcessA(

lpApplicationName: PAnsiChar;

lpCommandLine: PAnsiChar;

lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;

bInheritHandles: BOOL;

dwCreationFlags: DWORD;

lpEnvironment: Pointer;

lpCurrentDirectory: PAnsiChar;

const lpStartupInfo: TStartupInfo;

var lpProcessInformation: TProcessInformation): BOOL;

Функция порождает новый дочерний процесс и его первый поток (нить).

В рамках этого процесса выполняется указанный файл lpApplicationName с командной строкой lpCommandLine. Впрочем, параметр lpApplicationName может быть равен nil, а имя выполняемого модуля в этом случае должно быть первым элементом командной строки, задаваемой параметром lpCommandLine. Сам выполняемый модуль может быть любого вида: 32-разрядным приложением Windows, приложением MS-DOS и т.п. Однако если из приложения Windows создается процесс MS-DOS, то параметр lpApplicationName должен быть равен nil, а имя файла и его командная строка включаются в lpCommandLine. Так что, как правило, чтобы не ошибиться, проще всегда задавать lpApplicationName = nil и помещать всю информацию в lpCommandLine.

Если путь к файлу не задан, то файл ищется в тех же каталогах и в той же последовательности, которая рассматривалась для функции WinExec.

Параметры lpProcessAttributes, lpThreadAttributes, lpEnvironment, bInheritHandles определяют наследование дочерним процессом свойств родительского процесса. Если не вдаваться в подробности наследования, то можно первые три из этих параметров задавать равными nil, а последний — false.

Параметр lpCurrentDirectory указывает на строку, определяющую текущий каталог дочернего процесса. Если параметр равен nil, текущий каталог совпадает с родительским.

Параметр dwCreationFlags определяет флаги, задающие характеристики создаваемого процесса. Эти флаги определяют тип процесса (например, CREATE_NEW_CONSOLE — создание нового консольного приложения), характер взаимоотношения с родительским процессом и класс приоритета нового процесса:

Параметр IpStartupInfo указывает на структуру типа TStartupInfo, определяющую основное окно дочернего процесса. Из всех полей этой структуры обязательным для заполнения является только cb — размер в байтах данной структуры. Остальные можно не заполнять, что обеспечит вид окна по умолчанию.

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

Если функция CreateProcess успешно выполнена, она возвращает ненулевое

значение (true). Если произошла ошибка — возвращается 0 (false).

Пример:

var

Form1: TForm1;

StartInfo:TStartupInfo;

ProcInfo:TProcessInformation;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);

begin

FillChar(StartInfo, Sizeof(StartInfo),#0);

StartInfo.cb:=sizeof(StartInfo);

if not CreateProcess(nil,'command.com',nil,nil,false,

Create_new_console or high_priority_class, nil,

nil,Startinfo,procInfo)

then

ShowMessage('no') else ShowMessage('yes');

end;

  1. Функция ShellExecute (стр 450)

  1. Организация многопоточных приложений (стр. 471)

Класс TThread

Одним из способов создания приложения с несколькими потоками является использование компонента типа TThread. TThread — это абстрактный класс, позволяющий создать в приложении отдельную нить выполнения (поток). Для того чтобы ввести TThread в свое приложение, надо выполнить команду File | New Other и в открывшемся окне Депозитария на странице New выбрать пиктограмму Thread Object.

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

unit Unit3;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]