using System;
using System.Collections.Generic;
using System.Text;
using Autodesk.AutoCAD.Runtime;
using System.Runtime.InteropServices;
using Autodesk.AutoCAD.DatabaseServices;
namespace CaddZone.AutoCAD.DatabaseServices
{
class DBUtils
{
// This is a managed workaround for getting a non-erased
// SymbolTableRecord, when there are also erased ones with
// the same name:
public static ObjectId GetTableRecordId(ObjectId TableId, string Name)
{
ObjectId id = ObjectId.Null;
using (Transaction tr = TableId.Database.TransactionManager.StartTransaction())
{
SymbolTable table = (SymbolTable)tr.GetObject(TableId, OpenMode.ForRead);
if (table.Has(Name))
{
id = table[Name];
if (!id.IsErased)
return id;
foreach (ObjectId recId in table)
{
if (!recId.IsErased)
{
SymbolTableRecord rec = (SymbolTableRecord)tr.GetObject(recId, OpenMode.ForRead);
if (string.Compare(rec.Name, Name, true) == 0)
return recId;
}
}
}
}
return id;
}
// This is a much better/faster solution that P/Invokes
// AcDbSymbolTableRecord::getAt() directly from managed code:
public static class AcDbSymbolTable
{
// Acad::ErrorStatus AcDbSymbolTable::getAt(wchar_t const *, class AcDbObjectId &, bool)
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acdb17.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode,
EntryPoint = "?getAt@AcDbSymbolTable@@QBE?AW4ErrorStatus@Acad@@PB_WAAVAcDbObjectId@@_N@Z")]
public static extern ErrorStatus getAt(IntPtr symbolTable, string name, out ObjectId id, bool getErased);
}
public static class AcDbSymbolTable18
{
// Acad::ErrorStatus AcDbSymbolTable::getAt(wchar_t const *, class AcDbObjectId &, bool)
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acdb18.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode,
EntryPoint = "?getAt@AcDbSymbolTable@@QBE?AW4ErrorStatus@Acad@@PB_WAAVAcDbObjectId@@_N@Z")]
public static extern ErrorStatus getAt(IntPtr symbolTable, string name, out ObjectId id, bool getErased);
}
public static class AcDbSymbolTable17
{
// Acad::ErrorStatus AcDbSymbolTable::getAt(wchar_t const *, class AcDbObjectId &, bool)
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("acdb17.dll", CallingConvention = CallingConvention.ThisCall, CharSet = CharSet.Unicode,
EntryPoint = "?getAt@AcDbSymbolTable@@QBE?AW4ErrorStatus@Acad@@PB_WAAVAcDbObjectId@@_N@Z")]
public static extern ErrorStatus getAt(IntPtr symbolTable, string name, out ObjectId id, bool getErased);
}
public static ObjectId GetSymbolTableRecordId(SymbolTable table, string name)
{
ObjectId id = ObjectId.Null;
String AcadVer = Autodesk.AutoCAD.ApplicationServices.Application.Version.ToString();
AcadVer = AcadVer.Substring(0, AcadVer.IndexOf("."));
ErrorStatus es;
switch (AcadVer)
{
case "17":
es = AcDbSymbolTable17.getAt(table.UnmanagedObject, name, out id, false);
break;
case "18":
es = AcDbSymbolTable18.getAt(table.UnmanagedObject, name, out id, false);
break;
default:
es = AcDbSymbolTable17.getAt(table.UnmanagedObject, name, out id, false);
break;
}
//ErrorStatus es = AcDbSymbolTable.getAt(table.UnmanagedObject, name, out id, false);
return id;
}
public static ObjectId GetSymbolTableRecordId(ObjectId TableId, string name)
{
using (Transaction tr = TableId.Database.TransactionManager.StartTransaction())
{
SymbolTable table = (SymbolTable)tr.GetObject(TableId, OpenMode.ForRead);
try
{
return GetSymbolTableRecordId(table, name);
}
finally
{
tr.Commit();
}
}
}
}
}
07.08.09
Дополнения для CaddZone
Немного доработал класс CaddZone, представленный здесь: добавил обработку нескольких версий AutoCAD (2007-2010; выйдет 2011, посмотрим и на нее). Фактической ценности - минимум, сделано только для собственного архива ;)
| Действия: |
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий