Hi everyone,I have developed an ArcMap add-in (COM/ATL-Application written in C++). This add-in reads IMG-files (Erdas Imagine format), does some calculations and writes new IMG-files. Optionally the new IMG-files can be visualized in ArcMap.Sometimes after closing the add-in and closing ArcMap I get the Message "An unhandled win32 exception occurred in ArcMap.exe" from Visual Studio Debugger. I monitored this only when visualizing the map in ArcMap and if the add-in was built in release mode. No exception occour if the add-in was build in debug mode.In environments without Visual Studio, I monitor that the ArcMap.exe prozess doesn't disappear after closing ArcMap (instead of the exception message above).In Method ShowDistibutionMap the variable HRESULT hr is everytime S_OK.The error is not solid reproducable.I'm using- Visual Studio 2005 Professional Edition- ArcGIS Desktop 9.2.0.1324 with ArcGIS Service Pack: 6 (build 9.2.6.1500)- C++What is the cause of the exceptions? How can I avoid it?Any help would be greatly appreciated.Thanks,Rainer
HRESULT CRasterUtil::ShowDistibutionMap(
const CString& sRasterFile,
const char* pTableFile,
IRasterLayer* pRasterLayer
)
{
if ( !PathFileExists( sRasterFile ) )
return S_FALSE;
CSplitPath sp( sRasterFile );
CString sPath = sp.GetDrive() + sp.GetDirectory();
CString sFile = sp.GetFileName() + sp.GetExtension();
CString sTmpFile = sPath + sp.GetFileName() + "_at oll" + sp.GetExtension();
if ( PathFileExists( sTmpFile ) )
remove( sTmpFile );
IWorkspaceFactoryPtr ipWkspFac(CLSID_RasterWorkspaceFactory);
//Open Workspace
IWorkspacePtr ipWksp;
HRESULT hr = ipWkspFac->OpenFromFile(sPath.AllocSysString(), 0, &ipWksp);
// Open the Geo file dataset
IRasterDatasetPtr pGeoDataset;
hr = ((IRasterWorkspacePtr) ipWksp)->OpenRasterDataset(sFile.AllocSysString(),&pGeoDataset);
//IRasterLayerPtr pRasterLayer(CLSID_RasterLayer);
hr = pRasterLayer->CreateFromDataset(pGeoDataset);
IRasterPtr pRaster;
hr = pRasterLayer->get_Raster( &pRaster );
IRasterPropsPtr sRasterProp( pRaster );
double dSizeX;
double dSizeY;
getCellSize(sRasterProp, dSizeX, dSizeY);
double dFactor = 1;
if( m_normalizeTrafficVolume )
{
double cp2 = 2.;
double dFac = 1000. / dSizeX;
dFactor = pow(dFac, cp2);
}
HISTODATA* pHisto = GetHistogram(pTableFile);
if ( pHisto == NULL)
return S_FALSE;
SAFEARRAYBOUND rgsabound;
_variant_t var;
_variant_t Array;
rgsabound.lLbound = 1;
rgsabound.cElements = pHisto->lCount;
// Equivalent to: Dim aiNew(1 To 8) As Double.
SAFEARRAY *pDoubleArray = SafeArrayCreate(VT_R8, 1, &rgsabound);
if( !pDoubleArray )
return S_FALSE;
SAFEARRAY *pLongArray = SafeArrayCreate(VT_UI4, 1, &rgsabound);
if( !pLongArray )
return S_FALSE;
for (long i=0; i<pHisto->lCount; i++)
{
double dVal = pHisto->pValue * dFactor;
SafeArrayPutElement(pDoubleArray, &i, (void *)&dVal ); //&pHisto->pValue);
SafeArrayPutElement(pLongArray, &i, (void *)&pHisto->pFrequence);
}
//Delete the data struct
if ( pHisto )
{
if ( pHisto->pFrequence )
delete pHisto->pFrequence;
if ( pHisto->pValue )
delete pHisto->pValue;
delete pHisto;
}
VARIANT sValues;
VariantInit(&sValues);
sValues.vt = VT_ARRAY|VT_R8;
sValues.parray = pDoubleArray;
VARIANT sFrequence;
VariantInit(&sFrequence);
sFrequence.vt = VT_ARRAY|VT_UI4;
sFrequence.parray = pLongArray;
if ( m_StatusBar )
{
hr = m_StatusBar->put_Message(0, L"Preparing distribution map for Atoll...");
hr = m_StatusBar->put_Visible(VARIANT_TRUE);
}
IRasterBandCollectionPtr pRasterCol(pRaster);
// Create classfy renderer and QI RasterRenderer interface
IRasterClassifyColorRampRendererPtr pClassRen(CLSID_RasterClassifyColorRampRenderer);
IRasterRendererPtr pRasRen = pClassRen;
hr = pRasRen->putref_Raster( pRaster );
hr = pRasRen->Update();
// To set classification method, we need to get the histogram of the
// raster. To simplify the sample, we only consider a raster that has
// a table.
if ( m_StatusBar )
{
hr = m_StatusBar->put_Message(0, L"Prepare distribution map for Atoll...");
hr = m_StatusBar->put_Visible(VARIANT_TRUE);
}
IRasterBandCollectionPtr pBandCol( pRaster );
IEnumRasterBandPtr pEnumRasterBand;
hr = pRasterCol->get_Bands(&pEnumRasterBand);
IRasterBandPtr pRasBand;
hr = pEnumRasterBand->Next( &pRasBand );
BSTR sField = L"Value [Erlang/qkm]";
double dMax = 0.;
IClassifyPtr pClassify(CLSID_Quantile); //EqualInterval);
// Create EqualInterval classification and obtain the UID
//hr = pClassify->SetHistogramData( vValues, vFrequences);
hr = pClassify->SetHistogramData( sValues, sFrequence);
int NumOfClass = 20; //5;
hr = pClassify->Classify( &NumOfClass );
VARIANT ClassBreak;
hr = pClassify->get_ClassBreaks( &ClassBreak );
double *clsBreaks; // Pointer to double elements
SafeArrayAccessData(ClassBreak.parray, (void**) &clsBreaks);
IUIDPtr ipUID;
hr = pClassify->get_ClassID( &ipUID );
// Using IRasterClassifyUIProperties to set classification method to
// the raster classify render. If it is not set, NatrualBreak
// classification will be used
IRasterClassifyUIPropertiesPtr pClassProp (pClassRen);
hr = pClassProp->putref_ClassificationMethod( ipUID );
// Set raster classify renderer
hr = pClassRen->put_ClassCount( NumOfClass );
hr = pClassRen->put_ClassField( sField );
for (int i=0; i<NumOfClass; i++)
double dval = clsBreaks;
hr = pClassRen->put_Break(0, 0);
//for (int i=2; i<NumOfClass; i++)
for (int i=0; i<NumOfClass; i++)
hr = pClassRen->put_Break(i+1, clsBreaks); //*dFACTOR);
// Create a color ramp to use
IAlgorithmicColorRampPtr ipRamp(CLSID_AlgorithmicColorRamp);
IRgbColorPtr pStartColor(CLSID_RgbColor);
hr = pStartColor->put_Red(0);
hr = pStartColor->put_Blue(255);
hr = pStartColor->put_Green(0);
hr = ipRamp->put_FromColor(pStartColor);
IRgbColorPtr pEndColor(CLSID_RgbColor);
hr = pEndColor->put_Red(0);
hr = pEndColor->put_Blue(0);
hr = pEndColor->put_Green(255);
hr = ipRamp->put_ToColor( pEndColor );
long lCount = NumOfClass; //256;
hr = ipRamp->put_Size( lCount );
VARIANT_BOOL ok;
hr = ipRamp->CreateRamp(&ok);
// Create symbol for the classes
IFillSymbolPtr ipFSymbol(CLSID_SimpleFillSymbol);
ISymbolPtr ipSymbol(ipFSymbol);
IEnumColorsPtr pEnumColors;
hr = ipRamp->get_Colors ( &pEnumColors );
IRgbColorPtr pColorStart(CLSID_RgbColor);
hr = pColorStart->put_Red(255);
hr = pColorStart->put_Blue(255);
hr = pColorStart->put_Green(255);
IRgbColorPtr pRedColor(CLSID_RgbColor);
hr = pRedColor->put_Red(255);
hr = pRedColor->put_Blue(0);
hr = pRedColor->put_Green(0);
IColorPtr pColor;
for (int i=0; i<lCount; i++)
{
hr = pEnumColors->Next ( &pColor );
if ( i == 0)
hr = ipFSymbol->put_Color( pColorStart );
else if ( i == (lCount - 1) )
hr = ipFSymbol->put_Color( pRedColor );
else
hr = ipFSymbol->put_Color( pColor );
hr = pClassRen->put_Symbol(i, ipSymbol);
double dIntervalEnd = 0.;
if ( i )
dIntervalEnd = (i == (lCount - 1)) ? dMax : clsBreaks[i + 1]; //*dFACTOR;
_bstr_t bstrClsBreaksBegin(clsBreaks); //*dFACTOR); // i==1 ? 1 : clsBreaks*dFACTOR);
_bstr_t bstrClsBreaksEnd(dIntervalEnd);
if ( i )
bstrClsBreaksBegin += CComBSTR(L" - ") + bstrClsBreaksEnd;
hr = pClassRen->put_Label(i, bstrClsBreaksBegin.Detach());
}
// Update the renderer and plug into layer
hr = pRasRen->Update();
hr = pRasterLayer->putref_Renderer( pRasRen );
// Save img as layer
CString sLayerFile(sRasterFile);
sLayerFile.Append(".lyr");
if ( PathFileExists( sLayerFile ) )
remove( sLayerFile );
IGxLayerPtr pGxLayer(CLSID_GxLayer);
IGxFilePtr pFile(pGxLayer);
hr = pFile->put_Path( sLayerFile.AllocSysString() );
hr = pGxLayer->putref_Layer( pRasterLayer );
return hr;
}