Кампоненты страницы SYSTEM

КОМПОНЕНТЫ  СТРАНИЦЫ SYSTEM

В этом разделе не описаны расположенные  на этой странице компоненты TDDEClient, TDDEClientItem, TDDEServer И TDDEServerItem.

Они рассчитаны на поддержку устаревшей технологии межпрограммного обмена данными DDE - Dynamic Data Exchange (динамический обмен данными), которая в современных программах полностью вытеснена технологией OLE.

18.4.1. TTimer - таймер

Компонент TTimer (таймер) служит для отсчета интервалов реального времени. Его свойство interval определяет интервал времени в  миллисекундах, который должен пройти от включения таймера до наступления события onTimer. Таймер включается при установке значения True в его свойство Enabled. Раз включенный таймер все время будет возбуждать события onTimer до тех пор, пока его свойство Enabled не примет значения False.

Следует учесть, что в силу специфики реализации аппаратного таймера персонального IBM-совместимого компьютера минимальный  реально достижимый интервал отсчета  времени не может быть меньше 55 миллисекунд (этот интервал называется тиком). Более того, любой интервал времени, отсчитываемый с помощью таймера, всегда кратен 55 миллисекундам. Чтобы убедиться в этом, проделайте следующий эксперимент, в котором подсчитывается среднее время между двумя срабатываниями таймера:

  • Положите на пустую форму компонент TTimer. Установите в его свойство interval любое число в диапазоне от 1 до 55 включительно.
  • Напишите такой обработчик события onTimer:

var

BegTime: TDateTime;

procedure TFormI.TimerlTimer(Sender: TObject);

var

h, m, s, ms: Word;// Переменные для декодирования времени

const

MaxTick = 10; // Количество интервалов таймера

begin

if Tag = 0 then

BegTime := Time; // Запоминаем начальное время

Tag := Tag + 1; // Наращиваем счетчик тиков

if Tag = MaxTick then

begin

Timeri.Enabled := False; // Выключаем таймер

// Декодируем значение 1 тика

DecodeTime((Time-BegTime)/MaxTick, h, m, s, ms);

// Выводим результат в заголовке окна:

Caption := IntToStr(s) + ' s ' + IntToStr(ms) + ' ms'

end

end;

Обратите  внимание на определение глобальной переменной BegTime в области видимости процедуры TimerlTimer. Необходимость нескольких (MaxTick) срабатываний для точного усреднения результата связана с тем, что системные часы также обновляются каждые 55 мс. После запуска программы в заголовке окна вы увидите строку

О s 55 ms,

в которой указывается, сколько реального  времени разделяет два соседних события OnTimer. Этот результат повторится для любых значений константы MaxTick. Если вы установите Interval таймера в  диапазоне от 56 до 110 миллисекунд, в  заголовке будет указано 110 ms И Т. Д.

18.4.1.1. Мультимедийный таймер

В ряде практически важных применений (при разработке игр, в системах реального  времени для управления внешними устройствам и т. п.) интервал 55 мс может оказаться слишком велик. Современный ПК имеет мультимедийный таймер, период срабатывания которого может быть от 1 мс и выше. Однако этот таймер не имеет компонентного воплощения, поэтому для доступа к нему приходится использовать функции API.

Общая схема его использования такова. Сначала готовится процедура обратного вызова (call back) с таким заголовком:

procedure TimeProc(uID, uMsg: UINT; dwUser, dwi, dw2: DWORD);

stdcall;

Здесь uID - идентификатор события таймера (см. ниже); uMsg - не используется; dwuser - произвольное число, передаваемое процедуре в момент запуска таймера; dwi, dw2 - не используются. Запуск таймера реализуется функцией

function timeSetEnet(uDelay, uResolution: UINT;

IpTimeProc:Pointer;

dwUser: DWORD;

fuEvent: UINT): UINT;

stdcall;

external 'winmm.dll';

Здесь uDelay - требуемый период срабатывания таймера (в мс);

uResolution - разрешение таймера; значение 0 означает, что события срабатывания  таймера будут возникать с  максимально возможной частотой; в целях снижения нагрузки  на систему вы можете увеличить  это значение; IpTimeProc - адрес процедуры обратного вызова; dwUser - произвольное число, которое передается процедуре обратного вызова и которым программист может распоряжаться по своему усмотрению; fuEvent - параметр, управляющий периодичностью возникновения события таймера: time_oneshot (0) - событие возникает только один раз через uDelay мс; time_periodic (1) - события возникают периодически каждые uDelay мс. При успешном обращении функция возвращает идентификатор события таймера или 0, если обращение было ошибочным.

Таймер останавливается, и связанные  с ним системные ресурсы освобождаются  функцией

function timeKillEvent(uID: UINT): UINT;

stdcall; external 'winmm.dll';

Здесь uID - идентификатор события таймера, полученный с помощью timeSetEvent.

В следующем примере иллюстрируется особенность использования мультимедийного таймера.

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons, ExtCtrls;

type

TfmExample = class(TForm)

Panell: TPanel;

bbRun: TBitBtn;

bbClose: TBitBtn;

edinput: TEdit;

IbOutput: TLabel;

mmOutput: TMemo;

procedure bbRunClick(Sender: TObject);

procedure FormActivate(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations

end;

var

fmExample: TfmExample;

implementation

{$R *.DFM} // Объявление экспортируемых  функций:

function timeSetEvent(uDelay, uReolution: UINT; IpTimeProc:

Pointer;

dwUser: DWORD; fuEvent: UINT): Integer;

stdcall;

external

'winmm';

function timeKillEvent (uiD: UINT): Integer;

stdcall;

external 'winmm' ;

// Объявление глобальных переменных

var

uEventID: UINT; // Идентификатор события таймера

BegTime: TDateTime; // Засечка времени

Counter: Integer; // Счетчик повторений

Delay: Word; // Период срабатывания

procedure ProcTime(uID, msg:. UINT; dwUse, dwi, dw2: DWORD);

stdcall;

// Реакция на срабатывание таймера (процедура обратного вызова)

var

h, m, s, ms: Word; // Переменные для декодирования времени

const

MaxCount = 55; // Количество повторений

begin

timeKillEvent(uEventID); // Останавливаем таймер

Counter := Counter+1; // Наращиваем счетчик

if Counter=MaxCount then // Конец цикла?

begin // - Да: декодируем время

DecodeTime((Time-BegTime)/MaxCount, h, m, s, ms);

fmExample.mmOutput.Lines.Add(

// Сообщаем результат

Format('Задано %s ms. Получено %d ms', [fmExample.edinput.Text, ms ] ) ) ;

fmExample.edinput.Text := ''; // Готовим повторение fmExample.edinput.SetFocus

end

else // - Нет: вновь пускаем таймер

uEventID := timeSetEvent(Delay,0,@ProcTime,0,1);

end;

procedure TfmExample.bbRunClick(Sender: TObject);

// Запускает таймер, edinput содержит требуемый период.

begin

// Проверяем задание периода

if edinput.Text='' then Exit;

try

Delay := StrToInt(edinput.Text)

except

ShowMessage('Ошибка ввода числа');

edinput.SelectAll;

edinput.SetFocus ;

Exit

end;

Counter := 0;

// Сбрасываем счетчик

BegTime := Time;

// Засекаем время

// Запускаем таймер:

uEventID := timeSetEvent(Delay,0,@ProcTime,О,1);

if uEventID=0 then

ShowMessage('Ошибка запуска таймера')

end;

procedure TfmExample.FormActivate(Sender: TObject);

begin

edinput.SetFocus

end;

end.

18.4.2. TPaintBox - окно для  рисования

Назначение компонента TPaintBox - дать вам простое окно с канвой для  рисования произвольных изображений. Канва содержится в свойстве Canvas компонента, графические инструменты - в свойствах Font, pen и Brush, а собственно рисование осуществляется в обработчике события OnPaint. Особенности использования этих инструментов см. в п. 16.4. Например, следующий обработчик создаст окно, показанное на рис. 18.35:

Рис. 18.35. Пример использования TPaintBox

procedure TFormI.PaintBoxIPaint(Sender: TObject);

var

X, Y: Integer;

begin

with PaintBoxl, Canvas do

begin

Brush.Color := cIRed;

Ellipse (0, 0, Width, Height);

Font.Name := 'Arial';

Font.Size := Height div 5;

Font.Style := [fsBold, fsltalic];

Font.Color := clWhite;

X := (Width - TextWidth('Delphi')) div 2;

Y := (Height - TextHeight('D')) div 2;

TextOut(X, Y, 'Delphi')

end

end;

При повторении примера положите на пустую форму компонент

TPaintBox И установите его размеры: Height = 100/ Width = 300.

18.4.3. TMediaPlayer - медиаплейер

Компонент TMediaPlayer представляет собой  набор кнопок (рис. 18.36), предназначенных  для управления различными мультимедийными устройствами (компакт-дисками, звуковыми картами и т. п.). 

Рис. 18.36. Кнопки компонента TMediaPlayer

Если ваш компьютер оснащен  звуковой картой, вставьте этот компонент в пустую форму, в его свойство FileName поместите название любого файла с расширением WAV (из каталога с: | winsows | media), установите в свойство Autoopen компонента значение True и запустите программу - после щелчка мышью по кнопке вы услышите звучание выбранного музыкального фрагмента. Как видите, использование компонента предельно просто. Он автоматически распознает тип мультимедийного устройства по расширению файла и берет на себя управление этим устройством. Разумеется, в каждый момент времени компонент может управлять лишь одним устройством, однако с помощью изменения содержимого FileName или явно с помощью свойства DeviceType программа может менять устройство, связанное с компонентом.

Каждая кнопка компонента имеет  собственное имя, позволяющее программисту сделать какую-либо кнопку невидимой  или недоступной. В следующей  таблице приводится имя и назначение каждой кнопки (под носителем информации подразумеваются файлы и физические устройства, которые могут служить источником или приемником информации).

  btStop

Останавливает запись или воспроизведение

 btNext

Позиционирует устройство на следующую  дорожку или в конец носителя информации, если устройство не имеет  дорожек

  btPrev

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

  btStep

рожек Позиционирует устройство на один блок кадров ближе к концу  носителя информации. Количество кадров в блоке

  btBack

содержится в свойстве Frames компонента Позиционирует устройство на один блок кадров ближе к началу носителя информации

btRecord

Начинает запись в носитель информации

  btEject

Освобождает устройство от носителя информации

  btPlay

Запуск

  btPause

Пауза


 

 

Свойства компонента:

property AutoEnable: Boolean; 

Разрешает/запрещает автоматическое определение доступных и запрещенных кнопок

property AutoOpen: Boolean; 

 

 

 

 

Разрешает/запрещает автоматический старт записи/воспроизведения в  момент создания формы, в которую  вставлен компонент

property AutoRewind: Boolean; 

 

 

 

 

 

 

 

 

 

 

 

 

Разрешает/запрещает автоматическую

“перемотку” носителя информации в  момент начала записи или воспроизведения.

Игнорируется, если устройство имеет  дорожки или если установлены  значения в свойства startpos и EndPos

TMPDevCaps = (mpCanStep, mpCanEject, mpCanPlay, mpCanRecord,

mpUsesWindows);

TMPDevCapsSet = set of

TMPDevCaps;

Содержит возможности устройства, связанного с компонентом mpCanStep, - может  смещать носитель на кадр вперед или  назад (устройство типа Animation, AVI Video, Digital Video, Overlay, или VCR); mpCanEject - может автоматически удалять носитель из устройства; mpCanPlay - может воспроизводить информацию; mpCanRecord - может записывать информацию; mpUsesWindows - может использовать окно для отображения процесса

property Capabilities: TMPDevCap

sSet; TMPBtnType = (btPlay, btPause, btStop, btNext, btPrev, btStep,

btBack, btRecord, btEject);

Кнопки, перечисленные в этом свойстве, будут использовать умалчиваемые цвета, не перечисленные кнопки будут черно-белыми.

TButtonSet = set of TMPBtnType;property ColoredButtons: Tbutton Set;

По умолчанию множество ColoredButtons содержит все кнопки 

property DeviceID: Word; 

Содержит Windows-идентификатор устройства, связанного с компонентом. Доступно только для чтения

TMPDeviceTypes = (dtAutoSelect,

dtAVIVideo, dtCDAudio, dtDAT,

dtDigitalVideo, dtMMMovie,

dtOther, dtOverlay, dtScanner, dtSequencer, dtVCR, dtVideodisc,

dtWaveAudio);

property DeviceType: TMPDevice

Types;

Содержит тип устройства. Если Device-

Type" dtAutoSelect, тип определяется

автоматически по расширению файла в свойстве FileName. Каждое мультимедийное устройство в момент инсталляции указывает в файле system. ini, файлы с какими расширениями оно поддерживает

property Display: TWinContrn:  

Содержит ссылку на окно для устройств, которые могут его использовать в процессе записи/воспроизведения

property DisplayRect: TRect; 

 

 

 

 

 

 

Содержит область окна Display, которое  устройство может использовать для  отображения процесса записи/воспроизведения. Для улучшения процесса отображения  рекомендуется в DisplayRect указывать умалчиваемые размеры(задаются координатами 0,0 для правого нижнего угла)

property EnabledButtons: TButtonSet; 

Содержит множество доступных  кнопок (тип TButtonSet описан выше для свойства ColoredButtons)

property EndPos: Longint; 

 

 

 

 

 

 

Содержит положение носителя информации в момент прекращения записи или воспроизведения. Переустановка значения приводит к

повторению записи или воспроизведения

property Error: Longint; 

Содержит код ошибки. Доступно только для чтения

property ErrorMessage: String; 

Содержит сообщение об ошибке. Доступно только для чтения

property FileName: String; 

 

 

Содержит имя читаемого или  записываемого файла

property Frames: Longing;  

Определяет  количество кадров, пропускаемых при  выполнении методов step или Back

property Length: Longint;  

Содержит текущую длину носителя информации. Доступно только для чтения

TMPModes = (mpNotReady,-ipStopped, mpPlaying, mpRecord-

ing, mpSeeking, mpPaused,

-npOpen) ;

property Mode: TMPModes; 

 

 

 

 

Показывает текущее состояние  мультимедийного устройства: mpNotReady - не готово; mpStopped - остановлено; mpPlaying -

воспроизводит информацию; mpRecording -записывает информацию; mpSeeking -

перемещает носитель информации;

mpPaused - Приостановлено; mpOpen - от крыто.  Доступно только для чтения

property Notify: Boolean;

PNotifyValues = (nvSuccessful,

Superseded, nvAborted, nvFailre);

Содержит True, если методы Back, Close, Eject, Next, Open, Pause, PauseOnly, Play, Previous, StartRecording, Resume, Rewind, Step и Stop будут создавать событие OnNotify

Содержит результат последней  команды, создающей событие OnNotify: nvSuccessful - выполнена успешно; nvSuperseded

property NotifyValue: TMPNotify;

Values; 

 

 

заменена другой командой; nvAborted досрочно прервана; nvFailure - завершилась ошибкой. Доступно только для чтения

property Position: Longint;  

Содержит текущую позицию носителя информации

property Shareable: Boolean; 

 

 

 

 

Разрешает/запрещает  другим компонентам

и программам использовать устройство,

связанное с данным компонентом

property Start: Longing; 

 

 

 

 

 

 

Содержит позицию от начала носителя, с которой начинается запись или  воспроизведение. Определяется в момент открытия устройства и доступно только для чтения

property StartPos: Longint; 

 

 

 

 

Содержит текущую позицию от начала носителя, с которого начинается запись или воспроизведение

TMPTimeFormats = (tfMilliseconds,

tfHMS, tfMSF, tfFrames,tfSMPTE24, tfSMPTE25, tfSMPTESO,tfSMPTE30Drop, tfBytes, tfSam ples, tfTMSF);property TimeFormat: TMPTimeFor

mats;

Определяет формат представления данных в свойствах StartPos, Length, Position, Start и Endpos (см. пояснения ниже) 

 

 

property TrackLength[TrackNum: Integer]: Longint;

Возвращает длину (в формате TimeFormat) дорожки с индексом TrackNum. Доступно только для чтения

property TrackPosition[TrackNum:

Integer]: Longint 

 

 

Возвращает стартовую позицию (в  формате

TimeFormat) дорожки С индексом TrackNum.

Доступно только для чтения

property Tracks: Longint; 

 

 

Содержит количество дорожек в  открытом

устройстве. Доступно только для чтения

property VisibleButtons: TButtonSet;  

Содержит множество видимых  кнопок (тип TButtonSet описан выше для свойства ColoredButtons)

property Wait: Boolean;  

 

 

 

 

Если содержит True, управление возвращается в программу только после завершения перехода устройства в другое состояние, связанное с методами Back, Close, Eject, Next, Open, Pause, PauseOnly, Play, Previous, StartRecording, Resume, Rewind, Step или Stop


 

 Если свойство AutoEnabie имеет значение True, компонент  автоматически по типу устройства или расширению файла и значению свойства Mode определяет, какие кнопки будут доступны пользователю. Если AutoEnabie=Faise, доступными будут только те кнопки, которые входят в множество EnabiedButtons. Множество Enabied-

Buttons игнорируется, если AutoEnable=True.

Свойство AutoRewind игнорируется, если устройство имеет дорожки или если процесс  записи/воспроизведения вызван изменением значения в свойстве StartPos или Endpos.

Положение носителя В свойствах StartPos, Length, Position, Start и EndPos В Зависимости от значения свойства TimeFormat должно интерпретироваться следующим образом (отсчет ведется от начала носителя информации):

tfMilliseconds

Миллисекунды в диапазоне от 0 до 4 294 967 295 Часы, минуты, секунды.

tfHMS

Занимают в порядке перечисления по одному байту начиная с младшего. Старшин байт Longint не используется

tfMSF

Минуты, секунды и кадры. Занимают в порядке перечисления по одному байту начиная с младшего. Старший  байт Longint не используется

tfFrames

Кадры в диапазоне от 0 до 4 294 967 295

tfSMPTE24

Часы, минуты. секунды и количество блоков по 24 кадра в секунду. Занимают в порядке перечисления по одному байту начиная с младшего

tfSMPTE25

Часы, минуты, секунды и количество блоков по 25 кадров в секунду

tfSMPTE30

Часы, минуты, секунды и количество блоков по 30 кадров в секунду

tfSMPTE30Drop

Часы, минуты, секунды и количество пропущенных блоков по 30 кадров в  секунду

tfBytes

Байты в диапазоне от 0 до 4 294 967 295

tfSamples

Количество условных блоков информации в диапазоне от 0 до 4294967295

tfTMSF

Дорожки, минуты, секунды и кадры. Занимают в порядке перечисления по одному байту начиная с младшего


 

 

Свойство TimeFormat недоступно из окна Инспектора объектов и устанавливается автоматически  при открытии мультимедийного устройства методом open. В связи с этим значения в свойствах StartPos, Position и EndPos могут устанавливаться, а в свойствах Length, Start, TrackLength И TrackPosition Становятся действительными только после вызова СPеn.

Методы компонента:

procedure AutoButtonSet(Btn: TMPBtnType); dynamic; 

 

 

Реализует разрешение/запрещение кнопок компонента при установке в свойство AutoEnable значения True Перемещает текущую  позицию в носителе информации назад  на количество кадров, содержащихся В  свойстве Frames

procedure Back;

По умолчанию вызывает обработчик события OnClick.

procedure Click(Button: TMPBtnType; var DoDefault: eoolean); dynamic ;

Предназначен для перекрытия в  потомках

procedure Close;

Закрывает связанное с компонентом  устройство

procedure DoNotify; dynamic;

По умолчанию вызывает обработчик события OnNotify. Предназначен для перекрытия в потомках

procedure Eject;

Выгружает носитель информации из устройства

procedure MMNotify(var Message: TMessage); message :MCINOTIFY;

Реализует отклик на сообщение Windows мм mcinotify. По умолчанию вызывает метод DoNotify

procedure Next;

Перемещает текущую позицию  носителя на начало следующей дорожки, а если устройство

не имеет дорожек - в конец  носителя

procedure Notification ( AComponent: TComponent; Operation:

TOperation); override;

Извещает компонент AComponent о том, что завершилась операция Operation  

procedure Open;

Открывает мультимедийное устройство

procedure Pause;  

Приостанавливает процесс воспроизведения  или записи информации. Если устройство уже было

приостановлено, восстанавливает процесс с помощью вызова метода Resume

procedure PauseOnly; 

 

 

Приостанавливает процесс воспроизведения

или записи информации. Если устройство уже было приостановлено, ничего не делает

procedure Play;  

 

 

Начинает воспроизведение с позиции StartPos, а если это свойство не установлено - с текущей позиции position

procedure PostClick (Button:

TMPBtnType); dynamic; 

Реализует отклик на событие OnPostClick. По умолчанию вызывает соответствующий  обработчик события

procedure Previous;  

 

 

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

procedure Resume; 

 

 

Восстанавливает процесс записи или  воспроизведения. Вызывается при повторном  щелчке по кнопке btPause

procedure Rewind; 

Перемещает текущую позицию  носителя к положению, определяемому  свойством Start

procedure Save; 

Сохраняет информацию в файле с  именем FileName

procedure StartRecording; 

Начинает  запись информации с текущей позиции  или позиции StartPos

procedure Step; 

 

 

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

procedure Stop;

Прекращает запись или воспроизведение  информации

Для компонента определены следующие  события:

EMPNotify = procedure (Sender:

TObject; Button: TMPBtnType;

var DoDefault: Boolean) of object;

property OnClick: EMPNotify;

Возникает после щелчка по кнопке Button компонента. Если DoDefault=True, вызывается метод, связанный с этой кнопкой 

 

 

 

 

 

 

property OnNotify: TNotifу Event;  

Возникает после завершения вызова одного из методов Back, Close, Eject, Next, Open, Pause, PauseOnly, Play, Previous, Resume, Rewind, StartRecording, Step или Stop,если свойство Notify имеет значение True

EMPPostNotify = procedure

(Sender: TObject; Button: TMPBtnType) of object;

property OnPostClick: EMPPost-Notify;

Если wait=True, событие OnPostClick возникает  только после завершения соответствующей  операции, вызванной событием OnClick, в противном случае - немедленно после OnClick


Иногда требуется воспроизвести короткий звуковой сигнал для привлечения внимания пользователя программы - например, после завершения длительного , по времени процесса- обновления данных. Стандартная для Delphi процедура без параметров Веер извлекает сигнал из системного динамика только в том случае, если ПК не оснащен звуковой картой. С другой стороны, мощные возможности компонента TMediaPlayer кажутся излишними для решения этой задачи на ПК, оснащенных звуковой картой. В этом случае может пригодиться API-функция MessageBeep, с помощью которой Windows 32 озвучивает стандартниге диалоговые окна. Единственным параметром обращения к ней является один из следующих идентификаторов стандартного звука: mb_IconAsfcerisk, mb_IconExcla-mation, mb_IconHand, mb IconQuestion, mb Ok. Обращение с параметром $ffffffff игнорирует звуковую карту и извлекает “бип” из системного динамика. Сразу после обращения функция возвращает управление программе и воспроизводит звук асинхронно.

Значительно более богатыми возможностями в этом отношении имеет, API-функция PlaySound, которая способна воспроизводить любые звуковые клипы.

Заголовок функции:

function PlaySound(pszSound: PChar; hmod: HINST;

fdw.Sound: Cardinal): .Boolean;

3десь pszSound - имя воспроизводимого  файла; hmod - указывает Экземпляр программы, если звук берется из ресурсного файла ( в противном случае содержит 0); fdwSound - параметр, уточняющий воспроизведение. Его значениями могут быть: snd_async звук воспроизводится асинхронно (функция возвращает управление сразу после обращения к ней); end loop звук воспроизводится постоянно до тех пор, пока не будет .вызвана та же функция с параметром pszSound=0;

SND_NOSTOP функция пытается  воспроизвести звук, если устройство  не занято; в противном случае  не воспроизводит ничего; если  устройство занято, но этот параметр не указан, функция прервет воспроизведение старого звука и начнет воспроизведение нового;

SND_NOWAIT если устройство  занято, функция не будет воспроизводить  новый звук;

SND_PORGE. прекращает, воспроизведение  всех звуков для данной задачи;

SND SYNC воспроизводит звук  синхронно и возвращает управление  только после полного его воспроизведения.

18.4.4. TOleContainer - контейнер  объектов OLE

Компонент является удобным контейнером  для размещения связанного или внедренного OLE-объекта. Такие объекты (таблицы, картинки, фрагменты текста и т. п.) на форме Delphi-программы выглядят как обычно или заменяются пиктограммами. Замечательной особенностью OLE-объекта является то, что его активизация (обычно с помощью двойного щелчка мышью) приводит к активизации связанной с объектом программы, которая называется OLE-сервером и которая после загрузки показывает на экране свое окно и предоставляет пользователю средства редактирования объекта.

Типичными OLE-серверами являются такие  системные утилиты, как Paint и Notepad, текстовый процессор Word, табличный процессор Excel и др.

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

  • Создайте новое приложение с пустой формой и вставьте в нее компонент TOleContainer. Установите в его свойство Align значение alСlient.
  • Сохраните проект вместе с формой в каком-либо каталоге и скопируйте средствами Windows в этот же каталог файл Athena, bmp, который находится В каталоге Images | Splash | 16color[См. замечание в начале главы.].
  • Напишите такой обработчик события OnCreate для формы Form1:

procedure TFormI.FormCreate(Sender: TObject);

begin

{Поскольку в следующем операторе  имя файла указано без маршрута  поиска, файл 'athena.bmp' должен находиться  в каталоге запуска программы!}

OleContainerI.CreateObjectFromFile('athena.bmp',False)

end; 

Запустите программу и дважды щелкните по изображению мышью. После паузы, вызванной загрузкой программы-сервера, вы увидите окно, показанное на рис. 18.37.

Рис. 18.37. Пример связывания OLE-обьекта с сервером Paint

Теперь вы можете использовать средства графического редактора Paint для редактирования изображения. Чтобы завершить редактирование, нажмите Esc - окно примет первоначальный вид, но изображение в нем сохранит все внесенные в него изменения.

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

Компонент может создавать как  связанные, так и внедренные объекты  и открывать окно сервера как  в отдельном окне, так и в  окне содержащей его программы. В  последнем случае при запуске  сервера происходит автоматическая замена опций главного меню программы с групповыми индексами 1, 3 и 5 (если они есть) на опции главного меню сервера, а также вставка в окно программы инструментальных панелей сервера. Если компонент открывается в окне программы, его свойство Align (или такое же

свойство панели, на которую он помещен) должно иметь значение alClient.

Свойства компонента:

property AllowActiveDoc: Boolean;

Разрешает/запрещает компоненту использовать специализированный интерфейс для  документов loleDocumentSite

property AllowInPlace: Boolean; 

 

 

 

 

 

 

 

 

Определяет способ размещения OLE-

сервера. Если имеет значение True и  свойство Icon=False, окно сервера с редактируемым  объектом размещается в пределах размера компонента, в противном  случае создается отдельное окно для сервера

(независимо от значения icon)

TAutoActivate = (aaManual, aaGet-

Focus, aaDoubleClick) ; property AutoActivate: TAutoActivate;

Определяет способ активизации OLE-

объекта: aaManual - активизируется путем программного вызова метода doVerb(ovShow);aaGetFocus - активизирует ся при получении фокуса ввода; aaDouble Click - активизируется при двойном щелчке мышью

property AutoVerbMenu: Boolean;

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

TBorderStyle = bsNone..bsSingle;

property BorderStyle: Tborder Style;

Определяет стиль рамки: bsNone - компонент  не имеет рамки; bsSingle - компонент  имеет рамку толщиной 1 пиксель

property CanPaste: Boolean; 

 

 

Содержит True, если буфер clipboard

содержит OLE-объект (или связь с ним), который(ую) можно вставить в компонент. Доступно только для чтения

property CopyOnSave: Boolean; 

 

 

 

 

Если содержит True, перед сохранением  объекта в файле или потоке он предварительно сжимается для  экономии размеров файла (потока). Если в компоненте размещен очень большой объект и динамической памяти может не хватить для создания временной копии сжатого объекта, в свойство следует поместить значение False

property Iconic: Boolean; 

 

 

 

 

 

 

Содержит True, если объект будет заменяться пиктограммой OLE-сервера, и False если объект изображается так, как он будет виден в окне сервера

property Linked: Boolean; 

 

 

 

 

 

 

Содержит True, если объект связан с  программой, и False - если является ее частью (внедрен в нее). Доступно только для чтения

property Modified: Boolean- 

 

 

Содержит True, если объект был изменен (в том числе заменен другим или уничтожен)

Property Newlnserted: Boolean;

Содержит True, если объект был заново создан с помощью метода insertOb jectDialog. В этом случае вызывайте DoVerb (ovShow), чтобы показать объект в окне сервера. Доступно только для чтения

property ObjectVerbs: TStrings;

Содержит список команд, которые  программа может посылать серверу. Доступно только для чтения

property OldStreamFormat: Boolean; 

 

 

В это свойство следует поместить True перед чтением объекта из файла  или потока, если объект был создан версией Delphi 1

property OleClassName: String; 

Содержит имя класса, под которым  был зарегистрирован OLE-сервер в  реестре Windows. Доступно только для чтения

property OleObject: Variant;

Содержит ссылку на OLE-объект

property OleObjectInterface:

IQleObject;

Предоставляет доступ к OLE-объекту  через интерфейс сloleObject

property PrimaryVerb: Integer; TSizeMode = (smClip, smCenter,

smScale, smStretch, smAutoSize) ;

property SizeMode: TSizeMode;

Содержит индекс умалчиваемой команды  для OLE-объектаОпределяет способ размещения OLEобъекта в контейнере: smClip - отсекаются любые части объекта, выходящие  за границы контейнера; smCenter - центрируется в контейнере; smScale - масштабируется так, чтобы целиком заполнить границы контейнера; smStretch - масштабируется так, чтобы не нарушились пропорции объекта; smAutoSize - изменяются границы контейнера, чтобы полностью отобразить объект без искажений

property SourceDoc: String;

Содержит имя файла для связанного объекта

type TObjectState = (osEmpty,

osLoaded, osRunning, osOpen, os-

InPlaceActive, osUIActive);

property State: TObjectState; 

 

 

 

 

 

 

 

 

 

 

Определяет состояние OLE-объекта: osEmpty - контейнер не содержит объект; osLoaded - объект загружен, но его сервер не запущен; osRuftning - запущен OLE-сервер; osOpen - объект открыт в отдельном окне; osinPlaceActive - объект открыт в окне контейнера, но сервер еще не заменил опции меню и инструментальные панели программы на свои (промежуточное состояние перед osOIActive); osUIActive -объект открыт в окне контейнера

property Storagelnterface: IStorage;  

Открывает доступ к интерфейсу низкого  уровня istorage, использующемуся для  обращения к API OLE

Методы компонента:

function ChangeIconDialog: Boolean; 

 

 

Создает и показывает диалоговое окно

смены пиктограммы, заменяющей изображение  объекта. Возвращает True, если пользователь закрыл окно кнопкой ОК

procedure Close; 

Закрывает сервер. Все сделанные  к этому моменту изменения в объекте автоматически сохраняются

procedure Copy;rocedure CreateLinkToFile(const FileName: String; Iconic: Boolean) ;

Создает связанный объект по имени  файла-FileName. Параметр Iconic содержит True, если изображение объекта заменяется пиктограммой

procedure CreateObject(const OleClassName: String; Iconic: Boolean) ;

Создает внедренный объект по имени  класса сервера oleClassName. Параметр iconic содержит True, если изображение объекта заменяется пиктограммой

procedure CreateObjectFromFile(const FileName: String;Iconic: Boolean) ;  

Создает внедренный объект по имени  файла FileName. Параметр iconic содержит True, если изображение объекта заменяется пиктограммой

procedure CreateObjectFromInfo

(const Createlnfo: TCreateInfo);

Создает объект по информации, хранящейся в Createlnfo (см.ниже)

procedure DestroyObject; 

Уничтожает объект без сохранения сделанных в нем изменений

procedure DoVerb(Verb: Integer);

Требует от объекта выполнить действие с индексом verb из списка objectVerbs

function GetIconMetaPict:

HGlobal;

Возвращает указатель на распределенный в куче метафайл для прорисовки пиктограммы  объекта на другой канве

function InsertObjectDialog: Boolean;  

Создает и показывает диалоговое окно создания объекта. Возвращает True, если пользователь закрыл окно кнопкой OK

procedure LoadFromFile (constFileName: String);  

Загружает объект из файла FileName. Если OldStreamFormat содержит True, загружает объект, созданный с помощью Delphi 1

procedure LoadFromStream(Stream:TStream) ;

Загружает объект из потока Stream. Если OldStreamFormat содержит True, загружает объект, созданный с помощью Delphi 1

function ObjectPropertiesDialog:Boolean;  

Создает и показывает диалоговое окно изменения свойств объекта. Возвращает True, если пользователь закрыл окно кнопкой OK

procedure Paste;  

Создает объект по данным, хранящимся в буфере Сlipboard

function PasteSpecialDialog: Boolean; 

 

 

Создает и показывает диалоговое окно специальной вставки объекта. Возвращает True, если пользователь закрыл окно кнопкой  ОК

procedure Run;  

Запускает сервер, но не активизирует объект. Активизация объекта при  запущенном сервере происходит значительно  быстрее

procedure SaveAsDocument(const

FileName: Strings-

Сохраняет объект в файле FileName с  ис

пользованием формата OLE Document

procedure SaveToFile(const FileName: String) ;  

 

 

 

 

Сохраняет объект в файле FileName. Если OldStreamFormat содержит True, объект может  быть загружен программой, созданной  с помощью Delphi 1

procedure SaveToStream(Stream:TStream);

Сохраняет объект в потоке Stream. Если OldStreamFormat содержит True, объект может быть загружен программой, созданной с помощью Delphi 1

procedure UpdateObject;

Обновляет объект, вновь загружая его из источника

procedure UpdateVerbs;

Обновляет список Objectverbs (некоторые команды могут его изменить, например, команда Play может заменить Play на Stop)


Метод СreateObjectFrominfo использует запись типа

type

TCreateInfo = record

CreateType: TCreateType;

ShowAsIcon: Boolean;

IconMetaPict: HGlobal;

ClassID: TCLSID;

FileName: String;

DataObject: IDataObject;

end;

type TCreateType = (ctNewObject, ctFromFile, ctLinkToFile, ctFromData, ctLinkFromData) ;

поля которой имеют следующие  назначения:

CreateType

Тип объекта и его источник: ctNewObject - внедренный объект, заданный идентификатором класса ClassID; ctFromFile - внедренный из файла FileName; ctLinkToFile - связанный С файлом FileName; ctFromData - внедренный по данным DataObject; CtLinkFromData -связанный сданными DataObject

ShowAsIcon

Если True, объект изображается пиктограммой

IconMetaPict

Дескриптор глобальной памяти, в  которой распределен метафайл для  пиктограммы. Если содержит 0 и showAslcon= True, используется стандартная пиктограмма  Идентификатор класса сервера

ClassID

FileName

Имя файла

DataObject

Данные для объекта


 

 

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

property OnActivate: TNoti-fyEvent;

Возникает сразу после активизации  объекта

property OnDeactivate: TNotifyEvent;

Возникает сразу после перехода объекта в неактивное состояние 

type TObjectMoveEvent = procedure( OleContainer: TOleCon-tainer; const Bounds: TRect) of object;

Возникает при перемещении или  изменении размеров объекта. Параметр Bounds содержит границы объекта в  координатах клиентской части контейнера

property On.ObjectMoye: TObjectMoveEvent; property OnResize: TNotifyEvent;

Возникает при изменении размеров окна контейнера


 

 

18.5. КОМПОНЕНТЫ  СТРАНИЦЫ DIALOGS

В состав Windows входит ряд типовых  диалоговых окон, таких как окно выбора загружаемого файла, окно выбора шрифта, окно для настройки принтера и т. д. В Delphi реализованы классы, объекты которых дают программисту удобные способы создания и использования таких окон.

Работа со стандартными диалоговыми  окнами осуществляется в три этапа.

Вначале на форму помещается соответствующий  компонент и осуществляется настройка его свойств (следует заметить, что собственно компонент-диалог не виден в момент работы программы, видно лишь создаваемое им стандартное окно). Настройка свойств может проходить как на этапе конструирования, так и в ходе прогона программы. Как и для любых других компонентов, программист не должен заботиться о вызове конструктора и деструктора диалога - эти вызовы реализуются автоматически в момент старта и завершения программы.

На втором этапе осуществляется вызов стандартного для диалогов метода Execute, который создает и показывает на экране диалоговое окно. Вызов этого метода обычно располагается внутри обработчика какого-либо события. Например, обработчик выбора опции меню

Открыть файл может вызвать метод Execute Диалога TOpenDialog, обработчик нажатия инструментальной кнопки сохранить может вызвать такой же метод у компонента TSaveDialog и т. д. Только после обращения к Execute на экране появляется соответствующее диалоговое окно. Окно диалога является модальным окном, поэтому сразу после обращения к Execute дальнейшее выполнение программы приостанавливается до тех пор, пока пользователь не закроет окно. Поскольку Execute - логическая функция, она возвращает в программу True, если результат диалога с пользователем был успешным.

Проанализировав результат Execute, программа  может выполнить третий этап - использование  введенных с помощью диалогового  окна данных - имени файла, настроек принтера, выбранного шрифта и т. д.

Проиллюстрируем сказанное следующим  примером. Создадим простую программу для просмотра содержимого текстового файла. Для этого на пустую форму поместите компонент TOpenDialog, a также кнопку TButton и редактор TMето. При работе программы щелчок по кнопке будет сигналом о необходимости загрузить в редактор новый файл. Создайте такой обработчик события OnClick этой кнопки:

procedure TForml.ButtonlClick(Sender: TObject);

var

S: String;

F: TextFile;

begin

// Настраиваем диалог на отбор текстовых файлов:

OpenDialogI.Filter :== 'Текстовые  файлы|*.txt|'+ 'Файлы Паскаля|*.pas';

// Выполняем диалог и анализируем его результат if OpenDialogI.Execute and FileExists(OpenDialogI.FileName) then

begin

// Результат успешный - пользователь выбрал файл

// Открываем файл

AssignFile(F, OpenDialogI.FileName) ;

Reset(F);

Memol.Lines.Clear; // Очищаем редактор

while not EOF(F) do // и наполняем его

begin

ReadLn(F, S) ;

Memol.Lines.Add(S)

end;

CloseFile(F)

end

end;

18.5.1. TOpenDialog и TSaveDialog - диалоги  открытия и сохранения файлов

Эти компоненты имеют идентичные свойства и поэтому рассматриваются вместе. Пример окна TOpenDialog показан на рис. 18.38.

Свойство FileName: string содержит маршрут  поиска и выбранный файл при успешном завершении диалога. Программа может  использовать это свойство для доступа  к файлу с целью читать из него данные (TOpenDialog) или записывать в него (TSaveDialog). Замечу, что пользователь может ввести произвольное имя и, следовательно, указать несуществующий файл. Для записи это не имеет значения, но при чтении отсутствие файла может привести к краху программы. Чтобы избежать этого, можно проверить существование файла глобальной функцией FileExists, как это сделано в предыдущем примере, или использовать механизм обработки исключительных ситуаций.

Рис. 18.38. Стандартное окно TOpenDialog

Свойство Filter: string используется для  фильтрации (отбора) файлов, показываемых в диалоговом окне. Это свойство можно устанавливать с помощью  специального редактора на этапе  конструирования формы или программно, как это сделано в предыдущем примере. Для доступа к редактору достаточно щелкнуть по кнопке в строке Filter окна Инспектора объектов. При программном вводе фильтры задаются одной длинной строкой, в которой символы “|” служат для разделения фильтров друг от друга, а также для разделения описания фильтруемых файлов от соответствующей маски выбора. Например, оператор

OpenDialogI.Filter := 'Текстовые  файлы|*.txt| Файлы Паскаля|*.раs';

задает две маски - для отбора файлов с расширениями раs и TXT.

Установить начальный каталог  позволяет свойство InitialDir string. Например:

OpenDialogI.InitiaiDir := 'c:\program files\borland\delphi5\source';

С помощью свойства DefaultExt: String [ 3 ] формируется  полное имя файла, если при ручном вводе пользователь не указал расширение. В этом случае к имени файла прибавляется разделительная точка и содержимое этого свойства.

В диалоговом окне для ручного ввода  предусмотрен элемент TEdit, который при  желании можно заменить на TCоmbовох. Для этого необходимо свойству FileEditStyle придать значение fsComboBox вместо умалчиваемого fsEdit. Если выбран комбинированный список, с ним можно связать протокол выбора имен. Для этого используется свойство HistoryList: TStrings, содержимое которого будет появляться в выпадающем списке. Этот список не пополняется автоматически, поэтому за его содержимым должна следить программа. Например:

if OpenDialogI.Execute then

begin

HistoryList.Add(OpenDialogI.FileName);

end;

Настройка диалога может варьироваться  с помощью свойства

TOpenOption = (ofReadOnly, ofOverwritePrompt, ofHideReadOnly, ofNoChangeDir, ofShowHelp, ofNoValidate, ofAllowMultiSelect, ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofCre-atePrompt, ofShareAware, ofNoReadOnlyReturn, ofNoTestFileCre-ate, ofNoNetworkButton, ofNoLongNames, ofOldStyleDialog, of-NoDereferenceLinks) ;

TOpenOptions = set of TOpenOption;

property Options: TOpenOptions;

Значения этого свойства имеют  следующий смысл:

ofReadOnly

Устанавливает переключатель Только для чтения

ofOverwritePrompt

Требует согласия пользователя при  записи в существующий файл

ofHideReadOnly

Прячет переключатель Только для чтения

OfNoChangeDir

Запрещает смену каталога

ofShowHelp

Включает в окно кнопку Help

ofNoValidate

Запрещает автоматическую проверку правильности набираемых в имени файла символов

OfAllowMultiSelect

Разрешает множественный выбор  файлов

ofExtensionDifferent  

При завершении диалога наличие  этого значения в свойстве options говорит  о том, что пользователь ввел расширение, отличающееся от умалчиваемого

ofPathMustExist  

Разрешает указывать файлы только из существующих каталогов

ofFileMustExist

Разрешает указывать только существующие файлы

ofCreatePrompt

Требует подтверждения для создания несуществующего файла

ofShareAware

Разрешает выбирать файлы, используемые другими параллельно выполняемыми программами

OfNoReadOnlyReturn

Запрещает выбор файлов, имеющих  атрибут Только для чтения

ofNoTestFileCreate  

Запрещает проверку доступности сетевого или локального диска

OfNoNetworkButton

Запрещает вставку кнопки для создания сетевого диска

ofNoLongNames

Запрещает использование длинных  имен файлов

ofOldStyleDialog

Создает диалог в стиле Windows 3-х