Kselax.ru

Hacker Kselax — the best hacker in the world

Menu
  • Блог
  • Контакты
  • wp plugin генератор
  • Русский
    • Русский
    • English
Menu

OLE Автоматизация. Создание OLE програмы для использование в excel

Posted on 21 июля, 2015 by admin

Здорова!

Сегодня разберем пример OLE в котором мы создадим COM объект с применением технологии OLE автоматизации. Пример будет банковская программа. Будем создавать в Visual Studio 10, запускаем ее и создаем самое простое приложение на MFC на основе диалоговых окон. Приложение назовем «OLE_EXE».

mfc dlg

на следующем шаге удаляем все галочки

mfc dlg1

обязательно ставим галочку «Автоматизация»

mfc dlg2

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

mfc обозреватель решений

Удалим следующие файлы: OLE_EXEDlg.h, OLE_EXEDlg.cpp, DlgProxy.h, DlgProxy.cpp, так же удалим из ресурсов диалог IDD_OLE_EXE_DIALOG.

В файле OLE_EXE.cpp удалим строчки #include «OLE_EXEDlg.h» и #include «OLE_EXEDlg.h»

в файле OLE_EXE.cpp заменим содержимое функции IninInstance

1
2
3
4
5
6
7
8
9
10
11
12
TRACE("Cex25a1App::InitInstance\n");
AfxOleInit();
if(RunEmbedded()||RunAutomated())
{
//компонент запущен COM
COleTemplateServer::RegisterAll();
return TRUE;
}
//Компонент запущен непосредственно пользователем
COleObjectFactory::UpdateRegistryAll();
AfxMessageBox(L"Банковский сервер зарегистрирован");
return FALSE;

Используя class Wizard добавим класс CBank к нашему проекту. Обязательно поставьте галочку «создать по идентификатору типа», у вас создастся идентификатор класса по которому ваш компонент будет находится в реестре GUID.

mfc ole

Жмем «Готово», у вас создастся два файла

Bank.h »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
 
 
// конечный объект команды CBank
 
class CBank : public CCmdTarget
{
DECLARE_DYNCREATE(CBank)
 
public:
CBank();
virtual ~CBank();
 
virtual void OnFinalRelease();
 
protected:
DECLARE_MESSAGE_MAP()
DECLARE_OLECREATE(CBank)
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
};

Bank.cpp »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Bank.cpp: файл реализации
//
 
#include "stdafx.h"
#include "OLE_EXE.h"
#include "Bank.h"
 
 
// CBank
 
IMPLEMENT_DYNCREATE(CBank, CCmdTarget)
 
 
CBank::CBank()
{
EnableAutomation();
// Чтобы обеспечить работу приложения в течение всего периода активности объекта автоматизации OLE,
// конструктор вызывает AfxOleLockApp.
AfxOleLockApp();
}
 
CBank::~CBank()
{
// Чтобы прервать работу приложения, когда все объекты созданы
// при помощи OLE-автоматизации, деструктор вызывает AfxOleUnlockApp.
AfxOleUnlockApp();
}
 
 
void CBank::OnFinalRelease()
{
// Когда будет освобождена последняя ссылка на объект автоматизации,
// вызывается OnFinalRelease. Базовый класс автоматически
// удалит объект. Перед вызовом базового класса добавьте
// дополнительную очистку, необходимую вашему объекту.
 
CCmdTarget::OnFinalRelease();
}
 
 
BEGIN_MESSAGE_MAP(CBank, CCmdTarget)
END_MESSAGE_MAP()
 
 
BEGIN_DISPATCH_MAP(CBank, CCmdTarget)
END_DISPATCH_MAP()
 
// Примечание: мы добавили поддержку для IID_IBank, чтобы обеспечить безопасную с точки зрения типов привязку
//  из VBA. Этот IID должен соответствовать GUID, связанному с
//  disp-интерфейсом в файле .IDL.
 
// {AA6D9C56-813D-45FF-99FA-E3E1B5B85DEB}
static const IID IID_IBank =
{ 0xAA6D9C56, 0x813D, 0x45FF, { 0x99, 0xFA, 0xE3, 0xE1, 0xB5, 0xB8, 0x5D, 0xEB } };
 
BEGIN_INTERFACE_MAP(CBank, CCmdTarget)
INTERFACE_PART(CBank, IID_IBank, Dispatch)
END_INTERFACE_MAP()
 
// {91ED4E19-C337-463C-B93E-FF83FFB14FA2}
IMPLEMENT_OLECREATE_FLAGS(CBank, "OLE_EXE.Bank", afxRegApartmentThreading, 0x91ed4e19, 0xc337, 0x463c, 0xb9, 0x3e, 0xff, 0x83, 0xff, 0xb1, 0x4f, 0xa2)
 
 
// обработчики сообщений CBank

Как видим создалось два идентификатора GUID, один для интерфейса IID_IBank, а второй GUID этот тот GUID который регистрирует модуль в реестре windows.

В «окне классов» у нас появился подраздел новый где находится интерфейс IBank

mfc IBank

Кликаем правой клавишей на IBank, выбираем «добавить»=>»Добавить метод…» и мы попадаем в окошко добавления методов

OLE add method

жмем «Далее» в появившемся окошке ничего не меняем и жмем «Готово» и у нас добавился в файле Bank.cpp в карту диспетчеризации новый метод, так же создалась сам метод в классе CBank заполнился также файл OLE_EXE.idl — это файл в котором на языке IDL записан OLE интерфейс.

Таким же способом добавим еще один метод Deposit возвращающий значение типа void и принимающий в качестве параметра тип DOUBLE

Добавим еще свойство Balance

mfc ole add property

теперь добавим к самому классу CBank переменную член m_dBalance типа double, у нас предыдущий мастер не создал переменную потому что мы выбрали параметр «get/set Methods». Поэтому мы ее создаем через обычный мастер добавления свойств к классу.

mfc add prp

заполним сгенерированые функции кодом, я полностью приведу файл Bank.cpp уже с заполненными функциями

Показать »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// Bank.cpp: файл реализации
//
 
#include "stdafx.h"
#include "OLE_EXE.h"
#include "Bank.h"
 
 
// CBank
 
IMPLEMENT_DYNCREATE(CBank, CCmdTarget)
 
 
CBank::CBank()
: m_dBalance(0)
{
EnableAutomation();
// Чтобы обеспечить работу приложения в течение всего периода активности объекта автоматизации OLE,
// конструктор вызывает AfxOleLockApp.
AfxOleLockApp();
}
 
CBank::~CBank()
{
// Чтобы прервать работу приложения, когда все объекты созданы
// при помощи OLE-автоматизации, деструктор вызывает AfxOleUnlockApp.
AfxOleUnlockApp();
}
 
 
void CBank::OnFinalRelease()
{
// Когда будет освобождена последняя ссылка на объект автоматизации,
// вызывается OnFinalRelease. Базовый класс автоматически
// удалит объект. Перед вызовом базового класса добавьте
// дополнительную очистку, необходимую вашему объекту.
 
CCmdTarget::OnFinalRelease();
}
 
 
BEGIN_MESSAGE_MAP(CBank, CCmdTarget)
END_MESSAGE_MAP()
 
 
BEGIN_DISPATCH_MAP(CBank, CCmdTarget)
DISP_FUNCTION_ID(CBank, "Withdrawal", dispidWithdrawal, Withdrawal, VT_R8, VTS_R8)
DISP_FUNCTION_ID(CBank, "Deposit", dispidDeposit, Deposit, VT_EMPTY, VTS_R8)
DISP_PROPERTY_EX_ID(CBank, "Balance", dispidBalance, GetBalance, SetBalance, VT_R8)
END_DISPATCH_MAP()
 
// Примечание: мы добавили поддержку для IID_IBank, чтобы обеспечить безопасную с точки зрения типов привязку
//  из VBA. Этот IID должен соответствовать GUID, связанному с
//  disp-интерфейсом в файле .IDL.
 
// {AA6D9C56-813D-45FF-99FA-E3E1B5B85DEB}
static const IID IID_IBank =
{ 0xAA6D9C56, 0x813D, 0x45FF, { 0x99, 0xFA, 0xE3, 0xE1, 0xB5, 0xB8, 0x5D, 0xEB } };
 
BEGIN_INTERFACE_MAP(CBank, CCmdTarget)
INTERFACE_PART(CBank, IID_IBank, Dispatch)
END_INTERFACE_MAP()
 
// {91ED4E19-C337-463C-B93E-FF83FFB14FA2}
IMPLEMENT_OLECREATE_FLAGS(CBank, "OLE_EXE.Bank", afxRegApartmentThreading, 0x91ed4e19, 0xc337, 0x463c, 0xb9, 0x3e, 0xff, 0x83, 0xff, 0xb1, 0x4f, 0xa2)
 
 
// обработчики сообщений CBank
 
 
DOUBLE CBank::Withdrawal(DOUBLE dAmount)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
 
// TODO: добавьте код обработчика отправки
TRACE("CBank::Withdrawl dAmount=%f, m_dBalance=%f ",dAmount,m_dBalance);
if(dAmount<0.0)
{
return 0.0;
}
if(dAmount<=m_dBalance)
{
m_dBalance-=dAmount;
return m_dBalance;
}
//если больше возвращаем то что есть на счету
double dTemp=m_dBalance;
m_dBalance=0.0;
return dTemp;
}
 
 
void CBank::Deposit(DOUBLE dAmount)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
 
if(dAmount<0.0)
{
return;
}
m_dBalance+=dAmount;
}
 
 
DOUBLE CBank::GetBalance(void)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
 
return m_dBalance;
}
 
 
void CBank::SetBalance(DOUBLE newVal)
{
AFX_MANAGE_STATE(AfxGetAppModuleState());
TRACE("К сожалению, это невозможно!\n");
}

Собираем программу и запускаем один раз чтобы зарегистрировать.

Дальше подготавливаем 4 макроса Excel

Показать »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Dim Bank As Object
Sub LoadBank()
    Set Bank = CreateObject("OLE_EXE.Bank")
End Sub
 
Sub UnloadBank()
    Set Bank = Nothing
End Sub
 
Sub DoDeposit()
    Range("D4").Select
    Bank.Deposit (ActiveCell.Value)
End Sub
 
Sub DoWithdrawal()
    Range("E4").Select
    Dim amt
    amt = Bank.Withdrawal(ActiveCell.Value)
    Range("E5").Select
    ActiveCell.Value = amt
End Sub
 
Sub DoInquiry()
    Dim amt
    amt = Bank.Balance()
    Range("G4").Select
    ActiveCell.Value = amt
End Sub

Запускаем excel, создаем книгу новую, добавляем 5 кнопки и добавляем макросы excel к книге. Каждой кнопке присваиваем свой макрос. Как добавить макрос и кнопку к excel читайте тут. Вот скрин приложения excel:

excel macro

Дальше нажимаем кнопку «Load Bank Program» у нас загружается модуль, затем нажимаем «Deposit» и вводим сумму которую хотим получить на счет, например мы ввели 500 и нажали 3 раза на «Deposit» у нас положится на счет 1500. Проверить сколько на счету нажмите кнопку «Balance Inqury». Чтобы снять нажмите «Withdrawal» и оно будет снимать введенную сумму.

Отладка OLE объекта или COM объекта.

И так ребятки рассмотрим как можно отладить наш объект. Для этого заходим в visual studio 2010 в «свойства проекта» и на вкладке отладка выставляем следующие настройки:

ole debug

Нажимаем кнопку отладка или F5 и у нас VS запускается в режиме ожидания, дальше мы заходим в excel, подгружаем наш модуль и в отладчике смотрим что происходит, отладчик должен реагировать на действия. На этом в принципе все.

 

[youtube]https://www.youtube.com/watch?v=zPWlSsDUIQw[/youtube]

 

Добавить комментарий Отменить ответ

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Рубрики

  • C++ (293)
  • JavaScript (1)
  • linux (1)
  • MFC (39)
  • node.js (2)
  • React (3)
  • vBulletin (5)
  • Visual Studio (9)
  • wordpress (18)
  • Разное (29)

Метки

Ajax bootstrap CentOS CLI expressjs FormData GDlib google Invisible reCAPTCHA JWT media MFC php react-router-dom redux repository wordpress RTTI STL vBulletin vector Visual Studio WINAPI wordpress wp-plugins XMLHttpRequest Двоичное дерево Задачи С++ Игры С++ Исключения С++ О-большое Операторы_С++ Перегрузка операторов С++ Поиск С++ Потоки Проектирование_С++ С++ Типы_С++ Типы С++ Шаблоны С++ библиотеки локализация макросы С++ сортировка С++

Свежие комментарии

  • RA3PKJ к записи visual C++, создание диалоговых окон.
  • JasonReant к записи Создание и использование статических библиотек .lib в visual studio.
  • MyWin2020 к записи Программка для заполнения форума на vBulletin 3.8.7
  • ScottJip к записи Создание и использование статических библиотек .lib в visual studio.
  • ArnoldKig к записи Создание и использование статических библиотек .lib в visual studio.
©2021 Kselax.ru Theme by ThemeGiant