3

Last time I checked, arcgis doesn't honor IPersistVariant in layer extensions. Rather advanced code has been provided here showing how to implement IPersistStream.

Is there something simpler?

Kirk Kuykendall
  • 25,787
  • 8
  • 65
  • 153

2 Answers2

4

You can easily bridge the implementation of IPersistStream with IPersistVariant using VariantStreamIO class. The code below is a simple demonstration which saves and loads a text value.

using System;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.esriSystem;

namespace LayerExtensionPersistenceSample
{
    [ComVisible(true)]
    [ProgId("LayerExtensionPersistenceSample.LayerExtension")]
    [Guid("...")]
    [ClassInterface(ClassInterfaceType.None)]
    public class LayerExtension : IPersistStream
    {
        private string _persistedTextValue;

        #region Implementation of IPersistStream

        public void GetClassID(out Guid classId)
        {
            classId = GetType().GUID;
        }

        public void IsDirty()
        {
        }

        public void Load(IStream pstm)
        {
            var variantStreamIo = new VariantStreamIOClass();
            variantStreamIo.Stream = pstm;

            try
            {
                _persistedTextValue = (string)variantStreamIo.Read();
            }
            finally
            {
                Marshal.FinalReleaseComObject(pstm);
                Marshal.FinalReleaseComObject(variantStreamIo);
            }
        }

        public void Save(IStream pstm, int fClearDirty)
        {
            var variantStreamIo = new VariantStreamIOClass();
            variantStreamIo.Stream = pstm;

            try
            {
                variantStreamIo.Write(_persistedTextValue);
            }
            finally
            {
                Marshal.FinalReleaseComObject(pstm);
                Marshal.FinalReleaseComObject(variantStreamIo);
            }
        }

        public void GetSizeMax(out _ULARGE_INTEGER pcbSize)
        {
            // returning 0 seems to work without any problems
            pcbSize = new _ULARGE_INTEGER();
            pcbSize.QuadPart = 0;
        }

        #endregion
    }
}

This way you can use the simpler IPersistVariant interface even when IPeristStream is enforced for some reason.

Petr Krebs
  • 10,291
  • 1
  • 22
  • 33
0

If the data you need to store is simple enough, you can use store your data in an IPropertySet and add it as via the ILayerExtensions interface. This can cause a few headaches because it is a relatively common trick so you may step on someone else's IPropertySet.

James Schek
  • 1,072
  • 6
  • 9