1. 新建项目
这里我们使用ATL,来接受C# COM控件向外发送的事件。
2. 初始化ATL
#include "stdafx.h"
CComModule _module;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
_module.Init(NULL, hModule);//初始化
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
_module.Term();//释放
}
break;
}
return TRUE;
}
3. 定义一个显示UI的接口类
IShowUI.h
#ifdef DLL_SHOW_UI
#define DLL_CLASS _declspec(dllimport)
#else
#define DLL_CLASS _declspec(dllexport)
#endif
#ifndef _ISHOW_UI_H_
#define _ISHOW_UI_H_
#include
#include
using std::function;
class DLL_CLASS IShowUI
{
protected:
IShowUI();
virtual ~IShowUI();
public:
static IShowUI* CreateInstance();
static void DestoryInstance(IShowUI* pIShowUI);
public:
virtual void SetCallback(function* pCallback) = 0;
virtual void ShowDialog(BSTR bstrDialogType, BSTR bstrParam) = 0;
};
#endif
IShowUI.cpp
#include "IShowUI.h"
#include "ShowUIImpl.h"
IShowUI::IShowUI()
{
}
IShowUI::~IShowUI()
{
}
IShowUI* IShowUI::CreateInstance()
{
IShowUI* pIShowUI = new CShowUIImpl;
return pIShowUI;
}
void IShowUI::DestoryInstance(IShowUI* pIShowUI)
{
if (pIShowUI)
{
delete pIShowUI;
}
}
4. 定义一个显示UI的实现类
ShowUIImpl.h
#ifndef _SHOW_UI_IMPL_H_
#define _SHOW_UI_IMPL_H_
#include "IShowUI.h"
#ifdef _DEBUG
#import "../NetActiveX/bin/Debug/NetActiveX.tlb"
#else
#import "../NetActiveX/bin/Release/NetActiveX.tlb"
#endif
class CHandleEvent;
class CShowUIImpl : public IShowUI
{
public:
CShowUIImpl();
virtual ~CShowUIImpl();
public:
virtual void SetCallback(function* pCallback);
virtual void ShowDialog(BSTR bstrDialogType, BSTR bstrParam);
private:
function* m_pCallback;
CHandleEvent* m_pHandleEvent;
NetActiveX::IShowDialogPtr m_showDialogPtr;
};
#endif
ShowUIImpl.cpp
#include "stdafx.h"
#include "IShowUI.h"
#include "ShowUIImpl.h"
#include "SystemString.h"
#include
//处理C# COM控件发送的事件
class CHandleEvent : public IDispEventImpl<0,
CHandleEvent,
&(__uuidof(NetActiveX::IEvent)),
&(__uuidof(NetActiveX::__NetActiveX)),
1,
0>
{
public:
CHandleEvent()
{
m_pCallback = NULL;
}
void SetEventCallback(std::function* pCallback)
{
m_pCallback = pCallback;
}
STDMETHOD(NotifyEvent)(BSTR bstr)
{
if (m_pCallback)
{
(*m_pCallback)(bstr);
}
return S_OK;
}
BEGIN_SINK_MAP(CHandleEvent)
SINK_ENTRY_EX(0, (__uuidof(NetActiveX::IEvent)), 20, NotifyEvent)//事件处理函数,此处的事件ID=20必须和C# NotifyEvent定义的完全一样
END_SINK_MAP()
private:
function* m_pCallback;//事件处理回调函数
};
CShowUIImpl::CShowUIImpl()
{
CoInitialize(NULL);
m_pCallback = NULL;
m_pHandleEvent = new CHandleEvent;
m_showDialogPtr = NetActiveX::IShowDialogPtr(__uuidof(NetActiveX::ShowDialogImpl));
}
CShowUIImpl::~CShowUIImpl()
{
delete m_pHandleEvent;
m_pHandleEvent = NULL;
CoUninitialize();
}
void CShowUIImpl::SetCallback(function* pCallback)
{
m_pCallback = pCallback;
}
void CShowUIImpl::ShowDialog(BSTR bstrDialogType, BSTR bstrParam)
{
if (m_showDialogPtr.GetInterfacePtr())
{
CSystemString strDialogType(bstrDialogType);
CSystemString strParam(bstrParam);
m_pHandleEvent->SetEventCallback(m_pCallback);//设置事件处理回调函数
m_pHandleEvent->DispEventAdvise(m_showDialogPtr);//注册事件
m_showDialogPtr->ShowDialog(strDialogType.GetBSTR(), strParam.GetBSTR());
m_pHandleEvent->DispEventUnadvise(m_showDialogPtr);//取消事件
}
}
5. 其他辅助类
SystemString.h
#ifndef _SYSTEM_STRING_H_
#define _SYSTEM_STRING_H_
class CSystemString
{
public:
explicit CSystemString(BSTR bstr)
{
if (bstr)
{
m_bstr = SysAllocString(bstr);
}
else
{
m_bstr = NULL;
}
}
~CSystemString()
{
Clear();
}
void Clear()
{
if (m_bstr)
{
SysFreeString(m_bstr);
m_bstr = NULL;
}
}
BSTR GetBSTR() {return m_bstr;}
private:
CSystemString(CSystemString&);
CSystemString& operator =(CSystemString&);
private:
BSTR m_bstr;
};
#endif
6. 新建一个C++ win32控制台应用程序,调用DLL显示C#对话框
#include "stdafx.h"
#include
#include
#define DLL_SHOW_UI
#include "IShowUI.h"
using std::string;
using std::wstring;
#pragma comment(lib, "DllInterface.lib")
class EmployeeData
{
public:
void ParseString(wstring s)
{
int beg = -1;
int end = -1;
beg = 0;
end = s.find(L",", beg);
if (end != -1)
{
m_name = s.substr(beg, end - beg);
beg = end + 1;
}
end = s.find(L",", beg);
if (end != -1)
{
m_sex = s.substr(beg, end - beg);
beg = end + 1;
}
end = s.find(L",", beg);
if (end != -1)
{
m_age = _wtoi(s.substr(beg, end - beg).c_str());
beg = end + 1;
}
end = s.find(L",", beg);
if (end != -1)
{
m_phone = s.substr(beg, end - beg);
beg = end + 1;
}
end = s.length();
if (beg < end)
{
m_mobile = s.substr(beg, end - beg);
}
}
wstring ToString()
{
wstring s = L"";
wchar_t psz[32] = {0};
s += m_name;
s = s + L"," + m_sex;
s = s + L"," + _itow(m_age, psz, 10);
s = s + L"," + m_phone;
s = s + L"," + m_mobile;
return s;
}
wstring m_name;
wstring m_sex;
int m_age;
wstring m_phone;
wstring m_mobile;
};
void Callback(BSTR bstr)
{
EmployeeData employee;
employee.ParseString(bstr);
}
int _tmain(int argc, _TCHAR* argv[])
{
IShowUI* pShowUI = IShowUI::CreateInstance();
EmployeeData employee;
function call = std::bind(&Callback, std::tr1::placeholders::_1);
employee.m_name = L"123";
employee.m_sex = L"男";
employee.m_age = 10;
employee.m_phone = L"123456";
employee.m_mobile = L"13245678952";
BSTR bstr = L"EmployeeDialog";
wstring s = employee.ToString();
BSTR bstrParam = (BSTR)s.c_str();
pShowUI->SetCallback(&call);//设置事件响应回调
pShowUI->ShowDialog(bstr, bstrParam);//显示员工属性对话框
IShowUI::DestoryInstance(pShowUI);
pShowUI = NULL;
return 0;
}
c#调用c++制作的基于mfc的ocx控件
原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/51286926 原文中有问题部分已修改. c#调用c++制作的基于mfc的ocx控件 ...
Ruby操作VBA的注意事项和技巧(2):宏里调用和控制窗体以及窗体上的控件、不同workbook之间的宏互相调用
4.宏里调用并控制窗体以及窗体上的各种控件 1 Sub Criterion_Check() 2 If Workbooks.count = 0 Then '如果当前没有打开的工作薄的话需要发出警告 3 ...
Delphi 在DLL中使用DevExpress控件时出错解决办法
测试环境 DevExpress VCL 14.1.3 和XE7 问题:在dll使用cxGrid控件时 如果不添加列标题 则不报错 查询无数据集显示,如果加上标题 就报错了 这段为报错部分 fun ...
Android调用相机拍摄照片并显示到 ImageView控件中
在前面的一篇文章中曾介绍过简单的开启相机照相功能,详见 Android简单调用相机Camera功能,实现打开照相功能 ,这一次就会将前面拍摄的照片显示到ImageView中,形成一个完整的效果 看实例 ...
C#调用ActiveX控件
背景:最近项目中需要用到ActiveX控件,项目是在.Net平台下开发的.因此就直接在项目中添加了对ActiveX控件的引用,添加引用成功.在代码中实例化类的实例也没有问题,但在调用其方法或属性时总是 ...
Java 通过 jacob调用OCX控件
安装好要调用的ocx驱动,并通过注册表查询其对应的clsid. 下载jacob-1.18解压,将jacob-1.18-x86.dll文件复制到D:\Program Files (x86)\Java\j ...
C#调用第三方ocx控件 (winform /aspx)
C#调用第三方ocx控件 1..net环境在工具箱上点右键,选择自定义工具箱,然后选择你需要的COM或者OCX控件就可以了. 2.在自定义工具箱中加入相应的控件,设置id,在客户端脚本中直接引用它 ...
Qt开发Activex笔记(二):Qt调用Qt开发的Activex控件
若该文为原创文章,转载请注明原文出处本文章博客地址:https://blog.csdn.net/qq21497936/article/details/113789693 长期持续带来更多项目与技术分享 ...
VS2010 开发 VB6.0 activeX控件 dll
项目源码 https://download.csdn.net/download/csdn_z_s/10427764 开发环境 操作系统: win7 64位 旗舰版 Java语言开发环境: Eclip ...
随机推荐
个人纪录(初)----Ueditor文本编辑器的引用
源码下载地址:http://ueditor.baidu.com/website/ 打开源码参考.html 把ueditor引入自己的web项目下. 在需要引入文本的地方写个div,设置样式等. 并且在 ...
POJ 1442 Black Box
第k大数维护,我推荐Treap..谁用谁知道.... Black Box Time ...
Reverse Linked List II [LeetCode]
Reverse a linked list from position m to n. Do it in-place and in one-pass. For example:Given 1-> ...
Open-Drain V.S. Push-Pull
作者:crifan (http://bbs.chinaunix.net)邮箱:green-waste@163.com [Open-Drain与Push-Pull]GPIO的功能,简单说就是可以根据自己 ...
左移运算符<;<;
在许多计算机编程语言(例如:C语言.C++语言.Java语言.JavaScript语言,Pascal语言等)中,“<
cycle标签和random两种方式美化表格
一:cycle标签实现给表格变色 1.
学习字典才联想到要和 JSP 说再见了
最开始只是想让页面能够映射出我的字典值,然而却发现了更大的问题. 假如你自己做一个 demo ,需要前台页面映射出字典数据你会怎么做呢?大致的思路应该是有的,准备字典,准备数据,然后将两部分进行映射. ...
JavaSE(十)之Map总结 (转)
http://www.cnblogs.com/zhangyinhua/p/7545979.html 阅读目录(Content) 一.Map接口 1.1.为什么Collection不能满足集合的所有功能 ...
Spark学习笔记--Linux安装Spark集群详解
本文主要讲解如何在Linux环境下安装Spark集群,安装之前我们需要Linux已经安装了JDK和Scala,因为Spark集群依赖这些.下面就如何安装Spark进行讲解说明. 一.安装环境 操作系统 ...
lua字符串对齐函数
最近要用到字符串对齐,开始只是一部分字符串,就直接加空格了,后来发现有很多, 于是写了个字符串对齐的函数. --功能:分割字符串 --参数:带分割字符串,分隔符 --返回:字符串表 function ...