除了最后一個輸出面積到excel沒做,其他都是做了的。只支持AcDbPolyline和AcDbCircle。這是我模仿網上的動態圖做的,主要是為了練習。下面我把自己的一些心得分享出來。使用到的一些幫助內可以在張帆、朱文俊的書《AutoCAD ObjectARX(VC)開發基礎與實例教程 》找到,csdn有源碼,不過大多要積分,我這有源碼,可以留言,我發郵箱。這個插件我分享在了明經論壇上了。
我首頁就有地址。不過需要的,我也可以發郵件。
開發的時候,一定要在最開始建立一個ErrorStatus 的變量,一般在操作實體的時候都會返回這個類型的值,調試的時候發現哪出錯了,可以通過它來知道錯誤的詳細信息,然后在百度上一搜就有解決辦法了。
做這個插件的時候,感覺使用了MFC,在打開實體時,如果不對文檔進行加鎖,打開實體的步驟直接報錯,返回Acad::eLockViolation,這時就需要這樣做:
acDocManager->lockDocument(acDocManager->curDocument()); //.....操作 acDocManager->unlockDocument(acDocManager->curDocument());
加鎖和解鎖一定是成對出現的。大概意思就是文檔管理器對當前文檔加鎖和解鎖。
在標注面積的時候發現,面積過大,標注面積所用的字體如果不按比例變化,就有可能會很小不方便看,所以,我這里采用了按面積比例的方式改變字體高度。
double area = 0.0; pl->getArea(area); if (textHeight <= 0.0) { textHeight = (int)sqrt(area) / 7; }
在做面積求和的時候,使用到了acedSSGet,這個方法用法多的很,我主要是想實現框選,然后遍歷出選擇的實體。這個開發文檔里面有詳細介紹,第一個參數表示:操作類型,二三個是點,第四個是過濾器。
通過acedSSLength(ssName, &length);得到所選實體集合的長度。
通過acedSSName(ssName, i, ent);遍歷實體得到實體。
最后通過acdbGetObjectId(oId, ent)得到實體id。

ads_name ssName; if (acedSSGet(NULL, NULL, NULL, NULL, ssName) != RTNORM) { return; } int length; acedSSLength(ssName, &length); for (int i = 0; i < length; i++) { ads_name ent; acedSSName(ssName, i, ent); AcDbObjectId oId; if (acdbGetObjectId(oId, ent) == ErrorStatus::eOk) { AcDbEntity * pEnt = NULL; ErrorStatus es; es = acdbOpenObject(pEnt, oId, AcDb::OpenMode::kForWrite); if (es == ErrorStatus::eOk) { vecEnts.push_back(pEnt); } } }
在做統計面積到cad表格中時,用到了acedTraceBoundary這個命令,這個方法是高版本cad才有,
它也有替代方法,我在另一篇博客寫過的https://www.cnblogs.com/HelloQLQ/p/12228308.html。
在封閉區間按點的時候,有可能會報錯說eInvalidInput,這個時候把圖形放大了在點,就准確些。
要實現點一個封閉圖形,就在表格添加一行的功能,那就必須先添加好表個的頭部,記錄這個表格的id,用while循環點擊,每點一次就打開關閉一次表格就可以了。
我遇到的問題有CString轉ACHAR*,這樣可以解決:
ACHAR* ach1=strIndex.AllocSysString();
在做輸入面積到txt文檔時,用到了c++的流對象:
ofstream myfile(chPath, ofstream::trunc);
這個對象操作的時char*對象,把CString轉成char*的方法:
USES_CONVERSION; char *chPath= T2A(fpath);