ATL建立Com的相关学习和编程总结

    Com的相关概念学习,网上有很多资料,我也是一篇一篇的资料学习而来的,这里相关概念就不做赘述了。Com的学习,光看资料是不行的,虽然可能概念方面你都掌握了,但是给你个任务编写个Com组件,都不知道怎么去下手。博主也是看了几天的资料仍是一头雾水,最后查找相关的代码详解,才一步步知道怎么编程。但是网上相关的实例比较少,总结的详细的也就更少了。写这篇博客的目的是想把我学习的过程总结下,同时也把自己过程中遇到的问题和解决方法写下来方便以后查看。

    ATL(ActiveX Template Library,活动模板库)是一套C++的模板库,利用它可以很方便地建立小型的、基于COM的组件,对COM组件的开发提供了最大限度的代码自动生成以及可视化的支持。模板是ATL的核心技术。

一、创建Com:


点击ok选择dll,Support options选择Support MFC 点击finish创建



系统会自动生成两个项目,其中结尾带PS的不做操作,具体什么作用没有具体研究
其中 为项目的生成文件,可以做具体的调用文件。源文件中有一个.idl文件为项目的信息文件,可以查看项目的注册键值。
右键项目添加一个ATL Simple Object类


进入类的创建界面,只需输入short name也就是类的名称,其他项自动添加



在生成的MyMath.h文件中如下代码
class ATL_NO_VTABLE CMyMath :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMyMath, &CLSID_MyMath>,
	public IDispatchImpl<IMyMath, &IID_IMyMath, &LIBID_ComTestLib, /*wMajor =*/ 1, /*wMinor =*/ 0>
为用ATL建立Com的派生类,CComObjectRootEx提供IUnknown实现方法和组件线程模型,包括管理引用计数,CComCoClass提供缺省积累行为和定义类工厂;IDispatchImpl是个类模版,提供IDispatch接口实现。
DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

public:

	//方法和变量的声明位置

};

OBJECT_ENTRY_AUTO(__uuidof(MyMath), CMyMath)
public下是具体的方法和变量的声明,这是头文件中的。ATL提供了很好的创建方法机制,所以最好不要自己写,容易出错。

下面添加一个加法方法:
点击到Class View在当前项目中有个定义类的接口(I+方法名),我的为IMyMath,右键它有个添加方法,方法的返回值都是HRESULT。其中下方是定义方法的参数,in为输入参数,out为返回参数,返回参数都是为指针。


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

public:

	STDMETHOD(Add)(LONG num1, LONG num2, LONG* result);
	STDMETHOD(Sub)(LONG num1, LONG num2, LONG* result);
	STDMETHOD(mul)(LONG num1, LONG num2, LONG* result);
	STDMETHOD(Div)(LONG num1, LONG num2, LONG* result);
};
public中声明了4个方法,切记不要随便改动函数构造,如果改了,不仅源文件和头文件里的需要改,在.idl文件中的也需要相应的修改。
在源文件中就可以做具体操作了:
STDMETHODIMP CCxMath::Add(LONG num1, LONG num2, LONG* result)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: Add your implementation code here
	LONG lResult = num1 + num2;
	*result = lResult;
	return S_OK;
}
其中返回值,最好加一个中间参数,否则有的情况下多个调用时,某一处被释放了,其他就调用不到相应的值了。
好了,一个简单的Com就可以拉,生成就可以调用了。

二、com的调用

com的调用方法有很多种,下面是我用的其中一种

需要引用com生成的两个文件

#include “ComTest.h"
#include “ComTest_i.c“

        CoInitialize(NULL);
	IMyMath* pMath;
	HRESULT hr;
	hr = ::CoCreateInstance(CLSID_MyMath, NULL, CLSCTX_ALL, IID_IMyMath, (void**)&pMath);
	if (SUCCEEDED(hr)&&pMath != NULL)
	{
		LONG l;
		CString strNum1,strNum2;
		GetDlgItem(IDC_EDIT1)->GetWindowText(strNum1);
		GetDlgItem(IDC_EDIT2)->GetWindowText(strNum2);
		//long s = _ttoi(strNum1);
		//long ss = _ttoi(strNum2);
		pMath->Add(_ttoi(strNum1),_ttoi(strNum2),&l);
		CString strResult;
		strResult.Format(L"%d",l);
		GetDlgItem(IDC_EDIT3)->SetWindowText(strResult);
	}

其他调用方法:

#include "ComTest.h"
#include "ComTest_i.c"
   ::CoInitialize( NULL );
    IUnknown * pUnk = NULL;
    IMyMath * pMath = NULL;   
    HRESULT hr;
    hr = ::CoCreateInstance(CLSID_MyMath,NULL,
                                 CLSCTX_INPROC_SERVER,IID_IUnknown, 
                                 (LPVOID *) &pUnk);
     if( FAILED( hr ) )throw( _T(“组件没注册!") );
     hr = pUnk->QueryInterface(IID_IMyMath,(LPVOID *)&pMath );
     if( FAILED( hr ) )throw( _T("没有接口?") );
     hr = pMath->Add( 1, 2, &nSum );  //调用组件函数

#include "ComTest.h"
#include "ComTest_i.c“
    ::CoInitialize( NULL );
     CComPtr < IUnknown > spUnk;	
    CComPtr < IFun > spFun;		
    HRESULT hr;
    hr = spUnk.CoCreateInstance( CLSID_Fun );
    if( FAILED( hr ) )	throw( _T("没注册组件") );
     hr = spUnk.QueryInterface( &spFun );
     if( FAILED( hr ) )	throw( _T("没有接口") );
     hr = spFun->Add( 1, 2, &nSum );
我就列举几种,其他的方法网上很多

在调用过程中,.h和.c文件必须同时调用,不然会出现很多未知的问题。

总结的有点乱,先写到这,以后有时间再更新新内容。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值