Автор: Пользователь скрыл имя, 06 Февраля 2013 в 01:52, аттестационная работа
Класс TList -- универсальный список. Он представляет собой массив нетипированных указателей и поэтому годится для хранения набора любых, в том числе разнотипных, данных и объектов. При добавлении/удалении в список данные не создаются и не уничтожаются -- эта обязанность лежит на программисте. Приведем доступные ему методы и свойства класса.
const
InfoServer = 'infoserv';
TimeConversation = 'TimeTopic';
ServerTimeItem = 'Timeltem' ;
SCannotStart = 'Cannot start conversation';
procedure TFormI.TimeButtonClick(Sender: Tobject);
begin
if TimeButton.Down then begin
if not TimeConv.SetLink(InfoServer, TimeConversation) or not TimeConv.OpenLink then begin
MessageDIg(SCannotStart, mtError, [mbOk], 0) ;
TimeButton.Down := False;
end end else TimeConv.CloseLink;
end;
procedure TPormI.TimeConvOpen(Sender: TObject);
begin
ClientTimeItem.DDEConv := TimeConv;
ClientTimeItem.DDEItem := ServerTimeItem;
end;
Организация данных у клиента сходна с той, которая принята на сервере:
(Pb) property Text: String;
(Pb) property Lines: TStrings;
Свойство Text является подмножеством Lines и содержит первую строку этого набора.
Когда изменяются данные на сервере, эти изменения отражаются в TDDEClientItem. В этот момент происходит событие:
(Pb) property OnChange: TNotifyEvent;
В обработчике этого события и нужно предусмотреть реакцию на изменение данных -- пересчет формулы, обновление текста и т. п.
Принципы работы с DDE отражены в примере DDEINFO. Приложение-сервер запускает таймер и с установленным периодом формирует текстовые строки со значением текущего времени и количества свободной памяти. Эти строки являются элементами данных соответствующих тем DDE. На форме клиента находятся две кнопки -- Time и Memory. При их нажатии происходит попытка входа в соответствующий контакт. Если она была успешной, кнопка утапливается, и на ней отображается время или количество свободной памяти. При отжатии кнопки контакт разрывается.
Дополнительные компоненты
На странице Samples Палитры компонентов содержатся компоненты, использование которых расширяет возможности разработчика при проектировании пользовательского интерфейса приложения. Одновременно они служат примером создания собственных компонентов пользователя, поскольку такая возможность предусмотрена разработчиками Delphi. Ее полезность доказана опытом использования: практически каждая конференция в глобальных сетях, посвященная Delphi, наводнена самыми разнообразными самодельными компонентами, среди которых встречаются полезные и остроумные вещи.
Компонент TGauge
TObject-^TPersistent->
Модуль GAUGES
Страница Палитры компонентов Samples
Этот компонент моделирует индикатор, табло которого отображает значение некоторой величины в процентах. Например, можно в динамике отображать процент выполнения протекающего в приложении процесса (копирование или загрузку данных).
Стиль компонента задается свойством
(pb) property Kind: TGaugeKind;
TGaugeKind= (gkText, gkHorizontalBar, gkVerticalBar, gkPie, gkNeedle) ;
gkText -- текстовый вывод величины в процентах;
gkHorizontalBar -- горизонтальное заполнение;
gkVerticalBar -- вертикальное заполнение;
gkPie -- отклонение "стрелки спидометра";
gkNeedle -- заполнение сектора окружности.
Остальные свойства приведены в таблице:
(Pb) property Color; |
Определяет цвет панели компонента. Играет роль только при стилях gkPie, gkNeedle. |
(ру property ForeColor: TColor; |
Определяет цвет указателя текущего значения. |
(№) property BackColor: TColor; |
Определяет цвет указателя фона. |
(Pb) property MinValue: Longint; |
Определяет минимальное значение шкалы измерения. |
(pb) property MaxValue: Longint; |
Определяет максимальное значение шкалы измерения. |
(Pb) property Progress: Longint; |
Определяет абсолютное текущее значение индикатора. |
(Ro) property PercentDone: Longint ; |
Содержит значение в процентах (по отношению к MaxValue). |
(Pb) property ShowText: Boolean; |
Задает видимость цифр текущего значения на табло индикатора. |
Procedure AddProgress(Value: |
Используется для динамического изменения текущего значения. Value -- добавляемое значение. |
Компонент TCalendar
TObject^TPersistent^
-->TCustomControl--"TCustomGr id--"ТСа lends r
Модуль CALENDAR
Страница Палитры компонентов Samples
Компонент представляет собой календарь. Текущие год, месяц и день в календаре соответственно задаются свойствами:
J property Year: Integer;
property Month: Integer;
property Day: Integer;
Внешний вид его определяется свойствами:
(Pb) property GridLineWidth;
-- толщина разграничивающих линий;
(Pa property Color;
-- цвет панели компонента.
День, с которого начинается отображение недели, определяется свойством:
(Pb) property StartOfWeek: TDayOfWeek;
TDayOfWeek = 0..6 ;
О определяет неделю, принятую в англоязычных странах (первый день недели -- воскресенье), 1 задает более привычный порядок -- с понедельника. Следующие значения последовательно смещают начало недели дальше.
Свойство
(pVl property UseCurrentDate: Boolean;
возвращает True в случае совпадения текущих дат компонента и системных часов компьютера.
Свойство
property CalendarDate: TDateTime;
содержит текущую дату в формате TDataTime. Все даты текущего месяца размещаются в векторном свойстве:
(Ro) property CellText[ACol, ARow: Integer]: string;
Методы
procedure NextMonth;
procedure NextYear;
procedure PrevMonth;
procedure PrevYear;
соответственно увеличивают или уменьшают на единицу значение текущего месяца или года. Метод
procedure UpdateCalendar;
обновляет текущую дату календаря.
Компонент TColorGrld
TObject->TPersistent->
-"TCustomControl->TColorGrid
Модуль COLORGRD
Страница Палитры компонентов Samples
Компонент предназначен для выбора основного (передний план) и фонового цветов из шестнадцатицветной палитры. Текущее значение основного цвета отмечается на палитре символами FG (foreground), фонового цвета -- символами BG (background). Если они совпадают, показываются символы FB. Выбор основного цвета при работе компонента осуществляется нажатием левой кнопки мыши, фонового -- правой. Видимость символов fg и bg задается свойствами:
(pb) property PoregroundEnabled: Boolean;
(РЬ) property BackgroundEnabled: Boolean;
Но даже если свойства ForegroundEnabled и BackgroundEnabled выключены, свойство:
(Pb) property ClickEnablesColor: Boolean;
в значении True устанавливает режим обязательного показа символов FG и FB при выборе нового цвета.
При смене цвета вызывается событие OnChange. Текущие номера цветов в таблице устанавливаются свойствами:
property Foregroundlndex: Integer;
(Pb) property Backgroundlndex: Integer;
Их значения при выполнении приложения можно получить из свойств:
^Ro) property ForegroundColor: TColor;
(Ro) property BackgroundColor: TColor;
Порядок расположения ячеек цветовой таблицы в компоненте задается свойством:
(Pb) property GiidOrdering: TGridOrdering;
TGridOrderinci = ,gol6xl, go8x2, go4x4, go2x8, golxl6);
Использование интерфейса OLE
Значение, которое придается сегодня внедрению интерфейса OLE, трудно переоценить. Фирма Microsoft извещает о том, что на получение логотипа "Windows 95 Compatible" будут сертифицированы только те приложения, которые имеют средства работы с OLE.
Разъяснять суть механизмов OLE с точки зрения пользователя здесь не имеет смысла; кратко опишем их с точки зрения программиста.
В создаваемый вами документ могут быть добавлены данные, созданные другим приложением: формулы, таблицы, графические файлы и т. п. Такие данные, рассматриваемые вместе с приложением, которое умеет их обрабатывать, будем называть объектом OLE, а такое приложение -- сервером OLE. Дословный перевод аббревиатуры OLE означает "внедренные и связанные объекты". Разница между внедрением и связыванием состоит в том, где и как размещаются данные, представляющие объект. Внедренный объект хранится в самом документе и является его составной частью. Для связанного объекта хранится только ссылка на данные, которые могут находиться в другом документе или в другой части этого документа. Каждый из способов имеет свои достоинства и недостатки. Наличие внедренных объектов увеличивает размер документа, зато он обладает переносимостью, и несколько пользователей могут работать с ним одновременно. Когда объект связан, то он занимает гораздо меньше места, но такой документ нужно переносить вместе с данными, на которые он ссылается. Каждое изменение данных влечет за собой изменение во всех объектах, которые ссылаются на эти данные.
Возможности реализации OLE в рассматриваемой версии Delphi ограничены только поддержкой приема объектов. Тем, кто хочет создавать серверы OLE, придется подождать выпуска 32-разрядной версии Delphi, где возможности этого программного интерфейса будут реализованы в большей мере. В VCL имеется специальный компонент-контейнер, в который можно помещать данные OLE. Вставлять объекты в контейнер можно как на стадии разработки приложения, так и на стадии его выполнения. Здесь будет рассмотрен только последний вариант.
Компонент TOLEContainer
TObject->TPersistent-"
*>TCustomControl-"
Модуль TOCTRL
Страница Палитры компонентов System
Загрузить объект OLE в контейнер можно тремя путями:
* созданием нового объекта или связыванием с уже существующим через вызов диалога InsertOLEObjectDIg;
* "перетаскиванием" объекта из сервера OLE в форму, содержащую контейнер, с помощью Drag&Drop;
* помещением объекта из буфера обмена (посредством вызова диалога PasteSpecialDIg).
Общим является то, что во всех трех способах формируется поначалу определенная структура данных (типа BOLEInitInfo). Она является "визитной кар
точкой" сервера OLE и его данных. Как только значение указателя на нее присваивается свойству контейнера property PInitInfo: Pointer;
происходит процесс внедрения или связывания объекта. При этом может произойти активизация сервера. Несколько примеров использования этого свойства рассмотрено ниже.
Сразу после присвоения значения свойству контейнера PInitInfo потребность в созданной структуре отпадает. Ее можно уничтожить при помощи процедуры:
procedure ReleaseOLEInitInfо(PInitInfo: Pointer);
Контейнер, однако, продолжает хранить содержащуюся в этой структуре информацию. Для доступа к ней нужно воспользоваться свойством:
property Initlnfo: BOLEInitInfo;
Тип BOLEInitInfo не документирован Borland и его описание здесь не приводится.
Ниже будут подробнее рассмотрены все три варианта загрузки объекта OLE в контейнер.
Создание нового объекта
Этот способ применяется, когда вы хотите добавить к приложению данные из уже существующего файла, снабдив их возможностями одного из серверов OLE, который "умеет" с этими данными работать. Данные можно внедрить или связать. Можно также внедрить новый (пустой) объект, в этом случае сразу будет вызван сервер. В основе этого способа лежит вызов функции:
function InsertOLEObjectDIg(Form: TForm; HelpContext: THelpContext;
var PInitInfo: Pointer): Boolean;
Она инициализирует диалог, позволяющий создать новый объект OLE. В случае успешного окончания диалога создается структура типа BOLEInitInfo. Пример этого достаточно прост:
procedure TFormI-BitBtnIClick(Sender: Tobject);
var Thelnfo : Pointer;
begin
if InsertOLEObjectDIg(Self, 0, Thelnfo) then begin
OLEContainerI.PInitInfo := Thelnfo;
ReleaseOLEInitInfо(Thelnfo) ;
end;
end;
Регистрация форматов
Два других способа получения данных OLE -- через буфер обмена или посредством "перетаскивания" -- требуют выполнения предварительных операций.
Для того чтобы форма могла играть роль получателя данных, нужно сделать следующее:
1. Объявить ее как приемник объектов OLE.
2. Связать с ней список форматов буфера обмена, получение которых будет поддерживаться.
Обе этих задачи решает вызов функции:
procedure RegisterFormAsOLEDropTarget(
const Fmts: array of BOLEFormat);
Здесь Form -- регистрируемая форма, Fmts -- массив форматов. Каждый элемент массива форматов является записью типа:
BOLEFormat = Record
fmtid: Word;
fmCName: array [0.. 31] of char;
fmtResultName: array[0..31] of char;
fmtMedium: BOLEMedium;
fmtIsLinkable: Bool;
end;
Поля записи имеют следующее назначение:
fmtid -- идентификатор формата буфера обмена. Это может быть как стандартный формат (CF_TEXT, CF_BITMAP и др.), так и специальный формат для объектов OLE. В этом случае он должен быть зарегистрирован при помощи функции RegisterClipboardFormat (см. пример ниже);
fmtName -- имя, которое появится в списке форматов диалога PasteSpecialDIg;
fmtResultName -- имя формата, которое появится в комментариях внутри этого диалога. Например, если значение fmtResultName равно "Bitmap", то пользователь получит примерно следующий комментарий: "Inserts the contents of the Clipboard into your document as Bitmap";
fmtIsLinkable -- показывает, могут ли данные в этом формате играть роль связанных объектов.
fmtMedium -- константа, идентифицирующая тип данных в буфере обмена. Связана со значением поля fmtid следующим образом:
BOLEMEDSTREAM |
Связанные объекты OLE. |
BOLEMEDSTORAGE |
Внедренные объекты OLE. |
BOLEMEDMFPICT |
Метафайлы (CF.METAFILEPICT). |
BOLEMEDGDI |
Графические данные (CF BITMAP, CF SYLK, CF DIP, CF TIFF, CF DIB, CF PALETTE, CF PENDATA, CFJUFF, CFWAVE). |
BOLEMEDHGLOBAL |
Все прочие данные. |
Специально для вычисления значения поля fmtMedium по формату данных предусмотрена функция:
function BOLEMediumCalc(frntid: Word): BOLEMedium;
Заполнить требуемый массив можно, например, так:
var
FEmbedClipFmt, FLinkClipFmt: Word;
Fmts: array[0..2] of BOLEFormat;
FEmbedClipFmt := RegisterClipboardFormat('
FLinkClipFmt := RegisterClipboardFormat('Link Source');
Fmts[0].fmtid := FEmbedClipFmt;
Fmts[0].fmtMedium := BOLEMediumCalc(FEmbedClipFmt);
Fmts[0].fmtIsLinkable := False;
StrPCopy (Fmts[0].fmtName, '%s');
StrPCopy (Fmts[0].fmtResultName, '%s');
Fmts[l].fmtid := FLinkClipFmt;
Fmts[l].fmtMedium := BOLEMediumCalc(FLinkClipFmt);
Fmts[1].fmtIsLinkable := True;
StrPCopy (Fmts[1].fmtName, '%s');
StrPCopy (Fmts[1].fmtResultName, '%s');
Fmts[2].fmtid := CF_BITMAP;
Fmts[2].fmtMedium := BOLEMediumCalc(CF_BITMAP);
Fmts[2].fmtIsLinkable := False;
StrPCopy (Fmts[2].fmtName, 'Bitmap');
StrPCopy (Fmts[2].fmtResultName, 'Device-dependent Bitmap');
RegisterFormAsOLEDropTarget(
Для упрощения создания элемента списка форматов есть функция:
function OLEFormat(AFmtId: Word; AName, AResultName: String;
AIsLinkable: Bool): BOLEFormat;
Она заполняет структуру типа BOLEFormat переданными ей параметрами и возвращает указатель на нее. Приведенный выше фрагмент кода можно преобразовать так:
FEmbedClipFmt := RegisterClipboardFormat С Embedded Object');
FLinkClipFmt := RegisterClipboardFormat ('Link Source');
RegisterFormAsOLEDropTarget (Self,
[OLEFormat (PEmbedClipFmt, '%s', '%s', FALSE), OLEFormat (PLinkClipFmt, '%s', '%s', TRUE)]) ;
Для тех случаев, когда регистрацию формы и установку списка возможных форматов нужно произвести раздельно, предусмотрены процедуры: