Лабораторная работа 33 / лаб3
.docСанкт-Петербургский
государственный электротехнический университет
“ЛЭТИ”
______________________________________________________________________
кафедра МОЭВМ
Объектно-ориентированные технологии разработки программного обеспечения
Лабораторная работа N3 Применение протоколов связи приложений DDE и OLE
Вариант 11, 14
Выполнил: ст. гр. 3341 Постникова О. Е.
Проверил: доц. Спицын А.В.
Санкт-Петербург
2007
-
Знакомство с возможностями 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
-
Создание приложений с поддержкой 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