3

I'm trying to symbolize multiple layers with an emf logo. When debugging, it gets through the first layer then crashes. I'm thinking it might have something to do with the variable "emf1" not changing. I've tried a few things but can't get it to iterate properly.

    public void symbolize()
    {
        {
            IMxDocument pMxDoc;
            pMxDoc = (IMxDocument)ArcMap.Application.Document;

            IMap pMap;
            pMap = pMxDoc.FocusMap;

            IEnumLayer pLayers;
            pLayers = pMap.Layers;

            ILayer pLayer;
            pLayer = pLayers.Next();
            List<string> lyrName = new List<string>();

            while (pLayer != null)
            {
                if (pLayer.Name == "")
                {
                    break;
                }
                else
                {
                    lyrName.Add(pLayer.Name);
                }
            pLayer = pLayers.Next();
            }

            //QI
            IGeoFeatureLayer pGeoFLayer;
            pGeoFLayer = (IGeoFeatureLayer)pLayer;

            ISimpleMarkerSymbol pSym;
            pSym = new SimpleMarkerSymbol();
            pSym.Style = ESRI.ArcGIS.Display.esriSimpleMarkerStyle.esriSMSX;

            lyrName.ToArray();
            foreach (string name in lyrName)
            { 
            IPictureMarkerSymbol emf1 = new PictureMarkerSymbolClass();
            emf1.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureEMF, "C:\\EMF\\" + name + "_Logo.emf");
            emf1.Angle = 0;
            emf1.Size = 24;
            emf1.XOffset = 0;
            emf1.YOffset = 0;

            ISimpleRenderer pRenderer;
            pRenderer = new SimpleRenderer();
            pRenderer.Symbol = (ISymbol)emf1;
            pGeoFLayer.Renderer = (IFeatureRenderer)pRenderer;
            }

            IActiveView pActiveView;
            pActiveView = (IActiveView)pMap;
            pActiveView.Refresh();
            pMxDoc.UpdateContents();
        }

    }

enter image description here

This is the error message that pops up, this is a pretty standard error message for me.

  • Do you receive an error with the crash? If so, can you post a screenshot above? – MaryBeth Mar 15 '16 at 20:40
  • Updated my comment with the error screenshot – sbell423 Mar 15 '16 at 21:11
1

You are casting pLayer to an IGeoFeatureLayer object but it is possible for the pLayer object to be null in your code. Add a check for null before the QI.

Where you set the emf symbol (emf1.CreateMarkerSymbolFromFile) it would be good first to check that the picture marker exists at the input string location.

Also, you'd need to check the documentation but I'm not sure if a IPictureMarkerSymbol can be directly cast to an ISymbol where you have this line:

pRenderer.Symbol = (ISymbol)emf1;

Another problem with the code is that the picture marker symbol is being set on the same geofeaturelayer object in the foreach loop. After you create the symbol you need a sub loop that enums through each of the map layers and sets the symbol for each layer. I would refactor you code to something like this:

public void symbolize()
    {
        {
            IMxDocument pMxDoc = (IMxDocument)ArcMap.Application.Document;

            IMap pMap = pMxDoc.FocusMap;

            IEnumLayer pLayers = pMap.Layers;
            pLayers.Reset();

            ILayer pLayer = null;

            while ((pLayer = pLayers.Next()) != null)
            {
                if (pLayer.Name == "") continue;
                if (!System.IO.File.Exists("C:\\EMF\\" + pLayer.Name + "_Logo.emf")) continue;

                IPictureMarkerSymbol emf1 = new PictureMarkerSymbolClass();
                emf1.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureEMF, "C:\\EMF\\" + pLayer.Name + "_Logo.emf");
                emf1.Angle = 0;
                emf1.Size = 24;
                emf1.XOffset = 0;
                emf1.YOffset = 0;

                //QI
                IGeoFeatureLayer pGeoFLayer;
                pGeoFLayer = (IGeoFeatureLayer)pLayer;

                ISimpleRenderer pRenderer;
                pRenderer = new SimpleRenderer();
                pRenderer.Symbol = (ISymbol)emf1;
                pGeoFLayer.Renderer = (IFeatureRenderer)pRenderer;

                System.Runtime.InteropServices.Marshal.ReleaseComObject(pLayer);
            }

            IActiveView pActiveView = (IActiveView)pMap;
            pActiveView.Refresh();
            pMxDoc.UpdateContents();
        }

    }

Finally, I don't see an error handler in your code. Make sure that the procedure which calls symbolize() has a try/catch block to handle any errors. Often when there is a COM error in a custom command that does not have error handling then it will crash ArcMap.

  • I used the try/catch block and it didn't yield any errors. I'm thinking it could have something to do with the foreach loop? Not sure. It's not the prenderer line because it works when I only have one layer. – sbell423 Mar 15 '16 at 23:02
  • I'd be surprised if ArcMap was crashing that way if you had a try/catch block at the top of the stack. Is this code being called from a command button? Is there a catch in the command OnClick() event? – Rich Wawrzonek Mar 15 '16 at 23:18
  • I had the wrong catch exception. Here is the error "error object not set to an instance of an object". Is it because I have a null somewhere? – sbell423 Mar 15 '16 at 23:22
  • Updated my answer with another issue in the foreach loop. – Rich Wawrzonek Mar 15 '16 at 23:25
  • Yes, this works. It is also great that there is a section to check if the emf file exists. My next step was to add a symbol marker for layers without an emf file. I suppose I can put an else statement below the "system.Runtime" line to handle these exceptions. Thank you! – sbell423 Mar 16 '16 at 0:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.