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

879 lines
20 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "acdocman.h"
#include "tgas.h"
#include "Project.h"
///////////////////////////////////////////////////////////
// 取得楼层数据库的DBF文件名称
TARCH_EXP int GetProjectDbf(XString &m_sDbfFile)
{
XString sDwgPrefix, sDwgPrefix1;
xg_getvar(_T("DWGPREFIX"), sDwgPrefix);
XString sTemp(256);
sTemp << sDwgPrefix << _T("building.dbf");
m_sDbfFile = sTemp;
if (!FindFile(m_sDbfFile))
{
FieldInfo fields[4];
fields[0] = FieldInfo(_T("floor"), _T('C'), 64);
fields[1] = FieldInfo(_T("dwgfile"), _T('C'), 64);
fields[2] = FieldInfo(_T("height"), _T('N'), 10);
CodeBase db;
XDbfTable *pTable = db.Create(m_sDbfFile, fields, 4);
if (pTable != NULL)
{
adsout << _T("\n不能创建") << sTemp;
return RTERROR;
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
// 把形如“1,2~6,9”的串离散为1,2,3,4,5,6,9
// Status:没有仔细分析字符的合法性
TARCH_EXP BOOL StrToIntList(const TCHAR* pszDesc, DList<int> &lstResult)
{
int i = 1;
TCHAR szWord[256] = _T("");
while(CT_strnth(pszDesc, i, szWord))
{
TCHAR *pSep = _tcschr(szWord, _T('~'));
if (pSep==NULL && *szWord!=_T('-'))
pSep = _tcschr(szWord, _T('-'));
if (pSep)
{
int nTo = _ttoi(pSep + 1);
*pSep = EOS;
int nFrom = _ttoi(szWord);
if (nFrom >= nTo)
return FALSE;
for (int n=nFrom; n<=nTo; n++)
{
for (int j=0; j<lstResult.Length(); j++)
{
if (*lstResult[j] == n) // Already exist
return FALSE;
}
lstResult.Append(new int(n));
}
}
else
{
int n = _ttoi(szWord);
for (int j=0; j<lstResult.Length(); j++)
{
if (*lstResult[j] == n) // Already exist
return FALSE;
}
lstResult.Append(new int(n));
}
i++;
}
return lstResult.Length()>0;
}
///////////////////////////////////////////////////////////
TARCH_EXP int GetFloorData(const TCHAR *sDwgPrefix, XDbfTable &grp, DList<XFloorData> &lstFloors)
{
for (grp.MoveFirst(); !grp.IsEOF(); grp.MoveNext())
{
int nHeight;
CString sDwg, sFloor;
GET_FIELD((&grp), _T("floor"), sFloor);
GET_FIELD((&grp), _T("dwgfile"), sDwg);
GET_FIELD((&grp), _T("height"), nHeight);
if (!sFloor || !sDwg)
{
adsout << /*UMSG*/_T("\n项目数据库有错!");
return RTERROR;
}
XString sFullDwgName(256);
sFullDwgName << sDwgPrefix << sDwg;
// if (dlg.m_bUseExpl3d) sFullDwgName << _T("_3D");
sFullDwgName << _T(".DWG");
if (!FindFile(sFullDwgName))
{
adsout << /*UMSG*/_T("\n标准层模型'") << sFullDwgName << _T("'不存在!");
return RTERROR;
}
DList<int> lstIndexes;
if (!StrToIntList(sFloor, lstIndexes))
{
adsout << /*UMSG*/_T("\n楼层的描述有错!");
return RTERROR;
}
for (int i=0; i<lstIndexes.Length(); i++)
{
int nIdx = *lstIndexes[i];
if (lstFloors.FindNode(&nIdx, XFloorData::CompareForFind))
{
adsout << /*UMSG*/_T("\n有重复楼层号出现!");
return RTERROR;
}
lstFloors.Append(new XFloorData(nIdx, sFullDwgName, nHeight));
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
TARCH_EXP int GetFloorData(XDbfTable &grp, DList<XFloorData> &lstFloors)
{
XString sDwgPrefix;
xg_getvar(_T("DWGPREFIX"), sDwgPrefix);
return GetFloorData(sDwgPrefix, grp, lstFloors);
}
///////////////////////////////////////////////////////////
TARCH_EXP int CheckFloorData(DList<XFloorData> &lstFloors)
{
if (!lstFloors)
return RTERROR;
lstFloors.QuickSort(XFloorData::CompareForSort);
int nFirst = lstFloors[0]->m_nIndex;
for (int i=0; i<lstFloors.Length(); i++)
{
int nFloorNum = nFirst+i;
if (nFirst<0 && nFloorNum>=0) // 有地下室时没有0层
nFloorNum++;
if (lstFloors[i]->m_nIndex != nFloorNum)
{
adsout << /*UMSG*/_T("\n缺少第") << nFloorNum << _T("层数据!");
return RTERROR;
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
bool HasFloorInFrame(const DList<XFloorData>&floors)
{
for (long i=0;i<floors.Length();i++)
{
if (floors[i].m_bFloorInFrame)
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int XFloorData::CompareForSort(const XFloorData *p1, const XFloorData *p2)
{
if (p1->m_nIndex > p2->m_nIndex)
return 1;
if (p1->m_nIndex < p2->m_nIndex)
return -1;
return 0;
}
int XFloorData::CompareForFind(const XFloorData *p1, const void *p2)
{
int idx2 = *(const int *)p2;
if (p1->m_nIndex > idx2)
return 1;
if (p1->m_nIndex < idx2)
return -1;
return 0;
}
bool XFloorData::IsSameData(const XFloorData&f)const
{
if (f.m_sDwgFile==m_sDwgFile && f.m_bFloorInFrame && m_bFloorInFrame)
{
if (m_bFloorInFrame)
return f.m_ptMin==m_ptMin && f.m_ptMax==m_ptMax;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CArchive& TProjectItem::operator >>(CArchive&ar)const // ok
{
return ar<<GetType()<<m_sName; // 保存类型和名称
}
CArchive& TProjectItem::operator <<(CArchive&ar) // ok
{
return ar>>m_sName; // 只读名称,类型提前读
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TProjectItemEx::SetData(char *pData,int size) // ok
{
m_iByteSize = size;
if (m_pBuf != NULL)
{
delete[] m_pBuf;
m_pBuf = NULL;
}
m_pBuf = pData;
}
CArchive& TProjectItemEx::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator >>(ar);
ar<<GetLength();
for (int i=0;i<GetLength();i++)
{
ar<<(*this)[i];
}
return ar;
}
CArchive& TProjectItemEx::operator <<(CArchive&ar) // ok
{
TProjectItem::operator <<(ar);
if (m_pBuf != NULL)
delete[] m_pBuf;
if (GetLength() > 0)
m_pBuf = new char[GetLength()];
else
m_pBuf = NULL;
ar>>m_iByteSize;
for (int i=0; i<GetLength(); i++)
{
ar>>(*this)[i];
}
return ar;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CArchive& TProjectGroupItem::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator>>(ar);
ar<<GetLength();
for (long i=0;i<GetLength();i++)
GetPData(i)>>ar;
return ar;
}
CArchive& TProjectGroupItem::operator <<(CArchive&ar) // ok
{
Clear();
TProjectItem::operator<<(ar);
long num;
ar>>num;
for (long i=0;i<num;i++)
{
int type;
ar>>type;
TProjectItem*pItem = NULL;
switch(type)
{
case TYPE_PJ_ITEM:
pItem = new TProjectItem;
break;
case TYPE_PJ_GROUP:
pItem = new TProjectGroupItem;
break;
case TYPE_PJ_FLOOR:
pItem = new TProjectFloor;
break;
case TYPE_PJ_FILE:
pItem = new TProjectFile;
break;
case TYPE_PROJECT:
pItem = new TProject;
break;
case TYPE_PJ_ITEM_EX:
pItem = new TProjectItemEx;
break;
default:
throw type;
}
*pItem<<ar;
AddTail(pItem);
}
return ar;
}
// flag==0:全部查找,flag==1:只找节点,flag==2:只找目录
TProjectItem* TProjectGroupItem::FindItem(CString sName,bool bFindSubGroup,int flag) // ok
{
for (MoveToFirst();!IsOut();MoveToNext())
{
if (flag == 0)
{
if (GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
else if (flag == 1)
{
if (!GetCurData()->IsGroup() && GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
else
{
if (GetCurData()->IsGroup() && GetCurData()->GetName() == sName)
return GetCurData();
else if (bFindSubGroup && GetCurData()->IsGroup())
{
TProjectGroupItem* pGroup = (TProjectGroupItem*)GetCurData();
TProjectItem* pItem = pGroup->FindItem(sName, bFindSubGroup, flag);
if (pItem != NULL)
return pItem;
}
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProjectFile::s_iVersion = 0;
CArchive& TProjectFile::operator >>(CArchive&ar)const // ok
{
TProjectItem::operator >>(ar);
return ar<<s_iVersion;
}
CArchive& TProjectFile::operator <<(CArchive&ar) // ok
{
TProjectItem::operator <<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProjectFloor::s_iVersion = 0;
CArchive& TProjectFloor::operator>>(CArchive&ar)const // ok
{
TProjectItem::operator>>(ar);
ar<<s_iVersion;
return ar<<m_sLayerNo<<m_fHeight<<m_iFlag
<<m_ptBase.x<<m_ptBase.y<<m_ptMin.x<<m_ptMin.y<<m_ptMax.x<<m_ptMax.y;
}
CArchive& TProjectFloor::operator<<(CArchive&ar) // ok
{
TProjectItem::operator<<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar>>m_sLayerNo>>m_fHeight>>m_iFlag>>
m_ptBase.x>>m_ptBase.y>>m_ptMin.x>>m_ptMin.y>>m_ptMax.x>>m_ptMax.y;
}
bool TProjectFloor::IsInclude(XPoint pt)const // ok
{
if (IsFloorInFrame())
{
if (pt.x<m_ptMin.x-1E-6)
return false;
if (pt.y<m_ptMin.y-1E-6)
return false;
if (pt.x>m_ptMax.x+1E-6)
return false;
if (pt.y>m_ptMax.y+1E-6)
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int TProject::s_iVersion = 0;
CArchive& TProject::operator>>(CArchive&ar)const
{
TProjectGroupItem::operator>>(ar);
ar<<s_iVersion;
return ar;
}
CArchive& TProject::operator<<(CArchive&ar)
{
TProjectGroupItem::operator<<(ar);
int ver;
ar>>ver;
if (ver>s_iVersion)
throw 0;
return ar;
}
TProject::~TProject() // ok
{
m_pTGExportWnd = m_pTGProjectBarWnd = NULL;
}
CString TProject::GetDwgFullName(CString szName)const
{
if (szName == _T(""))
return _T("");
if (szName.Find(_T(":")) != 1)
{
CString szPath;
GetFilePath(szPath);
szName = szPath + szName + _T(".dwg");
}
else
szName += _T(".dwg");
return szName;
}
CString TProject::GetDwgRelativeName(CString szFullName)const
{
if (szFullName == _T(""))
return szFullName;
CString szPath;
GetFilePath(szPath);
CString szTemp = szFullName;
szTemp.MakeLower();
szPath.MakeLower();
if (szTemp.Find(szPath) == 0)
szFullName = szFullName.Right(szFullName.GetLength() - szPath.GetLength());
szFullName = szFullName.Left(szFullName.GetLength()-4);
return szFullName;
}
void TProject::New(CString sFile,int flag) // ok
{
if (m_sFileFullName != _T(""))
Save();
Clear();
//...重设数据
m_sFileFullName = sFile;
if ((flag&HIDE_DWGSET) == 0) // 有图纸集
AddTail(new TProjectGroupItem(_T("图纸")));
if ((flag&HIDE_FLOOR) == 0) // 有楼层表
AddTail(new TProjectGroupItem(_T("楼层")));
}
BOOL bDisableEcho=FALSE;//是否提示
bool TProject::Load(CString sFile) // ok
{
if (m_sFileFullName != _T(""))
Save();
CFile file;
if (!file.Open(sFile,CFile::modeRead))
{
if (!bDisableEcho)
{
CString sDesc;
sDesc.Format(_T("无法打开工程文件:%s!"),sFile);
AfxMessageBox(sDesc);
}
return false;
}
m_sFileFullName = _T("");
CArchive ar(&file,CArchive::load);
try
{
int type;
ar>>type;
*this<<ar;
}
catch(...)
{
if (!bDisableEcho)
{
CString sDesc;
sDesc.Format(_T("读取工程文件:%s错误!\n你可能需要安装高版本上华软件,或文件已经损坏!"),sFile);
AfxMessageBox(sDesc);
}
return false;
}
m_sFileFullName = sFile;
return true;
}
bool TProject::Save()const // ok
{
CFile file;
if (!file.Open(m_sFileFullName,CFile::modeWrite|CFile::modeCreate))
{
CString sDesc;
sDesc.Format(_T("无法保存工程文件:%s!"),m_sFileFullName);
AfxMessageBox(sDesc);
return false;
}
file.SetLength(0);
file.Flush();
CArchive ar(&file,CArchive::store);
try
{
*this>>ar;
}
catch(...)
{
CString sDesc;
sDesc.Format(_T("保存工程文件:%s失败!"),m_sFileFullName);
AfxMessageBox(sDesc);
return false;
}
return true;
}
int TProject::GetFloorData(DList<XFloorData> &lstFloors)
{
TProjectGroupItem*pFloorTable = GetGroup(_T("楼层"));
if (pFloorTable == NULL)
return RTERROR;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut();pFloorTable->MoveToNext())
{
TProjectFloor *pFloor = (TProjectFloor*)pFloorTable->GetCurData();
CString sFullDwgName = GetDwgFullName(pFloor->GetName());
if (!FindFile(sFullDwgName))
{
adsout<< _T("\n标准层模型") << (const TCHAR*)sFullDwgName << _T("不存在!");
return RTERROR;
}
DList<int> lstIndex;
if (!pFloor->GetLayerIndexList(lstIndex))
{
adsout<<_T("\n楼层号输入有误!");
return RTERROR;
}
for (int i=0; i<lstIndex.Length(); i++)
{
if (lstFloors.FindNode(lstIndex[i], XFloorData::CompareForFind))
{
adsout << _T("\n有重复楼层号出现!");
return RTERROR;
}
XFloorData*pXFloor = new XFloorData(*lstIndex[i], sFullDwgName,(int)pFloor->GetHeight());
pXFloor->m_bFloorInFrame = pFloor->IsFloorInFrame();
pXFloor->m_ptBase = pFloor->GetBasePoint();
pFloor->GetRange(pXFloor->m_ptMin, pXFloor->m_ptMax);
lstFloors.Append(pXFloor);
}
}
return RTNORM;
}
bool TProject::Is(CString sFullName) const
{
return _tcsicmp(sFullName, m_sFileFullName) == 0;
}
// 获取工程文件保存路径
bool TProject::GetFilePath(CString &sPath) const
{
int si = m_sFileFullName.ReverseFind('\\');
if (si < 0)
return false;
sPath = m_sFileFullName.Left(si + 1);
return true;
}
// 获取工程文件名(带.tpr)
bool TProject::GetProjectName(CString &sName) const
{
int si = m_sFileFullName.ReverseFind('\\');
if (si < 0)
return false;
sName = m_sFileFullName.Mid(si + 1, m_sFileFullName.GetLength() - si - 1);
return true;
}
TProject g_project;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
Adesk::Boolean acedPostCommand(const TCHAR * );
bool WritePrjToDwg(const TCHAR* sPrjFile,const TCHAR *sFile)
{
AcApDocumentIterator*pIter = acDocManager->newAcApDocumentIterator();
if (pIter != NULL)
{
AcApDocument *pOldDoc = curDoc();
for (; !pIter->done(); pIter->step())
{
AcApDocument*pDoc = pIter->document();
if (pDoc->isReadOnly())
continue;
if (_tcsicmp(pDoc->fileName(), sFile) == 0)
{
acDocManager->activateDocument(pDoc);
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
DocSetProjectFile(sPrjFile);
acDocManager->unlockDocument(curDoc());
acedPostCommand(_T("QSAVE\n"));
acDocManager->activateDocument(pOldDoc);
delete pIter;
return true;
}
}
delete pIter;
}
AcDbDatabase db(false, true);
#if ADS < 21
if (db.readDwgFile(sFile, _SH_DENYNO, false) != Acad::eOk)
#else
if (db.readDwgFile(sFile, AcDbDatabase::kForReadAndAllShare, false) != Acad::eOk)
#endif
return false;
TDbConfig *pCfg = GetDwgGlobal(AcDb::kForWrite, &db);
if (pCfg != NULL)
{
pCfg->SetProjectFile(sPrjFile);
pCfg->close();
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
bool bRet = db.saveAs(sFile) == Acad::eOk;
acDocManager->unlockDocument(curDoc());
return bRet;
}
return false;
}
///////////////////////////////////////////////////////////
// 打开工程文件,不存在则尝试新建
bool OpenProjectDwg(CString szFullName)
{
static bool bIn = false;
if (bIn)
return false;
bIn = true;
if (szFullName == _T(""))
{
bIn = false;
return false;
}
// 如已经打开则只需切换当前文档
AcApDocumentIterator *pIter = acDocManager->newAcApDocumentIterator();
if (pIter != NULL)
{
for (; !pIter->done(); pIter->step())
{
AcApDocument*pDoc = pIter->document();
if (_tcsicmp(pDoc->fileName(), szFullName) == 0)
{
if (curDoc() != pDoc)
acDocManager->activateDocument(pDoc);
bIn = false;
return true;
}
}
delete pIter;
}
//需要打开或新建
Acad::ErrorStatus es = acDocManager->appContextOpenDocument(szFullName);
if (es == Acad::eOk)
{
bIn = false;
return true;
}
else if (!FindFile(szFullName))
{
// 文件不存在尝试新建文件
XString sDwt;
if (FindFile(_T("acad.dwt"),sDwt))
{
if (acDocManager->appContextNewDocument(sDwt) == Acad::eOk)
{
acDocManager->lockDocument(curDoc(), AcAp::kWrite, NULL, NULL, true);
if (acdbCurDwg()->saveAs(szFullName) == Acad::eOk &&
DocSetProjectFile(g_project.GetFileFullName()))
{
acDocManager->unlockDocument(curDoc());
bIn = false;
return true;//成功新建
}
acDocManager->unlockDocument(curDoc());
}
else
AfxMessageBox(XString(_T("新建文件:%s!失败!"), szFullName));
}
else
AfxMessageBox(XString(_T("新建文件:%s失败!未找到:acad.dwt模板文件"), szFullName));
}
else
AfxMessageBox(XString(_T("无法打开:%s!可能是高版本文件"), szFullName));
bIn = false;
return false;
}
///////////////////////////////////////////////////////////
bool GetFloorFiles(XStringList &lstFiles)
{
DualList<CString> sFiles;
TProjectGroupItem* pFloorTable = GetFloorTable();
if (pFloorTable == NULL)
return false;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut(); pFloorTable->MoveToNext())
sFiles.FindOrAddTail(g_project.GetDwgFullName(pFloorTable->GetCurData()->GetName()));
for (sFiles.MoveToFirst(); !sFiles.IsOut(); sFiles.MoveToNext())
lstFiles.Append(tstrnew(sFiles.GetCurData()));
return true;
}
///////////////////////////////////////////////////////////
int GetFloorData(DList<XFloorData> &lstFloors)
{
TProjectGroupItem *pFloorTable = GetFloorTable();
if (pFloorTable == NULL)
return RTERROR;
for (pFloorTable->MoveToFirst(); !pFloorTable->IsOut();pFloorTable->MoveToNext())
{
TProjectFloor *pFloor = (TProjectFloor*)pFloorTable->GetCurData();
CString sFullDwgName = g_project.GetDwgFullName(pFloor->GetName());
if (!FindFile(sFullDwgName))
{
adsout<< _T("\n标准层模型") << (const TCHAR*)sFullDwgName << _T("不存在!");
return RTERROR;
}
DList<int> lstIndex;
if (!pFloor->GetLayerIndexList(lstIndex))
{
adsout<<_T("\n楼层号输入有误!");
return RTERROR;
}
for (int i=0; i<lstIndex.Length(); i++)
{
if (lstFloors.FindNode(lstIndex[i], XFloorData::CompareForFind))
{
adsout << _T("\n有重复楼层号出现!");
return RTERROR;
}
XFloorData *pXFloor = new XFloorData(*lstIndex[i], sFullDwgName,(int)pFloor->GetHeight());
pXFloor->m_bFloorInFrame = pFloor->IsFloorInFrame();
pXFloor->m_ptBase = pFloor->GetBasePoint();
pFloor->GetRange(pXFloor->m_ptMin, pXFloor->m_ptMax);
lstFloors.Append(pXFloor);
}
}
return RTNORM;
}
///////////////////////////////////////////////////////////
// 返回指定图纸中,指定点所在的楼层框
TProjectFloor* HitTestFloor(const TCHAR* sDwg, XPoint pt) // ok
{
TProjectGroupItem* pTable = GetFloorTable();
if (pTable != NULL)
{
for (pTable->MoveToFirst(); !pTable->IsOut(); pTable->MoveToNext())
{
TProjectFloor* pFloor = (TProjectFloor*)pTable->GetCurData();
CString sFullName = g_project.GetDwgFullName(pFloor->GetName());
if (_tcsicmp(sFullName, sDwg) == 0 && pFloor->IsInclude(pt))
return pFloor;
}
}
return NULL;
}