在VC++6.0中用MFC进行COM编程

MFC类库实现基本COM组件-VS2019 方法二:在“类视图”里面,找到前面有“钥匙”标志的类->右键->添加->添加方法->按照情况选择添加参数,里面返回类型还可以选择类型(坐标也可以,未研究)打开VS2019->创建新项目->ATL项目>下一步->创建->勾选“支持CIM+1.0(T)”->确定。(1)新建的工程右键-> 添加 ->新建项 ->添加 ->自己写ProgID名字->完成。注意:result作为返回值,类型必须是指针,规定!输入截图中的语句,看见弹出框内容,成功。方法一:在下图三个文件中,手动添加代码。要以管理员的身份运行! 阅读详情

首先应当明确,MFC中是通过嵌套类而不是多重继承来实现COM接口的,通过接口映射机制将接口和实现该接口的嵌套类关联起来;MFC中提供一套简明的宏来实现嵌套类的定义.其次,MFC通过CCmdTarget类实现了IUnknown接口.

本文首先描述创建一个COM服务器的步骤和核心代码.然后说明客户程序关键代码.

此COM服务器实现一个TimeLogServer组件,为简明起见,此组件只有一个接口ITimeLog,通过ITimeLog的方法OutputLog可以将日志文本输出至日志文件.

创建一个MFC DLL工程,选择支持Automation(当然本程序不一定是自动化服务器,在这里这样做好处在于自动实现了几个必要的输出函数如DllGetClassObject,DllRegisterServer等,否则要自己写)

第一节 COM服务器

一. 声明组件和接口

1.写一个GUIDs.h,在GUIDs.h中声明组件和接口的GUID

//声明组件GUID {A433E701-E45E-11d3-97B5-52544CBA7F28}
//DEFINE_GUID(CLSID_TimeLogServer, 
//0xa433e701, 0xe45e, 0x11d3, 0x97, 0xb5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28);
static const IID CLSID_TimeLogServer = 
{0xa433e701, 0xe45e, 0x11d3, {0x97, 0xb5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28}};
// 声明接口GUID{A433E702-E45E-11d3-97B5-52544CBA7F28}
//DEFINE_GUID(IID_ITimeLog,
//0xa433e702, 0xe45e, 0x11d3, 0x97, 0xb5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28);
static const IID IID_ITimeLog = 
{0xa433e702, 0xe45e, 0x11d3, {0x97, 0xb5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28}};

2.写一个ITimeLogServer.h,在ITimeLogServer.h文件中声明组件和接口

//ITimeLogServer.h
#include "GUIDs.h"
//接口ITimeLog的声明
DECLARE_INTERFACE_(ITimeLog,IUnknown)
{
  	STDMETHOD(OutputLog)(BSTR* varLogText)PURE;
};

说明:1.宏DEFINE_GUID将组件和接口的progid与GUID相关联.可以用guidgen.exe工具产生.

2.宏DECLARE_INTERFACE_声明接口;该宏第一个参数为接口名,第二个参数为该接口的基类.声明没有基类的接口用DECLARE_INTERFACE宏.

3.宏STDMETHOD声明接口中的方法.此方法的返回值为HRESULT.PURE被解释为"=0",即此方法为纯虚函数.当方法的返回值不是HRESULT时,用宏STDMETHOD_(返回类型,函数名)(参数)PURE;

二.声明组件类CTimeLogServer和实现接口的嵌套类

在ClassWizard中添加新类CTimeLogServer,其基类选择为CCmdTarget.修改其头文件TimeLogServer1.h,加上#include "ITimeLogServer.h";同时在类声明体中加上

//声明实现ITimelog接口的嵌套类
	BEGIN_INTERFACE_PART(TimeLog,ITimeLog)//自动声明IUnknown接口的三个方法
	  STDMETHOD(OutputLog)(BSTR* varLogText);
	END_INTERFACE_PART(TimeLog)
	//声明接口映射
	DECLARE_INTERFACE_MAP()
	//声明类厂
	DECLARE_OLECREATE(CTimeLogServer)

三.实现类厂和接口映射

在CTimeLogServer的实现文件中写入:

//实现类厂
IMPLEMENT_OLECREATE(CTimeLogServer,"TimeLogServer",
           0xa433e701, 0xe45e, 0x11d3, 0x97, 0xb5, 0x52, 0x54, 0x4c, 0xba, 0x7f, 0x28);
//映射接口到相应的嵌套类
BEGIN_INTERFACE_MAP(CTimeLogServer,CCmdTarget)
  INTERFACE_PART(CTimeLogServer,IID_ITimeLog,TimeLog)
END_INTERFACE_MAP()
四.在组件的构造和析构函数中对全局对象计数
CTimeLogServer::CTimeLogServer()
{
	::AfxOleLockApp();
}

CTimeLogServer::~CTimeLogServer()
{
	::AfxOleUnlockApp();
}

五.为嵌套类实现IUnknown接口

//为嵌套类而实现IUnknown接口
STDMETHODIMP_(ULONG)
CTimeLogServer::XTimeLog::AddRef()
{
	METHOD_PROLOGUE(CTimeLogServer,TimeLog)
	return pThis->ExternalAddRef();
}

STDMETHODIMP_(ULONG)
CTimeLogServer::XTimeLog::Release()
{
	METHOD_PROLOGUE(CTimeLogServer,TimeLog)
	return pThis->ExternalRelease();
}

STDMETHODIMP
CTimeLogServer::XTimeLog::QueryInterface(REFIID riid,void**ppvObj)
{
	METHOD_PROLOGUE(CTimeLogServer,TimeLog)
	return pThis->ExternalQueryInterface(&riid,ppvObj);
}

说明:虽然CCmdTarget类已经实现了IUnknown接口,但是还必须通过上述代码来将嵌套类的IUnknown映射到CCmdTarget支持的IUnknown接口.METHOD_PROLOGUEH宏的两个参数分别是实现组件对象的类和实现接口的嵌套类.

六.实现ItimeLog接口的方法OutputLog

注意本组件的功能是往日志文件中输入日志.

1. 在组件类中添加一个文件指针:

  // Attributes
  public:
  protected:
	    FILE* m_logfile;

2. 初始化和退出

首先在CTimeLogServer的构造函数中进行一些初始化:

CTimeLogServer::CTimeLogServer()
{
	::AfxOleLockApp();
	CTime TimeStamp = CTime::GetCurrentTime();
	CString FileName;
	FileName.Format(_T("%s.log"),TimeStamp.Format("%Y%m%d"));
	m_logfile = fopen(FileName,_T("a"));
	if(m_logfile)
	{
		fprintf(m_logfile,_T("# # # # # # # # # # # # # # # # # /n"));
		fprintf(m_logfile,_T("开始于:%s"),(LPCTSTR)TimeStamp.Format("%Y年%m月%d日%H:%M %S"));
		fprintf(m_logfile,_T("/n"));
	}
}
//然后在析构函数中关闭文件
CTimeLogServer::~CTimeLogServer()
{
	::AfxOleUnlockApp();
	if(m_logfile)
	{
		CTime TimeStamp = CTime::GetCurrentTime();
		fprintf(m_logfile,_T("/n"));
		fprintf(m_logfile,_T("结束于:%s"),(LPCTSTR)TimeStamp.Format("%Y年%m月%d日%H:%M %S"));
        fprintf(m_logfile,_T("/n"));
		fprintf(m_logfile,_T("# # # # # # # # # # # # # # # # #/n"));
		fclose(m_logfile);
	}
}

3. 实现接口ITimeLog方法

//实现接口ITimeLog方法
STDMETHODIMP
CTimeLogServer::XTimeLog::OutputLog(BSTR* varLogText)
{
	METHOD_PROLOGUE(CTimeLogServer,TimeLog)
	if(pThis->m_logfile)
	{
		CTime TimeStamp = CTime::GetCurrentTime();
		CString NowTime = TimeStamp.Format("%Y年%m月%d日%H:%M:%S");
		CString LogText((LPCWSTR)*varLogText);
		fprintf(pThis->m_logfile,"/n%s/n%s/n%",NowTime,LogText);
		return NOERROR;
	}
	else
	{
		AfxMessageBox("没有日志文件!");
		return S_FALSE;
	}
}

七.完善组件服务器

在应用对象CTimeLogServerApp的 实现文件中,处理Instance()和ExitInstance()

BOOL CTimeLogServerApp::InitInstance()
{
	::AfxOleLockApp();
	// Register all OLE server (factories) as running.  This enables the
	//  OLE libraries to create objects from other applications.
	COleObjectFactory::RegisterAll();

	return TRUE;
}
int CTimeLogServerApp::ExitInstance() 
{
	// TODO: Add your specialized code here and/or call the base class
    ::AfxOleUnlockApp();	
	return CWinApp::ExitInstance();
}

第二节 客户程序

使用COM组件服务器的客户程序关键步骤是:初始化COM库,创建组件对象并获取IUnknown接口指针,查询接口并使用,释放组件.

    #include "ITimeLogServer.h"
    //初始化COM库,对组件实例化
	HRESULT hResult;
    IUnknown* pIUnknown;
	hResult = ::CoInitialize(NULL);
	if(FAILED(hResult))
	{
		::AfxMessageBox("不能初始化COM库!");
		return FALSE;
	}
	
    //创建组件实例
    pIUnknown = NULL;
	hResult = ::CoCreateInstance(CLSID_TimeLogServer,NULL,
		CLSCTX_INPROC_SERVER,IID_IUnknown,(void**)&pIUnknown);
	if(FAILED(hResult))
	{
		pIUnknown = NULL;
		::AfxMessageBox("不能创建TimeLog对象!");
		return FALSE;
	}
    //查询接口并使用
    if(pIUnknown!=NULL)
		{
			ITimeLog* pITimeLog;
			HResult=pIUnknown->QueryInterface(IID_ITimeLog,(void**)&pITimeLog);
			if(FAILED(hResult))
			{
				::AfxMessageBox("不能获取接口ITimeLog!");
				pIUnknown->Release();
				return;
			}
			BSTR bstrLogText;
			bstrLogText = m_logtext.AllocSysString();
			CString text((LPCWSTR)bstrLogText);
			::AfxMessageBox(text);
						
			if(FAILED(pITimeLog->OutputLog(&bstrLogText)))
			{
				::AfxMessageBox("日志输出出错!");
				pITimeLog->Release();
				return;
			}
			pITimeLog->Release();
			::AfxMessageBox("日志已经写入!");
		}
        //释放组件
        pIUnknown->Release();
        pIUnknown = NULL;
	    ::CoUninitialize();
MFC vc++6 读写Excel 1.Ctrl+W 执行 ClassWizard2.Add Class.../From a type Library... 在 Office 目录中,找到你想使用的类型库。(excel.exe)根据需要添加,(可以全部)(2003)3.包含头文件#include "excel.h"4.详见msdn:Automating Microsoft Office 97 and Microsoft 阅读详情

相关推荐

VC++ Windows平台字符透明编程大总结

VC++ Windows平台字符透明编程大总结程  化1. 前言Windows平台有用Unicode和不用的区分:WinNT到Windows2003一直使用Unicode;WindowsCE也是如此;Win95和Win98就非如此。Windows编程对于字符使用也有各种情况:Windows API的处理方式、MFC的处理方式、VC++的处理方式、COM的处理方式。本文对所有这些方式作了一个

4867

MFC中调用控制台CMD进行输出两种方法

MFC中调用控制台CMD进行输出两种方法 有需要的下载,主要是代码介绍 有需要的看看,上传备忘用的 MFC中调用控制台CMD进行输出两种方法

MFC实现COM组件(附完整源码)

MFC实现COM组件(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 708

C++ COM编程之QueryInterface函数(一)

前言 组件对外公布的是接口;一个组件可以实现多个接口,也就是说可以对外公布多个接口,之前也总结过了,你很少会100%的去完全了解一个组件的所有接口,就像你去学习编程一样,你几乎不可能去成为编程中的全才。那么,既然我们不能去完全的了解一个组件提供的所有接口,那么我们在实际开发中,如何去判断一个组件是否提供对应的接口呢?看文档?是的,是个好主意,在文档的海洋,找到一个知识点,真的很难,浪费时间和

liujiayu2的专栏 1893

掌握VC++ 6.0与MFC的入门教程

VC++ 6.0是微软公司开发的一款经典的集成开发环境,拥有深远的历史地位和广泛的影响。它的设计与开发时代背景,以及它如何成为90年代后期到21世纪初最流行的开发工具之一,是理解现代编程工具和技术的基础。MFC(Microsoft Foundation Classes)是微软公司提供的一套C++类库,用于快速开发Windows应用程序。它最初随Visual C++ 1.0一起发布,并随着后续版本的不断更新,融入了许多新技术和设计模式。

weixin_36382073的博客 929

掌握VC++ 6.0与MSDN:编程者的必备指南

本文还有配套的精品资源,点击获取 简介:VC++ 6.0是微软的经典集成开发环境,适合Windows平台上的应用程序开发。MSDN提供了丰富的微软技术文档和开发资源,是VC++ 6.0开发者的必备工具。本课程将引导你深入了解MFC库、ATL和COM编程、调试技巧、面向对象编程、Windows API、STL、资源管理和文件操作等关键知识点,帮助你充分利用VC++ 6.0和M...

weixin_35433448的博客 879

7.MFC实现简单的COM

使用MFC实现简单的COM,演示了整个COM构成,注释清晰,穿插讲了MFC实现COM的原理,对照本文和代码可以弄懂整个MFC COM实现方法。

文洲的专栏 4856

全面探索VC++6.0 MFC入门教程

MFC(Microsoft Foundation Classes)是微软公司推出的一套用于开发Windows应用程序的C++类库,它封装了许多Windows API,让开发者能够更容易地编写图形用户界面(GUI)应用程序。MFC提供了一套面向对象的框架,使得应用程序的开发更加模块化、结构化。在开始使用VC++6.0之前,首先需要进行安装与配置。VC++6.0是微软推出的Visual Studio系列产品之一,它提供了集成的开发环境,其中包括编辑器、调试器、编译器和链接器等。

weixin_42186015的博客 888

MFC com控件类

MFC的串口有两种操作方法,第一种是第三方库,SerialPort类;第二种是activeX控件MScomm控件。本文只介绍ActiveX控件方法。 activeX控件添加方法: VSdutio环境下可以直接在资源视图下右键dialog选择添加ActiveX控件。 打开工具箱->右键->选择项->COM组件,如图添加相应相即可: 添加控件后为控件后工程会自动添加两个文件:CMscomm.h,CMsconm.cpp, 它是MScomm控件类,使用过程中还需要添加“打开/关闭串口、设置.

qq_37730663的博客 1406

VC++ 6.0 企业版软件深入体验与应用

VC++ 6.0于1998年发布,成为企业开发人员的首选开发工具。它以高效稳定,拥有强大的MFC库,支持多种编程范式如面向过程,面向对象,以及模板编程。其设计目标是为开发人员提供一个快速、高效、友好的开发环境,特别是在Windows平台上进行企业级应用和系统软件的开发。编辑器是代码编写的直接场所,VC++ 6.0的编辑器支持语法高亮、代码折叠、代码自动补全等功能,大大提升了代码编写效率。此外,编辑器还支持类视图、文件大纲等视图方式,方便开发者快速定位代码。

weixin_28713083的博客 1024

VC++ 6.0中创建立体旋钮ActiveX控件的实践指南

VC++ 6.0是微软推出的一款经典的C++开发环境,其推出时间虽已久远,但对于一些老旧的系统或特定的项目需求来说,它仍不失为一个可靠的选择。安装VC++ 6.0需要满足一定的系统要求,通常来说,它需要运行在Windows NT 4.0或更高版本的操作系统上。对于硬件配置而言,至少需要一个奔腾处理器,以及至少64MB的RAM。随着现代计算能力的飞速发展,这样的配置要求看起来非常基础,但在当时,这已经能够满足大多数软件开发的需求。

weixin_35294091的博客 963

VC++6.0中用MFC进行COM编程

        首先应当明确,MFC中是通过嵌套类而不是多重继承来实现COM接口的,通过接口映射机制将接口和实现该接口的嵌套类关联起来;MFC中提供一套简明的宏来实现嵌套类的定义.其次,MFC通过CCmdTarget类实现了IUnknown接口。   本文首先描述创建一个COM服务器的步骤和核心代码.然后说明客户程序关键代码。  此COM服务器实现一个TimeLogServer组件,为简明起见

姜泉的专栏 1400

VC++ MFC 实现游戏手柄编程指南

MFC(Microsoft Foundation Classes)是微软公司提供的一套用于Visual C++开发Windows应用程序的类库。MFC封装了Windows API(应用程序编程接口),使得开发者能够使用面向对象的方式进行Windows平台下的软件开发。MFC库为常见的Windows任务提供了现成的解决方案,比如窗口管理、图形设备接口(GDI)绘图、设备上下文操作和用户界面元素。

weixin_34640289的博客 993

COM组件(MFC篇)

目 录 第1章 创建进程内组件1 1.1 目标1 1.2 创建项目3 1.2.1 VC++6.03 1.2.2 VC++20104 1.2.3 VC++6.0与VC++2010的区别6 1.3 升级项目6 1.3.1 增加接口定义文件6 1.3.2 覆盖应用程序类的InitInstance函数7 1.3.3...

予衡飞翔 2083

Frida+Objection保姆级教程:从环境搭建到实战Hook(含Wallbreaker插件使用)

本文提供了一份从零开始的Frida与Objection移动安全动态分析实战指南。详细讲解了Python环境配置、Frida-Server部署、Objection核心命令使用以及Wallbreaker插件安装与应用。通过实战案例演示如何Hook网络请求(如HttpURLConnection和OkHttp3),帮助安全研究人员快速掌握应用运行时行为分析与漏洞挖掘技能。

weixin_28318011的博客 103

阻容降压 vs 开关电源:5V小功率供电方案成本与安全深度对比

本文深度对比了阻容降压电路与开关电源在5V小功率供电方案中的核心差异。重点剖析了二者在成本、体积、效率、温升及安全隔离等方面的优劣,并结合智能温控器、LED驱动等典型应用场景,为硬件工程师提供了清晰的选型决策框架,帮助在成本与安全之间做出最佳权衡。

weixin_29310631的博客 702
上一篇: 利用其他编译器增强Visual C++的图形功能
下一篇: 《ATL Internals》书评 . 潘爱民
ShowMan
博客等级 码龄26年 280粉丝 321原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值