Скачиваний:
9
Добавлен:
01.05.2014
Размер:
113.66 Кб
Скачать

Санкт-Петербургский

государственный электротехнический университет

ЛЭТИ”

______________________________________________________________________

кафедра МОЭВМ

Объектно-ориентированные технологии разработки программного обеспечения

Лабораторная работа N3 Применение протоколов связи приложений DDE и OLE

Вариант 11, 14

Выполнил: ст. гр. 3341 Постникова О. Е.

Проверил: доц. Спицын А.В.

Санкт-Петербург

2007

  1. Знакомство с возможностями DDE и OLE с помощью Visual Basic

1.1. На Visual Basic for Application написать макрос, который с помощью DDE создает новую группу на рабочем столе и в ней новый программный элемент.

Макрос запускается из MS Excel. Диалоговое окно имеет вид:

Рис.1.1

При нажатии на первую кнопку выполняется блок команд:

Private Sub CommandButton1_Click()

Dim group As String

ch = DDEInitiate("Progman", "Progman")

group = TextBox1.Text

DDEExecute ch, "[CreateGroup(" + group + ")]"

DDETerminate ch

End Sub

При нажатии на вторую кнопку выполняется блок команд:

Private Sub CommandButton2_Click()

Dim item, command As String

item = TextBox2.Text

command = TextBox3.Text

ch = DDEInitiate("Progman", "Progman")

DDEExecute ch, "[AddItem(" + command + "," + item + ")]"

DDETerminate ch

End Sub

1.2. На Visual Basic for Application написать макрос, который с помощью DDE загружает в Excel файл с тестовой электронной таблицей, считывает и записывает в нее данные, закрывает файл.

Тестовая электрона таблица содержится в файле Test.xls.

test

lab3

test

test

lab3

test

Tabl.1

Текст макроса, перегружающего тестовую таблицу в текущую:

Sub DDE_EXCEL()

ch = DDEInitiate("Excel", "c:\ 1.2\test.xls")

Set b = Worksheets("Лист1").Range("A1")

For i = 1 To 3

For j = 1 To 3

a = DDERequest(ch, "R" & i & "C" & j)

b(i, j) = a(1)

Next j

Next i

Set b = Worksheets("Лист1").Range("A10")

DDEPoke ch, "R10C1", b(1)

DDEExecute ch, "[SAVE]"

DDEExecute ch, "[QUIT]"

DDETerminate ch

End Sub

1.3. На Visual Basic for Application (в Excel) написать макрос который с помощью OLE Automation запускает произвольное приложение и сохраняет в ячейках Excel информацию из него. В отчете объяснить отличия DDE от OLE Automation.

Используется приложение MS Word. Файлы с названием Doc1.doc и Doc2.doc

Текст макроса:

Sub Macro_1_3_1()

'Открывает файл doc1.doc в папке c:\1.3\msdn

'Считывает информацию из него

'

Dim wDoc As Object

Dim parCount As Long, wordCount As Long

Set wDoc = GetObject("c:\1.3\msdn\doc1.doc")

parCount = wDoc.Paragraphs.Count

wordCount = wDoc.Words.Count

Set wSheet = Sheets(1)

Dim k As Integer

Dim str As Integer

Dim stb As Integer

Dim w As Integer

stb = 1

str = 1

k = 7

While (k <= wordCount)

If (str <= Sqr(parCount)) Then

If wDoc.Words.Item(k + 1) <> "." Then

w = wDoc.Words.Item(k):

wSheet.Cells(stb, str).Value = w:

k = k + 8

Else

wSheet.Cells(stb, str).Value = wDoc.Words.Item(k) + wDoc.Words.Item(k + 1) + wDoc.Words.Item(k + 2):

k = k + 8 + 2

End If:

str = str + 1

'k = k + 8

Else

str = 1:

stb = stb + 1

End If

'If wDoc.Words.Item(k + 1) <> "." Then

' wSheet.Cells(k, 1).Value = wDoc.Words.Item(k):

' k = k + 8

' Else

' wSheet.Cells(k, 1).Value = wDoc.Words.Item(k) + wDoc.Words.Item(k + 1) + wDoc.Words.Item(k + 2):

' k = k + 8 + 2

'End If

Wend

'

End Sub

Sub Macro_1_3_2()

'

'

'

Dim wDoc As Object

Dim parCount As Long, wordCount As Long

Set wDoc = GetObject("c:\1.3\msdn\doc2.doc")

parCount = wDoc.Paragraphs.Count

wordCount = wDoc.Words.Count

'Set wSheet = Sheets(2)

Set wSheet = Application.Worksheets.Add()

Dim k As Integer

Dim str As Integer

Dim stb As Integer

Dim w As Integer

stb = 1

str = 1

k = 7

While (k <= wordCount)

If (str <= Sqr(parCount)) Then

If wDoc.Words.Item(k + 1) <> "." Then

w = wDoc.Words.Item(k):

wSheet.Cells(stb, str).Value = w:

k = k + 8

Else

wSheet.Cells(stb, str).Value = wDoc.Words.Item(k) + wDoc.Words.Item(k + 1) + wDoc.Words.Item(k + 2):

k = k + 8 + 2

End If:

str = str + 1

'k = k + 8

Else

str = 1:

stb = stb + 1

End If

'If wDoc.Words.Item(k + 1) <> "." Then

' wSheet.Cells(k, 1).Value = wDoc.Words.Item(k):

' k = k + 8

' Else

' wSheet.Cells(k, 1).Value = wDoc.Words.Item(k) + wDoc.Words.Item(k + 1) + wDoc.Words.Item(k + 2):

' k = k + 8 + 2

'End If

Wend

'

End Sub

  1. Создание приложений с поддержкой OLE на C++

  • На Visual C++ с помощью OLE Automation реализовать в приложении операции из разд. 1.1 и 1.2.

На Visual C++ реализовано приложение, запускающее MS Word и занесение в него текста.

Наиболее важная часть программы приведена ниже:

void CWordTestDlg::OnButton1()

{

_Application app;

if (!app.CreateDispatch("Word.Application"))

{

AfxMessageBox("Ошибка при старте Worda!");

return;

}

else

app.SetVisible(TRUE);

Documents oDocs;

_Document oDoc;

COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

oDocs=app.GetDocuments();

oDocs.Add(covOptional,covOptional,covOptional,covOptional);

oDoc=oDocs.Item(COleVariant(long(1)));

oDoc.Activate();

Paragraphs oPars;

Paragraph oPar;

Selection oSel;

oSel = app.GetSelection();

oPars=oSel.GetParagraphs();

oPar=oPars.Add(covOptional);

oSel.TypeText("Мой текст");

}

  • Дополнить приложение по индивидуальному заданию из л/р 2 возможностями OLE контейнера, OLE сервера, OLE сервера автоматизации.

За реализацию функций OLE контейнера отвечает класс CPart32CntrItem, находящийся в файлах CntrlItem.h и CntrlItem.cpp. Класс наследован от COleClientItem.

В класс добавляем переменную CRect m_Rect для ограничения области вывода объекта OLE.

За реализацию функций OLE сервера отвечает класс CPart32SrvrItem наследованный от класса COleServerItem и находящийся в файлах SrvrItem.h и SrvrItem.cpp

Реализация сервера автоматизации:

В интерфейс IPart32 добавляем следующие функции:

[id(1)] short getCount(short num);

[id(2)] void showWnd();

[id(3)] void Triangle(short x, short y, short base, short height, short num);

[id(4)] void Trapezium(short x, short y, short base, short height, short cutof, short num);

[id(5)] void TextTrapezium(short x, short y, short base, short height, short cutof, LPCTSTR Text, short num);

[id(6)] void Text(short x, short y, LPCTSTR Text, short num);

[id(7)] void deleteElem(short index, short num);

Реализуются они в классе CPart32Doc:

void CPart32Doc::showWnd()

{

POSITION pos = GetFirstViewPosition();

CView* pView = GetNextView(pos);

if (pView != NULL)

{

CFrameWnd* pFrameWnd = pView->GetParentFrame();

pFrameWnd->ActivateFrame(SW_SHOW);

pFrameWnd = pFrameWnd->GetParentFrame();

if (pFrameWnd != NULL)

pFrameWnd->ActivateFrame(SW_SHOW);

}

}

short CPart32Doc::getCount(short num)

{

// TODO: Add your dispatch handler code here

if (num==1)

{

return set1.count();

}

else

{

return set2.count();

}

}

void CPart32Doc::Triangle(short x, short y, short base, short height, short num)

{

Shape* sh;

sh=new CTriangleEntity(base,height,x,y);

if (num==1)

{

set1.insertEl(index1++,sh);

}

else

{

set2.insertEl(index2++,sh);

}

UpdateAllViews(NULL);

}

void CPart32Doc::Trapezium(short x, short y, short base, short height, short cutof, short num)

{

Shape* sh;

sh=new CTrapeziumEntity(10,base,height,x,y);

if (num==1)

{

set1.insertEl(index1++,sh);

}

else

{

set2.insertEl(index2++,sh);

}

UpdateAllViews(NULL);

}

void CPart32Doc::TextTrapezium(short x, short y, short base, short height, short cutof, LPCTSTR Text, short num)

{

Shape* sh;

sh=new CTextTrapeziumEntity(Text,10,base,height,x,y);

if (num==1)

{

set1.insertEl(index1++,sh);

}

else

{

set2.insertEl(index2++,sh);

}

UpdateAllViews(NULL);

}

void CPart32Doc::Text(short x, short y, LPCTSTR Text, short num)

{

Shape* sh;

sh=new CTextEntity(Text,x,y);

if (num==1)

{

set1.insertEl(index1++,sh);

}

else

{

set2.insertEl(index2++,sh);

}

UpdateAllViews(NULL);

}

void CPart32Doc::deleteElem(short index, short num)

{

if (num==1)

{

set1.deleteEl(index);

}

else

{

set2.deleteEl(index);

}

UpdateAllViews(NULL);

}

В роли контроллера автоматизации выступает приложение Controller.

В нем подключен класс-интерфейс:

class IPart32 : public COleDispatchDriver

{

public:

IPart32() {} // Calls COleDispatchDriver default constructor

IPart32(LPDISPATCH pDispatch) : COleDispatchDriver(pDispatch) {}

IPart32(const IPart32& dispatchSrc) : COleDispatchDriver(dispatchSrc) {}

// Attributes

public:

// Operations

public:

void showWnd();

short getCount(short nom);

void Triangle(short x, short y, short Base, short Height, short nom);

void Trapezium(short x, short y, short Base, short Height, short Cutof, short nom);

void TextTrapezium(short x, short y, short Base, short Height, short Cutof, LPCTSTR text, short nom);

void text(short x, short y, LPCTSTR text, short nom);

void DeleteElem(short index, short nom);

void SetUnion();

void SetCross();

void SetSub();

};

/////////////////////////////////////////////////////////////////////////////// IPart32 operations

void IPart32::showWnd()

{

InvokeHelper(0x1, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);

}

short IPart32::getCount(short nom)

{

short result;

static BYTE parms[] =

VTS_I2;

InvokeHelper(0x2, DISPATCH_METHOD, VT_I2, (void*)&result, parms,

nom);

return result;

}

void IPart32::Triangle(short x, short y, short Base, short Height, short nom)

{

static BYTE parms[] =

VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_I2;

InvokeHelper(0x3, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

x, y, Base, Height, nom);

}

void IPart32::Trapezium(short x, short y, short Base, short Height, short Cutof, short nom)

{

static BYTE parms[] =

VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_I2;

InvokeHelper(0x4, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

x, y, Base, Height, Cutof, nom);

}

void IPart32::TextTrapezium(short x, short y, short Base, short Height, short Cutof, LPCTSTR text, short nom)

{

static BYTE parms[] =

VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_I2 VTS_BSTR VTS_I2;

InvokeHelper(0x5, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

x, y, Base, Height, Cutof, text, nom);

}

void IPart32::text(short x, short y, LPCTSTR text, short nom)

{

static BYTE parms[] =

VTS_I2 VTS_I2 VTS_BSTR VTS_I2;

InvokeHelper(0x6, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

x, y, text, nom);

}

void IPart32::DeleteElem(short index, short nom)

{

static BYTE parms[] =

VTS_I2 VTS_I2;

InvokeHelper(0x7, DISPATCH_METHOD, VT_EMPTY, NULL, parms,

index, nom);

}

void IPart32::SetUnion()

{

InvokeHelper(0xa, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);

}

void IPart32::SetCross()

{

InvokeHelper(0xb, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);

}

void IPart32::SetSub()

{

InvokeHelper(0xc, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);

}

В приложении вызываются методы класса-интерфейса:

Инициализация:

if (!serv.CreateDispatch("part32.Document"))

{

AfxMessageBox("Ошибка при старте Serv!");

return;

}

}

Открытие окна:

void CControllerDlg::OnStartserv()

{

// TODO: Add your control notification handler code here

serv.showWnd();

}

Создание и удаление элемента:

void CControllerDlg::OnCreate()

{

UpdateData(true);

int nom=m_figs.GetCaretIndex();

if (nom==0)

{

if ((m_x==0)&&(m_y==0)&&(m_base==0)&&(m_height==0))

{

AfxMessageBox("Не заданы нужные параметры!");

return;

}

serv.Triangle(m_x,m_y,m_base,m_height,m_num);

}

else

if (nom==1)

{

if ((m_x==0)&&(m_y==0)&&(m_base==0)&&(m_height==0))

{

AfxMessageBox("Не заданы нужные параметры!");

return;

}

serv.Trapezium(m_x,m_y,m_base,m_height,10,m_num);

}

else

if (nom==2)

{

if ((m_x==0)&&(m_y==0)&&(m_base==0)&&(m_height==0)&&(m_text==""))

{

AfxMessageBox("Не заданы нужные параметры!");

return;

}

serv.TextTrapezium(m_x,m_y,m_base,m_height,10,m_text,m_num);

}

else

if (nom==3)

{

if ((m_x==0)&&(m_y==0)&&(m_text==""))

{

AfxMessageBox("Не заданы нужные параметры!");

return;

}

serv.text(m_x,m_y,m_text,m_num);

}

m_cnt=serv.getCount(m_num);

UpdateData(false);

}

void CControllerDlg::OnDelete()

{

UpdateData(true);

serv.DeleteElem(m_delindex,m_num);

m_cnt=serv.getCount(m_num);

UpdateData(false);

}

Форма приложения изображена на рисунке:

Рис.3 Приложение part32