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

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 необходимо:

  1. Создать на форме компонент WordApplication

WordApplication1: TWordApplication;

  1. Открыть документ

Fname:=GetCurrentDir+'/Blank.doc';

WordApplication1.Documents.Open(Fname, EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam,

EmptyParam, EmptyParam, EmptyParam,EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam);

  1. Соединиться с Сервером Word и подключиться к документу.

WordApplication1.Connect;

  1. Переходим в начало документа

start:=wdStory;

WordApplication1.Selection.HomeKey(start, EmptyParam);

  1. Поиск и замена в документе фрагмент '<Фамилия>' заменяем на ‘Королев’

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);

  1. Сделать видимым документ, с помощью свойства 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;

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