Imports AADS = Autodesk.AutoCAD.DatabaseServices
Imports AAG = Autodesk.AutoCAD.Geometry
Imports AAGI = Autodesk.AutoCAD.GraphicsInterface
Imports System.Text.RegularExpressions
''' <summary>
'''
''' </summary>
''' <remarks></remarks>
''' <web>
''' http://stackoverflow.com/questions/608332/best-way-to-get-a-type-object-from-a-string-in-net
''' </web>
''' <todo>
''' 1. Errors for private methods and/or non shared methods
''' 2. MethodField
''' 3. ScriptField
''' 4. allow arguments
''' </todo>
Public Class MacroField_Overrule
Inherits AAGI.DrawableOverrule
Private Const MACROFIELD_REGEX As String = "(#<DotNetField\()(.*?)(\)>#)"
Private Const MACROFIELD_BEGIN_CODE As String = "#<DotNetField("
Private Const MACROFIELD_END_CODE As String = ")>#"
Public Overloads Overrides Function WorldDraw(ByVal d As AAGI.Drawable, ByVal wd As AAGI.WorldDraw) As Boolean
Dim CurrentText As AADS.DBText = DirectCast(d, AADS.DBText)
Dim rx As Regex = New Regex(MACROFIELD_REGEX)
If rx.IsMatch(CurrentText.TextString) = True Then
Dim iStyle As New Autodesk.AutoCAD.GraphicsInterface.TextStyle()
Dim styleId As AADS.ObjectId = CurrentText.TextStyleId
Dim myEvaluator As MatchEvaluator = New MatchEvaluator(AddressOf MacroFieldEvaluator)
If PInvoke.fromAcDbTextStyle(iStyle.UnmanagedObject, styleId) = Autodesk.AutoCAD.Runtime.ErrorStatus.OK Then
Try
wd.Geometry.Text(CurrentText.Position, _
CurrentText.Normal, _
AAG.Vector3d.XAxis.RotateBy(CurrentText.Rotation, AAG.Vector3d.ZAxis), _
Regex.Replace(CurrentText.TextString, MACROFIELD_REGEX, myEvaluator), _
True, _
iStyle)
Catch ex As Exception
wd.Geometry.Text(CurrentText.Position, _
CurrentText.Normal, _
AAG.Vector3d.XAxis.RotateBy(CurrentText.Rotation, AAG.Vector3d.ZAxis), _
Regex.Replace(CurrentText.TextString, MACROFIELD_REGEX, String.Format("{0}{1}{2}", "*", ex.Message, "*")), _
True, _
iStyle)
End Try
Else
wd.Geometry.Text(CurrentText.Position, _
CurrentText.Normal, _
AAG.Vector3d.XAxis.RotateBy(CurrentText.Rotation, AAG.Vector3d.ZAxis), _
Regex.Replace(CurrentText.TextString, MACROFIELD_REGEX, myEvaluator), _
True, _
New AAGI.TextStyle())
End If
Else
MyBase.WorldDraw(d, wd)
End If
Return True
End Function
Private Function MacroFieldEvaluator(ByVal m As Match) As String
Dim ClassMethod As String = m.Value.Replace(MACROFIELD_BEGIN_CODE, "").Replace(MACROFIELD_END_CODE, "")
Dim FieldClassType As Type = FindType(ClassMethod.Substring(0, ClassMethod.LastIndexOf(".")))
Dim FieldClass As Object = Activator.CreateInstance(FieldClassType)
Dim FieldClassMethod As System.Reflection.MethodInfo = FieldClassType.GetMethod(ClassMethod.Substring(ClassMethod.LastIndexOf(".") + 1))
'If ClassMethod.Contains("(*)") Then
' Dim ClassMethodName As String = ClassMethod.Substring(0, ClassMethod.IndexOf("("))
' 'if "asdf" then string else number (regex)
' Dim ClassMethodArgs() As Object = ClassMethod.Substring(ClassMethod.IndexOf("(")).Replace("(", "").Replace(")", "").Split(",", options:=StringSplitOptions.RemoveEmptyEntries)
' Return FieldClassMethod.Invoke(FieldClass, Nothing)
'Else
Return FieldClassMethod.Invoke(FieldClass, Nothing)
'End If
End Function
Private Function FindType(ByVal name As String) As Type
Dim base As Type = Reflection.Assembly.GetExecutingAssembly.GetType(name, False, True)
If base IsNot Nothing Then Return base
For Each assembly As Reflection.Assembly In AppDomain.CurrentDomain.GetAssemblies
base = assembly.GetType(name, False, True)
If base IsNot Nothing Then Return base
Next
Throw New System.TypeLoadException(String.Format("Cannot find type '{0}'", name))
End Function
End Class