// FloorRectReacter.cpp : 实现文件 // #include "stdafx.h" #include "FloorRectReacter.h" #include "FloorRectEditDlg.h" #include "ProjectManager.h" #include "TCheckFloorRectData.h" // 全局楼层框反映器 TFloorRectDbReactor *g_pFloorRectDbReactor = NULL; TFloorRectDocReactor *g_pFloorRectDocReactor = NULL; // 全局楼层框处理类对象 TFloorRectDealSystem *g_pFloorRectData = NULL; // 全局控制切换文档标签时,是否修改工程 bool g_bChangeCurProject = true; // 打开文档 void OpenDoc(void *pData) { AcApDocument* pDoc = acDocManager->mdiActiveDocument(); //记录当前文档 if (acDocManager->isApplicationContext()) { acDocManager->pushResourceHandle(acedGetAcadResourceInstance()); acDocManager->appContextOpenDocument((const TCHAR *)pData); acDocManager->popResourceHandle(); acDocManager->activateDocument(pDoc); // 这里将文档切换回原来的文档,以便该文档继续执行代码 } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Begin TFloorRectDocReactor void TFloorRectDocReactor::documentCreated(AcApDocument* pDocCreating) { if (g_pFloorRectDbReactor == NULL) { g_pFloorRectDbReactor = new TFloorRectDbReactor; } AcDbDatabase *pDb = pDocCreating->database(); if (pDb != NULL) { pDb->addReactor(g_pFloorRectDbReactor); } } void TFloorRectDocReactor::documentToBeDestroyed(AcApDocument* pDocToDestroy) { AcDbDatabase *pDb = pDocToDestroy->database(); if (pDb != NULL) { pDb->removeReactor(g_pFloorRectDbReactor); g_pFloorRectDbReactor = NULL; } } // sg add 100514,集成原文档反应器TProjectDocReactor的功能,处理文档切换过程中,对应切换工程 void TFloorRectDocReactor::documentActivated(AcApDocument* pActivatedDoc) { if (g_bChangeCurProject) { CString sNewFile = DocGetProjectFile(); if (sNewFile != _T("") && FindFile(sNewFile) && !g_project.Is(sNewFile)) { if (g_project.Load(sNewFile) && g_projectBar.GetSafeHwnd() != NULL) g_projectBar.Refresh(); } } } // End TFloorRectDocReactor ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Begin TFloorRectDocReactor // 将实体添加到当前DWG时的处理函数 void TFloorRectDbReactor::objectAppended(const AcDbDatabase* dwg, const AcDbObject* dbObj) { // 不使用数据库反映器 if (!g_bMonitorDbAction) { return; } if (dwg==acdbCurDwg() && NULL!=dbObj) // append { // 只处理楼层框对象 if (!dbObj->isKindOf(TDbFloorRect::desc())) { return; } g_pFloorRectData->ObjectAppended(dbObj); } } void TFloorRectDbReactor::objectModified(const AcDbDatabase* dwg, const AcDbObject* dbObj) { // 不使用数据库反映器 if (!g_bMonitorDbAction) { return; } if (dwg==acdbCurDwg() && NULL!=dbObj) // append { // 只处理楼层框对象 if (!dbObj->isKindOf(TDbFloorRect::desc())) { return; } g_pFloorRectData->ObjectModified(dbObj); } } // 将实体从当前DWG中删除时的处理 void TFloorRectDbReactor::objectErased(const AcDbDatabase* dwg, const AcDbObject* dbObj, Adesk::Boolean pErased) { // 不使用数据库反映器 if (!g_bMonitorDbAction) { return; } if (dwg==acdbCurDwg() && NULL!=dbObj) { // 只处理楼层框对象 if (!dbObj->isKindOf(TDbFloorRect::desc())) { return; } if (pErased == Adesk::kTrue) // erased { g_pFloorRectData->ObjectErased(dbObj); } else // unerased { g_pFloorRectData->ObjectUnerased(dbObj); } } } // End TFloorRectDbReactor ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Begin TFloorRectItem TFloorRectItem::TFloorRectItem() { m_nRowIndex = -1; m_csPrompt = _T(""); m_csDwgFile = _T(""); } void TFloorRectItem::SetFloors(const AcDbIntArray &aryFloors) { m_aryFloors = aryFloors; } // 获取楼层号 void TFloorRectItem::GetFloors(AcDbIntArray &aryFloors) const { aryFloors = m_aryFloors; } // 获取提示语 CString TFloorRectItem::GetPrompt() const { return m_csPrompt; } ///////////////////////////////////////////////////////////////////// // 根据图纸名称,搜索对应行号和工程名称的对象,得到对象ID bool TFloorRectItem::SetObjIdFromDwg(AcApDocument*& pDoc, bool &bIsOpenAlready) { bIsOpenAlready = false; pDoc = NULL; if (!FindFile(m_csDwgFile)) { m_csPrompt = _T(""); return false; } AcApDocument *pCurDoc = curDoc(); if (NULL == pCurDoc) { m_csPrompt = _T("当前程序未打开图形文件"); return false; } // 查询要打开的文档是否已经是打开状态 AcApDocumentIterator *pDocIter = acDocManager->newAcApDocumentIterator(); for (; !pDocIter->done(); pDocIter->step()) { // 搜索对应的文档指针 if (0 == m_csDwgFile.CompareNoCase(pDocIter->document()->fileName())) { pDoc = pDocIter->document(); bIsOpenAlready = true; break; } } delete pDocIter; if (NULL == pDoc) { TPushMemVar pushVar(g_bChangeCurProject, false); // 打开文档 if (acDocManager->isApplicationContext()) { OpenDoc((void *)(LPCTSTR)m_csDwgFile); } else { acDocManager->executeInApplicationContext(OpenDoc, (void *)(LPCTSTR)m_csDwgFile); } pDocIter = acDocManager->newAcApDocumentIterator(); for (; !pDocIter->done(); pDocIter->step()) { // 搜索对应的文档指针 if (0 == m_csDwgFile.CompareNoCase(pDocIter->document()->fileName())) { pDoc = pDocIter->document(); bIsOpenAlready = false; break; } } delete pDocIter; if (NULL == pDoc) { m_csPrompt = (_T("不能打开文件%s!"), m_csDwgFile); return false; } } acDocManager->setCurDocument(pDoc); // 搜索文件内的所有楼层框 struct resbuf * pResbuf = acutBuildList(RTDXF0, _T("TCH_FLOORRECT"), NULL); ads_name ssPickSet, ent; acedSSGet(_T("_X"), NULL, NULL, pResbuf, ssPickSet); acutRelRb(pResbuf); long lLen = 0; acedSSLength(ssPickSet, &lLen); if (lLen < 1) { acedSSFree(ssPickSet); acDocManager->setCurDocument(pCurDoc); return false; } acDocManager->lockDocument(curDoc()); // 遍历选择集中的楼层框 AcDbObjectId idObj; bool bRet = false; for(long i = 0; i < lLen; i++) { if (RTNORM == acedSSName(ssPickSet, i, ent)) { if (Acad::eOk == acdbGetObjectId(idObj, ent)) { TDbFloorRect *pEnt = NULL; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbFloorRect, pEnt); // 查找表格索引号相同的楼层框 if (pEnt->GetTableIndex() == m_nRowIndex) { // 楼层框工程名称与当前工程名称相同时 if (g_pFloorRectData->GetProjectName().CompareNoCase(pEnt->GetSpare()) == 0) { // 当一张图纸里有多个同工程名称、同行号的楼层框时,优先找到一个与m_idObj不同的id if (m_idObj.isValid() && idObj.isValid() && m_idObj == idObj) { bRet = true; } else { m_idObj = idObj; bRet = true; break; } } else // 修改对象的工程名称 { m_idObj = idObj; bRet = true; if (Acad::eOk == pEnt->upgradeOpen()) { pEnt->disableUndoRecording(Adesk::kTrue); pEnt->SetSpare(g_pFloorRectData->GetProjectName()); pEnt->disableUndoRecording(Adesk::kFalse); pEnt->downgradeOpen(); } } } OPENOBJ_END(); } } } acedSSFree(ssPickSet); acDocManager->unlockDocument(curDoc()); acDocManager->setCurDocument(pCurDoc); if (bRet) { return true; } m_csPrompt = _T("在文件中未搜索到对应的楼层框对象"); return false; } ///////////////////////////////////////////////////////////////////// // 与楼层框对象交互 // 设置层高 bool TFloorRectItem::SetHeight(CString csHeight, bool bCloseDoc) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 bool bRetVal = false; // 返回值 // 打开文件,得到对应的ID if (SetObjIdFromDwg(pDoc, bIsOpenAlready)) { acDocManager->lockDocument(pDoc); // 锁定文档 OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite , TDbFloorRect, pFloorRect); if (pFloorRect == NULL) { m_csPrompt = _T("无法打开楼层框对象!"); bRetVal = false; } else { pFloorRect->disableUndoRecording(Adesk::kTrue); double dHeight = _tstof(csHeight); pFloorRect->SetFloorHeight(dHeight);// 修改楼层框的层高 pFloorRect->disableUndoRecording(Adesk::kFalse); bRetVal = true; } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return bRetVal; } // 获取层号 bool TFloorRectItem::GetName(CString &csName, bool bCloseDoc) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 bool bRetVal = false; // 返回值 // 打开文件,得到对应的ID if (SetObjIdFromDwg(pDoc, bIsOpenAlready)) { acDocManager->lockDocument(pDoc); OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect); if (NULL == pFloorRect) { m_csPrompt = _T("无法打开楼层框对象"); bRetVal = false; } else { csName = pFloorRect->GetFloorName(); // 得到相应的楼层名称 bRetVal = true; } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return bRetVal; } // 设置层号 bool TFloorRectItem::SetName(CString csName, bool bCloseDoc) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 bool bRetVal = false; // 返回值 // 打开文件,得到对应的ID if (SetObjIdFromDwg(pDoc, bIsOpenAlready)) { acDocManager->lockDocument(pDoc); // 锁定文档 OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect); if (pFloorRect == NULL) { m_csPrompt = _T("无法打开楼层框对象!"); bRetVal = false; } else { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetFloorName(csName); pFloorRect->disableUndoRecording(Adesk::kFalse); bRetVal = true; } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return bRetVal; } // 设置行号 bool TFloorRectItem::SetRowIndex(int nRowIndex, bool bCloseDoc) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 bool bRetVal = false; // 返回值 // 打开文件,得到对应的ID if (SetObjIdFromDwg(pDoc, bIsOpenAlready)) { acDocManager->lockDocument(pDoc); // 锁定文档 OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect); if (NULL == pFloorRect) { m_csPrompt = _T("无法打开楼层框对象!"); bRetVal = false; } else { m_nRowIndex = nRowIndex; pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(nRowIndex); // 把索引号写入楼层框对象 pFloorRect->disableUndoRecording(Adesk::kFalse); bRetVal = true; } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return bRetVal; } // 设置全部数据 bool TFloorRectItem::SetData(CString csHeight, CString csName, int nRowIndex, bool bCloseDoc) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 bool bRetVal = false; // 返回值 // 打开文件,得到对应的ID if (SetObjIdFromDwg(pDoc, bIsOpenAlready)) { acDocManager->lockDocument(pDoc); // 锁定文档 OPENOBJ_BEGIN(m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect); if (pFloorRect == NULL) { m_csPrompt = _T("无法打开楼层框对象!"); bRetVal = false; } else { m_nRowIndex = nRowIndex; double dHeight = _tstof(csHeight); pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetFloorHeight(dHeight); pFloorRect->SetFloorName(csName); pFloorRect->SetTableIndex(nRowIndex); pFloorRect->disableUndoRecording(Adesk::kFalse); bRetVal = true; } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return bRetVal; } ///////////////////////////////////////////////////////////////////// // 以下函数对层高字符串进行检查 // 检查输入楼层高是否合理,自动去掉前后的空格 bool TFloorRectItem::IsHeightLegal(CString &csHeight) { XCheckFloorRectData xCheckData; bool bRet = xCheckData.IsHeightLegal(csHeight); m_csPrompt = xCheckData.GetPrompt(); return bRet; } // 检查层号是否合法,同时给赋值 bool TFloorRectItem::IsNameLegal(CString &csName) { XCheckFloorRectData xCheckData; if (!xCheckData.IsNameLegal(csName)) { m_csPrompt = xCheckData.GetPrompt(); return false; } xCheckData.GetFloors(m_aryFloors); return true; } // End TFloorRectItem ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// // Begin TFloorRectDealSystem TFloorRectDealSystem::TFloorRectDealSystem(const CString &csName) { SetProjectName(csName); m_csPrompt = _T(""); } TFloorRectDealSystem::~TFloorRectDealSystem() { } // 工程名称 void TFloorRectDealSystem::SetProjectName(const CString &csName) { // 根据工程名称,获取不带扩展名的工程名称 int nRet = csName.Find(_T("."), 0); if (nRet > -1) { m_csProjectName = csName.Left(nRet); } else // 不带扩展名的情况 { m_csProjectName = csName; } } // 获取工程名称 CString TFloorRectDealSystem::GetProjectName() const { return m_csProjectName; } // 获取提示语 CString TFloorRectDealSystem::GetPrompt() const { return m_csPrompt; } ///////////////////////////////////////////////////////////////////// // 处理对象变化消息,主要处理复制、删除操作,更新楼层表对象 void TFloorRectDealSystem::ObjectAppended(const AcDbObject* dbObj) { // 转化为楼层框对象 TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj; if (0 > pFloorRect->GetTableIndex() || m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0) { return; } if (pFloorRect->isWriteEnabled()) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); } else if (Acad::eOk == pFloorRect->upgradeOpen()) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); pFloorRect->downgradeOpen(); } } void TFloorRectDealSystem::ObjectModified(const AcDbObject* dbObj) { TDbFloorRect *pFloorRect = (TDbFloorRect*) dbObj; if (0 > pFloorRect->GetTableIndex() || m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0) { return; } XCheckFloorRectData xCheckData; AcDbIntArray aryFloors; // 楼层框对应的楼层号数组 xCheckData.IsNameLegal(CString(pFloorRect->GetFloorName())); xCheckData.GetFloors(aryFloors); if (!CheckFloorNoInProject(aryFloors, pFloorRect->GetTableIndex())) { AfxMessageBox(m_csPrompt); } TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层")); if (NULL != pTable) { // 修改工程中的楼层表格 TADSGePoint3d ptCenter = pFloorRect->GetCenter(); TADSGePoint3d ptMin = pFloorRect->GetLowLeft(); TADSGePoint3d ptMax = pFloorRect->GetUpRight(); pTable->SetGridData(pFloorRect->GetTableIndex(), ptMin, ptMax, pFloorRect->GetBase(), pFloorRect->GetFloorName(), pFloorRect->GetFloorHeight()); // 修改楼层表组和楼层号数组 CString csDwgName; GetCurDwgFileName(csDwgName.GetBuffer(_MAX_PATH)); csDwgName.ReleaseBuffer(); csDwgName = g_project.GetDwgFullName(csDwgName); TFloorRectItem item; item.m_nRowIndex = pFloorRect->GetTableIndex(); item.m_csDwgFile = csDwgName; item.m_idObj = pFloorRect->objectId(); item.IsNameLegal(CString(pFloorRect->GetFloorName())); UpdateItem(item); } } void TFloorRectDealSystem::ObjectErased(const AcDbObject* dbObj) { // 转化为楼层框对象 TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj; int iRowIndex = pFloorRect->GetTableIndex(); if (m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0 || iRowIndex < 0) { // 实体不属于当前工程或者是已作废(行号为-1)的楼层框,返回 return; } // 删除楼层框时将索引行号置为-1,使楼层框与表格断开绑定关系 if (pFloorRect->isWriteEnabled()) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); } else if (Acad::eOk == pFloorRect->upgradeOpen()) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); pFloorRect->downgradeOpen(); } // 更新楼层表格 TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层")); if (NULL != pTable) { // 更新m_aryFloorTable,删除相应行号的记录 RemoveItem(iRowIndex, false); // 更新删除行之后的楼层框的索引 int iLen = pTable->m_grid.GetRowNum(), iIndex = -1; for (int i = iRowIndex + 1; i < iLen; i++) { // 对iRowIndex后的所有楼层框对象的行号进行更新 iIndex = FindItem(i); if (-1 == iIndex) { continue; } TPushMemVar pushVar(g_bMonitorDbAction, FALSE); TFloorRectItem *pItem = &m_aryFloorTable.GetAt(iIndex); pItem->SetRowIndex(i - 1); pItem->m_nRowIndex = i - 1; m_aryFloorTable.SetAt(iIndex, *pItem); } if (iLen > iRowIndex) { // 删除一行 pTable->m_grid.DelRow(iRowIndex); pTable->m_grid.Refresh(); } } } void TFloorRectDealSystem::ObjectUnerased(const AcDbObject* dbObj) { // 转化为楼层框对象 TDbFloorRect *pFloorRect = (TDbFloorRect *)dbObj; int iRowIndex = pFloorRect->GetTableIndex(); if (m_csProjectName.CompareNoCase(pFloorRect->GetSpare()) != 0 || iRowIndex < 0) { // 实体不属于当前工程或者是已作废(行号为-1)的楼层框,返回 return; } if (pFloorRect->isWriteEnabled()) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); return; } // 更新楼层表格 TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层")); if (NULL != pTable) { // 更新添加一行之后的楼层框的索引 int iLen = pTable->m_grid.GetRowNum(); int iIndex = -1; for (int i = iLen - 1; i >= iRowIndex; i--) { // 对iRowIndex后的所有楼层框对象的行号进行更新 iIndex = FindItem(i); if (-1 == iIndex) { continue; } TPushMemVar pushVar(g_bMonitorDbAction, FALSE); TFloorRectItem item = m_aryFloorTable.GetAt(iIndex); item.SetRowIndex(i + 1); item.m_nRowIndex = i + 1; m_aryFloorTable.SetAt(iIndex, item); } // 获取图纸名称 XString szFullName, szName; xg_getvar(_T("DWGPREFIX"), szFullName); // 存储图形文件的驱动器/目录前缀 xg_getvar(_T("DWGNAME"), szName); // 存储用户输入的图形名 szFullName << szName; // 根据楼层框的参数生成一个对应的楼层表格数据 TFloorGridData *pGridData = new TFloorGridData(); CString szFileName = g_project.GetDwgRelativeName((const TCHAR*)szFullName); pGridData->m_szName = szFileName; // 向表格中添加一条记录 pTable->m_grid.InsertRow(iRowIndex); if (!pTable->m_grid.IsValidRow(iRowIndex)) { return; } pTable->m_grid.GetRow(iRowIndex).SetExtendData((WRowData*) pGridData); TADSGePoint3d ptCenter = pFloorRect->GetCenter(), ptMin = pFloorRect->GetLowLeft(), ptMax = pFloorRect->GetUpRight(); pTable->SetGridData(iRowIndex, ptMin, ptMax, pFloorRect->GetBase(), pFloorRect->GetFloorName(), pFloorRect->GetFloorHeight()); // 添加一条对应的TFloorRectItem信息 CString csDwgName; GetCurDwgFileName(csDwgName.GetBuffer(_MAX_PATH)); csDwgName.ReleaseBuffer(); csDwgName = g_project.GetDwgFullName(csDwgName); TFloorRectItem item; item.m_nRowIndex = iRowIndex; item.m_csDwgFile = csDwgName; item.m_idObj = pFloorRect->objectId(); item.IsNameLegal(CString(pFloorRect->GetFloorName())); // 添加一条信息,修改楼层框时不响应消息 AddItem(item, false); } } ///////////////////////////////////////////////////////////////////// // 表格数据和楼层框对象的数据交换,主要处理更新操作 // 根据楼层框对象更新工程数据,如果图纸已经打开,就不再进行楼层框ID的搜索以提高效率 bool TFloorRectDealSystem::UpdatePrjFloorFromObj(TProjectFloor *&pFloor, TFloorRectItem &item, bool IsDWGOpen, bool bCloseDoc) { if (NULL == pFloor) { return false; } AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 if (!IsDWGOpen) { if (!item.SetObjIdFromDwg(pDoc, bIsOpenAlready)) { // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } m_csPrompt = item.GetPrompt(); return false; } } else { AcApDocumentIterator *pDocIter = acDocManager->newAcApDocumentIterator(); for (; !pDocIter->done(); pDocIter->step()) { // 搜索对应的文档指针 if (0 == item.m_csDwgFile.CompareNoCase(pDocIter->document()->fileName())) { pDoc = pDocIter->document(); break; } } delete pDocIter; } if (NULL == pDoc) { return false; } acDocManager->lockDocument(pDoc); // 锁定文档 // 打开楼层框实体,把相关参数写入pFloor OPENOBJ_BEGIN(item.m_idObj, AcDb::kForRead, TDbFloorRect, pFloorRect); if (pFloorRect == NULL) { m_csPrompt = _T("无法打开楼层框对象"); acDocManager->unlockDocument(pDoc); return false; } pFloor->SetBasePoint(pFloorRect->GetBase()); pFloor->SetRange(pFloorRect->GetLowLeft(), pFloorRect->GetUpRight()); pFloor->SetLayerNo(pFloorRect->GetFloorName()); pFloor->SetHeight(pFloorRect->GetFloorHeight()); OPENOBJ_END(); acDocManager->unlockDocument(pDoc); // 如果文档是程序中打开的,则关闭 if (bCloseDoc && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } return true; } // 根据表行数据更新楼层框对象 bool TFloorRectDealSystem::UpdateObjFromRow(short nRow) { TFloorRectItem *pFind = NULL; if (!GetItem(nRow, *pFind)) // 未找到 { return false; } // 找到楼层框,更新数据 TFloorTable *pTable = (TFloorTable*)g_projectBar.FindGroupBox(_T("楼层")); if (NULL == pTable) { m_csPrompt = _T("获取楼层表数据失败! "); return false; } // 获取层高 CString csHeight = pTable->m_grid.GetCell(nRow, 1).GetText(); // 设置层高,首先会检查用户输入是否合理 bool bRet = pFind->IsHeightLegal(csHeight); if (!bRet) { m_csPrompt = pFind->GetPrompt(); return false; } // 获取层号 CString csNum = pTable->m_grid.GetCell(nRow, 0).GetText(); // 首先,对单楼层号字符串进行分析,判断输入是否正确,修改行号 bRet = pFind->IsNameLegal(csNum); if (!bRet) { m_csPrompt = pFind->GetPrompt(); return false; } // 然后,在全工程中进一步查找,是否存在重复楼层号 AcDbIntArray aryFloors; // 楼层框对应的楼层号数组 pFind->GetFloors(aryFloors); bRet = CheckFloorNoInProject(aryFloors, nRow); if (!bRet) { return false; } pFind->SetData(csNum, csHeight, nRow); return true; } // 更新处理系统 void TFloorRectDealSystem::UpdateDealSystem() { // 首先,清空原数据 int i(0), nLength = (int)m_aryFloorTable.GetSize(); for (i=0; iMoveToFirst();!pTable->IsOut();pTable->MoveToNext()) { TProjectFloor *pFloor = (TProjectFloor*)pTable->GetCurData(); if (pFloor == NULL) { i++; continue; } // 添加新对象 TFloorRectItem item; item.m_nRowIndex = i; // 获取图纸名称 CString csDwgName = g_project.GetDwgFullName(pFloor->GetName()); item.m_csDwgFile = csDwgName; // 从工程中获取层号 CString csFloorNo = pFloor->GetLayerNo(); // 图纸名不为空,但不能找到图纸文件 // 或者在存在表格和楼层框对应关系时,不能在图纸中找到楼层框对象,准备给出提示 if ((!csDwgName.IsEmpty() && !FindFile(csDwgName)) || (pFloor->IsFloorInFrame() && !item.GetName(csFloorNo, false))) { csPrompt.Format(csPrompt + _T("%d、"), i + 1); bPrompt = true; } // 判断单层输入是否合法,并给数组赋值 if (!item.IsNameLegal(csFloorNo)) { adsout << _T("\n") << (LPCTSTR)item.GetPrompt(); } m_aryFloorTable.Add(item); // 对“<框选>”过的标准层,根据新打开的图纸里的楼层框对象信息,更新tpr文件内容 if (pFloor->IsFloorInFrame()) { if (UpdatePrjFloorFromObj(pFloor, item, true, false)) { pTable->SetCurData(pFloor); } } i++; } // 判断是否提示不存在的图纸或楼层框 if (bPrompt) { csPrompt.TrimRight(_T("、")); csPrompt += _T("行数据,无法找到指定图纸或框选的楼层范围。"); adsout << _T("\n") << (LPCTSTR)(csPrompt); } // 检查整个工程中的重复楼层号 if (!CheckAllFloors()) { adsout << _T("\n") << (LPCTSTR)m_csPrompt; } } ///////////////////////////////////////////////////////////////////// // 操作楼层表数组的函数 // 在数组中,查找指定数据的下标,未找到时返回-1 int TFloorRectDealSystem::FindItem(short nRow) const { int nIndex = -1; int nLength = (int)m_aryFloorTable.GetSize(); for (int i=0; im_nRowIndex == nRow) { nIndex = i; break; } } return nIndex; } // 获取一条楼层框数据,未找到时返回false bool TFloorRectDealSystem::GetItem(short nRow, TFloorRectItem &item) { int nIndex = FindItem(nRow); if (-1 == nIndex) // 没有找到 { return false; } item = m_aryFloorTable.GetAt(nIndex); return true; } // 添加一条楼层框数据 bool TFloorRectDealSystem::AddItem(TFloorRectItem &item, bool bReplace, bool bNotify) { int nIndex = FindItem(item.m_nRowIndex); if (-1 != nIndex) { if (bReplace) { TPushMemVar pushVar(g_bMonitorDbAction, bNotify); TFloorRectItem itemTemp = m_aryFloorTable.GetAt(nIndex); itemTemp.m_idObj = item.m_idObj; // 保证优先找到一个与itemTemp.m_idObj不同的楼层框 if (!itemTemp.SetRowIndex(-1)) { m_csPrompt = itemTemp.GetPrompt(); } } m_aryFloorTable.RemoveAt(nIndex); } // 添加数据 m_aryFloorTable.Add(item); return true; } // 根据item里的行号,更新一条楼层框数据 bool TFloorRectDealSystem::UpdateItem(TFloorRectItem &item) { int nIndex = FindItem(item.m_nRowIndex); if (-1 == nIndex) // 未找到则返回 { return false; } // 添加数据 m_aryFloorTable.SetAt(nIndex, item); return true; } // 根据nRow,替换一条楼层框数据 void TFloorRectDealSystem::ReplaceItem(short nRow, TFloorRectItem &item) { int nIndex = FindItem(nRow); if (-1 != nIndex) { m_aryFloorTable.RemoveAt(nIndex); } m_aryFloorTable.Add(item); } // 根据行号删除一条记录 bool TFloorRectDealSystem::RemoveItem(short nRow, bool bDelEnt, bool bNotify, bool bCloseDoc) { int nIndex = FindItem(nRow); if (-1 == nIndex) { return false; } TFloorRectItem item; item = m_aryFloorTable.GetAt(nIndex); if (bDelEnt) { AcApDocument *pDoc = NULL; // 打开的文档的指针 bool bIsOpenAlready = true; // 是否文档已经是打开状态 // 打开文件,得到对应的ID if (item.SetObjIdFromDwg(pDoc, bIsOpenAlready)) { TPushMemVar pushVar(g_bMonitorDbAction, bNotify); acDocManager->lockDocument(pDoc); OPENOBJ_BEGIN(item.m_idObj, AcDb::kForWrite, TDbFloorRect, pFloorRect); if (pFloorRect != NULL) { pFloorRect->disableUndoRecording(Adesk::kTrue); pFloorRect->SetTableIndex(-1); pFloorRect->disableUndoRecording(Adesk::kFalse); pFloorRect->erase(); } OPENOBJ_END(); acDocManager->unlockDocument(pDoc); } // 如果文档是程序中打开的,则关闭 if (bCloseDoc && !bIsOpenAlready && NULL != pDoc && NULL != pDoc->database()) { if (Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".QSAVE "), false) && Acad::eOk == acDocManager->sendStringToExecute(pDoc, _T(".CLOSE "), false)) { acDocManager->activateDocument(pDoc); } } } m_aryFloorTable.RemoveAt(nIndex); return true; } ///////////////////////////////////////////////////////////////////// // 在整个工程里,检查是否存在重复楼层号 bool TFloorRectDealSystem::CheckFloorNoInProject(const AcDbIntArray &aryFloors, short nIgnoreRow) { // 获取要忽略的楼层框的楼层号 AcDbIntArray aryFloorsIgnore; int nIndex = FindItem(nIgnoreRow); if (-1 != nIndex) { m_aryFloorTable.GetAt(nIndex).GetFloors(aryFloorsIgnore); } AcDbIntArray aryFloorsTotal; if (!GetFloors(aryFloorsTotal)) // 工程内无楼层数据时,返回true { return true; } int nLength = aryFloors.logicalLength(); for (int i=0; iaddReactor(g_pFloorRectDocReactor); } } else { if (g_pFloorRectDocReactor != NULL) { acDocManagerPtr()->removeReactor(g_pFloorRectDocReactor); delete g_pFloorRectDocReactor; g_pFloorRectDocReactor = NULL; } } } // 初始化楼层表处理系统 void InitFloorRectDealSystem(bool bTrue) { if (bTrue) { // 获取工程名称 CString csProjectName; g_project.GetProjectName(csProjectName); if (g_pFloorRectData == NULL) // 首次启动软件 { g_pFloorRectData = new TFloorRectDealSystem(csProjectName); } else // 切换工程 { g_pFloorRectData->SetProjectName(csProjectName); } g_pFloorRectData->UpdateDealSystem(); } else // 退出软件时,清理数据 { if (g_pFloorRectData != NULL) { delete g_pFloorRectData; g_pFloorRectData = NULL; } } }