////ATL方式也是智能指针,我们不需要手动释放 //CComPtr
//ipFtLayer.CoCreateInstance(CLSID_FeatureLayer);
//
//ipFtLayer->putref_FeatureClass(ipFeatureClassTest);
//m_MapControl.Create(L\
////QI
//IDataset *ipDset;
//ipFtLayer.QueryInterface(&ipDset);
//BSTR bSName=SysAllocString(L\
//ipDset->get_Name(&bSName);
//ipFtLayer->put_Name(bSName);
//m_MapControl.put_BackColor(16777215);
//m_MapControl.AddLayer(ipFtLayer,0); //
////第三种方式,这个比智能指针有优势,自动QueryInterface /*IFeatureLayerPtr ipFeatureLayer;
HRESULT hr = ipFeatureLayer.CreateInstance(CLSID_FeatureLayer);
ipFeatureLayer->putref_FeatureClass(ipFeatureClassTest); m_MapControl.Create(L\
m_MapControl.put_BackColor(16777215);
}
m_MapControl.AddLayer(ipFeatureLayer,0);*/
////第四种方式
/*IFeatureLayerPtr ipFeatureLayer(CLSID_FeatureLayer); ipFeatureLayer->putref_FeatureClass(ipFeatureClassTest); IDatasetPtr ipDs(ipFeatureClassTest);
m_MapControl.Create(L\ m_MapControl.put_BackColor(16777215); BSTR bSName=SysAllocString(L\ ipDs->get_Name(&bSName);
ipFeatureLayer->put_Name(bSName);
m_MapControl.AddLayer(ipFeatureLayer,0);*/
//m_MapControl.AddShapeFile(L\数据\\\\1\
添加一个获取要素类的类,如下图:
创建完类之后,添加一个获取要素类的函数(该函数的代码,等看完后面的代码说明之后应该就一目了然)
IFeatureClassPtr CWsClass::GetFeatureClass(BSTR sWorkspacePath,BSTR sFileName) {
IFeatureClassPtr ipFeatureClasses; if(m_workspace!=NULL) {
ipWorkspaceFactory->OpenFromFile(sWorkspacePath,NULL,&m_workspace); CComPtr
ipWorkspaceFactory.CoCreateInstance(CLSID_ShapefileWorkspaceFactory ); IWorkspace * m_workspace;
}
IFeatureWorkspacePtr ipFeatWorksapce(m_workspace);
HRESULT hr= ipFeatWorksapce->OpenFeatureClass(sFileName,&ipFeatureClasses);
}
if(FAILED(hr))
return NULL;
return ipFeatureClasses;
运行后可以看到如下效果(已经说了,不要嘲笑界面)
1.2.6 代码解释
需要对Windows编程和MFC有了解,在这里我只介绍和ArcGIS Engine相关的.
1.2.6.1 如何实例化对象
1.2.6.1.1 最原始做法(我自己这样称呼,学习COM的时候就是这种方式吧)
ArcGIS Engine 的组件库都是基于COM技术的,在COM中我们都是通过接口来完成任务的,但是在使用接口之前,必须要知道这个接口指向的是那个对象,也就是说我们必须实例化对象,然后将对象的返回地址赋给一个接口变量,在C#中这种关系似乎很清楚,如下:
IRasterGeometryProc pRasterGProc = new RasterGeometryProcClass();
之后我们就可以通过pRasterGProc相关操作了,但是我们现在用的是C++,上面这个是不能用了,如果看过《COM本质论》或者其他和COM相关的书籍的人可能知道在COM中是通过CoCreateInstance函数来获取一个对象的指针变量的,具体的代码如下:
// 查看注册表或者tlh文件{E663A651-8AAD-11D0-BEC7-00805F7C4268} 完完全全通过COM自己创建对象 HRESULT
hr1=::CoCreateInstance(CLSID_FeatureLayer,NULL,CLSCTX_ALL,IID_IFeatureLayer,(void**)&ipFeatureLayerX);
if(FAILED(hr1))
return;
//赋值
ipFeatureLayerX->putref_FeatureClass(ipFeatureClassTest);
在COM中,因为一个类可以实现多个接口,每个接口只可以访问自己定义的方法,如果要使用定义在别的接口中的方法呢?我们自然而然的想到了将这个接口“切换”过去,通俗的讲就是这样,只不过专业术语要做QueryInterface(接口查询/访问,英语的理解就行了,不纠结这个翻译了),在C#中我们使用一个as就可以解决问题,如下(IRaster QI到IRasterProps 上):
IRaster pRaster = pRasterLayer.Raster;
IRasterProps pRasterPro = pRaster as IRasterProps;
C++中的做法和这个不一样,但是目的一样,都是为了“切换”到另外一个接口上,因为要素