- •Структура модуля
- •Interface
- •Implementation
- •Interface
- •Implementation
- •4. Инкапсуляция
- •7. Области видимости
- •Interface
- •Implementation
- •Interface
- •Implementation
- •Interface
- •Implementation
- •10. Функции работы с файлами
- •11. Построение пользовательского интерфейса
- •Interface
- •Implementation
- •С помощью объекта Range выделим диапазон
- •Компонент tDataSource
Interface
uses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};
type
My = class(TThread)
private
procedure SetName;
protected
procedure Execute; override;
end;
Implementation
{$IFDEF MSWINDOWS}
// что курсивом не обязательно
type
TThreadNameInfo = record
FType: LongWord; // must be 0x1000
FName: PChar; // pointer to name (in user address space)
FThreadID: LongWord; // thread ID (-1 indicates caller thread)
FFlags: LongWord; // reserved for future use, must be zero
end;
{$ENDIF}
{ My }
procedure My.SetName;
{$IFDEF MSWINDOWS}
var
ThreadNameInfo: TThreadNameInfo;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
ThreadNameInfo.FType := $1000;
ThreadNameInfo.FName := 'MyThread';
ThreadNameInfo.FThreadID := $FFFFFFFF;
ThreadNameInfo.FFlags := 0;
try
RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
except
end;
{$ENDIF}
end;
procedure My.Execute;
begin
SetName; // не обязательно
{ Здесь размещается код потока}
end;
end.
Класс My наследует от TThread ряд методов. Прежде всего, это конструктор Creates, создающий объект потока:
constructor Create(CreateSuspended: Boolean);
Параметр CreateSuspended конструктора определяет способ выполнения по-
тока. Если СreateSuspended = false, то выполнение процедуры Execute начинается немедленно после создания объекта. Если CreateSuspended = true, то выполнение начнется только после того, как будет вызван метод Resume:
procedure Resume;
Эта процедура имеет две области применения. Во-первых, она запускает вы-
полнение, если объект потока был создан с CreateSuspended = true. Во-вторых, она запускает приложение, приостановленное ранее методом Suspend:
procedure Suspend;
Таким образом, вы можете в любой момент приостановить выполнение потока методом Suspend, а затем продолжить выполнение методом Resume.
В процедуре Execute можно непосредственно писать операторы выполнения, вызовы каких-то функций. При этом не исключены конфликты между параллельно выполняемыми нитями. В этом случае в процедуре надо вызывать метод Synchronize
procedure Synchronize(Method: TThreadMethod);
В этом определении Method — процедура, работающая с компонентами VCL. Таким образом, при работе с компонентами VCL надежнее строить выполнение следующим образом. Вы пишете процедуру, выполняющую необходимые действия с компонентами VCL. Пусть вы дали ей имя Work. Тогда вы включаете ее объявление в класс потока, например, в раздел private, даете в разделе implementation ее описание, а процедура Execute в этом случае может, например, состоять из единственного оператора Synchronizе(Work):
interface
uses
Classes, …;
type
Т = class(TThread)
private
{ Private declarations }
procedure Work;
protected
procedure Execute; override;
end;
implementation
…
procedure T.Work;
begin
end;
procedure T.execute;
begin
Synchronize(Work)
end;
Нормальное завершение выполнения потока происходит при завершении процедуры Execute. Однако возможно и досрочное завершение выполнения потока. Для этого в его процедуру Execute должна быть введена проверка булева свойства Terminated (завершено).
При нормальной работе это свойство равно false. Но если какая-то внешняя нить вызвала метод Terminate объекта данного потока, то Terminated становится равным true. Если предполагается возможность такого завершения выполнения потока, то процедура Execute должна периодически проверять значение Terminate и при получении значения true должна завершаться. Например:
procedure Tl.Execute;
begin
repeat
<какие-то операции>
until Terminated;
end;
Пример окно с двумя кнопками и полем TEdit. Одна кнопка запускает поток, который в поле каждую секунду TEdit заносит число увеличивающееся на 1:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, unit2;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Thread:My;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
Thread:=My.Create(false);
Thread.FreeOnTerminate:=true;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Thread.Terminate;
end;
end.
unit Unit2;
interface
uses
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};
type
My = class(TThread)
private
procedure Work;
protected
procedure Execute; override;
end;
var
i:integer;
implementation
uses unit1, SysUtils;
procedure My.Work;
begin
Form1.Edit1.SetTextBuf(PChar(IntToStr(i)));
end;
procedure My.Execute;
begin
i:=0;
repeat
i:=i+1;
Synchronize(work);
sleep(1000);
until Terminated
end;
end.
РАБОТА С ПРИЛОЖЕНИЯМИ WORD И EXCEL
Технология COM (Component Object Model — компонентная модель объектов) предоставляет возможность одной программе (клиенту) работать с объектом другой программы (сервера). СОМ — это модель объекта, которая предусматривает полную совместимость во взаимодействии между компонентами, написанными разными компаниями и на разных языках. При этом неважно, где выполняются программы: в одном потоке, в разных потоках, на разных компьютерах.
С точки зрения СОМ приложение содержит несколько объектов (в частном случае может быть один объект). Каждый объект имеет один или несколько интерфейсов. В интерфейсе описаны методы объекта, к которым могут получить доступ внешние программы.
Внешние приложения, обращающиеся к объекту СОМ, являются клиентами СОМ. Клиент получает указатель на интересующий его интерфейс объекта и через этот указатель может вызывать методы объекта.
Таким образом, клиенту достаточно знать интерфейсы объекта и предостав-
ляемые ими методы. Об остальном позаботится система. В нужный момент она запустит сервер СОМ, если он еще не был запущен, сервер создаст объект, объект загрузит все необходимые ему данные и клиенту вернутся указатели на объект и его интерфейсы, с которыми он может работать.
Начиная с Delphi 5, взаимодействие с Word, Excel и многими другими распространенными программами, входящими в стандартную установку Windows и Microsoft Office, может осуществляться из приложений Delphi с помощью компонентов, размещенных в библиотеке на странице Servers.
Приложения Office поставляют сервера COM, которые предоставляют интерфейс доступа к приложению и его объектам. Благодаря этому, разработчик в среде Delphi имеет возможность, создав контроллер автоматизации, управлять сервером.
Всегда существует задающий приложение корневой объект, он всегда называется Application. Каждое приложение Office имеет свой собственный корневой объект – WordApplication, ExcelApplication.
Как только открывается новый документ, будь то PowerPoint, Excel, Word, автоматически создается каркас нового документа, который представляет собой набор библиотек с классами. Объекты этих классов будут доступны в данном документе. Задачей разработчика контроллера автоматизации является получить доступ к корневому объекту сервера, выстроить цепочку доступа к объектам – участникам (встроенным объектам), правильно передать параметры.
Работа с приложением Microsoft Word
Если на главную форму выкладываем компоненту с закладки Servers, которая называется, например WordApplication, то при запуске приложения запустится сервер автоматизации Microsoft Word, этот факт можно обнаружить, запустив на выполнение Task Manager и выбрав закладку Processes. Среди прочих процессов мы обнаруживаем WINWORD.EXE. При этом выполняются следующие действия:
При создании формы, в системном реестре, по идентификатору CLSID был найден сервер Word.Application
Запущено на выполнение приложение, находящееся по адресу в реестре (ProgID)
Сервер предоставил нашему приложению, которое и является контроллером автоматизации интерфейс, через который мы и получим доступ к объекту Application.
Практически всегда при работе с сервером Word вам приходится иметь дело сосвойством Documents. Это свойство представляет собой собрание всех документов, открытых в Word в данный момент. Каждый документ представлен в этом собрании как объект Document, имеющий в свою очередь собственные свойства и методы. Общее число открытых документов определяется свойством Count собрания документов Documents.
При вызове из Delphi любого метода сервера СОМ аргументы (кроме аргументов типа Text) передаются только как объекты типа OleVariant. Если какие-то аргументы не являются обязательными, то все равно они должны фигурировать в вызове метода. Только вместо их значений может быть указана EmptyParam —переменная типа OleVariant, используемая вместо необязательных параметров. Эта переменная объявлена в модулях System и OleCtrls. Таким образом, если вы хотите создать новый документ на основе обычного шаблона, вы можете записать оператор:
WordApplicationl.Documents.Add(EmptyParam,EmptyParam, EmptyParam, EmptyParam);
Важным свойством сервера Word является свойство Selection, являющееся
ссылкой на объект Selection — выделенный фрагмент текста в активном документе или, если нет выделения, то просто текущая позиция курсора в активном документе. Этот объект имеет методы InsertBefore и Insert After, аргументом в которые передается текст, вставляемый в активный документ соответственно до или после объекта Selection.
Сохранение активного документа в файле с заданным именем можно осуществить методом SaveAs класса Document, передавая в него как аргумент типа OleVariant имя файла с путем к нему. Если путь отсутствует, то файл сохраняется в текущем каталоге.
Пример:
procedure TForm1.Button3Click(Sender: TObject);
var a:OleVariant;
fileName:OleVariant;
begin
a:=true;
WordApplication1.Documents.Add(EmptyParam,EmptyParam,EmptyParam,EmptyParam);
WordApplication1.Selection.InsertAfter(''+#13);
WordApplication1.Selection.InsertAfter('hello korolev');
fileName:='c:\my1.doc';
WordApplication1.ActiveDocument.SaveAs(fileName, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam
, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam
, EmptyParam);
WordApplication1.Visible:=false;
end;
Пример замены в документе Word:
Пусть у нас имеется документ Microsoft Word:
1. Порядковый номер <Шифр>
2. От гр. <Фамилия> <Имя> <Отчество>
Фамилия имя отчество
Требуется открыть Microsoft Word, подставить значение Шифр и Фамилия, Имя, Отчество. Для работы с этим документом Microsoft Word необходимо:
Создать на форме компонент WordApplication
WordApplication1: TWordApplication;
Открыть документ
Fname:=GetCurrentDir+'/Blank.doc';
WordApplication1.Documents.Open(Fname, EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
Соединиться с Сервером Word и подключиться к документу.
WordApplication1.Connect;
Переходим в начало документа
start:=wdStory;
WordApplication1.Selection.HomeKey(start, EmptyParam);
Поиск и замена в документе фрагмент '<Фамилия>' заменяем на ‘Королев’
doc:='<Фамилия>';
text:='Королев';
FOne:=wdFindStop;
ROne:=wdReplaceOne;
WordApplication1.Selection.Find.Execute(doc, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, FOne, EmptyParam, text, ROne, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
Сделать видимым документ, с помощью свойства WordApplication - Visible:
WordApplication1.Visible:=true;
Полный пример:
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleServer, WordXP;
type
TForm2 = class(TForm)
WordApplication1: TWordApplication;
Button1: TButton;
procedure Button1Click(Sender: TObject);
Procedure zamena(doc,baz:oleVariant);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
var
FOne,ROne,start:OleVariant;
Fname:OleVariant;
begin
Fname:='d:\Blank.doc';
WordApplication1.Documents.Open(Fname, EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
WordApplication1.Connect;
zamena('<Фамилия>','Королев');
WordApplication1.Visible:=true;
end;
Procedure TForm2.zamena(doc,baz:oleVariant);
Var FOne,ROne,start:OleVariant;
begin
start:=wdStory;
WordApplication1.Selection.HomeKey(start, EmptyParam);
FOne:=wdFindStop;
ROne:=wdReplaceOne;
WordApplication1.Selection.Find.Execute(doc, EmptyParam, EmptyParam, EmptyParam,
EmptyParam, EmptyParam, EmptyParam, FOne, EmptyParam,
baz, ROne, EmptyParam, EmptyParam, EmptyParam, EmptyParam);
end;
end.
Работа с приложением Microsoft Excel
Компонент TExcelApplication - это сервер, с помощью которого осуществляется доступ к объекту Appication и запускается приложение Excel.
Основные свойства компонента TExcelApplication аналогичны свойствам компонента TWordApplication.
Для подключения к Excel и работы с ним нам понадобится переменная типа Variant:
Excel:Variant;
Далее создаем OLE объект:
OLE (англ.Object Linking and Embedding, произносится как oh-lay [олэй]) — технология связывания и внедрения объектов в другие документы и объекты, разработанные корпорацией Майкрософт. В1996 годуMicrosoft переименовала технологию OLE 2.0 в ActiveX.
Excel:=CreateOleObject('Excel.Application');
Добавляем новую книгу:
Excel.Workbooks.Add;
Показываем Excel:
Excel.Visible:=true;