组件对象模型与ATL实现
2010-09-04 20:48:02 来源:WEB开发网四 添加实现代码
下面增加添加元素的方法,即去除前面IDL文件中的注释为:
[id(1),helpstring("向集合增加一个元素,返回引用")] HRESULT Add([out,retval] ILayer** ppRef);
[id(1),helpstring("向集合增加一个元素,返回引用")] HRESULT Add([out,retval] IShape** ppRef);
在Layers.h中,添加方法的实现代码如下:
public:
STDMETHODIMP Add(ILayer** ppRef)
{
CComPtr<ILayer> spObj;
HRESULT hr = CLayer::CreateInstance(&spObj);
if (SUCCEEDED(hr))
{
m_coll.push_back(spObj);
return spObj.CopyTo(ppRef);
}
return hr;
}
在Shapes.h中,添加方法的实现代码如下:
public:
STDMETHODIMP Add(IShape** ppRef)
{
CComPtr<IShape> spObj;
HRESULT hr = CShape::CreateInstance(&spObj);
if (SUCCEEDED(hr))
{
m_coll.push_back(spObj);
return spObj.CopyTo(ppRef);
}
return hr;
}
现在,我们的集合对象已经基本好了。同时,通过一系列的改动,我们把Layers和Shapes指定为不可创建的对象,所以,我们可以把它们的注册表条目彻底删除:把Layers.rgs和Shapes.rgs大胆地彻底消灭掉。当你消灭了它们,编译会提示2条错误,双击错误,在文件MapLib.rc中,把下面的条目删除:
IDR_LAYERS REGISTRY "Layers.rgs"
IDR_SHAPES REGISTRY "Shapes.rgs"
特别值得注意:
依照此方法,你可以删除任何不需要独立创建的COM对象。比如本例中的Shape和Layer对象也不需要在注册表里注册,所以你也可以仿照Layers和Shapes的处理方式,改变向导生成的代码,删除它们的条目。如果你仍然想单独创建它们,你可以在根对象接口(这里是ICanvas)中添加创建的方法,如CreateObject,而在CreateObject方法内部实现上,采用C++创建对象,而不是使用COM类厂(需要通过注册表的GUID机制创建对象,速度比用C++创建对象慢了不知道多少倍。尤其在脚本中创建对象,使用new ActiveXObject方法是异常慢的)这样做的好处是,你在注册表中只需要留有根对象条目,简洁的多拉。
我们的Layers是通过Canvas得到的,因此,添加属性到ICanvas中:
// MapLib.idl : MapLib 的IDL 源
...
interface ICanvas : IDispatch{
......
[propget,id(1),helpstring("得到图层对象的引用")] HRESULT Layers([out, retval] ILayers** ppRef);
// [id(2),helpstring("使用C++创建对象的例子")] HRESULT CreateObject([in] BSTR bstrObjName, [out, retval] IDispatch** ppOutObj);
}
赞助商链接