Kselax.ru

Hacker Kselax — the best hacker in the world

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

Создание OLE приложения dll с использованием диалогового окна MFC

Posted on 22 июля, 201522 июля, 2015 by admin

Здорова!

Сегодня разберем как создать с помощью технологии OLE автоматизация приложение dll которое будет подгружаться в excel и запускать диалоговое окно простейшее. Мы пошагово рассмотрим как это делать.

1 Создание проекта

Создавать мы будем в Visual Studio 2010, запускаем ее и выбираем «создать проект», выбираем «Библиотека DLL MFC», назовем его «MyOleDlg»

mfc ole add

нажимаем «ОК», затем жмем «Далее» и в следующем окошке выбираем «Обычная DLL со статической связью с MFC» и ставим обязательно галочку «Автоматизация»

mfc ole automation

Жмем «Готово», мастер у нас создаст каркас приложения со следующим набором файлов

mfc ole workspace

 

вод код файлов

MyOleDlg.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
26
27
// MyOleDlg.h: главный файл заголовка для DLL MyOleDlg
//
 
#pragma once
 
#ifndef __AFXWIN_H__
#error "включить stdafx.h до включения этого файла в PCH"
#endif
 
#include "resource.h" // основные символы
 
 
// CMyOleDlgApp
// Про реализацию данного класса см. MyOleDlg.cpp
//
 
class CMyOleDlgApp : public CWinApp
{
public:
CMyOleDlgApp();
 
// Переопределение
public:
virtual BOOL InitInstance();
 
DECLARE_MESSAGE_MAP()
};

MyOleDlg.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
// MyOleDlg.cpp: определяет процедуры инициализации для DLL.
//
 
#include "stdafx.h"
#include "MyOleDlg.h"
 
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
 
//
//TODO: если эта библиотека DLL динамически связана с библиотеками DLL MFC,
// все функции, экспортированные из данной DLL-библиотеки, которые выполняют вызовы к
// MFC, должны содержать макрос AFX_MANAGE_STATE в
// самое начало функции.
//
// Например:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // тело нормальной функции
// }
//
// Важно, чтобы данный макрос был представлен в каждой
// функции до вызова MFC. Это означает, что
// он должен быть первым оператором
// функции и предшествовать даже любым объявлениям переменных объекта,
// поскольку их конструкторы могут выполнять вызовы к MFC
// DLL.
//
// В Технических указаниях MFC 33 и 58 содержатся более
// подробные сведения.
//
 
// CMyOleDlgApp
 
BEGIN_MESSAGE_MAP(CMyOleDlgApp, CWinApp)
END_MESSAGE_MAP()
 
 
// создание CMyOleDlgApp
 
CMyOleDlgApp::CMyOleDlgApp()
{
// TODO: добавьте код создания,
// Размещает весь важный код инициализации в InitInstance
}
 
 
// Единственный объект CMyOleDlgApp
 
CMyOleDlgApp theApp;
 
const GUID CDECL _tlid = { 0xCB0DA8CD, 0x2737, 0x4AB7, { 0xA6, 0x55, 0x1E, 0xF4, 0xB8, 0xBE, 0x4, 0x8A } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
 
 
// инициализация CMyOleDlgApp
 
BOOL CMyOleDlgApp::InitInstance()
{
CWinApp::InitInstance();
 
// Регистрирует все OLE-серверы (фабрики) как работающие. Это позволяет
//  библиотекам OLE создавать объекты из других приложений.
COleObjectFactory::RegisterAll();
 
return TRUE;
}
 
// DllGetClassObject - возвращает фабрику класса
 
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllGetClassObject(rclsid, riid, ppv);
}
 
 
// DllCanUnloadNow - разрешает COM выгрузить DLL
 
STDAPI DllCanUnloadNow(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return AfxDllCanUnloadNow();
}
 
 
// DllRegisterServer - добавляет записи в системный реестр
 
STDAPI DllRegisterServer(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))
return SELFREG_E_TYPELIB;
 
if (!COleObjectFactory::UpdateRegistryAll())
return SELFREG_E_CLASS;
 
return S_OK;
}
 
 
// DllUnregisterServer - удаляет записи из системного реестра
 
STDAPI DllUnregisterServer(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
return SELFREG_E_TYPELIB;
 
if (!COleObjectFactory::UpdateRegistryAll(FALSE))
return SELFREG_E_CLASS;
 
return S_OK;
}

 

2 Добавляем диалог

Проект мы создали, добавим теперь в наш проект ресурс диалог (заходим в окошко ресурсов, кликаем правок клавишей мышки и из контекстного меню выбираем добавить ресурс, дальше выбираем ресурс dialog)

mfc ole dialog

Добавим к нему класс, для этого кликаем правой клавишей мышки по нашему диалогу и выбираем «Добавить класс…», назовем класс CMyDialo     mfc ole add class dialog

жмем «Готово», мастер создаст два файла

MyDialog.h »

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
 
 
// диалоговое окно CMyDialog
 
class CMyDialog : public CDialog
{
DECLARE_DYNAMIC(CMyDialog)
 
public:
CMyDialog(CWnd* pParent = NULL);   // стандартный конструктор
virtual ~CMyDialog();
 
// Данные диалогового окна
enum { IDD = IDD_DIALOG1 };
 
protected:
virtual void DoDataExchange(CDataExchange* pDX);    // поддержка DDX/DDV
 
DECLARE_MESSAGE_MAP()
};

MyDialog.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
// MyDialog.cpp: файл реализации
//
 
#include "stdafx.h"
#include "MyOleDlg.h"
#include "MyDialog.h"
#include "afxdialogex.h"
 
 
// диалоговое окно CMyDialog
 
IMPLEMENT_DYNAMIC(CMyDialog, CDialog)
 
CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(CMyDialog::IDD, pParent)
{
 
}
 
CMyDialog::~CMyDialog()
{
}
 
void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
 
 
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
END_MESSAGE_MAP()
 
 
// обработчики сообщений CMyDialog

Добавим две переменные к нашему диалогу для двух элементов управления editControl, для этого правой клавишей кликаем по диалогу из контекстного меню выбираем «добавить переменную…»

mfc ole add variable

Добавляем и вторую переменную таким же способом через мастер

mfc ole add variable1

На этом все диалог у нас создан

3 Создание класса объекта COM с использованием OLE автоматизации

И так диалог мы добавили, осталось нам добавить наш класс который будет вызывать диалог. Назовем его CMyDialog_Auto, он будет наследоваться от класса CCmdTarget чтобы использовать возможности MFC, я не сильно понимаю что там за возможности, наверно в нем используется диспетчеризация и функции из него вызываются, там память очищают и всю фигню делают. В общем создаем класс, кликаем правой клавишей мышки в «Окне классов», выбираем в контекстном меню «Добавить класс…», выбираем в появившемся окне «Класс MFC»

mfc ole create class

обязательно не забудьте поставить галочку «Создается по идентификатору типа», без этого у вас класс и приложение не будет регистрироваться в реестре, если мы выставляем эту опцию то у нас создается идентификатор GUID для класса. Все жмем готово и мастер создает два файла

MyDialog_Auto.h »

 

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

MyDialog_Auto.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
// MyDialog_Auto.cpp: файл реализации
//
 
#include "stdafx.h"
#include "MyOleDlg.h"
#include "MyDialog_Auto.h"
 
 
// CMyDialog_Auto
 
IMPLEMENT_DYNCREATE(CMyDialog_Auto, CCmdTarget)
 
 
CMyDialog_Auto::CMyDialog_Auto()
{
EnableAutomation();
// Чтобы обеспечить работу приложения в течение всего периода активности объекта автоматизации OLE,
// конструктор вызывает AfxOleLockApp.
AfxOleLockApp();
}
 
CMyDialog_Auto::~CMyDialog_Auto()
{
// Чтобы прервать работу приложения, когда все объекты созданы
// при помощи OLE-автоматизации, деструктор вызывает AfxOleUnlockApp.
AfxOleUnlockApp();
}
 
 
void CMyDialog_Auto::OnFinalRelease()
{
// Когда будет освобождена последняя ссылка на объект автоматизации,
// вызывается OnFinalRelease. Базовый класс автоматически
// удалит объект. Перед вызовом базового класса добавьте
// дополнительную очистку, необходимую вашему объекту.
 
CCmdTarget::OnFinalRelease();
}
 
 
BEGIN_MESSAGE_MAP(CMyDialog_Auto, CCmdTarget)
END_MESSAGE_MAP()
 
 
BEGIN_DISPATCH_MAP(CMyDialog_Auto, CCmdTarget)
END_DISPATCH_MAP()
 
// Примечание: мы добавили поддержку для IID_IMyDialog_Auto, чтобы обеспечить безопасную с точки зрения типов привязку
//  из VBA. Этот IID должен соответствовать GUID, связанному с
//  disp-интерфейсом в файле .IDL.
 
// {35EFA93C-2419-4349-BAE6-CFA5E43A2633}
static const IID IID_IMyDialog_Auto =
{ 0x35EFA93C, 0x2419, 0x4349, { 0xBA, 0xE6, 0xCF, 0xA5, 0xE4, 0x3A, 0x26, 0x33 } };
 
BEGIN_INTERFACE_MAP(CMyDialog_Auto, CCmdTarget)
INTERFACE_PART(CMyDialog_Auto, IID_IMyDialog_Auto, Dispatch)
END_INTERFACE_MAP()
 
// {611C69EF-328F-494B-8E56-18D80EEDA81E}
IMPLEMENT_OLECREATE_FLAGS(CMyDialog_Auto, "MyOleDlg.MyDialog_Auto", afxRegApartmentThreading, 0x611c69ef, 0x328f, 0x494b, 0x8e, 0x56, 0x18, 0xd8, 0xe, 0xed, 0xa8, 0x1e)
 
 
// обработчики сообщений CMyDialog_Auto

так же в «Окне классов» у нас появился новый подраздел с интерфейсом IMyDialog_Auto

mfc ole IMy_Dialog_Auto

Кликая по нему правой клавишей мышки мы добавляем функции  и члены к нашему управляемому объекту. Добавим к нашему классу два свойства «LongData» и «TextData» и одну функцию DisplayDialog. Кликаем правой клавишей мышки над IMyDialog_Auto, в появившемся контекстном меню выбираем «Добавить»->»Добавить свойство…», в появившемся окошке выставляем настройки как на скрине ниже

mfc ole add property

Жмем «Далее» и дальше «Готов», снова таким же способом добавляем свойство «TextData»

mfc ole add property1

Жмем «Далее», затем «Готово». Можно сразу «Готово» нажать. Так теперь добавляем метод, для этого так же само кликаем правой клавишей мышки, только уже из контекстного меню выбираем «Добавить»->»Добавить метод…», в появившемся окошке вводим название метода

mfc ole add property2

Жмем «Далее» и «Готово». Посмотрим карту диспетчеризации в файле MyDialog_Auto.cpp

1
2
3
4
5
BEGIN_DISPATCH_MAP(CMyDialog_Auto, CCmdTarget)
DISP_PROPERTY_NOTIFY_ID(CMyDialog_Auto, "LongData", dispidLongData, m_LongData, OnLongDataChanged, VT_I4)
DISP_PROPERTY_NOTIFY_ID(CMyDialog_Auto, "TextData", dispidTextData, m_TextData, OnTextDataChanged, VT_VARIANT)
DISP_FUNCTION_ID(CMyDialog_Auto, "DisplayDialog", dispidDisplayDialog, DisplayDialog, VT_BOOL, VTS_NONE)
END_DISPATCH_MAP()

Видно что добавилось два свойства LongData и TextData и функция DisplayDialog. в наш класс CMyDialog_Auto добавились две protected переменные члены и 3 функции

1
2
3
4
5
6
7
8
9
10
11
void OnLongDataChanged(void);
LONG m_LongData;
enum
{
dispidDisplayDialog = 3L,
dispidTextData = 2,
dispidLongData = 1
};
void OnTextDataChanged(void);
VARIANT m_TextData;
VARIANT_BOOL DisplayDialog(void);

Функции void OnLongDataChanged и OnTextDataChanged это функции отклика, типо когда меняется переменные они вроде как вызываются. А функция DisplayDialog это функция которая будет вызываться из excel и будет создавать диалоговое окошко. И так заполним эти функции, я вам уже приведу полные файлы с кодом.

MyDialog_Auto.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
#pragma once
 
 
// конечный объект команды CMyDialog_Auto
 
class CMyDialog_Auto : public CCmdTarget
{
DECLARE_DYNCREATE(CMyDialog_Auto)
 
public:
CMyDialog_Auto();
virtual ~CMyDialog_Auto();
 
virtual void OnFinalRelease();
 
protected:
DECLARE_MESSAGE_MAP()
DECLARE_OLECREATE(CMyDialog_Auto)
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
void OnLongDataChanged(void);
LONG m_LongData;
 
enum
{
dispidDisplayDialog = 3L,
dispidTextData = 2,
dispidLongData = 1
};
void OnTextDataChanged(void);
VARIANT m_TextData;
VARIANT_BOOL DisplayDialog(void);
};

MyDialog_Auto.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
// MyDialog_Auto.cpp: файл реализации
//
 
#include "stdafx.h"
#include "MyOleDlg.h"
#include "MyDialog_Auto.h"
#include "MyDialog.h"
 
 
// CMyDialog_Auto
 
IMPLEMENT_DYNCREATE(CMyDialog_Auto, CCmdTarget)
 
 
CMyDialog_Auto::CMyDialog_Auto()
{
EnableAutomation();
::VariantInit(&m_TextData);//инициализация
m_LongData=0;
// Чтобы обеспечить работу приложения в течение всего периода активности объекта автоматизации OLE,
// конструктор вызывает AfxOleLockApp.
AfxOleLockApp();
}
 
CMyDialog_Auto::~CMyDialog_Auto()
{
// Чтобы прервать работу приложения, когда все объекты созданы
// при помощи OLE-автоматизации, деструктор вызывает AfxOleUnlockApp.
AfxOleUnlockApp();
}
 
 
void CMyDialog_Auto::OnFinalRelease()
{
// Когда будет освобождена последняя ссылка на объект автоматизации,
// вызывается OnFinalRelease. Базовый класс автоматически
// удалит объект. Перед вызовом базового класса добавьте
// дополнительную очистку, необходимую вашему объекту.
 
CCmdTarget::OnFinalRelease();
}
 
 
BEGIN_MESSAGE_MAP(CMyDialog_Auto, CCmdTarget)
END_MESSAGE_MAP()
 
 
BEGIN_DISPATCH_MAP(CMyDialog_Auto, CCmdTarget)
DISP_PROPERTY_NOTIFY_ID(CMyDialog_Auto, "LongData", dispidLongData, m_LongData, OnLongDataChanged, VT_I4)
DISP_PROPERTY_NOTIFY_ID(CMyDialog_Auto, "TextData", dispidTextData, m_TextData, OnTextDataChanged, VT_VARIANT)
DISP_FUNCTION_ID(CMyDialog_Auto, "DisplayDialog", dispidDisplayDialog, DisplayDialog, VT_BOOL, VTS_NONE)
END_DISPATCH_MAP()
 
// Примечание: мы добавили поддержку для IID_IMyDialog_Auto, чтобы обеспечить безопасную с точки зрения типов привязку
//  из VBA. Этот IID должен соответствовать GUID, связанному с
//  disp-интерфейсом в файле .IDL.
 
// {35EFA93C-2419-4349-BAE6-CFA5E43A2633}
static const IID IID_IMyDialog_Auto =
{ 0x35EFA93C, 0x2419, 0x4349, { 0xBA, 0xE6, 0xCF, 0xA5, 0xE4, 0x3A, 0x26, 0x33 } };
 
BEGIN_INTERFACE_MAP(CMyDialog_Auto, CCmdTarget)
INTERFACE_PART(CMyDialog_Auto, IID_IMyDialog_Auto, Dispatch)
END_INTERFACE_MAP()
 
// {611C69EF-328F-494B-8E56-18D80EEDA81E}
IMPLEMENT_OLECREATE_FLAGS(CMyDialog_Auto, "MyOleDlg.MyDialog_Auto", afxRegApartmentThreading, 0x611c69ef, 0x328f, 0x494b, 0x8e, 0x56, 0x18, 0xd8, 0xe, 0xed, 0xa8, 0x1e)
 
 
// обработчики сообщений CMyDialog_Auto
 
 
void CMyDialog_Auto::OnLongDataChanged(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
// TODO: добавьте код обработчика свойства
TRACE("CMyDialog_Auto::OnLongDataChanged\n");
}
 
 
void CMyDialog_Auto::OnTextDataChanged(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
// TODO: добавьте код обработчика свойства
TRACE("CMyDialog_Auto::OnTextDataChanged\n");
}
 
 
VARIANT_BOOL CMyDialog_Auto::DisplayDialog(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
// TODO: добавьте код обработчика отправки
TRACE("Entering CEx25bAuto::DisplayDialog %p\n", this);
    BOOL bRet = TRUE;
    AfxLockTempMaps();  // See MFC Tech Note #3
    CWnd* pTopWnd = CWnd::FromHandle(::GetTopWindow(NULL));
    try {
      CMyDialog dlg(pTopWnd);
      if (m_TextData.vt == VT_BSTR){
dlg.m_pString = m_TextData.bstrVal; // converts double-byte
                                              //  character to
                                      //  single-byte
                                      //  character                                                                                                                      
      }
  dlg.m_pLong = m_LongData;
      if (dlg.DoModal() == IDOK) {
        m_TextData = COleVariant(dlg.m_pString).Detach();
        m_LongData = dlg.m_pLong;
        bRet = TRUE;
      }
      else {
        bRet =  FALSE;
      }
    }
    catch (CException* pe) {
      TRACE("Exception: failure to display dialog\n");
      bRet =  FALSE;
  pe->Delete();
    }
    AfxUnlockTempMaps();
    return bRet;
}

Так же посмотрим что добавилось в файл MyOleDlg.idl

MyOleDlg.idl »

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
// MyOleDlg.idl: источник библиотеки типов для MyOleDlg.dll
// Этот файл будет обработан компилятором MIDL для создания
// библиотеки типов (MyOleDlg.tlb).
 
#include "olectl.h"
[ uuid(CB0DA8CD-2737-4AB7-A655-1EF4B8BE048A), version(1.0) ]
library MyOleDlg
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
//  Первичный интерфейс диспетчеризации для MyDialog_Auto
[ uuid(35EFA93C-2419-4349-BAE6-CFA5E43A2633) ]
dispinterface IMyDialog_Auto
{
properties:
[id(1) ] LONG LongData;
[id(2) ] VARIANT TextData;
methods:
[id(3)] VARIANT_BOOL DisplayDialog(void);
};
 
//  Сведения о классе для MyDialog_Auto
 
[ uuid(611C69EF-328F-494B-8E56-18D80EEDA81E) ]
coclass MyDialog_Auto
{
[default] dispinterface IMyDialog_Auto;
};
};

не понятная фигня создалась. IDL это язык интерфейсов. tlb файл я пока что не разобрал что это такое, он у нас нигде не создается вроде.

Все ребятки создаем проект нажимаем Ctr+F5, у нас создастся наша dll.

4 Регистрация dll

Теперь нам нужно ее зарегистрировать, для этого существуют специальные утилиты, но мы просто возьмем и скопируем нашу dll в windows/system32 и из командной строки запускаем

windows 7 regsvr32

нажимаем «OK» и нас уведомляют об успешном выполнении регистрации

RegSvr32

Все наша DLL зарегистрирована в реестре, теперь можно тестировать наш модуль

Добавление модуля к excel создание макросов

[tip]как добавлять макросы в excel и кнопки читайте в тут[/tip]

Я использую excel 2010, запускаем наш 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
Dim Dllcomp As Object
Private Declare Sub CoFreeUnusedLibraries Lib "OLE32" ()
 
Sub LoadDllComp()
    Set Dllcomp = CreateObject("MyOleDlg.MyDialog_Auto")
    Range("C3").Select
    Dllcomp.LongData = Selection.Value
    Range("D3").Select
    Dllcomp.TextData = Selection.Value
End Sub
 
Sub RefreshDllComp() 'Gather Data button
    Range("C3").Select
    Dllcomp.LongData = Selection.Value
    Range("D3").Select
    Dllcomp.TextData = Selection.Value
    Dllcomp.DisplayDialog
    Range("C3").Select
    Selection.Value = Dllcomp.LongData
    Range("D3").Select
    Selection.Value = Dllcomp.TextData
End Sub
    
Sub UnloadDllComp()
    Set Dllcomp = Nothing
    Call CoFreeUnusedLibraries
End Sub

Добавляем кнопки как на скрине ниже и каждой кнопке присваиваем свой макрос

excel button

Нажимаем Load DLL у нас подгружается наша DLL, дальше Gather Data жмем у нас подгружается диалоговое окно, вводим данные нажимаем Ок и у нас в excele меняются данные. Нажав Unload DLL мы выгружаем DLL.

5 Как отлаживать нашу DLL

Для этого мы в отладчике указываем наше приложение Excel, и запускаем отладчик, вот какие настройки должны быть в «свойствах проекта» во вкладке «Отладка»

mfc ole debug

Запускаем отладку и отладчик переходит в режим ожидания, затем мы запускаем excel и подгружаем наш модуль и в выводе отладки смотрим что у нас выводится

mfc ole debug1

На этом все.

 

[youtube]https://www.youtube.com/watch?v=KUou63e5jnY[/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