// ============================================================================ // = 文 件 名 : StandardCheckDlg.cpp // = 版 本 号 : v1.0 // = 作 者 : Lixl // = 创建时间 : 2012-05-11 // = 功能描述 : 标准检查功能 : 实现文件 // Copyright (C), 1994-2012, Beijing Tangent Engineering Software Co. Ltd. // ============================================================================ #include "stdafx.h" #include "StandardCheckDlg.h" #include using namespace std; // 标准检查主函数 void StandardCheck() { CStandardCheckDlg* pDlg = new CStandardCheckDlg(); if (pDlg) { pDlg->Create(IDD_STANDARDCHECK, acedGetAcadFrame()); pDlg->ShowWindow(SW_NORMAL); } } // 获得字体样式idTextStyle的所使用的中文字体名称,英文字体名称 BOOL GetTextStyleFileName(const AcDbObjectId& idTextStyle, CString &sChinaFontName, CString &sEngFontName) { AcDbObject* pEnt = NULL; if (Acad::eOk == acdbOpenObject(pEnt, idTextStyle, AcDb::kForRead)) { AcDbTextStyleTableRecord* pRec = AcDbTextStyleTableRecord::cast(pEnt); if (NULL != pRec) { Adesk::Boolean bBold(Adesk::kFalse), bItalic(Adesk::kFalse); TCHAR* pfileName = NULL; #if ADS > 20 Adesk::Boolean bold, italic; Charset charset; Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch; Autodesk::AutoCAD::PAL::FontUtils::FontFamily family; pRec->font(pfileName, bBold, bItalic, charset, pitch, family); #else int nCharset, nPitchAndFamily; pRec->font(pfileName, bBold, bItalic, nCharset, nPitchAndFamily); #endif // modify by cq 2017-01-05 支持CAD2017 if (pfileName && 0 != _tcscmp(pfileName, _T(""))) {// WINDOWS字体 pRec->close(); return FALSE; } // AUTOCAD字体 const TCHAR* pShxName = NULL; const TCHAR* pBigFontFileName = NULL; pRec->fileName(pShxName); pRec->bigFontFileName(pBigFontFileName); pRec->close(); sEngFontName = pShxName; if(pBigFontFileName) sChinaFontName = pBigFontFileName; else sChinaFontName = _T(""); int idx(0); if(sEngFontName != _T("")) //先检查英文字体文件 { // 有点带.SHX,有的不带,发现了就去掉.后缀 idx = sEngFontName.Find(_T(".")); if(idx > -1) sEngFontName = sEngFontName.Left(idx); } if(sChinaFontName != _T(""))//再检查中文字体文件 { idx = sChinaFontName.Find(_T(".")); if(idx > -1) sChinaFontName = sChinaFontName.Left(idx); } return TRUE; } } return FALSE; } IMPLEMENT_DYNAMIC(CStandardCheckDlg, CModelessDialog) CStandardCheckDlg::CStandardCheckDlg(CWnd* pParent /*=NULL*/) : CModelessDialog(CStandardCheckDlg::IDD, pParent) { } CStandardCheckDlg::~CStandardCheckDlg() { } void CStandardCheckDlg::DoDataExchange(CDataExchange* pDX) { CModelessDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_STC_PIE, m_wndPie); DDX_Control(pDX, IDC_LST_CHINAFONT, m_wndlstChinaFont); DDX_Control(pDX, IDC_LST_CADFONT, m_wndlstCADFont); } BEGIN_MESSAGE_MAP(CStandardCheckDlg, CModelessDialog) ON_BN_CLICKED(IDC_BTN_CHECKLAYER, OnBnClickedBtnCheckLayer) ON_BN_CLICKED(IDC_BTN_CHECKFONT, OnBnClickedBtnCheckfont) ON_BN_CLICKED(IDC_BTN_SHOWILLEGAL, OnBnClickedBtnShowillegal) ON_WM_CLOSE() ON_WM_DESTROY() END_MESSAGE_MAP() BOOL CStandardCheckDlg::OnInitDialog() { CModelessDialog::OnInitDialog(); // 初始化饼图 m_wndPie.SetStyle(CTGSizeDescrWnd::kPie); m_wndPie.SetPer(0); // 初始化上华标准图层文件向量 if (!GetTangentLayer()) return FALSE; return TRUE; } // 从上华图层文件LAYERDEF.DAT中得到所有上华图层 BOOL CStandardCheckDlg::GetTangentLayer() { // CString sLayerFilePath = g_csSysPath; XString fullFile; if(FindFile(_T("layerdef.dat"), fullFile)) { FILE *fp=fopen(_AS(fullFile), "r"); if(!fp) { AfxMessageBox(_T("layerdef.dat文件无法打开,请检查.")); return FALSE; } // 清空上华标准信息 m_vecStardLayerName.clear(); m_vecStardLayer.clear(); m_vecStardLayerColor.clear(); // 0层,Defpoints,ASHADE,当做标准图层 m_vecStardLayerName.push_back(_T("0层")); m_vecStardLayer.push_back(_T("0")); m_vecStardLayerColor.push_back(7); m_vecStardLayerName.push_back(_T("Defpoints层")); m_vecStardLayer.push_back(_T("Defpoints")); m_vecStardLayerColor.push_back(7); m_vecStardLayerName.push_back(_T("ASHADE层")); m_vecStardLayer.push_back(_T("ASHADE")); m_vecStardLayerColor.push_back(7); // 读取上华图层定义文件,获得标准信息 CStringArray arLayerInfo; char sBuf[256]=""; char* pRowText = NULL; while(!feof(fp)) { // 清空变量值 memset(sBuf, 0, 256); arLayerInfo.RemoveAll(); pRowText = NULL; // 获得一行数据,解析一行 pRowText = fgets(sBuf, 255, fp); if (NULL == pRowText) continue; strtok(pRowText, " \t"); while(NULL != pRowText) { arLayerInfo.Add(pRowText); pRowText = strtok(NULL, " \t"); } // 查看图层信息完整 if ((int)arLayerInfo.GetSize() >= 3) { m_vecStardLayerName.push_back(arLayerInfo[0]); m_vecStardLayer.push_back(arLayerInfo[1]); m_vecStardLayerColor.push_back(_ttoi(arLayerInfo[2])); } } fclose(fp); } int dd = m_vecStardLayer.size(); return m_vecStardLayer.size() > 0; } // 查询子串(不计大小写) class SearchSubCString { public: SearchSubCString(const CString &sVal) { m_sVal = sVal; m_sVal.MakeLower(); } bool operator()(const CString &sArg) { if(sArg.Find(_T("PIPE")) != -1) { int i = 1; } if (sArg.Compare(_T("0")) == 0) { if (m_sVal.Compare(sArg) == 0) { return true; } else { return false; } } CString sTemp = sArg; sTemp.MakeLower(); if (m_sVal.Find(sTemp) != -1) { return true; } return false; } private: CString m_sVal; }; // 检查图层 void CStandardCheckDlg::OnBnClickedBtnCheckLayer() { // 获得所有实体 if (!GetAllEntityFromDwg(m_arCurDwgEnts)) return ; // 清空现有图层文件 m_vecLegalLayer.clear(); m_vecIllegalLayer.clear(); CString sLayer; AcDbEntity* pEnt = NULL; int nNum = m_arCurDwgEnts.length(); acedSetStatusBarProgressMeter(_T("标准检查进行中,请等待..."), 0, nNum); for (int i = 0; i < nNum; i++) { acedSetStatusBarProgressMeterPos(i); if (Acad::eOk == acdbOpenAcDbEntity(pEnt, m_arCurDwgEnts[i], AcDb::kForRead)) { sLayer.Empty(); sLayer = pEnt->layer(); pEnt->close(); // 不包含在标准图层中,非标准图层,放入非法图层容器 // if (m_vecStardLayer.end() == find(m_vecStardLayer.begin(), m_vecStardLayer.end(), sLayer)) if (m_vecStardLayer.end() != find_if(m_vecStardLayer.begin(), m_vecStardLayer.end(), SearchSubCString(sLayer))) { // 包含在标准图层中,标准图层,放入合法图层容器 if (m_vecLegalLayer.end() == find(m_vecLegalLayer.begin(), m_vecLegalLayer.end(), sLayer)) m_vecLegalLayer.push_back(sLayer); } else { if (m_vecIllegalLayer.end() == find(m_vecIllegalLayer.begin(), m_vecIllegalLayer.end(), sLayer)) m_vecIllegalLayer.push_back(sLayer); } } } acedRestoreStatusBar(); // 非法图层数量和所有图层数量的比值,为饼图比例 double dAllLayerNum = GetCurLayerNum(); double dIlligealNum = (double)m_vecIllegalLayer.size(); double dPer = dIlligealNum / dAllLayerNum * 100.0; if ((dPer > -1E-10) && (dPer - 100.0 < 1E-10)) { m_wndPie.SetPer(dPer); m_wndPie.Invalidate(); } } // 获得所有实体id,acedSSGet方法 BOOL CStandardCheckDlg::GetAllEntityFromDwg(AcDbObjectIdArray& arEnts) { arEnts.setLogicalLength(0); // 锁定文档 acDocManager->lockDocument(acDocManager->curDocument()); // 所有图层结果缓冲区 struct resbuf* pRblist = NULL; pRblist = acutBuildList(8, _T("*"), NULL); ads_name ss; int nRet = acedSSGet(_T("X"), NULL, NULL, pRblist, ss); if (RTNORM == nRet) { #if ADS > 20 int nEntCount = 0; #else long nEntCount = 0; #endif nRet = acedSSLength(ss, &nEntCount); ads_name ent; AcDbObjectId id; for ( long i = 0; i < nEntCount; i++) { if (RTNORM == acedSSName(ss, i, ent) && Acad::eOk == acdbGetObjectId(id, ent)) { arEnts.append(id); } } } acutRelRb(pRblist); acDocManager->unlockDocument(acDocManager->curDocument()); return arEnts.length() > 0; } // 从图形数据库中取得所有图层数量 int CStandardCheckDlg::GetCurLayerNum() { int nLayerNum(0); // 锁定文档 acDocManager->lockDocument(acDocManager->curDocument()); AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) { // 打开图层表 AcDbLayerTable* pLayTab = NULL; if (Acad::eOk == pDb->getLayerTable(pLayTab, AcDb::kForRead)) { AcDbLayerTableIterator* pLayIt = NULL; if (Acad::eOk == pLayTab->newIterator(pLayIt)) { // 遍历每个图层 // TCHAR* pszName; // AcDbLayerTableRecord* pLayRec = NULL; for (; !pLayIt->done(); pLayIt->step()) { // pLayRec = NULL; // if (Acad::eOk == pLayIt->getRecord(pLayRec, AcDb::kForRead)) // { // pLayRec->getName(pszName); // pLayRec->close(); // } ++nLayerNum; } delete pLayIt; } // 关闭图表 pLayTab->close(); } } acDocManager->unlockDocument(acDocManager->curDocument()); return nLayerNum; } // 从当前图纸上获得所有文字使用到的文字样式id void CStandardCheckDlg::GetTextStyleIdFromEnts(AcDbObjectIdArray& arTextStyleId) { arTextStyleId.setLogicalLength(0); // 获得所有文字实体 AcDbObjectIdArray arTextEnt; if (!GetAllTextEntsOfCurDwg(arTextEnt)) return ; AcDbEntity* pEnt = NULL; AcDbText* pText = NULL; AcDbMText* pMText = NULL; TDbText* pTDdText = NULL; TDbMText* pTDbMText = NULL; // 提取所有文字实体中的文字样式id int nPos(0); AcDbObjectId idStyle; int nTextEntsNum = arTextEnt.length(); for (int i = 0; i < nTextEntsNum; i++) { if (Acad::eOk == acdbOpenAcDbEntity(pEnt, arTextEnt[i], AcDb::kForRead)) { idStyle.setNull(); if (Adesk::kTrue == pEnt->isKindOf(AcDbText::desc())) { pText = AcDbText::cast(pEnt); idStyle = pText->textStyle(); } else if (Adesk::kTrue == pEnt->isKindOf(AcDbMText::desc())) { pMText = AcDbMText::cast(pEnt); idStyle = pMText->textStyle(); } else if (Adesk::kTrue == pEnt->isKindOf(TDbText::desc())) { pTDdText = TDbText::cast(pEnt); idStyle = pTDdText->GetStyleId(); } else if (Adesk::kTrue == pEnt->isKindOf(TDbMText::desc())) { pTDbMText = TDbMText::cast(pEnt); idStyle = pTDbMText->GetStyleId(); } else { CString sClassName = pEnt->isA()->name(); sClassName += _T("\n"); acutPrintf(sClassName); } // 字体样式id可用,且不包含在数组中,再添加 if (idStyle.isValid() && Adesk::kTrue != arTextStyleId.find(idStyle, nPos, 0)) { arTextStyleId.append(idStyle); } } } } // 得到当前DWG图纸的所有文字实体 : acedSSGet方法 BOOL CStandardCheckDlg::GetAllTextEntsOfCurDwg(AcDbObjectIdArray& arEnts) { arEnts.setLogicalLength(0); // 锁定文档 acDocManager->lockDocument(acDocManager->curDocument()); // 所有图层结果缓冲区 struct resbuf* pRblist = NULL; // 注:若在此处添加DXF,需要GetTextStyleIdFromEnts中处理此种实体,获得其StyleId. pRblist = acutBuildList(RTDXF0, _T("TEXT,MTEXT,ATS_TEXT,ATS_MTEXT"), NULL); ads_name ss; int nRet = acedSSGet(_T("X"), NULL, NULL, pRblist, ss); if (RTNORM == nRet) { #if ADS > 20 int nEntCount = 0; #else long nEntCount = 0; #endif nRet = acedSSLength(ss, &nEntCount); ads_name ent; AcDbObjectId id; for ( long i = 0; i < nEntCount; i++) { if (RTNORM == acedSSName(ss, i, ent) && Acad::eOk == acdbGetObjectId(id, ent)) { arEnts.append(id); } } } acutRelRb(pRblist); acDocManager->unlockDocument(acDocManager->curDocument()); return arEnts.length() > 0; } // 遍历数据库文字样式表,获取所有文字样式id,(不只是用到的,可能有数据库中存在但实体没用到的样式) void CStandardCheckDlg::GetTextStyleIdFromDwg(AcDbObjectIdArray& arTextStyleId) { // 锁定文档 acDocManager->lockDocument(acDocManager->curDocument()); vector vecTextStyle; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) { // 打开字体样式表 AcDbTextStyleTable* pTextTab = NULL; if (Acad::eOk == pDb->getTextStyleTable(pTextTab, AcDb::kForRead)) { AcDbTextStyleTableIterator* pTextIt = NULL; if (Acad::eOk == pTextTab->newIterator(pTextIt)) { pTextTab->close(); arTextStyleId.setLogicalLength(0); TCHAR* pszName; AcDbTextStyleTableRecord* pTextStyleRec = NULL; for (int i = 0; !pTextIt->done(); pTextIt->step(), i++) { pTextIt->getRecord(pTextStyleRec, AcDb::kForRead); pszName = NULL; pTextStyleRec->getName(pszName); vecTextStyle.push_back(pszName); arTextStyleId.append(pTextStyleRec->objectId()); } delete pTextIt; } } } acDocManager->unlockDocument(acDocManager->curDocument()); } // 隐藏标准图层,显示错误图层 void CStandardCheckDlg::OnBnClickedBtnShowillegal() { // CRect rc; // GetWindowRect(&rc); // MoveWindow(0, 0, rc.Width(), rc.Height(), TRUE); // 现有标准图层为空,重新获取 if ((int)m_vecLegalLayer.size() <= 0) OnBnClickedBtnCheckLayer(); SetStandardLayerOff(true); } // bOff : true关闭标准图层, false打开标准图层 void CStandardCheckDlg::SetStandardLayerOff(bool bOff/* = true*/) { // 锁定文档 acDocManager->lockDocument(acDocManager->curDocument()); AcDbDatabase* pDb = acdbCurDwg(); if (pDb) { Acad::ErrorStatus es = Acad::eOk; AcDbLayerTable* pLayTab = NULL; es = pDb->getLayerTable(pLayTab, AcDb::kForWrite); if (Acad::eOk == es) { AcDbLayerTableIterator* pIt = NULL; if (Acad::eOk == pLayTab->newIterator(pIt)) { AcDbLayerTableRecord* pLayRec = NULL; CString sLayer; TCHAR* pszLayer; for ( ; !pIt->done(); pIt->step()) { pLayRec = NULL; es = pIt->getRecord(pLayRec, AcDb::kForWrite); if (Acad::eOk == es) { if (Acad::eOk == pLayRec->getName(pszLayer)) { sLayer = pszLayer; if (m_vecLegalLayer.end() != find(m_vecLegalLayer.begin(), m_vecLegalLayer.end(), sLayer)) pLayRec->setIsOff(bOff); } pLayRec->close(); } } delete pIt; } pLayTab->close(); } } acDocManager->unlockDocument(acDocManager->curDocument()); // 重绘DWG PostCommand(_T("redraw")); } void CStandardCheckDlg::OnBnClickedBtnCheckfont() { // 获得当前图纸上实体使用的字体样式ID数组 AcDbObjectIdArray arTextStyleId; // 获得所有文字实体使用的样式id数组 GetTextStyleIdFromEnts(arTextStyleId); // 获得所有字体样式id数组 // GetTextStyleIdFromDwg(arTextStyleId); int nTextStyleNum = arTextStyleId.length(); if (nTextStyleNum <= 0) return; // 中文文字容器,英文文字容器 vector vecChinaFont; vector vecCADFont; TCHAR* pfileName = NULL; CString sChinaFontName, sEngFontName; // 遍历每个字体样式id,获取其包含的中英文字体名称 for (int i = 0; i < nTextStyleNum; i++) { if (GetTextStyleFileName(arTextStyleId[i], sChinaFontName, sEngFontName)) { if(sEngFontName != _T("")) //先检查英文字体文件 { if (vecCADFont.end() == find(vecCADFont.begin(), vecCADFont.end(), sEngFontName)) vecCADFont.push_back(sEngFontName); } if(sChinaFontName != _T(""))//再检查中文字体文件 { if (vecChinaFont.end() == find(vecChinaFont.begin(), vecChinaFont.end(), sChinaFontName)) vecChinaFont.push_back(sChinaFontName); } } } // 将中英文字体名称添加到列表中 m_wndlstCADFont.ResetContent(); m_wndlstChinaFont.ResetContent(); if (vecChinaFont.size() <= 0) m_wndlstChinaFont.AddString(_T("无")); else { for (i = 0; i < (int)vecChinaFont.size(); i++) { m_wndlstChinaFont.AddString(vecChinaFont[i]); } } if (vecCADFont.size() <= 0) m_wndlstCADFont.AddString(_T("无")); else { for (i = 0; i < (int)vecCADFont.size(); i++) { m_wndlstCADFont.AddString(vecCADFont[i]); } } } void CStandardCheckDlg::OnOK() { if ((int)m_vecLegalLayer.size() > 0) { SetStandardLayerOff(false); } DestroyWindow(); PostCommand(_T("\33")); } void CStandardCheckDlg::OnClose() { if ((int)m_vecLegalLayer.size() > 0) { SetStandardLayerOff(false); } DestroyWindow(); PostCommand(_T("\33")); } void CStandardCheckDlg::OnDestroy() { CModelessDialog::OnDestroy(); delete this; }