ArcEngineUtilities.cpp
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // #include "ArcEngineUtilities.h" // Function to convert pixel units to map units. This function also // serves as an example of how to check HRESULTs and return them if a // failing HRESULT is encountered. HRESULT ConvertPixelsToMapUnits (IActiveView *pActiveView, double pixelUnits, double *mapUnits) { if (0 == pActiveView) return E_INVALIDARG; double realWorldDisplayExtent, sizeOfOnePixel, pixelExtent; long right, left; IScreenDisplayPtr ipSD; IDisplayTransformationPtr ipDT; IEnvelopePtr ipEnv; tagRECT bounds; HRESULT hr = pActiveView->get_ScreenDisplay(&ipSD); if (FAILED(hr)) return hr; hr = ipSD->get_DisplayTransformation(&ipDT); if (FAILED(hr)) return hr; hr = ipDT->get_DeviceFrame(&bounds); if (FAILED(hr)) return hr; right = bounds.right; left = bounds.left; pixelExtent = (double)(right - left); if (pixelExtent <= 0.0) return E_FAIL; hr = ipDT->get_VisibleBounds(&ipEnv); if (FAILED(hr)) return hr; hr = ipEnv->get_Width(&realWorldDisplayExtent); if (FAILED(hr)) return hr; sizeOfOnePixel = realWorldDisplayExtent / pixelExtent; *mapUnits = sizeOfOnePixel * pixelUnits; return S_OK; } // Returns the index in pMapControl's map of the layer w/ name inName, // or -1 if no layer is found. Note that if a layer is a sublayer in // a group layer it won't be found here. long GetIndexOfLayerName (IMapControl3 *pMapControl, const char *inName) { if (!inName || !pMapControl) return -1; CComBSTR bsInLayerName (inName); CComBSTR bsTmpLayerName; ILayerPtr ipLayer; long numLayers; pMapControl->get_LayerCount(&numLayers); for (long i=0; i<numLayers; i++) { pMapControl->get_Layer(i, &ipLayer); ipLayer->get_Name(&bsTmpLayerName); if (bsTmpLayerName == bsInLayerName) return i; } return -1; } // Adds some commonly used items to a toolbar control using ProgIDs void AddStandardToolbarItems(IToolbarControl *pToolbarControl) { if (0 == pToolbarControl) return; long itemIndex; CComVariant varTool; varTool = L"esriControlCommands.ControlsOpenDocCommand"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapPanTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomInTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomOutTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomInFixedCommand"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomOutFixedCommand"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomPanTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapFullExtentCommand"; pToolbarControl->AddItem( varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomToLastExtentBackCommand"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsMapZoomToLastExtentForwardCommand"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsSelectTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); varTool = L"esriControlCommands.ControlsSelectFeaturesTool"; pToolbarControl->AddItem(varTool, 0, -1, VARIANT_FALSE, 0, esriCommandStyleIconOnly, &itemIndex); } // Returns a layer based on its name using RecursiveGetLayerFromName // to search GroupLayers. If 2 layers have the same name it will // return the 1st layer found. HRESULT GetLayerFromName (IMapControl3* pMapControl, BSTR bsLayerName, ILayer** ppOutLayer) { if (!ppOutLayer) return E_POINTER; if (!pMapControl || !bsLayerName) return E_INVALIDARG; // Initialize output if (*ppOutLayer) (*ppOutLayer)->Release(); *ppOutLayer = 0; long layerCount; pMapControl->get_LayerCount(&layerCount); for (long i=0; i<layerCount; ++i) { ILayerPtr ipLayer; pMapControl->get_Layer(i, &ipLayer); if (RecursiveGetLayerFromName(ipLayer, bsLayerName, ppOutLayer) == S_OK) return S_OK; } return S_FALSE; } // Recursive function to return a layer based on its name. If 2 // layers have the same name it will return the 1st layer found. If // the layer is a grouplayer the function first checks whether the // group layer's name is a match and if not it then proceeds to check // sublayers. HRESULT RecursiveGetLayerFromName (ILayer* pLayer, BSTR bsSearchName, ILayer** ppOutLayer) { if (!ppOutLayer) return E_POINTER; if (!pLayer || !bsSearchName) return E_INVALIDARG; // Initialize output if (*ppOutLayer) (*ppOutLayer)->Release(); *ppOutLayer = 0; CComBSTR bsName; pLayer->get_Name(&bsName); if (bsName == bsSearchName) { *ppOutLayer = pLayer; if (*ppOutLayer) { (*ppOutLayer)->AddRef(); return S_OK; } } ICompositeLayerPtr ipCompLayer(pLayer); if (ipCompLayer) { long layerCount; ipCompLayer->get_Count(&layerCount); for (long i=0; i<layerCount; ++i) { ILayerPtr ipSubLayer; ipCompLayer->get_Layer(i, &ipSubLayer); if (RecursiveGetLayerFromName(ipSubLayer, bsSearchName, ppOutLayer) == S_OK) return S_OK; } } return S_FALSE; } // // Returns a set with all layers that implement IFeatureLayer using // // RecursiveGetFeatureLayerSet to search GroupLayers. // HRESULT GetFeatureLayerSet (IMapControl3* pMapControl, ISet* pSet) // { // if (!pMapControl || !pSet) // return E_INVALIDARG; // long layerCount; // pMapControl->get_LayerCount(&layerCount); // for (long i=0; i<layerCount; ++i) // { // ILayerPtr ipLayer; // pMapControl->get_Layer(i, &ipLayer); // RecursiveGetFeatureLayerSet(ipLayer, pSet); // } // return S_OK; // } // // Recursive function which adds to a set all layers that implement // // IFeatureLayer. // HRESULT RecursiveGetFeatureLayerSet (ILayer* pLayer, ISet* pSet) // { // if (!pLayer || !pSet) // return E_INVALIDARG; // ICompositeLayerPtr ipCompLayer(pLayer); // if (ipCompLayer) // { // long layerCount; // ipCompLayer->get_Count(&layerCount); // for (long i=0; i<layerCount; ++i) // { // ILayerPtr ipSubLayer; // ipCompLayer->get_Layer(i, &ipSubLayer); // RecursiveGetFeatureLayerSet(ipSubLayer, pSet); // } // } // else // { // IFeatureLayerPtr ipFeatLayer(pLayer); // if (ipFeatLayer) // pSet->Add(ipFeatLayer); // } // return S_OK; // } // Calls RecursiveCheckLayerNames to check the layers in the map for // duplicate names. Returns S_OK if the layer names are OK, S_FALSE if // there are duplicates. HRESULT CheckLayerNames (IMapControl3* pMapControl) { if (!pMapControl) return E_INVALIDARG; WStringSet wss; long layerCount; pMapControl->get_LayerCount(&layerCount); for (long i=0; i<layerCount; ++i) { ILayerPtr ipLayer; pMapControl->get_Layer(i, &ipLayer); HRESULT hr = RecursiveCheckLayerNames(ipLayer, wss); if (hr == S_FALSE || FAILED(hr)) return hr; } return S_OK; } // Recursively checks the layers in the map for duplicate // names. Returns S_OK if the layer names are OK, S_FALSE if there are // duplicates. HRESULT RecursiveCheckLayerNames (ILayer* pLayer, WStringSet& wss) { if (!pLayer) return E_INVALIDARG; CComBSTR bsName; pLayer->get_Name(&bsName); wstring wsName(bsName); WStringSet::iterator it = wss.find(wsName); if (it != wss.end()) return S_FALSE; // Insert the name into the set wss.insert(wsName); ICompositeLayerPtr ipCompLayer(pLayer); if (ipCompLayer) { long layerCount; ipCompLayer->get_Count(&layerCount); for (long i=0; i<layerCount; ++i) { ILayerPtr ipSubLayer; ipCompLayer->get_Layer(i, &ipSubLayer); HRESULT hr = RecursiveCheckLayerNames(ipSubLayer, wss); if (hr == S_FALSE || FAILED(hr)) return hr; } } return S_OK; }