#include "StdAfx.h" #include "StdArx.h" #include "resource.h" #include "TInterfaceModifyMsgContext.h" PickSet g_ssLastSel(SS_FREE); // 上次选择集 CString g_csLastCmd; // 上次命令 AcGeTol g_globalTol; // 用于记录AcGePoint3d比较精度 void AddCommand(LPCTSTR cmdGroup, LPCTSTR cmdInt, LPCTSTR cmdLoc, const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = -1); // From TAuxTools.cpp extern void GetTHvacParamFromDwg(); extern void SetTHvacParamToDwg(LPCTSTR pszKey = NULL); DLLIMPEXP void SetSysPointEqual(double dDistance) { AcGeContext::gTol.setEqualPoint(dDistance); } DLLIMPEXP void SetSysVectorEqual(double dVector) { AcGeContext::gTol.setEqualVector(dVector); } // mcl add.获取风管是否加粗.用于非暖通环境时正确显示。临时方法,有待统一设置图纸相关参数 // delete by hh 2011-01-04 是否加粗保存在图纸中 见函数GetTHvacParamFromDwg /*void SetDuctThickByDwg() { AcDbBlockTable* pBlockTable = NULL; AcDbBlockTableRecord* pTableRecord = NULL; if(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead) != Acad::eOk) return; pBlockTable->close(); if(pBlockTable->getAt(ACDB_MODEL_SPACE, pTableRecord, AcDb::kForRead) != Acad::eOk) return; pTableRecord->close(); CString csIsThick = TAuxTools::ReadXdata(pTableRecord->id(), HVAC_SHOWWIDTH); SetGlobalContext(HVAC_SHOWWIDTH, _ttoi(csIsThick)); PickSet ssObj(SS_FREE); if (GetEntByDxf(ssObj, _T("ATS_DBHVACDUCT,ATS_DBHFITTING,ATS_DBHEQUIPMENT"), 1)==Acad::eOk) UpdateGraphic(ssObj); }*/ //{{AFX_ARX_MSG void InitApplication(); void UnloadApplication(); void OnDwgLoaded(); //}}AFX_ARX_MSG //{{AFX_ARX_ADDIN_FUNCS void RegisterDbxApp(); //}}AFX_ARX_ADDIN_FUNCS //MY_RES_HERE; // mcl changed 2010.04.19.采用新建筑Ge库后,替换为下面方式 // static AFX_EXTENSION_MODULE TchPipeBaseDLL = { NULL, NULL }; // extern "C" { // HINSTANCE _hdllInstance; // } // extern "C" BOOL APIENTRY //name modified // extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) // { // _hdllInstance = hInstance; // return TRUE; // } // // InitModule(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)//name modified // { // if (dwReason == DLL_PROCESS_ATTACH) { // // Extension DLL one-time initialization // if (!AfxInitExtensionModule(TchPipeBaseDLL, hInstance)) // return 0; // CTemporaryResourceOverride::SetDefaultResource(_hdllInstance); // // Insert this DLL into the resource chain // new CDynLinkLibrary(TchPipeBaseDLL); // // } // else if (dwReason == DLL_PROCESS_DETACH) // { // AfxTermExtensionModule(TchPipeBaseDLL); // } // return 1; // ok // } HINSTANCE _hdllInstance = NULL ; AC_IMPLEMENT_EXTENSION_MODULE(PipeBaseDll); extern void InitAol(const TCHAR *szAppName); extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/) { if (dwReason == DLL_PROCESS_ATTACH) { _hdllInstance = hInstance; PipeBaseDll.AttachInstance(hInstance); } else if (dwReason == DLL_PROCESS_DETACH) { PipeBaseDll.DetachInstance(); } return TRUE; } extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt) { switch (msg) { case AcRx::kInitAppMsg: // InitModule(_hdllInstance, DLL_PROCESS_ATTACH, NULL); acrxDynamicLinker->unlockApplication(pkt); acrxDynamicLinker->registerAppMDIAware(pkt); InitApplication(); break; case AcRx::kLoadDwgMsg: // mcl add 2010.08.02。处理与dwg自身有关参数 OnDwgLoaded(); break; case AcRx::kUnloadAppMsg: UnloadApplication(); // InitModule(_hdllInstance, DLL_PROCESS_DETACH, NULL); break; case AcRx::kSaveMsg: // add by hh 2011-01-05 保存动态扩展数据到图纸 // change by hh 图纸中已有动态数据时 不再保存,避免错误写入其他图纸设置到全局参数中的数据 BOOL bTemp = FALSE; // 使用“显示遮挡”参数进行判断 if(!TAuxTools::GetTHvacDataFromDwg(KEY_HIDEDRAW, bTemp)) SetTHvacParamToDwg(); break; } return AcRx::kRetOK; } //建立关系反应器 TDbMakeObjAssocReactor* g_pObjAssocReactor = NULL; //关系维护反应器 TDbRelInterfaceReactor* g_pRelInterfaceReactor = NULL; //全局datamap TDbXDataMap g_mapClass2Cmd; //全局消息 TInterfaceModifyMsgContext g_iMsgContext; AcDbMatchProperties* g_pMatchPro = NULL; void PBTest(); void ReSlectOrig(); void InitApplication() { //{{AFX_ARX_INIT acrxRegisterService(TCHPIPEBASE_DBXSERVICE); TDbInterfacesObj::rxInit(); TDbPipeBase::rxInit(); TDbPipeBase::InitMatchProtocol(TRUE); TDbFittingBase::rxInit(); TDbPartBase::rxInit(); TDbEquipmentBase::rxInit(); TDbInterfaceRecord::rxInit(); TDbFittingCreatorService::rxInit(); TDbCableDim::rxInit(); TDbECabletry::rxInit(); TDbEFitting::rxInit(); TDbEEquipment::rxInit(); TDbEImpFittingCreatorService::rxInit(); TDbHvacDuct::rxInit(); TDbHvacFitting::rxInit(); TDbHvacEquipment::rxInit(); TDbHvacDimension::rxInit(); TDbHvacDimensionEx::rxInit(); TDbHImpFittingCreatorService::rxInit(); TDbEquRelativeDim::rxInit(); //}}AFX_ARX_INIT //3.安装扩展协议 acrxBuildClassHierarchy(); //1.安装反应器 g_pObjAssocReactor = new TDbMakeObjAssocReactor; g_pRelInterfaceReactor = new TDbRelInterfaceReactor; acedEditor->addReactor(g_pRelInterfaceReactor); AcDbDatabase* pDb = NULL; #if ADS > 20 AcArray pDbArray = acdbActiveDatabaseArray(); int iLen = pDbArray.length(); for (int i = 0; i < iLen; i++) { pDb = pDbArray.at(i); if (NULL != pDb) { pDb->addReactor(g_pObjAssocReactor); } } #else AcDbVoidPtrArray* pDbArray = acdbActiveDatabaseArray(); if (pDbArray != NULL) { for (int i = 0; i < pDbArray->length(); i++) { pDb = (AcDbDatabase*)pDbArray->at(i); if (pDb != NULL) { pDb->addReactor(g_pObjAssocReactor); } } } #endif // modify by cq 2017-01-05 支持CAD2017 //2.安置桥架专业创建器 TDbEImpFittingCreatorService* pCurFittingCreator = new TDbEImpFittingCreatorService; acrxDynamicLinker->registerService(KEY_FITCAB, pCurFittingCreator); // 安装暖通专业创建器 TDbHImpFittingCreatorService* pHvacFittingCreator = new TDbHImpFittingCreatorService; acrxDynamicLinker->registerService(KEY_FITHVAC, pHvacFittingCreator); // modify begin // SetSysPointEqual(1.e-3); // SetSysVectorEqual(1.e-6); g_globalTol.setEqualPoint(1.E-3); g_globalTol.setEqualVector(1.E-6); // modify end by cq 2017-10-31 暖通TFS30202、建筑TFS8208 在纯CAD中做过裁剪内部的块,用上华建筑打开,提示有图形错误。 // 修改方法:把目前isEqualTo函数 改成.distanceTo() < 1E-3 ;equalPoint()替换成 1E-3 //默认设置 SetGlobalContext(KEY_HIDEDRAW,1); RegisterDbxApp(); AddCommand(_T("PipeBase"),_T("PBTest"),_T("PBTest"),ACRX_CMD_MODAL| ACRX_CMD_USEPICKSET,PBTest); AddCommand(_T("PipeBase"),_T("ReSelOrig"),_T("ReSelOrig"),ACRX_CMD_USEPICKSET|ACRX_CMD_REDRAW,ReSlectOrig); } //add liaoy 170705 增加反应器的更新接口操作 void PipeBaseCommandEndedUser(const CString& sCmd) { if (g_pRelInterfaceReactor) { g_pRelInterfaceReactor->commandEndedUser(sCmd); } } //add end void PBTest() { // add by hh 2011-08-09 接口记录从字典移动到数据库中 TDbInterfaceRecord* pIntfRec = TAuxTools::GetIntfPtrFromDB(); if(NULL != pIntfRec) { if(Acad::eOk == pIntfRec->upgradeOpen()) { TInterface itf; AcGePoint3d pt(22804.81,10126.16,3338.72); AcGeVector3d vtDir(1,0,0); BOOL bFind = pIntfRec->Find(pt,vtDir,itf); pIntfRec->downgradeOpen(); } pIntfRec->close(); return; } // add end AcDbDictionary* pNamedDict = NULL; if (Acad::eOk == acdbCurDwg()->getNamedObjectsDictionary(pNamedDict,AcDb::kForRead)) { AcDbDictionary* pDict = NULL; if (Acad::eOk == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForRead)) { TDbInterfaceRecord* pInterfaceRec = NULL; if (Acad::eOk == pDict->getAt(KEY_IRECORD,(AcDbObject*&)pInterfaceRec,AcDb::kForWrite)) { TInterface itf; AcGePoint3d pt(22804.81,10126.16,3338.72); AcGeVector3d vtDir(1,0,0); BOOL bFind = pInterfaceRec->Find(pt,vtDir,itf); pInterfaceRec->close(); } pDict->close(); } pNamedDict->close(); } } // mcl add 2011.2.12.重新选择用户最后选择的实体,解决选取实体时,按“P”,上次选择失效问题。 // 因为更新遮挡会创建新选择集,从而破坏上次选择集 void ReSlectOrig() { if (!g_csLastCmd.IsEmpty() && g_ssLastSel.Length() > 0) { ads_command(RTSTR, _T("select"), RTPICKS, (TLong_ptr*)g_ssLastSel, RTNONE); acedPostCommand(_T(" ")); PostCommand(g_csLastCmd + _T("\n")); // 弥补由于运行本函数(命令)而中断用户上次命令问题 PostCommand(_T("\33")); g_csLastCmd.Empty(); g_ssLastSel.Free(); } } void UnloadApplication() { //{{AFX_ARX_EXIT deleteAcRxClass(TDbHvacDuct::desc()); deleteAcRxClass(TDbHvacFitting::desc()); deleteAcRxClass(TDbHvacEquipment::desc()); deleteAcRxClass(TDbHvacDimension::desc()); deleteAcRxClass(TDbHvacDimensionEx::desc()); deleteAcRxClass(TDbHImpFittingCreatorService::desc()); deleteAcRxClass(TDbCableDim::desc()); deleteAcRxClass(TDbECabletry::desc()); deleteAcRxClass(TDbEFitting::desc()); deleteAcRxClass(TDbEEquipment::desc()); deleteAcRxClass(TDbEImpFittingCreatorService::desc()); deleteAcRxClass(TDbPartBase::desc()); deleteAcRxClass(TDbPipeBase::desc()); TDbPipeBase::InitMatchProtocol(FALSE); deleteAcRxClass(TDbFittingBase::desc()); deleteAcRxClass(TDbEquipmentBase::desc()); deleteAcRxClass(TDbInterfacesObj::desc()); deleteAcRxClass(TDbInterfaceRecord::desc()); deleteAcRxClass(TDbFittingCreatorService::desc()); //}}AFX_ARX_EXIT delete acrxServiceDictionary->remove(TCHPIPEBASE_DBXSERVICE); //1.删除桥架专业创建器 delete acrxServiceDictionary->remove(KEY_FITCAB); // 删除暖通专业创建器 delete acrxServiceDictionary->remove(KEY_FITHVAC); //2.卸载掉所有数据库中的反应器 AcDbDatabase* pDb = NULL; #if ADS > 20 AcArray pDbArray = acdbActiveDatabaseArray(); int iLen = pDbArray.length(); for (int i = 0; i < iLen; ++i) { pDb = pDbArray.at(i); if (pDb != NULL) { pDb->removeReactor(g_pObjAssocReactor); } } #else AcDbVoidPtrArray* pDbArray = acdbActiveDatabaseArray(); if (pDbArray != NULL) { for (int i = 0; i < pDbArray->length(); i++) { pDb = (AcDbDatabase*)pDbArray->at(i); if (pDb != NULL) { pDb->removeReactor(g_pObjAssocReactor); } } } #endif // modify by cq 2017-01-05 支持CAD2017 if (g_pObjAssocReactor != NULL) { delete g_pObjAssocReactor; g_pObjAssocReactor = NULL; } acedEditor->removeReactor(g_pRelInterfaceReactor); if (g_pRelInterfaceReactor != NULL) { delete g_pRelInterfaceReactor; g_pRelInterfaceReactor = NULL; } acedRegCmds->removeGroup(_T("PipeBase")); } void OnDwgLoaded() { // change by hh 2011-01-04 读取暖通专业动态扩展数据 //if (g_nProductId != 6) // 暖通环境由 thvacCmd.arx中onDwgLoad()中处理 // SetDuctThickByDwg(); GetTHvacParamFromDwg(); } void AddCommand(LPCTSTR cmdGroup, LPCTSTR cmdInt, LPCTSTR cmdLoc, const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal) { TCHAR cmdLocRes[65]; if (idLocal != -1) { ::LoadString(_hdllInstance, idLocal, cmdLocRes, 64); acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc); } else { acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc); } } DLLIMPEXP void MakeSureDbHasAssocReactor(AcDbDatabase* pDb,TToolKitBase* pToolKit = NULL) { AcDbDictionary* pNamedDict = NULL; // //add by sps 2013.1.15 是否显示遮挡延伸 // CRegProperty regProp(GetRegLocation(), _T("TCableTray")); // regProp.SetTopRootKey(HKEY_CURRENT_USER); // BOOL bShow = FALSE; // if (!regProp.GetValue(KEY_SHOW_EXTEND, bShow)) // bShow = FALSE; // SetLayerOnOff(LAY_CABLETRAY_HIDE, bShow); if (Acad::eOk == pDb->getNamedObjectsDictionary(pNamedDict,AcDb::kForWrite)) { AcDbDictionary* pDict = NULL; if (Acad::eKeyNotFound == pNamedDict->getAt(KEY_IRECORD,(AcDbObject*&)pDict,AcDb::kForWrite)) { AcDbObjectId idDict; pDict = new AcDbDictionary; pNamedDict->setAt(KEY_IRECORD,pDict,idDict); } pNamedDict->close(); if (!pDict->has(KEY_IRECORD)) { TDbInterfaceRecord* pInterfaceRec = new TDbInterfaceRecord; g_pRelInterfaceReactor->m_mapDbToIRecPtr.SetAt(pDb,pInterfaceRec); pInterfaceRec = new TDbInterfaceRecord; AcDbObjectId idT; pDict->setAt(KEY_IRECORD,pInterfaceRec,idT); pInterfaceRec->close(); } pDict->close(); } pDb->removeReactor(g_pObjAssocReactor); pDb->addReactor(g_pObjAssocReactor); if (g_pRelInterfaceReactor != NULL) { g_pRelInterfaceReactor->m_pToolKit = pToolKit; g_pRelInterfaceReactor->AddToolKit(pToolKit); } } void PickInterfaceModifyMsgs(TInterfaceModifyMsgs& msgs,AcDbDatabase* pDb) { if (pDb == NULL) pDb = acdbCurDwg(); CPtrArray* pArray = NULL; if (g_iMsgContext.m_mapDb2TIMsgs.Lookup(pDb,(void*&)pArray)) { TDbInterfaceMsgObj* pmsgObj = NULL; TInterfaceModifyMsg msg; for (int i = 0;i < pArray->GetSize();i++) { pmsgObj = (TDbInterfaceMsgObj* )pArray->GetAt(i); if (pmsgObj != NULL) { pArray->SetAt(i,NULL); pmsgObj->GetModifyMsg(msg); msgs.append(msg); delete pmsgObj; } } pArray->RemoveAll(); } } //设置全局参数 void SetGlobalContext(LPCTSTR pszKey,LPCTSTR pszCmd) { if (pszKey != NULL && pszCmd != NULL) { g_mapClass2Cmd.SetAt(pszKey,pszCmd); } } //设置全局参数 void SetGlobalContext(LPCTSTR pszKey,int nVal) { if (pszKey != NULL) { g_mapClass2Cmd.SetAt(pszKey,nVal); } } BOOL GetGlobalContext(LPCTSTR pszKey,int& nVal) { if (pszKey != NULL) { return g_mapClass2Cmd.GetAt(pszKey,nVal); } return FALSE; } BOOL GetGlobalContext(LPCTSTR pszKey,CString& sCmd) { if (pszKey != NULL) { return g_mapClass2Cmd.GetAt(pszKey,sCmd); } return FALSE; } TDbXDataMap* GetGlobalContext() { return &g_mapClass2Cmd; } double _ttof(LPCTSTR pszString) { bool bSign = false; bool bPowerSign = false; bool bExponent = true; bool bMantissa = false; int nPower = 0; double dExponent = 0.0; double dMantissa = 0.0; double dScale = 1.0; TCHAR* pIn = (TCHAR*)pszString; if (*pIn == _T('-')) { *pIn++; bSign = true; } while (*pIn != 0) { // capture digits if ((*pIn >= _T('0')) && (*pIn <= _T('9'))) { if (bExponent) { dExponent *= 10.0; dExponent += (*pIn - _T('0')); } else if (bMantissa) { dMantissa *= 10.0; dMantissa += (*pIn - _T('0')); dScale *= 10.0; } else { nPower *= 10; nPower += (*pIn - _T('0')); } } else if ((*pIn == _T('e')) || (*pIn == _T('E')))// power { // sign if (*(++pIn) == _T('-')) { bPowerSign = true; } bMantissa = false; } else { // the first character that hasn't been accounted for already, // is assumed to be the separator // cross over if (bExponent) { bExponent = false; bMantissa = true; } // white space (including null) or bad char // we're done either way else { break; } } pIn++; } double dVal = dExponent + (dMantissa / dScale); if (nPower > 0) { for (; nPower > 0; nPower--) { if (bPowerSign) { dVal /= 10.0; } else { dVal *= 10.0; } } } if (bSign) { dVal *= -1.0; } return dVal; } void RegisterDbxApp() { int strLength; HMODULE hModule = GetModuleHandle(_T("shs_PipeBase.arx")); if (!hModule) return; // // Register the application. // TCHAR ThisAppRegistryPath[] = { _T("Software\\Autodesk\\ObjectARX\\3.0\\SampleApps\\TDbECabletry\\") }; const TCHAR* dbxRegRoot = acrxObjectDBXRegistryKey(); TCHAR DbxAppRegistryPath[256]; _tcscpy(DbxAppRegistryPath, dbxRegRoot); _tcscat(DbxAppRegistryPath, _T("\\Applications\\")); _tcscat(DbxAppRegistryPath, _T("shs_PipeBase")); // // Create the registry key under the DBX path // (use the variable DbxRegistryPath). // HKEY dbxKey; DWORD result; LONG status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, DbxAppRegistryPath, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &dbxKey, &result); if (ERROR_SUCCESS != status) return; // Create the 'LOADCTRLS' value. int loadReason = AcadApp::kOnProxyDetection | AcadApp::kOnLoadRequest | AcadApp::kTransparentlyLoadable; status = RegSetValueEx(dbxKey, _T("LOADCTRLS"), 0, REG_DWORD, (const BYTE*) &loadReason, sizeof(loadReason)); if (ERROR_SUCCESS != status) return; // Create the 'REGPATH' value. TCHAR regPath[256]; _tcscpy(regPath, _T("\\\\HKEY_LOCAL_MACHINE\\")); _tcscat(regPath, ThisAppRegistryPath); _tcscat(regPath, _T("shs_PipeBase")); status = RegSetValueEx(dbxKey, _T("REGPATH"), 0, REG_SZ, (const BYTE*) regPath, (DWORD)(_tcslen(regPath) + 1)); status = RegCloseKey(dbxKey); if (ERROR_SUCCESS != status) return; // // Create the registry key for this application // (use the variable ThisAppRegistryPath). // HKEY appKey; status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, ThisAppRegistryPath, 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &appKey, &result); if (ERROR_SUCCESS != status) return; HKEY prodKey; status = RegCreateKeyEx(appKey, _T("shs_PipeBase"), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &prodKey, &result); RegCloseKey(appKey); if (ERROR_SUCCESS != status) return; // Create the 'Loader' key. HKEY loaderKey; status = RegCreateKeyEx(prodKey, _T("Loader"), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &loaderKey, &result); if (ERROR_SUCCESS == status) { TCHAR modulePath[512]; strLength = GetModuleFileName(hModule, modulePath, 512); if (strLength) RegSetValueEx(loaderKey, _T("MODULE"), 0, REG_SZ, (const BYTE*)modulePath, strLength + 1); RegCloseKey(loaderKey); } // Create the 'Name' key. HKEY nameKey; status = RegCreateKeyEx(prodKey, _T("Name"), 0, _T(""), REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &nameKey, &result); if (ERROR_SUCCESS == status) { RegSetValueEx(nameKey, _T("shs_PipeBase"), 0, REG_SZ, (const BYTE*) _T("shs_PipeBase"), 13); RegCloseKey(nameKey); } RegCloseKey(prodKey); }