I looked at doing something similar quiet a while ago... you can create you're own field objects but only from ARX (from what i could tell) but i could never work out how to do via P/Invoke.
I ended up with a similar approach to Jeff H where i used an overrule that watched for particular coding. Once a match was found the overrule would then evaluate the 'text' within the codes and render the result. In my case the result was the return value of a .net function. The idea being that the one 'overrule field' could return the result of anything (ie. values from an external database, complex calculations, files, xdata, ... and not just properties of standard autocad objects).
Below is the code that i've been able to dig up that might help you decide to go down this path
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
hope this helps
cheers, Mark