做一个交互式绘制文字的工具,希望这次设置的Symbol,下次打开ArcMap时自动调用这个Symbol,并支持对其进行修改。
解决方法是将这个Symbol写入注册表中,每次自动读取上一次设置的Symbol,如果修改了Symbol,则自动写入注册表中。
相关文章:
注册表读写
http://blog.csdn.net/p424671075/article/details/6176219
ESRI COM对象序列化
http://blog.csdn.net/xgyb12458/article/details/4125911
Object与二进制的转换
http://www.cnblogs.com/jesszhu/archive/2013/08/22/3276556.html
阅读上述帖子后,开始着手写。首先想的是将ISymbol装箱为Object,再序列号为二进制,就可以写入注册表了。调试时显示这个Object不支持序列化
后来查阅到COM对象的序列化,需要用到IXMLSerializer,将COM对象序列化为字符,使用方式如下:
public string esriSerializer(object obj) { IXMLSerializer xmlSerializer = new XMLSerializerClass(); string xmlstring = xmlSerializer.SaveToString(obj, null, null); return xmlstring; } public object esriDeserializer(string str) { IXMLSerializer xmlSerializer = new XMLSerializerClass(); return xmlSerializer.LoadFromString(str, null, null); }
public string esriSerializer(object obj) { IXMLSerializer xmlSerializer = new XMLSerializerClass(); string xmlstring = xmlSerializer.SaveToString(obj, null, null); return xmlstring; } public object esriDeserializer(string str) { IXMLSerializer xmlSerializer = new XMLSerializerClass(); return xmlSerializer.LoadFromString(str, null, null); }
之后,在将字符串对象序列化为二进制,写入注册表即可。
序列化为与反序列化二进制的代码如下:
public byte[] BinarySerializer(object obj) { try { using (var ms = new MemoryStream()) { var formatter = new BinaryFormatter(); formatter.Serialize(ms, obj); var data = ms.ToArray(); return data; } } catch (InvalidOperationException) { throw; } } public object BinaryDeserializer(byte[] bt) { object obj=null; try { using (var ms = new MemoryStream(bt)) { var formatter = new BinaryFormatter(); obj=formatter.Deserialize(ms); } } catch (InvalidOperationException) { } return obj; }
读取与写入注册表代码如下:
/// <summary> /// 从注册表获取值 /// </summary> /// <param name="toolname">工具名称</param> /// <param name="key">值名称</param> /// <returns></returns> public object getValueFromReg(string toolname,string key) { object obj=null; try { RegistryKey rkey = Registry.LocalMachine; RegistryKey rootkey = Registry.LocalMachine; RegistryKey sftkey = rootkey.OpenSubKey("software", true); RegistryKey llcsft = sftkey.OpenSubKey("llcSft"); RegistryKey AddinCfg = llcsft.OpenSubKey("AddInConfig"); RegistryKey AddInName = AddinCfg.OpenSubKey(toolname); byte[] tmp = (byte[])AddInName.GetValue(key); obj = esriDeserializer(BinaryDeserializer(tmp).ToString()); } catch (System.Exception ex) { return null; } return obj; } /// <summary> /// 写入注册表 /// </summary> /// <param name="toolName">工具名称</param> /// <param name="pm">键值</param> /// <returns></returns> public bool setValueToReg(string toolName,KeyValuePair<string,object> pm) { try { RegistryKey rootkey = Registry.LocalMachine; RegistryKey sftkey = rootkey.OpenSubKey("software",true); RegistryKey llcsft = sftkey.CreateSubKey("llcSft"); RegistryKey AddinCfg = llcsft.CreateSubKey("AddInConfig"); RegistryKey AddInName = AddinCfg.CreateSubKey(toolName); AddInName.SetValue(pm.Key, BinarySerializer(esriSerializer(pm.Value)), RegistryValueKind.Binary); } catch (System.Exception ex) { } return true; }
使用中,直接调用setValueToReg,getValueFromReg两个函数即可。