#include "stdafx.h" #include "KTNormDoorDlg.h" #include "KTBlkRecsView.h" #include "dbobjptr.h" #include "KTSetting.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CAcExtensionModule Pool3dCmdDll; #define WM_VIEWDBLCLKSEL (WM_USER + 0x1200) KTNormDoorDlg::KTNormDoorDlg(CWnd* pParent /*=NULL*/) : CDialog(KTNormDoorDlg::IDD, pParent) , m_dHeight(2100) , m_dElRef(0) , m_sMaterial(_T("断桥铝合金玻璃门窗")) , m_sProvider(_T("斯卡特门窗")) { //{{AFX_DATA_INIT(KTNormDoorDlg) m_sDist = _T("300"); m_sNo = _T("No"); m_sWidth = _T("1500"); m_nInstyle = 2; //}}AFX_DATA_INIT m_dwData.m_sBlock = _T("KTDOOR02"); m_dwData.m_sBlock3D = _T("KTDOOR02_3D"); m_dwData.m_eInsStyle = kByCenter; m_dwData.m_nType = 2; m_sDwgFile = _T("KTDOOR02.dwg"); m_sDwg3DFile = _T("KTDOOR02_3D.dwg"); GET_CACHE(KTNormDoorDlg , %s%s%s%d%f%s%f%s%s , &m_sDist , &m_sNo , &m_sWidth , &m_nInstyle , &m_dHeight , &m_dwData.m_sBlock , &m_dwData.m_dBomEl , &m_dwData.m_sMaterial , &m_dwData.m_sProvider); } KTNormDoorDlg::~KTNormDoorDlg() { AcDbDatabase *pDb = NULL; for (int i = 0; i < m_arpDb.length(); i++) { pDb = (AcDbDatabase *)m_arpDb.at(i); delete pDb; } } void KTNormDoorDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_STATIC_PREVIEW, m_wndPreView); DDX_Control(pDX, IDC_TOOLTIP, m_wndTip); DDX_Control(pDX, IDC_COMBOWIDTH, m_wndComboWidth); DDX_Control(pDX, IDC_COMBONO, m_wndComboNo); DDX_Control(pDX, IDC_COMBODIST, m_wndComboDist); DDX_CBString(pDX, IDC_COMBODIST, m_sDist); DDX_CBString(pDX, IDC_COMBONO, m_sNo); DDX_CBString(pDX, IDC_COMBOWIDTH, m_sWidth); DDX_Radio(pDX, IDC_SEQU_INSERT, m_nInstyle); DDX_Text(pDX, IDC_EDIT1, m_dHeight); DDX_Text(pDX, IDC_EDIT2, m_dElRef); DDX_Text(pDX, IDC_EDIT12, m_sMaterial); DDX_Text(pDX, IDC_EDIT3, m_sProvider); } BEGIN_MESSAGE_MAP(KTNormDoorDlg, CDialog) //{{AFX_MSG_MAP(KTNormDoorDlg) ON_MESSAGE(WM_VIEWDBLCLKSEL, OnStaticPreview) ON_BN_CLICKED(IDC_SEQU_INSERT, OnSequInsert) ON_BN_CLICKED(IDC_FIXT_ONPIER, OnFixtOnpier) ON_BN_CLICKED(IDC_DOTE_CEN_INSERT, OnDoteCenInsert) ON_BN_CLICKED(IDC_CENT_INSERT, OnCentInsert) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipNotify) ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipNotify) //}}AFX_MSG_MAP ON_BN_CLICKED(IDC_BUTTON1, &KTNormDoorDlg::OnBnClickedButton1) ON_WM_DESTROY() END_MESSAGE_MAP() BOOL KTNormDoorDlg::OnToolTipNotify(UINT id, NMHDR *pNMHDR, LRESULT *pResult) { TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR; TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR; UINT_PTR nCtrlID = pNMHDR->idFrom; if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) || pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND)) { nCtrlID = ::GetDlgCtrlID((HWND)nCtrlID); } CString sTipText; if (nCtrlID == IDC_SEQU_INSERT) sTipText = _T("指定距离顺序插入"); else if(nCtrlID == IDC_DOTE_CEN_INSERT) sTipText = _T("轴网居中定位插入"); else if(nCtrlID == IDC_CENT_INSERT) sTipText = _T("按墙居中定位插入"); else if(nCtrlID == IDC_FIXT_ONPIER) sTipText = _T("沿墙指定距离插入"); #ifdef UNICODE if (pNMHDR->code == TTN_NEEDTEXTA) ::WideCharToMultiByte(CP_ACP , 0, sTipText, -1, pTTTA->szText, sizeof(pTTTA->szText), NULL, NULL ); else lstrcpyn(pTTTW->szText, sTipText, _tcslen(pTTTW->szText)); #else if (pNMHDR->code == TTN_NEEDTEXTA) lstrcpyn(pTTTA->szText, sTipText, _tcslen(pTTTA->szText)); else ::MultiByteToWideChar(CP_ACP , 0, sTipText, -1, pTTTW->szText, sizeof(pTTTW->szText) ); #endif // UNICODE *pResult = 0; m_wndTip.SetWindowText(sTipText); return TRUE; } BOOL KTNormDoorDlg::OnInitDialog() { CDialog::OnInitDialog(); EnableToolTips(); m_bmpStyle[0].LoadBitmap(IDB_SEQUINSERT); m_bmpStyle[1].LoadBitmap(IDB_DOTECENINS); m_bmpStyle[2].LoadBitmap(IDB_CENTINSERT); m_bmpStyle[3].LoadBitmap(IDB_BUTTERINST); ((CButton*)GetDlgItem(IDC_SEQU_INSERT))->SetBitmap(m_bmpStyle[0]); ((CButton*)GetDlgItem(IDC_DOTE_CEN_INSERT))->SetBitmap(m_bmpStyle[1]); ((CButton*)GetDlgItem(IDC_CENT_INSERT))->SetBitmap(m_bmpStyle[2]); ((CButton*)GetDlgItem(IDC_FIXT_ONPIER))->SetBitmap(m_bmpStyle[3]); ((CButton*)GetDlgItem(IDC_SEQU_INSERT))->SetCheck(2); if (!m_wndPreView.SubclassDlgItem(IDC_STATIC_PREVIEW,this)) return FALSE; CString sDwgFile; KTSetting::GetKTPsPath(sDwgFile); sDwgFile += _T("Support\\Cells\\"); sDwgFile += m_sDwgFile; m_sDwgFile = sDwgFile; ShowSlide(); #ifndef ZWCAD #if ARX>=20 m_wndPreView.mpView->setVisualStyle(AcGiVisualStyle::k2DWireframe); #else m_wndPreView.mpView->setMode(AcGsView::k2DOptimized); #endif #else #if defined(R24) m_wndPreView.mpView->setMode(AcGsView::k2DOptimized); #else m_wndPreView.mpView->setVisualStyle(AcGiVisualStyle::k2DWireframe); #endif #endif m_wndComboDist.EnableWindow(FALSE); InitGenDoorWidthCombo(); UpdateData(FALSE); return TRUE; } void KTNormDoorDlg::InitGenDoorWidthCombo() { LPCTSTR pszWidths[] = {_T("700"),_T("750"),_T("800"),_T("900"),_T("1000"),_T("1100"), _T("1200"),_T("1500"),_T("1800"),_T("2000"),_T("2400"),_T("2700"),_T("3000"),_T("3600"),0}; int i = 0; while(pszWidths[i] != NULL) { if (m_wndComboWidth.FindString(0,pszWidths[i]) == -1) { m_wndComboWidth.AddString(pszWidths[i]); } ++i; } } LRESULT KTNormDoorDlg::OnStaticPreview(WPARAM wparam,LPARAM lparam) { KTBlkRecsView recView; recView.SetCurRec(m_dwData.m_sBlock,FALSE); int nRes = recView.DoModal(); if (nRes == IDOK) { CString s3DFile; recView.GetCurRec(m_sDwgFile,m_dwData.m_sBlock,m_dwData.m_sBlock3D,s3DFile); m_sDwg3DFile = s3DFile; ShowSlide(); Invalidate(); RedrawWindow(); } return 0l; } void KTNormDoorDlg::ShowSlide() { AcDbDatabase *pDb = new AcDbDatabase(false); Acad::ErrorStatus es = pDb->readDwgFile(m_sDwgFile); if (es != Acad::eOk) { AfxMessageBox(CString(_T("打开文件失败 \"")) + m_sDwgFile + _T("\"")); delete pDb; return; } AcGsView *pView = m_wndPreView.view(); if (pView != NULL) pView->eraseAll(); // now initialise the drawing control InitDrawingControl(pDb,m_dwData.m_sBlock); m_arpDb.append(pDb); } Acad::ErrorStatus KTNormDoorDlg::InitDrawingControl (AcDbDatabase *pDb, const TCHAR *space) { // have we got a valid drawing if (pDb == NULL) return Acad::eNullBlockName; AcDbBlockTableRecordPointer spaceRec(space, pDb, AcDb::kForRead); // if ok if (spaceRec.openStatus() == Acad::eOk) { // initialize the preview control m_wndPreView.init(true); // set the view to the *Active* AutoCAD view CGsPreviewCtrl* pPreViewCtrl = &m_wndPreView; AcGeMatrix3d xform; SetViewTo(m_wndPreView.mpView, pDb, xform); AcDbBlockReference *pRef = new AcDbBlockReference(); pRef->setBlockTableRecord(spaceRec->objectId()); pRef->setPosition(AcGePoint3d::kOrigin); pRef->setRotation(0.0); bool bIsDoor = true; AcGeScale3d scale(500,500,500); if (!bIsDoor) scale.set(500,240,500); pRef->setScaleFactors(scale); pRef->setColorIndex(4); pPreViewCtrl->view()->add(pRef, pPreViewCtrl->model()); AcGePoint3d ptS,ptE; //绘制两侧墙体 AcDbLine* pLn = new AcDbLine; ptS.set(-550,120,0); ptE.set(-250,120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); pLn = new AcDbLine; ptS.set(-250,120,0); ptE.set(-250,-120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); pLn = new AcDbLine; ptS.set(-250,-120,0); ptE.set(-550,-120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); //R pLn = new AcDbLine; ptS.set(550,120,0); ptE.set(250,120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); pLn = new AcDbLine; ptS.set(250,120,0); ptE.set(250,-120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); pLn = new AcDbLine; ptS.set(250,-120,0); ptE.set(550,-120,0); pLn->setStartPoint(ptS);pLn->setEndPoint(ptE); pLn->setColorIndex(9); pPreViewCtrl->view()->add(pLn, pPreViewCtrl->model()); // tell the view to display this space m_wndPreView.view()->add(spaceRec.object(), m_wndPreView.model()); } return spaceRec.openStatus(); } bool KTNormDoorDlg::GetActiveViewPortInfo (AcDbDatabase *pDb, ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter) { // if not ok if (pDb == NULL) return false; // get the current working database as a backup AcDbDatabase *workingDataBase = acdbHostApplicationServices()->workingDatabase(); // now set the working database //acdbHostApplicationServices()->setWorkingDatabase(pDb); // make sure the active view port is uptodate //acedVports2VportTableRecords(); // open the view port records AcDbViewportTable *pVTable = NULL; Acad::ErrorStatus es = pDb->getViewportTable (pVTable, AcDb::kForRead); // if we opened them ok if (es == Acad::eOk) { AcDbViewportTableRecord *pViewPortRec = NULL; es = pVTable->getAt (_T("*Active"), pViewPortRec, AcDb::kForRead); if (es == Acad::eOk) { // get the height of the view height = pViewPortRec->height (); // get the width width = pViewPortRec->width (); // if the user wants the center of the viewport used if (getViewCenter == true) { struct resbuf rb; memset (&rb, 0, sizeof (struct resbuf)); // get the system var VIEWCTR acedGetVar (_T("VIEWCTR"), &rb); // set that as the target target = AcGePoint3d (rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); } // we want the viewports camera target setting else { // get the target of the view target = pViewPortRec->target (); } // get the view direction viewDir = pViewPortRec->viewDirection (); // get the view twist of the viewport viewTwist = pViewPortRec->viewTwist (); } // close after use pVTable->close (); pViewPortRec->close(); } // now restore the original working database // acdbHostApplicationServices()->setWorkingDatabase(workingDataBase); return (true); } ////////////////////////////////////////////////////////////////////////// // set the passed AcGsView to the *Active* AutoCAD AcDbDatabase view void KTNormDoorDlg::SetViewTo(AcGsView *pView, AcDbDatabase *pDb, AcGeMatrix3d& viewMat) { // we are going to set the view to the current view of the drawing // The overall approach is to calculate the extents of the database in the coordinate system of the view // Calculate the extents in WCS AcGePoint3d extMax(500,500,0); //= pDb->extmax(); AcGePoint3d extMin(-500,-500,0); //= pDb->extmin(); // get the view port information - see parameter list ads_real height = 0.0, width = 0.0, viewTwist = 0.0; AcGePoint3d targetView; AcGeVector3d viewDir; GetActiveViewPortInfo (pDb, height, width, targetView, viewDir, viewTwist, true); // we are only interested in the directions of the view, not the sizes, so we normalise. viewDir = viewDir.normal(); //********************************************** // Our view coordinate space consists of z direction // get a perp vector off the z direction // Make sure its normalised AcGeVector3d viewXDir = viewDir.perpVector ().normal(); // correct the x angle by applying the twist viewXDir = viewXDir.rotateBy (viewTwist, -viewDir); // now we can work out y, this is of course perp to the x and z directions. No need to normalise this, // as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length AcGeVector3d viewYDir = viewDir.crossProduct (viewXDir); // find a nice point around which to transform the view. We'll use the same point as the center of the view. AcGePoint3d boxCenter = extMin + 0.5 * ( extMax - extMin ); //********************************************** // create a transform from WCS to View space // this represents the transformation from WCS to the view space. (Actually not quite since // we are keeping the fixed point as the center of the box for convenience ) viewMat = AcGeMatrix3d::alignCoordSys (boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis, boxCenter, viewXDir, viewYDir, viewDir).inverse(); AcDbExtents wcsExtents(extMin, extMax); // now we have the view Extents AcDbExtents viewExtents = wcsExtents; // transforms the extents in WCS->view space viewExtents.transformBy (viewMat); //********************************************** // get the extents of the AutoCAD view double xMax = fabs(viewExtents.maxPoint ().x - viewExtents.minPoint ().x); double yMax = fabs(viewExtents.maxPoint ().y - viewExtents.minPoint ().y); //********************************************** // setup the view AcGePoint3d eye = boxCenter + viewDir; // upvector pView->setView(eye, boxCenter, viewYDir, xMax, yMax); // update the gsView if (pView != NULL) { pView->invalidate(); pView->update(); } } void KTNormDoorDlg::OnOK() { UpdateData(); double dWidth = _ttof(m_sWidth); if (dWidth < 1.0) { AfxMessageBox(_T("门宽度太小,请输入合适的宽度!")); return; } //创建blockrec id; if (!CreateBlockRecord()) { AfxMessageBox(_T("创建门窗二维块失败,检查软件安装是否正确!")); return; } if (!CreateBlockRecord3d()) { AfxMessageBox(_T("创建门窗三维块失败,检查软件安装是否正确!")); return; } m_dwData.m_dWidth = dWidth; m_dwData.m_sNo = m_sNo; m_dwData.m_dDistFr = _ttof(m_sDist); m_dwData.m_eInsStyle = (InsStyle)(m_nInstyle + 1); m_dwData.m_dHeight = m_dHeight; m_dwData.m_dBomEl = 0.0; SET_CACHE(KTNormDoorDlg , %s%s%s%d%f%s%f%s%s , m_sDist , m_sNo , m_sWidth , m_nInstyle , m_dHeight , m_dwData.m_sBlock , m_dwData.m_dBomEl , m_dwData.m_sMaterial , m_dwData.m_sProvider); CDialog::OnOK(); } void KTNormDoorDlg::OnCancel() { CDialog::OnCancel(); } DWDATA* KTNormDoorDlg::GetData() { AcDbBlockTable* pTable = NULL; acdbCurDwg()->getBlockTable(pTable,AcDb::kForRead); if (pTable != NULL) { pTable->getAt(m_dwData.m_sBlock,m_dwData.m_idRec); pTable->close(); } m_dwData.m_dHeight = m_dHeight; m_dwData.m_dBomEl = m_dElRef; m_dwData.m_sMaterial = m_sMaterial; m_dwData.m_sProvider = m_sProvider; return &m_dwData; } void KTNormDoorDlg::OnSequInsert() { m_dwData.m_eInsStyle = kByOrder; m_wndComboDist.EnableWindow(FALSE); } void KTNormDoorDlg::OnFixtOnpier() { m_dwData.m_eInsStyle = kByButter; m_wndComboDist.EnableWindow(TRUE); } void KTNormDoorDlg::OnDoteCenInsert() { m_dwData.m_eInsStyle = kByDoteCen; m_wndComboDist.EnableWindow(FALSE); } void KTNormDoorDlg::OnCentInsert() { m_dwData.m_eInsStyle = kByCenter; m_wndComboDist.EnableWindow(FALSE); } BOOL KTNormDoorDlg::CreateBlockRecord() { AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase(); AcDbBlockTable* pTbl = NULL; pWorkDb->getSymbolTable(pTbl, AcDb::kForRead); if (pTbl != NULL) { if ( Acad::eOk == pTbl->getAt(m_dwData.m_sBlock,m_dwData.m_idRec) ) { pTbl->close(); return TRUE; } pTbl->close(); } AcDbDatabase* pDb = new AcDbDatabase(false); ASSERT(pDB != NULL); if (pDb->readDwgFile(m_sDwgFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk) { delete pDb; return FALSE; } AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { delete pDb; return FALSE; } AcDbObjectId idBlock; pBT->getAt(m_dwData.m_sBlock, idBlock); pBT->close(); AcDbDatabase* pTempDb = NULL; pDb->wblock(pTempDb, idBlock); delete pDb; if (pTempDb == NULL) return FALSE; if (pWorkDb->insert(m_dwData.m_idRec, m_dwData.m_sBlock, pTempDb) != Acad::eOk) { delete pTempDb; return FALSE; } delete pTempDb; return TRUE; } BOOL KTNormDoorDlg::CreateBlockRecord3d() { TCHAR sDrive[MAX_PATH],sDir[MAX_PATH],sFileName[MAX_PATH],sExt[MAX_PATH]; #ifdef _UNICODE _wsplitpath(m_sDwgFile, sDrive, sDir, sFileName, sExt); #else _splitpath(m_sDwgFile, sDrive, sDir, sFileName, sExt); #endif AcDbDatabase* pWorkDb = acdbHostApplicationServices()->workingDatabase(); AcDbBlockTable* pTbl = NULL; pWorkDb->getSymbolTable(pTbl, AcDb::kForRead); if (pTbl != NULL) { if ( Acad::eOk == pTbl->getAt(m_dwData.m_sBlock3D, m_dwData.m_idRec3d) ) { pTbl->close(); return TRUE; } pTbl->close(); } CString sDwg3DFile; sDwg3DFile.Format(_T("%s%s%s"),sDrive,sDir,m_sDwg3DFile); AcDbDatabase* pDb = new AcDbDatabase(false); ASSERT(pDB != NULL); if (pDb->readDwgFile(sDwg3DFile, AcDbDatabase::kForReadAndAllShare) != Acad::eOk) { delete pDb; return FALSE; } AcDbBlockTable* pBT = NULL; pDb->getSymbolTable(pBT, AcDb::kForRead); if (pBT == NULL) { delete pDb; return FALSE; } AcDbObjectId idBlock; pBT->getAt(m_dwData.m_sBlock3D, idBlock); pBT->close(); AcDbDatabase* pTempDb = NULL; pDb->wblock(pTempDb, idBlock); delete pDb; if (pTempDb == NULL) return FALSE; if (pWorkDb->insert(m_dwData.m_idRec3d, m_dwData.m_sBlock3D, pTempDb) != Acad::eOk) { delete pTempDb; return FALSE; } delete pTempDb; return TRUE; } void KTNormDoorDlg::OnBnClickedButton1() { OnStaticPreview(0,0); } void KTNormDoorDlg::OnDestroy() { CDialog::OnDestroy(); }