Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

665 lines
16 KiB
C++

// ============================================================================
// = 文 件 名 : 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 <algorithm>
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<CString> 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<CString> vecChinaFont;
vector<CString> 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;
}