void ::OnMapobjectAddlayer()
{
_MapWinGIS::IFileManagerPtr fm;
fm.CreateInstance(__uuidof(_MapWinGIS::FileManager));
BSTR pVal;
VARIANT_BOOL vBool, bSupported;
CString filepath = OpenLayerFile(false);
BOOL fe = PathFileExists(filepath);
BSTR bStr = filepath.AllocSysString();
if(!fe)
{
AfxMessageBox(_T("New file, will create a new shapefile layer"));
_MapWinGIS::IShapefilePtr newlayer;
newlayer.CreateInstance(__uuidof(_MapWinGIS::Shapefile));
VARIANT_BOOL createFlag = newlayer->CreateNew(bStr, _MapWinGIS::ShpfileType::SHP_POLYLINE);
m_layerHandle = m_map.AddLayer(newlayer, true);
newlayer->Save(nullptr);
}
else
{
HRESULT hResult = fm->get_IsSupported(bStr, &bSupported);
if (bSupported == VARIANT_FALSE)
{
AfxMessageBox(_T("Datasource isn't supported by MapWinGIS"));
::SysFreeString(bStr); //finished using the BSTR
return;
}
else
{
LPDISPATCH obj = fm->Open(bStr, _MapWinGIS::tkFileOpenStrategy::fosAutoDetect, nullptr);
/*
if (obj != nullptr && fm->LastOpenIsSuccess)
{
m_layerHandle = m_map.AddLayer(obj, true);
}
*/
if (fm->LastOpenIsSuccess)
{
if (fm->LastOpenStrategy == _MapWinGIS::tkFileOpenStrategy::fosVectorLayer)
{
_MapWinGIS::IShapefilePtr shpfile;
shpfile.CreateInstance(__uuidof(_MapWinGIS::Shapefile));
shpfile = (IShapefilePtr)obj;
if (shpfile != nullptr)
m_layerHandle = m_map.AddLayer(shpfile, true);
}
else
{
_MapWinGIS::IImagePtr image;
image.CreateInstance(__uuidof(_MapWinGIS::Image));
image = (IImagePtr)obj;
if (image != nullptr)
m_layerHandle = m_map.AddLayer(image, true);
}
}
else
{
fm->get_ErrorMsg(fm->LastErrorCode, &pVal);
CString str(pVal);
AfxMessageBox(_T("Failed to open datasource: ") + str);
return;
}
}
}
::SysFreeString(bStr); //finished using the BSTR
m_map.Redraw();
}
The problem is in calling fm->get_IsSupported(bStr, &bSupported) as if returning BOOLEAN; It return S_OK. The solution is to check bSupported for supported shapefiles;
Yes, that’s correct. All COM calls from c++ return an HRESULT, and you check for S_OK. The return value of all functions (as you would see from a high-level language) will always instead be the last parameter when called from c++.