Casting works in both dbx db's and mdiactivedocument db's. See last function GetDBProxyCol.
This implementation implements irneb's suggestion of finding, collecting, then cleaning in a while loop. Worked like a charm.
Also of relevance: I removed the call to lispfunction to change working databaes. I didn't think I needed it, and was only a test. The only time I've needed to set working database was when working on attributes.
[LispFunction("cd:ProxyClean")]
public Boolean ProxyClean(ResultBuffer rb)
{
if (rb == null)
{ return false; }
TypedValue[] args = rb.AsArray();
if (args.Length != 1 || (LispDataType)args[0].TypeCode != LispDataType.ObjectId)
{ return false; }
//we accept any object from the drawing that is to be processed. I trend in sending modelspace, but it doesn't matter
//just need an object so the owning database can be retrieved
ObjectId objId = (ObjectId)args[0].Value;
Database db = objId.Database;
using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction())
{
CleanProxies(GetDBProxyCol(db, tr), db, tr);
tr.Commit();
return true;
}
}
//recieves a collection of proxy ONLY objectids. No checking to see if that's true
//will loop until all proxies are successfully stripped (opened for write)
private void CleanProxies(ObjectIdCollection proxyCol, Database db, Transaction tr)
{
while (proxyCol.Count > 0)
{
try
{
DBObject proxy = tr.GetObject(proxyCol[0], OpenMode.ForWrite) as DBObject;
using (DBObject newObj
= new Xrecord
()) {
proxy.HandOverTo(newObj, false, false);
proxyCol.RemoveAt(0);
}
}
catch
{ } //catch to try try again
}
}
//Alexander's algorithm ??
//gile - http://www.theswamp.org/index.php?topic=44880.msg501032#msg501032
//managed transaction base to retrieve all proxy objects in drawing by cycling through every object id db
private ObjectIdCollection GetDBProxyCol(Database db, Transaction tr)
{
ObjectIdCollection proxyCol
= new ObjectIdCollection
(); ObjectId id;
for (long l = db.BlockTableId.Handle.Value; l < db.Handseed.Value; l++)
{
if (!db
.TryGetObjectId(new Handle
(l
),
out id
)) continue;
if (!id.IsErased)
{
DBObject dbObj = tr.GetObject(id, OpenMode.ForRead) as DBObject;
ProxyObject proxyObj = dbObj as ProxyObject;
ProxyEntity proxyEnt = dbObj as ProxyEntity;
if (proxyObj != null || proxyEnt != null)
proxyCol.Add(id);
}
}
return proxyCol;
}
I can finally rest. Thanks to everyone who's input made this happen.
Gile for the primary source
Irneb for the directional guidance.
Jeff H for the base understanding.
And Alexander Rivilis for the suggestion of db iteration so that nothing is missed
I can't thank you guys enough, as I've been struggling through this one for three weeks (almost full time), and I was worried that I could have cycled the drawing manually by now.