Kselax.ru

Hacker Kselax — the best hacker in the world

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

OLE Автоматизация и использование директивы #import

Posted on 26 июля, 2015 by admin

Здорова!

Сегодня разберем что такое директива #import в OLE автоматизации.

1. Теория: «Что такое #import и как его использовать»

И так эта директива подгружает файл библиотеки типов tlb и из него как бы компилирует функции. Например строчка:

1
2
#import "OLE_EXE.tlb" rename_namespace("BankDriv1")
using namespace BankDriv1;

У нас подключается файл OLE_EXE.tlb и компилятор в этом случае создаст в подкаталогах Debug или Release файлы ole_exe.tlh и ole_exe.tli. TLH файл содержит объявление управляющего класса Bank и интеллектуального указателя (smart pointer)

1
_COM_SMARTPTR_TYPEDEF(IBank, __uuidof(IBank));

Макрос _COM_SMARTPTR_TYPEDEF генерирует тип IBankPtr, который инкапсулирует указатель на IDispatch компонента.

TLI — файл содержит inline реализацию функций функций членов.

В клиентской программе переменная-член встраивается в класс вид или другой класс примерно так:

1
IBankPtr m_bank;

Затем создается объект компонента при помощи оператора

1
m_bank.CreateInstance(__uuidof(Bank));

Теперь для вызова функций-членов, определенных в TLI файле, можно воспользоваться переопределенным оператором -> класса IBankPtr.

1
2
m_bank->Withdrawal(5);
m_bank->Deposit(3)

Когда объект m_bank покидает область видимости его деструктор вызывает COM-функцию Release()

2. Создание реальных примеров OLE автоматизаци с использованием директивы #import

Теперь перейдем к реальным примерам и попробуем их встроить, мы их создали в постах:

  1. http://www.kselax.ru/2015/07/ole-avtomatizaciya-sozdanie-ole-programy-dlya-ispolzovanie-v-excel/
  2. http://www.kselax.ru/2015/07/sozdanie-ole-prilozheniya-dll-s-ispolzovaniem-dialogovogo-okna-mfc/
  3. http://www.kselax.ru/2015/07/ole-avtomatizaciya-sozdanie-sdi-mfc-prilozheniya/

Сразу оговорюсь у меня есть проблемы по поводу встраивания этих примеров, не вышло нормально встроить первый пример и третий пример глючит, я его не исправлял.

Создаем обычное приложение SDI, назовем его MyTestImport

mfc create sdi

жмем «Готово», мастер подготовил нам каркас приложения. Скопируем в каталог с где находятся исходные коды файлы tlb библиотек OLE_EXE.tlb, MyOleDlg.tlb, MyOleClock.tlb. Откроем файл stdAfx.h и добавим в него строчки:

1
2
3
4
5
6
7
8
9
#include <afxdisp.h>        // классы автоматизации MFC
#import "OLE_EXE.tlb" rename_namespace("BankDriv1")
using namespace BankDriv1;
 
#import "MyOleDlg.tlb" rename_namespace("BankDriv2")
using namespace BankDriv2;
 
#import "MyOleClock.tlb" rename_namespace("BankDriv3")
using namespace BankDriv3;

Добавим к классу вида 4 закрытых члена

1
2
3
4
5
private:
IMyDialog_AutoPtr m_auto;
IBankPtr m_bank;
IMyOleClockPtr m_clock;
IAlarmPtr m_alarm;

Добавим новые пунткы в меню:

Bank Comp -> Load, Test, Unload

DLL Comp -> Load, Get Data, Unload

Clock Comp -> Load, Create Alarm, Refresh Time, Unload

От такое примерно меню получится:

mfc menu

Добавим к ним обработчики в класс вид и заполним кодом.

MyTestImportView.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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
// MyTestImportView.cpp : реализация класса CMyTestImportView
//
 
#include "stdafx.h"
// SHARED_HANDLERS можно определить в обработчиках фильтров просмотра реализации проекта ATL, эскизов
// и поиска; позволяет совместно использовать код документа в данным проекте.
#ifndef SHARED_HANDLERS
#include "MyTestImport.h"
#endif
 
#include "MyTestImportDoc.h"
#include "MyTestImportView.h"
#include "AlarmDialog.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
 
// CMyTestImportView
 
IMPLEMENT_DYNCREATE(CMyTestImportView, CView)
 
BEGIN_MESSAGE_MAP(CMyTestImportView, CView)
// Стандартные команды печати
ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMyTestImportView::OnFilePrintPreview)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
ON_COMMAND(ID_BANKCOMP_LOAD, &CMyTestImportView::OnBankcompLoad)
ON_UPDATE_COMMAND_UI(ID_BANKCOMP_LOAD, &CMyTestImportView::OnUpdateBankcompLoad)
ON_COMMAND(ID_BANKCOMP_TEST, &CMyTestImportView::OnBankcompTest)
ON_UPDATE_COMMAND_UI(ID_BANKCOMP_TEST, &CMyTestImportView::OnUpdateBankcompTest)
ON_COMMAND(ID_BANKCOMP_UNLOAD, &CMyTestImportView::OnBankcompUnload)
ON_UPDATE_COMMAND_UI(ID_BANKCOMP_UNLOAD, &CMyTestImportView::OnUpdateBankcompUnload)
ON_COMMAND(ID_DLLCOMP_LOAD, &CMyTestImportView::OnDllcompLoad)
ON_UPDATE_COMMAND_UI(ID_DLLCOMP_LOAD, &CMyTestImportView::OnUpdateDllcompLoad)
ON_COMMAND(ID_DLLCOMP_GETDATA, &CMyTestImportView::OnDllcompGetdata)
ON_UPDATE_COMMAND_UI(ID_DLLCOMP_GETDATA, &CMyTestImportView::OnUpdateDllcompGetdata)
ON_COMMAND(ID_DLLCOMP_UNLOAD, &CMyTestImportView::OnDllcompUnload)
ON_UPDATE_COMMAND_UI(ID_DLLCOMP_UNLOAD, &CMyTestImportView::OnUpdateDllcompUnload)
ON_COMMAND(ID_CLOCKCOMP_LOAD, &CMyTestImportView::OnClockcompLoad)
ON_UPDATE_COMMAND_UI(ID_CLOCKCOMP_LOAD, &CMyTestImportView::OnUpdateClockcompLoad)
ON_COMMAND(ID_Menu, &CMyTestImportView::OnMenu)
ON_UPDATE_COMMAND_UI(ID_Menu, &CMyTestImportView::OnUpdateMenu)
ON_COMMAND(ID_CLOCKCOMP_REFRESHTIME, &CMyTestImportView::OnClockcompRefreshtime)
ON_UPDATE_COMMAND_UI(ID_CLOCKCOMP_REFRESHTIME, &CMyTestImportView::OnUpdateClockcompRefreshtime)
ON_COMMAND(ID_CLOCKCOMP_UNLOAD, &CMyTestImportView::OnClockcompUnload)
ON_UPDATE_COMMAND_UI(ID_CLOCKCOMP_UNLOAD, &CMyTestImportView::OnUpdateClockcompUnload)
END_MESSAGE_MAP()
 
// создание/уничтожение CMyTestImportView
 
CMyTestImportView::CMyTestImportView()
{
// TODO: добавьте код создания
 
}
 
CMyTestImportView::~CMyTestImportView()
{
}
 
BOOL CMyTestImportView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: изменить класс Window или стили посредством изменения
//  CREATESTRUCT cs
 
return CView::PreCreateWindow(cs);
}
 
// рисование CMyTestImportView
 
void CMyTestImportView::OnDraw(CDC* /*pDC*/)
{
CMyTestImportDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
 
// TODO: добавьте здесь код отрисовки для собственных данных
}
 
 
// печать CMyTestImportView
 
 
void CMyTestImportView::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
AFXPrintPreview(this);
#endif
}
 
BOOL CMyTestImportView::OnPreparePrinting(CPrintInfo* pInfo)
{
// подготовка по умолчанию
return DoPreparePrinting(pInfo);
}
 
void CMyTestImportView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: добавьте дополнительную инициализацию перед печатью
}
 
void CMyTestImportView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: добавьте очистку после печати
}
 
void CMyTestImportView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
 
void CMyTestImportView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
 
 
// диагностика CMyTestImportView
 
#ifdef _DEBUG
void CMyTestImportView::AssertValid() const
{
CView::AssertValid();
}
 
void CMyTestImportView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
 
CMyTestImportDoc* CMyTestImportView::GetDocument() const // встроена неотлаженная версия
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyTestImportDoc)));
return (CMyTestImportDoc*)m_pDocument;
}
#endif //_DEBUG
 
 
// обработчики сообщений CMyTestImportView
 
 
void CMyTestImportView::OnBankcompLoad()
{
// TODO: добавьте свой код обработчика команд
//                      91ED4E19-C337-463C-B93E-FF83FFB14FA2
//    {91ED4E19-C337-463C-B93E-FF83FFB14FA2}
// 91ED4E19-C337-463C-B93E-FF83FFB14FA2
//struct __declspec(uuid("B889A72E-E496-42DD-9D70-35EE6C9161CE"))kkk;
if(m_bank.CreateInstance(__uuidof(Bank)) != S_OK) {
AfxMessageBox(L"Bank component not found");
return;
    }
}
 
 
void CMyTestImportView::OnUpdateBankcompLoad(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_bank.GetInterfacePtr() == NULL);
}
 
 
void CMyTestImportView::OnBankcompTest()
{
// TODO: добавьте свой код обработчика команд
try {
   m_bank->Deposit(20.0);
   m_bank->Withdrawal(15.0);
   TRACE("new balance = %f\n", m_bank->GetBalance());
    } catch(_com_error& e) {
AfxMessageBox(e.ErrorMessage());
    }
}
 
 
void CMyTestImportView::OnUpdateBankcompTest(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_bank.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnBankcompUnload()
{
// TODO: добавьте свой код обработчика команд
m_bank.Release();
}
 
 
void CMyTestImportView::OnUpdateBankcompUnload(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_bank.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnDllcompLoad()
{
// TODO: добавьте свой код обработчика команд
if(m_auto.CreateInstance(__uuidof(MyDialog_Auto)) != S_OK) {
AfxMessageBox(L"Ex25bAuto component not found");
return;
   }
}
 
 
void CMyTestImportView::OnUpdateDllcompLoad(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_auto.GetInterfacePtr() == NULL);
}
 
 
void CMyTestImportView::OnDllcompGetdata()
{
// TODO: добавьте свой код обработчика команд
try {
   m_auto->DisplayDialog();
   COleVariant vaData = m_auto->GetTextData();
   ASSERT(vaData.vt == VT_BSTR);
   CString strTextData = vaData.bstrVal;
   long lData = m_auto->GetLongData();
   TRACE("LCEx25dView::OnDlloleGetdata -- long = %ld, text = %S\n",
lData, strTextData);
    } catch(_com_error& e) {
AfxMessageBox(e.ErrorMessage());
    }
}
 
 
void CMyTestImportView::OnUpdateDllcompGetdata(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_auto.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnDllcompUnload()
{
// TODO: добавьте свой код обработчика команд
m_auto.Release();
}
 
 
void CMyTestImportView::OnUpdateDllcompUnload(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_auto.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnClockcompLoad()
{
// TODO: добавьте свой код обработчика команд
if(m_clock.CreateInstance(__uuidof(CMyOleClockDoc)) != S_OK) {
AfxMessageBox(L"Clock component not found");
return;
   }
   try {
   m_clock->PutFigure(0, COleVariant(L"XII"));
   m_clock->PutFigure(1, COleVariant(L"III"));
   m_clock->PutFigure(2, COleVariant(L"VI"));
   m_clock->PutFigure(3, COleVariant(L"IX"));
   OnClockcompRefreshtime();
   m_clock->ShowWin();
    } catch(_com_error& e) {
AfxMessageBox(e.ErrorMessage());
    }
}
 
 
void CMyTestImportView::OnUpdateClockcompLoad(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_clock.GetInterfacePtr() == NULL);
}
 
 
void CMyTestImportView::OnMenu()
{
// TODO: добавьте свой код обработчика команд
CAlarmDialog dlg;
try {
if (dlg.DoModal() == IDOK) {
COleDateTime dt(1995, 12, 23, dlg.m_nHours, dlg.m_nMinutes,
dlg.m_nSeconds);
LPDISPATCH pAlarm = m_clock->CreateAlarm(dt);
m_alarm.Attach((IAlarm*) pAlarm);  // releases prior object!
m_clock->RefreshWin();
}
    } catch(_com_error& e) {
AfxMessageBox(e.ErrorMessage());
    }
}
 
 
void CMyTestImportView::OnUpdateMenu(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnClockcompRefreshtime()
{
// TODO: добавьте свой код обработчика команд
COleDateTime now = COleDateTime::GetCurrentTime();
try {
   m_clock->PutTime(now);
   m_clock->RefreshWin();
    } catch(_com_error& e) {
AfxMessageBox(e.ErrorMessage());
    }
}
 
 
void CMyTestImportView::OnUpdateClockcompRefreshtime(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL);
}
 
 
void CMyTestImportView::OnClockcompUnload()
{
// TODO: добавьте свой код обработчика команд
m_clock.Release();
}
 
 
void CMyTestImportView::OnUpdateClockcompUnload(CCmdUI *pCmdUI)
{
// TODO: добавьте свой код обработчика ИП обновления команд
pCmdUI->Enable(m_clock.GetInterfacePtr() != NULL);
}

Так же добавим диалог для установки будильника и его класс будет называться CAlarmDialog, сам диалог имеет вид

mfc dialog

и класс диалога

AlarmDialog.h »

 

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
#pragma once
 
 
// диалоговое окно CAlarmDialog
 
class CAlarmDialog : public CDialog
{
DECLARE_DYNAMIC(CAlarmDialog)
 
public:
CAlarmDialog(CWnd* pParent = NULL);   // стандартный конструктор
virtual ~CAlarmDialog();
 
// Данные диалогового окна
enum { IDD = IDD_DIALOG1 };
 
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // поддержка DDX/DDV
 
DECLARE_MESSAGE_MAP()
public:
int m_nHours;
int m_nMinutes;
int m_nSeconds;
};

AlarmDialog.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
// AlarmDialog.cpp: файл реализации
//
 
#include "stdafx.h"
#include "MyTestImport.h"
#include "AlarmDialog.h"
#include "afxdialogex.h"
 
 
// диалоговое окно CAlarmDialog
 
IMPLEMENT_DYNAMIC(CAlarmDialog, CDialog)
 
CAlarmDialog::CAlarmDialog(CWnd* pParent /*=NULL*/)
: CDialog(CAlarmDialog::IDD, pParent)
, m_nHours(0)
, m_nMinutes(0)
, m_nSeconds(0)
{
 
}
 
CAlarmDialog::~CAlarmDialog()
{
}
 
void CAlarmDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT1, m_nHours);
DDV_MinMaxInt(pDX, m_nHours, 1, 24);
DDX_Text(pDX, IDC_EDIT2, m_nMinutes);
DDV_MinMaxInt(pDX, m_nMinutes, 1, 59);
DDX_Text(pDX, IDC_EDIT3, m_nSeconds);
DDV_MinMaxInt(pDX, m_nSeconds, 1, 59);
}
 
 
BEGIN_MESSAGE_MAP(CAlarmDialog, CDialog)
END_MESSAGE_MAP()
 
 
// обработчики сообщений CAlarmDialog

Все нажимаем F5 и проверяем приложение. Увы первый модуль не находится, хоть он и зарегистрирован у нас в системе, я проверял через программку OLE Viewer там интерфейса нету IBank, он его не находит, хз. что я только не делал, раз 5 пересоздавал проект первого приложения но ничего не вышло, короче забил я на это, не охота время терять. Второе приложение вроде все нормально подгружается и работает. Третье подключение глючит, вылетает исключение когда мы устанавливаем второй раз будильник и сам будильник не устанавливается в окошке часов когда установлен будильник должна буква A появится, а она не появляется. Нужно доделывать эту программку в коде лазить разбираться почему так происходит. Эти примеры я взял с книги, там они как бы рабочие примеры, там версия VS6 используется у меня 10, мб. поэтому и глюки.

 

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

Ваш адрес 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 Двоичное дерево Задачи С++ Игры С++ Исключения С++ О-большое Операторы_С++ Перегрузка операторов С++ Поиск С++ Потоки Проектирование_С++ С++ Типы_С++ Типы С++ Шаблоны С++ библиотеки локализация макросы С++ сортировка С++

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

  • ExchiNuGs к записи Программка для заполнения форума на vBulletin 3.8.7
  • RA3PKJ к записи visual C++, создание диалоговых окон.
  • admin к записи Как удалить изображение из google
  • Shakanris к записи Программка для заполнения форума на vBulletin 3.8.7
  • костя к записи visual C++, создание диалоговых окон.
©2021 Kselax.ru Theme by ThemeGiant