ClonableObj\ClonableObjClass.cs
// Copyright 2012 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. // using System; using System.Collections; using System.Text; using System.Runtime.InteropServices; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using System.IO; namespace ClonableObj { [Guid(ClonableObjClass.GUID)] [ProgId("ClonableObj.ClonableObjClass")] [ClassInterface(ClassInterfaceType.None)] [ComVisible(true)] public sealed class ClonableObjClass : ESRI.ArcGIS.esriSystem.IClone, ESRI.ArcGIS.esriSystem.IPersistStream { public const string GUID = "C97C7707-3A8B-4933-953E-8AF605851FCC"; //class members private int m_version = 1; private ISpatialReference m_spatialRef = null; private IPoint m_point = null; private string m_name = string.Empty; private ArrayList m_arr = null; private Guid m_ID; public ClonableObjClass() { m_ID = Guid.NewGuid(); m_spatialRef = new UnknownCoordinateSystemClass(); } #region public properties public string Name { get { return m_name; } set { m_name = value; } } public int Version { get { return m_version; } } public ISpatialReference SpatialReference { get { return m_spatialRef; } set { m_spatialRef = value; } } public Guid ID { get { return m_ID; } } public IPoint Point { get { return m_point; } set { m_point = value; } } public ArrayList ManagedArray { get { return m_arr; } set { m_arr = value; } } #endregion #region IClone Members public void Assign(IClone src) { //1. make sure that src is pointing to a valid object if (null == src) { throw new COMException("Invalid object."); } //2. make sure that the type of src is of type 'ClonableObjClass' if (!(src is ClonableObjClass)) { throw new COMException("Bad object type."); } //3. assign the properties of src to the current instance ClonableObjClass srcClonable = (ClonableObjClass)src; m_name = srcClonable.Name; m_version = srcClonable.Version; //it is not possible to copy guids... //m_ID = srcClonable.ID; //don't clone the spatial reference, since in this case we want both object to //reference the same spatial reference (for example like features in a featureclass //which share the same spatial reference) m_spatialRef = srcClonable.SpatialReference; //clone the point. Use deep cloning if (null == srcClonable.Point) m_point = null; else { IObjectCopy objectCopy = new ObjectCopyClass(); object obj = objectCopy.Copy((object)srcClonable.Point); m_point = (IPoint)obj; } m_arr = (ArrayList)srcClonable.ManagedArray.Clone(); } public IClone Clone() { //ClonableObjClass obj = new ClonableObjClass(); //obj.Assign(this); //use the C++ way to clone the object. Write it into a memory stream IObjectCopy objectCopy = new ObjectCopyClass(); object obj = objectCopy.Copy((object)this); return (IClone)obj; } public bool IsEqual(IClone other) { //1. make sure that the 'other' object is pointing to a valid object if (null == other) throw new COMException("Invalid object."); //2. verify the type of 'other' if (!(other is ClonableObjClass)) throw new COMException("Bad object type."); ClonableObjClass otherClonable = (ClonableObjClass)other; //test that all ot the object's properties are the same. //please note the usage of IsEqual when using ArcObjects components that //supports cloning if (otherClonable.Version == m_version && otherClonable.Name == m_name && otherClonable.ID == m_ID && otherClonable.ManagedArray == m_arr && ((IClone)otherClonable.SpatialReference).IsEqual((IClone)m_spatialRef) && ((IClone)otherClonable.Point).IsEqual((IClone)m_point)) return true; return false; } public bool IsIdentical(IClone other) { //1. make sure that the 'other' object is pointing to a valid object if (null == other) throw new COMException("Invalid object."); //2. verify the type of 'other' if (!(other is ClonableObjClass)) throw new COMException("Bad object type."); //3. test if the other is the 'this' if ((ClonableObjClass)other == this) return true; return false; } #endregion #region IPersistStream Members public void GetClassID(out Guid pClassID) { pClassID = new Guid(ClonableObjClass.GUID); } public void GetSizeMax(out _ULARGE_INTEGER pcbSize) { pcbSize.QuadPart = 0; } public void IsDirty() { return; } public void Load(IStream pStm) { System.Runtime.InteropServices.ComTypes.IStream stream = (System.Runtime.InteropServices.ComTypes.IStream)pStm; //load the information from the stream object obj = null; obj = PeristStream.PeristStreamHelper.Load(stream); m_version = Convert.ToInt32(obj); obj = PeristStream.PeristStreamHelper.Load(stream); byte[] arr = (byte[])obj; m_ID = new Guid(arr); obj = PeristStream.PeristStreamHelper.Load(stream); m_name = Convert.ToString(obj); obj = PeristStream.PeristStreamHelper.Load(stream); m_spatialRef = obj as ISpatialReference; obj = PeristStream.PeristStreamHelper.Load(stream); m_ID = (Guid)obj; obj = PeristStream.PeristStreamHelper.Load(stream); m_point = obj as IPoint; obj = PeristStream.PeristStreamHelper.Load(stream); m_arr = obj as ArrayList; } public void Save(IStream pStm, int fClearDirty) { System.Runtime.InteropServices.ComTypes.IStream stream = (System.Runtime.InteropServices.ComTypes.IStream)pStm; //save the different objects to the stream PeristStream.PeristStreamHelper.Save(stream, m_version); PeristStream.PeristStreamHelper.Save(stream, m_ID.ToByteArray()); PeristStream.PeristStreamHelper.Save(stream, m_name); PeristStream.PeristStreamHelper.Save(stream, m_spatialRef); //save the guid PeristStream.PeristStreamHelper.Save(stream, m_ID); //save the point to the stream if (null == m_point) m_point = new PointClass(); PeristStream.PeristStreamHelper.Save(stream, m_point); if (null == m_arr) m_arr = new ArrayList(); PeristStream.PeristStreamHelper.Save(stream, m_arr); } #endregion } }