`

ATL总结一

 
阅读更多

    ATL(Active Template Library,活动模板库)使用c++模板作为自己的实现的基本特性。模板分为两种:函数模板和类模板。

   一. ATL如何使用模板

   以下例子并没有涉及真正的ATL类,只是展示ATL如何使用模板计数在基类里访问成员函数。首先我们看下面的两个类:

class CBase
{
public:
	CBase(){}
	~CBase(){}

	void BaseMethod()
	{
		cout << "BaseMethod in Base" << endl;
	}
};

class CMath : public CBase
{
public:
	CMath(){}
	~CMath(){}
};

    CMath类本身没有任何方法,但它继承了Cbase类的BaseMethod方法。

    

     下面我们就来看看CComObject类是如何根据ATL的类实现进行构建的。

  

template<class T>
class CComObject : public T
{
public:
	CComObject(){}
	~CComObject(){}

	void CallBaseMethod()
	{
		T *pT = static_cast<T*> (this); //就是这句关键的转换
		pT->BaseMethod();
	}
};

  通过把基类作为一个模板参数进行传递并使用该类型对类实现指针进行类型转换,就可以得到指向基类实现的一个直接指针。

 

    下面我们利用ATL来实现一个组件。ATL模板已经帮你实现了类厂,注册,你只需要专注组件的创建。

 (1)打开vs2010--->选择ATL,命名为Chapter3_Server->选择宿主为DLL。

    (2) 然后点击工程右键--->Add-->class。添加接口IMyMath。注意将属性改为custome,不要选择dual.

  (3)然后到MyMath.cpp中实现接口函数。

   (4)然后我们再添加一个接口IAdvancedMath,只能手动添加。

           v4.1 首先在chapter3_server.idl中修改如下:

// Chapter3_Server.idl : IDL source for Chapter3_Server
//

// This file will be processed by the MIDL tool to
// produce the type library (Chapter3_Server.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";

[
	object,
	uuid(3C88BDD5-D63E-49B8-9472-CDD02A1142F3),
	pointer_default(unique)
]
interface IMyMath : IUnknown{
	[] HRESULT Add([in] LONG lOp1, [in] LONG lOp2, [out] LONG* lpResult);
	[] HRESULT Sub([in] LONG lOp1, [in] LONG lOp2, [out] LONG* lpResult);
	[] HRESULT Mul([in] LONG lOp1, [in] LONG lOp2, [out] LONG* lpResult);
	[] HRESULT Div([in] LONG lOp1, [in] LONG lOp2, [out] LONG* lpResult);
};

[
  object,
  uuid(C5747916-8A10-411D-999F-FF0DE103D8D9),
  helpstring("IAdvancedMath Interface"),
  pointer_default(unique)
]
interface IAdvancedMath : IUnknown{
	[] HRESULT Factorial( [in] short sFact,[out,retval] long* pResult );
	[] HRESULT Fibonacci( [in] short sFib, [out,retval]  long* pResult);
};

[
	uuid(940F5ED1-F1EF-4BE9-8729-A03D70105738),
	version(1.0),
]
library Chapter3_ServerLib
{
	importlib("stdole2.tlb");
	[
		uuid(7EEEE9E3-FADD-44E2-86EE-D25C6CD902ED)		
	]
	coclass MyMath
	{
		[default] interface IMyMath;
		interface IAdvancedMath;
	};
};

      v4.2 到 MyMath.h头文件中修改如下:

// MyMath.h : Declaration of the CMyMath

#pragma once
#include "resource.h"       // main symbols



#include "Chapter3_Server_i.h"



#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif

using namespace ATL;


// CMyMath

class ATL_NO_VTABLE CMyMath :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CMyMath, &CLSID_MyMath>,
	public IMyMath,
	public IAdvancedMath
{
public:
	CMyMath()
	{
	}

DECLARE_REGISTRY_RESOURCEID(IDR_MYMATH)


BEGIN_COM_MAP(CMyMath)
	COM_INTERFACE_ENTRY(IMyMath)
	COM_INTERFACE_ENTRY(IAdvancedMath)
END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

//IMath
public:
	STDMETHOD(Add)(LONG lOp1, LONG lOp2, LONG* lpResult);
	STDMETHOD(Sub)(LONG lOp1, LONG lOp2, LONG* lpResult);
	STDMETHOD(Mul)(LONG lOp1, LONG lOp2, LONG* lpResult);
	STDMETHOD(Div)(LONG lOp1, LONG lOp2, LONG* lpResult);

//IAdvancedMath
public:
	STDMETHOD(Factorial)(short,long*);
	STDMETHOD(Fibonacci)(short,long*);
};

OBJECT_ENTRY_AUTO(__uuidof(MyMath), CMyMath)

      v4.3 到MyMath.cpp中实现函数

// MyMath.cpp : Implementation of CMyMath

#include "stdafx.h"
#include "MyMath.h"


// CMyMath



STDMETHODIMP CMyMath::Add(LONG lOp1, LONG lOp2, LONG* lpResult)
{
	// TODO: Add your implementation code here
	*lpResult = lOp1 + lOp2;
	return S_OK;
}


STDMETHODIMP CMyMath::Sub(LONG lOp1, LONG lOp2, LONG* lpResult)
{
	// TODO: Add your implementation code here
	*lpResult = lOp1 - lOp2;
	return S_OK;
}


STDMETHODIMP CMyMath::Mul(LONG lOp1, LONG lOp2, LONG* lpResult)
{
	// TODO: Add your implementation code here
	*lpResult = lOp1 * lOp2;
	return S_OK;
}


STDMETHODIMP CMyMath::Div(LONG lOp1, LONG lOp2, LONG* lpResult)
{
	// TODO: Add your implementation code here
	*lpResult = lOp1 / lOp2;
	return S_OK;
}

long calcFibonacci(short n)
{
	if( n <= 1 )
		return 1;
	return calcFibonacci(n-1) + calcFibonacci(n-2);
}

long calcFactorial(short n)
{
	if( n > 1 )
		return n * calcFactorial(n-1);
	else
		return 1;
}

STDMETHODIMP CMyMath::Factorial(short sOp,long* pResult)
{
	*pResult = calcFactorial(sOp);
	return S_OK;
}

STDMETHODIMP CMyMath::Fibonacci(short sOp,long* pResult)
{
	*pResult = calcFibonacci(sOp);
	return S_OK;
}

     编译即可。

      然后利用regsvr32进行注册。

 

     下面我们编写win32测试函数。

    

// TestChapter3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <tchar.h>
#include <InitGuid.h>
#include "..\..\Chapter3_Server\Chapter3_Server\Chapter3_Server_i.c"
#include "..\..\Chapter3_Server\Chapter3_Server\Chapter3_Server_i.h"

using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
	cout << "初始化com" << endl;
	if( FAILED(CoInitialize(NULL)) )
	{
		cout << "com初始化失败" << endl;
		return -1;
	}

	IMyMath* pMath;
	HRESULT hr =  CoCreateInstance( CLSID_MyMath,
		                            NULL,
									CLSCTX_INPROC,
									IID_IMyMath,
									(void**)&pMath);
	if( FAILED(hr) )
	{
		cout.setf(ios::hex,ios::basefield);
		cout << "Failed to Create server instance. HR =" << hr << endl;
	}

	cout << "get IMyMath interface succeed!" << endl;
	
	long result;
	pMath->Mul(100,8,&result);
	cout << "100*8=" << result << endl;

	IAdvancedMath* pAdvMath = NULL;
	hr = pMath->QueryInterface(IID_IAdvancedMath,(void**)&pAdvMath);
	if( FAILED(hr) )
	{
		cout << "QueryInterface for IAdvancedMath failed" << endl;
		pMath->Release();
		CoUninitialize();
		return -1;
	}

	cout << "get IAdvancedMath interface succeed!" << endl;
	pAdvMath->Factorial(10,&result);
	cout << "10!=" << result << endl;

	pAdvMath->Fibonacci(10,&result);
	cout << "Fibo(10)=" << result << endl;

	pMath->Release();
	pAdvMath->Release();
	CoUninitialize();
	return 0;
}

 

分享到:
评论

相关推荐

    C++标准库STL&ATL之总结

    1. ATL COM宏:ATL使用一系列宏简化了COM对象的创建,如DECLARE_OBJECT_IDL、DECLARE_IID、DECLARE_PROTECT_FINAL_CONSTRUCT等。 2. 小型基类:ATL提供了许多小而高效的基类,如CComPtr(智能指针)、CComQIPtr...

    ICESAT-2 +ATL03 + ATL08

    总结,ICESAT-2的ATL03和ATL08数据结合使用,能够提供强大的地表特征分析能力,尤其是对于森林覆盖区域和冰川研究。通过数据关联和筛选,可以获取到不同地物的精确高度信息,支持气候变化研究、森林生态学以及地形...

    COM_ATL 介绍

    1. **接口映射**:ATL提供了一种机制,通过`DECLARE_INTERFACE_MAP`宏将接口映射到实现,减少了手动实现IUnknown和其他接口的工作。 2. ** ATL基类**:如`CComObjectRootEx`和`CComCoClass`,它们处理了对象的引用...

    ATL开发与COM原理

    总结,ATL和COM是Windows开发中不可或缺的工具,它们为创建可重用、跨平台的组件提供了强大支持。了解和掌握ATL开发与COM原理,能够帮助开发者更好地构建和利用这些组件,提高软件的复用性和扩展性。

    用ATL生成一个简单的DLL并有测试程序调用该DLL

    1. **创建ATL项目** - 首先,在Visual Studio中创建一个新的ATL项目。选择“文件” -&gt; “新建” -&gt; “项目”,然后在项目类型中选择“ ATL”项目。在模板中选择“ATL简单对象”,输入项目名称如“SimpleDLL”。 2....

    ATL 消息互发

    1. 同样使用“ATL项目”模板创建一个新项目,命名为“Dll2”。 2. 在DLL2中,我们需要实现一个接口,比如IMessageReceiver,它包含一个ReceiveMessage方法用于接收来自DLL1的消息。 实现消息传递: 1. 在DLL1中,...

    VC ATL COM 入门实例教程

    1. 使用 ATL COM Wizard 创建一个新的 ATL 项目:在 Visual C++ 中,选择“ATL COM Wizard”并设置工程名和路径,然后选择“Dynamic Link Library”作为服务器类型。 2. 创建一个新的 ATL 对象:在 Workspace View ...

    ATL学习笔记.doc

    总结来说,ATL是C++开发者用来构建COM组件的强大工具,它简化了对象的实现过程,而VS2012提供了一套直观的向导来辅助创建和管理这些组件。通过理解ATL项目创建的步骤、COM组件的注册方法以及如何解决常见的编译和...

    ATL ActiveX密码控件

    1. ATL基础:ATL是微软提供的一个C++模板库,它简化了创建COM对象的复杂性。通过使用ATL,开发者可以快速创建高效、小型的COM组件,包括ActiveX控件。ATL利用模板技术和元类工厂,使得代码更简洁,减少了内存占用和...

    使用ATL对WORD编程

    1. 创建ATL项目:在Visual Studio中,选择ATL简单对象模板,为Word插件创建一个新的项目。 2. 定义接口:使用ATL的宏定义自定义接口,这些接口将暴露给Word应用调用。 3. 实现接口:实现接口中的方法,这些方法将...

    atl word插件源代码

    总结来说,"atl word插件源代码"项目展示了如何使用ATL和VS2012来开发一个与Word集成的插件,该插件支持特定的工具条功能,提供了对Word操作的自定义扩展。通过深入理解ATL、COM、Word Add-ins和VS2012的特性,...

    ICESat2_ATL07_ATL10_ATBD_r004.pdf

    总结起来,《ICESat-2_ATL07_ATL10_ATBD_r004.pdf》是研究和应用ICESat-2海洋冰层数据的科学家们的宝贵资源,它提供了从数据采集到产品生成的全面理论基础,为理解冰层动态变化和气候变化提供了关键的技术支撑。

    ATL设计组件

    总结,ATL设计组件是Windows开发中的一个重要工具,它简化了COM组件的创建和管理。通过ATLDemo项目,我们可以学习到如何使用ATL进行组件设计,理解COM对象的生命周期、接口实现以及如何进行事件处理。通过实践,...

    atl\ATL实现定制的IE浏览器栏·工具栏和桌面工具栏.rar

    总结来说,这个压缩包提供了使用ATL和VC++创建自定义COM组件的实例,特别是关于如何扩展IE浏览器、创建工具栏以及实现桌面工具栏的代码。开发者可以通过学习和理解这些代码,掌握如何利用ATL高效地开发Windows系统中...

    模拟ATL建立Auto Object Map

    总结来说,ATL的Auto Object Map是COM开发中的一个重要工具,它简化了对象注册和管理的过程。通过在VS2008中模拟ATL建立Auto Object Map,开发者可以更高效地创建和维护COM组件。在实际项目中,理解并正确使用Auto ...

    一个VC++编写视频采集ATL控件及C#测试

    总结来说,这个项目展示了如何利用VC++的ATL和DirectShow来创建一个视频采集控件,并在C#环境中对其进行测试和使用。这个过程中,开发者需要熟悉COM编程、ATL模板类、DirectShow滤镜图以及C#对COM组件的调用机制。...

    VC中使用ATL编写控件

    总结,使用VC2005和ATL编写ActiveX控件是一种高效的方式,它能够快速地创建具有复杂功能的Windows控件。ATL的模板和宏大大简化了COM编程,使得开发者能够专注于业务逻辑而不是底层细节。通过上述步骤,你可以构建、...

    ATL的温度计控件

    总结起来,通过VC和ATL技术,我们可以构建一个功能丰富的温度计控件,它结合了滑块的交互性、进度条的可视化和刻度的指示。控件的开发涉及窗口消息处理、图形绘制、事件响应以及属性管理等多个方面,这需要对Windows...

    C++中ATL与WTL学习

    #### 第一部分:ATL中的GUI类 **ATL背景知识** - **ATL与WTL的历史:** 应用程序开发语言(ATL)最初由Microsoft开发,旨在提供一种轻量级、高性能的组件开发框架。随着Windows的演进和技术的发展,ATL逐渐成为...

    ATL使用类型库实现IDispatch接口

    1. **创建ATL项目** - 使用Visual Studio创建一个新的ATL工程,选择" ATL Simple Object"模板。 - 在工程属性中,确保选中"Support Automation"选项,这样ATL会为项目自动生成支持IDispatch的代码。 2. **定义...

Global site tag (gtag.js) - Google Analytics