By Adam Nagy
When you right-click on a Dimension style in the Style and Standard Editor dialog, then you can select Replace Style. This will go through all the local Object Defaults and check if the given Dimension style is used by any of its dimension related settings (Angle Dimension, Baseline Dimension Set, Bend Note, etc) which have the dimension icon next to them. The ones that are using the selected Dimension style will be adjusted to use the other Dimension style you provided in the Replace Style dialog.
You can do the same programmatically. You can go through all the local ObjectDefaultsStyle objects and check their Dimension related properties, either by hard-coding them in your program or doing it using COM Type Information. This sample shows both.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using CT = System.Runtime.InteropServices.ComTypes;
using Inventor;
namespace TestConsole
{
class Program
{
#region Dynamic
[ComImport()]
[Guid("00020400-0000-0000-C000-000000000046")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDispatch
{
[PreserveSig]
int GetTypeInfoCount(out int Count);
[PreserveSig]
int GetTypeInfo
(
[MarshalAs(UnmanagedType.U4)] int iTInfo,
[MarshalAs(UnmanagedType.U4)] int lcid,
out CT.ITypeInfo typeInfo
);
[PreserveSig]
int GetIDsOfNames
(
ref Guid riid,
[MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.LPWStr)]
string[] rgsNames,
int cNames,
int lcid,
[MarshalAs(UnmanagedType.LPArray)] int[] rgDispId
);
[PreserveSig]
int Invoke
(
int dispIdMember,
ref Guid riid,
uint lcid,
ushort wFlags,
ref CT.DISPPARAMS pDispParams,
out object pVarResult,
ref CT.EXCEPINFO pExcepInfo,
IntPtr[] pArgErr
);
}
class COMIDispatch
{
public enum MethodType
{
Method = 0,
Property_Getter = 1,
Property_Putter = 2,
Property_PutRef = 3
}
public struct MethodInformation
{
public string m_strName;
public string m_strDocumentation;
public MethodType m_method_type;
}
// This static function returns an array containing
// information of all public methods of a COM object.
// Note that the COM object must implement the IDispatch
// interface in order to be usable in this function.
public static MethodInformation[]
GetMethodInformation(object com_obj)
{
IDispatch pDispatch = null;
try
{
// Obtain the COM IDispatch interface from the input
// com_obj object.
// Low-level-wise this causes a QueryInterface() to be
// performed on com_obj to obtain the IDispatch interface
// from it.
pDispatch = (IDispatch)com_obj;
}
catch (System.InvalidCastException)
{
// This means that the input com_obj
// does not support the IDispatch
// interface.
return null;
}
// Obtain the ITypeInfo interface from the object via its
// IDispatch.GetTypeInfo() method.
CT.ITypeInfo pTypeInfo = null;
// Call the IDispatch.GetTypeInfo() to obtain an ITypeInfo
// interface pointer from the com_obj.
// Note that the first parameter must be 0 in order to
// obtain the Type Info of the current object.
pDispatch.GetTypeInfo
(
0,
0,
out pTypeInfo
);
// If for some reason we are not able to obtain the
// ITypeInfo interface from the IDispatch interface
// of the COM object, we return immediately.
if (pTypeInfo == null)
{
return null;
}
// Get the TYPEATTR (type attributes) of the object
// via its ITypeInfo interface.
IntPtr pTypeAttr = IntPtr.Zero;
CT.TYPEATTR typeattr;
// The TYPEATTR is returned via an IntPtr.
pTypeInfo.GetTypeAttr(out pTypeAttr);
// We must convert the IntPtr into the TYPEATTR structure
// defined in the System.Runtime.InteropServices.ComTypes
// namespace.
typeattr = (CT.TYPEATTR)Marshal.PtrToStructure
(
pTypeAttr,
typeof(CT.TYPEATTR)
);
// Release the resources related to the obtaining of the
// COM TYPEATTR structure from an ITypeInfo interface.
// From now onwards, we will only work with the
// System.Runtime.InteropServices.ComTypes.TYPEATTR
// structure.
pTypeInfo.ReleaseTypeAttr(pTypeAttr);
pTypeAttr = IntPtr.Zero;
// The TYPEATTR.guid member indicates the default interface
// implemented by the COM object.
Guid defaultInterfaceGuid = typeattr.guid;
MethodInformation[] method_information_array =
new MethodInformation[typeattr.cFuncs];
// The TYPEATTR.cFuncs member indicates the total number of
// methods that the current COM object implements.
for (int i = 0; i < (typeattr.cFuncs); i++)
{
// We loop through the number of methods.
CT.FUNCDESC funcdesc;
IntPtr pFuncDesc = IntPtr.Zero;
string strName;
string strDocumentation;
int iHelpContext;
string strHelpFile;
// During each loop, we use the ITypeInfo.GetFuncDesc()
// method to obtain a FUNCDESC structure which describes
// the current method indexed by "i".
pTypeInfo.GetFuncDesc(i, out pFuncDesc);
// The FUNCDESC structure is returned as an IntPtr.
// We need to convert it into a FUNCDESC structure
// defined in the System.Runtime.InteropServices.ComTypes
// namespace.
funcdesc = (CT.FUNCDESC)Marshal.PtrToStructure
(
pFuncDesc,
typeof(CT.FUNCDESC)
);
// The FUNCDESC.memid contains the member id of the current
// function in the Type Info of the object.
// Use the ITypeInfo.GetDocumentation() with reference to
// memid to obtain information for this function.
pTypeInfo.GetDocumentation
(
funcdesc.memid,
out strName,
out strDocumentation,
out iHelpContext,
out strHelpFile
);
// Fill up the appropriate method_information_array element
// with field information.
method_information_array[i].m_strName = strName;
System.Diagnostics.Debug.WriteLine(strName);
method_information_array[i].m_strDocumentation =
strDocumentation;
if (funcdesc.invkind == CT.INVOKEKIND.INVOKE_FUNC)
{
method_information_array[i].m_method_type =
MethodType.Method;
}
else if (funcdesc.invkind ==
CT.INVOKEKIND.INVOKE_PROPERTYGET)
{
method_information_array[i].m_method_type =
MethodType.Property_Getter;
}
else if (funcdesc.invkind ==
CT.INVOKEKIND.INVOKE_PROPERTYPUT)
{
method_information_array[i].m_method_type =
MethodType.Property_Putter;
}
else if (funcdesc.invkind ==
CT.INVOKEKIND.INVOKE_PROPERTYPUTREF)
{
method_information_array[i].m_method_type =
MethodType.Property_PutRef;
}
// The ITypeInfo.ReleaseFuncDesc() must be called
// to release the (unmanaged) memory of the FUNCDESC
// returned in pFuncDesc (an IntPtr).
pTypeInfo.ReleaseFuncDesc(pFuncDesc);
pFuncDesc = IntPtr.Zero;
}
return method_information_array;
}
}
static void ReplaceDimensionStyle_Dynamic(
DrawingStylesManager stylesManager,
DimensionStyle replaceStyle,
DimensionStyle withStyle,
bool purge)
{
foreach (ObjectDefaultsStyle defaultStyle
in stylesManager.ObjectDefaultsStyles)
{
if (defaultStyle.StyleLocation ==
StyleLocationEnum.kLibraryStyleLocation)
continue;
// Get all the properties of the object
COMIDispatch.MethodInformation [] methodInfos =
COMIDispatch.GetMethodInformation(defaultStyle);
foreach (
COMIDispatch.MethodInformation methodInfo in methodInfos)
{
if (methodInfo.m_method_type ==
COMIDispatch.MethodType.Property_Getter)
{
object obj = defaultStyle.GetType().InvokeMember(
methodInfo.m_strName, BindingFlags.GetProperty, null,
defaultStyle, null);
if (obj == replaceStyle)
{
defaultStyle.GetType().InvokeMember(
methodInfo.m_strName, BindingFlags.SetProperty, null,
defaultStyle, new object[] { withStyle });
}
}
}
}
if (purge && replaceStyle.StyleLocation !=
StyleLocationEnum.kLibraryStyleLocation)
replaceStyle.Delete();
}
#endregion
#region Hard-Coded
static void ReplaceDimensionStyle_HardCoded(
DrawingStylesManager stylesManager,
DimensionStyle replaceStyle,
DimensionStyle withStyle,
bool purge)
{
foreach (ObjectDefaultsStyle defaultStyle
in stylesManager.ObjectDefaultsStyles)
{
if (defaultStyle.StyleLocation ==
StyleLocationEnum.kLibraryStyleLocation)
continue;
if (defaultStyle.AngularDimensionStyle == replaceStyle)
defaultStyle.AngularDimensionStyle = withStyle;
if (defaultStyle.BaselineDimensionStyle == replaceStyle)
defaultStyle.BaselineDimensionStyle = withStyle;
if (defaultStyle.BendNoteStyle == replaceStyle)
defaultStyle.BendNoteStyle = withStyle;
if (defaultStyle.BendTagStyle == replaceStyle)
defaultStyle.BendTagStyle = withStyle;
if (defaultStyle.ChainDimensionStyle == replaceStyle)
defaultStyle.ChainDimensionStyle = withStyle;
if (defaultStyle.ChamferNoteStyle == replaceStyle)
defaultStyle.ChamferNoteStyle = withStyle;
if (defaultStyle.DiameterDimensionStyle == replaceStyle)
defaultStyle.DiameterDimensionStyle = withStyle;
if (defaultStyle.HoleNoteStyle == replaceStyle)
defaultStyle.HoleNoteStyle = withStyle;
if (defaultStyle.HoleTagStyle == replaceStyle)
defaultStyle.HoleTagStyle = withStyle;
if (defaultStyle.LeaderTextStyle == replaceStyle)
defaultStyle.LeaderTextStyle = withStyle;
if (defaultStyle.LinearDimensionStyle == replaceStyle)
defaultStyle.LinearDimensionStyle = withStyle;
if (defaultStyle.OrdinateDimensionStyle == replaceStyle)
defaultStyle.OrdinateDimensionStyle = withStyle;
if (defaultStyle.OrdinateSetDimensionStyle == replaceStyle)
defaultStyle.OrdinateSetDimensionStyle = withStyle;
if (defaultStyle.PunchNoteStyle == replaceStyle)
defaultStyle.PunchNoteStyle = withStyle;
if (defaultStyle.RadialDimensionStyle == replaceStyle)
defaultStyle.RadialDimensionStyle = withStyle;
if (defaultStyle.ThreadNoteStyle == replaceStyle)
defaultStyle.ThreadNoteStyle = withStyle;
}
if (purge && replaceStyle.StyleLocation !=
StyleLocationEnum.kLibraryStyleLocation)
replaceStyle.Delete();
}
#endregion
static private void test()
{
const bool useHardCoded = true;
Application app = (Application)
System.Runtime.InteropServices.Marshal.
GetActiveObject("Inventor.Application");
DrawingDocument dwg = (DrawingDocument)app.ActiveDocument;
COMIDispatch.MethodInformation[] methodInfos =
COMIDispatch.GetMethodInformation(
dwg.StylesManager.ObjectDefaultsStyles[1]);
DrawingStylesManager stylesManager = dwg.StylesManager;
DimensionStyle style1 = stylesManager.DimensionStyles[1];
DimensionStyle style2 = stylesManager.DimensionStyles[2];
if (useHardCoded)
ReplaceDimensionStyle_HardCoded(
stylesManager, style1, style2, true);
else
ReplaceDimensionStyle_Dynamic(
stylesManager, style1, style2, true);
}
static void Main(string[] args)
{
test();
}
}
}