#include "StdAfx.h" #include "BlkRecsPreviewCtrl.h" #include "GsPreviewCtrl.h" #include "math.h" #include "dbobjptr.h" #include "KTCADUtilityEx.h" #include "EarThwormDef.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif int CBlkRecsPreviewCtrl::s_nSpace = 16; #define WM_VIEWDBLCLKSEL (WM_USER + 0x1200) #define ID_PREVIEWCTRL 401 namespace { CGsPreviewCtrl* CreatePreviewCtrl(CBlkRecsPreviewCtrl *pWnd, int &idAdd) { int oldR = pWnd->GetRow(); int oldC = pWnd->GetCol(); CRect rc(0, 0, 0, 0); CArray arCells; pWnd->DrawGridCell(NULL, arCells); rc = arCells.GetAt(0); DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"), dwStyle, rc, pWnd, ID_PREVIEWCTRL + idAdd); ++idAdd; pWnd->SetRow(oldR); pWnd->SetCol(oldC); return pPreViewCtrl; } int getEntitysForModelSpace(AcDbDatabase *pDb , AcDbVoidPtrArray &ptrs , AcDbExtents &ext , AcGePoint3d &ptOrig) { if (!pDb) return 0; Acad::ErrorStatus es; ptOrig = pDb->insbase(); AcDbExtents _ext; AcDbBlockTable* pTbl = NULL; if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead))) { AcDbBlockTableRecord* pBTR = NULL; if (Acad::eOk == pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForRead)) { AcDbBlockTableRecordIterator *pIter(NULL); if (Acad::eOk == pBTR->newIterator(pIter)) { AcDbEntity *pEnt(NULL); for (pIter->start(); !pIter->done(); pIter->step()) { pIter->getEntity(pEnt, AcDb::kForRead); if (!pEnt) continue; AcDbEntity *pClone = (AcDbEntity*)pEnt->clone(); pClone->getGeomExtents(_ext); ext.addExt(_ext); ptrs.append(pClone); pEnt->close(); } DELETE_PTR(pIter); pIter = NULL; } pBTR->close(); } pTbl->close(); } return ptrs.length(); } } static AcGePoint3d Mid(AcGePoint3d& ptGe1,AcGePoint3d& ptGe2) { return AcGePoint3d( (ptGe1.x + ptGe2.x) / 2.0, (ptGe1.y + ptGe2.y) / 2.0, (ptGe1.z + ptGe2.z) / 2.0); } CBlkRecsPreviewCtrl::CBlkRecsPreviewCtrl() { m_nRows = 1; m_nCols = 1; m_nCurSel = 0; m_bInit = FALSE; m_bLfFont = FALSE; m_nIDAdd = 0; } CBlkRecsPreviewCtrl::~CBlkRecsPreviewCtrl() { } BEGIN_MESSAGE_MAP(CBlkRecsPreviewCtrl, CWnd) //{{AFX_MSG_MAP(CBlkRecsPreviewCtrl) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_DESTROY() ON_WM_VSCROLL() //}}AFX_MSG_MAP END_MESSAGE_MAP() void CBlkRecsPreviewCtrl::SetLogFont(LOGFONT* plf) { if (plf != NULL) { memcpy(&m_lfFont,plf,sizeof(LOGFONT)); m_bLfFont = TRUE; } } BOOL CBlkRecsPreviewCtrl::Init(int nRows,int nCols,int nCount,AcDbDatabase* pDb) { if (nRows * nCols <= 0) return FALSE; DestroyAll(); m_bInit = TRUE; m_nRows = nRows; m_nCols = nCols; CRect rc(0,0,0,0); //GetClientRect(rc); CArray arCells; DrawGridCell(NULL,arCells); rc = arCells.GetAt(0); if (nCount > 0) { // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = NULL; for (int i = 0;i < nCount;i++) { pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + i); m_nIDAdd = i; InitDrawingControl(pPreViewCtrl,pDb); pPreViewCtrl->SetOrbitFlag(OBF_PAN | OBF_ZOOM | OBF_ORBIT); #ifndef ZWCAD #if ARX>=20 pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #else pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #endif #endif m_arPreViewCtrls.Add(pPreViewCtrl); } int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT,0,nPages - 1); } else { ShowScrollBar(SB_VERT,FALSE); } } m_bInit = FALSE; return TRUE; } bool CBlkRecsPreviewCtrl::InitSingleCtrlFor3D(AcDbEntity *pEnt, LPCTSTR sName,BOOL bExtDef) { if (!pEnt) return false; AcDbExtents ext; //pEnt->getGeomExtents(ext); if (bExtDef) ext.set(AcGePoint3d(-500, -500,-500), AcGePoint3d(500, 500,500)); else pEnt->getGeomExtents(ext); CGsPreviewCtrl *pCtrl = CreatePreviewCtrl(this, m_nIDAdd); pCtrl->init(true); pCtrl->SetOrbitFlag(OBF_PAN | OBF_ZOOM | OBF_ORBIT); pCtrl->InitFromCurrentView3D(ext, false); pCtrl->Add(pEnt); pCtrl->view()->invalidate(); pCtrl->view()->zoomExtents(ext.minPoint(), ext.maxPoint()); pCtrl->Invalidate(); pCtrl->RedrawWindow(); m_arPreViewCtrls.Add(pCtrl); CString sKey; sKey.Format(_T("%p"), pCtrl); m_mapEntPtr2Name.SetAt(sKey, sName); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT, 0, nPages - 1); } else { ShowScrollBar(SB_VERT, FALSE); } return true; } bool CBlkRecsPreviewCtrl::InitSingleCtrlFor2D(AcDbEntity *pEnt, LPCTSTR sName) { if (!pEnt) return false; AcDbExtents ext; pEnt->getGeomExtents(ext); CGsPreviewCtrl *pCtrl = CreatePreviewCtrl(this, m_nIDAdd); pCtrl->init(true); pCtrl->SetOrbitFlag(OBF_PAN | OBF_ZOOM | OBF_COTE); pCtrl->InitFromCurrentView2D(ext, false); pCtrl->Add(pEnt); pCtrl->view()->invalidate(); pCtrl->Invalidate(); pCtrl->RedrawWindow(); m_arPreViewCtrls.Add(pCtrl); CString sKey; sKey.Format(_T("%p"), pCtrl); m_mapEntPtr2Name.SetAt(sKey, sName); m_arPreViewCtrls.Add(pCtrl); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT, 0, nPages - 1); } else { ShowScrollBar(SB_VERT, FALSE); } return true; } bool CBlkRecsPreviewCtrl::InitDBCtrlFor2D(LPCTSTR pszDWG, LPCTSTR sName) { if (!pszDWG) return false; AcDbDatabase *pDb = new AcDbDatabase(false); Acad::ErrorStatus es = pDb->readDwgFile(pszDWG); if (es != Acad::eOk) { AfxMessageBox(CString(_T("读取文件失败 \"")) + pszDWG + _T("\"")); DELETE_PTR(pDb); return false; } AcDbVoidPtrArray ptrs(0); AcDbExtents ext; AcGePoint3d ptInsbase(AcGePoint3d::kOrigin); getEntitysForModelSpace(pDb, ptrs, ext, ptInsbase); if (ptrs.isEmpty()) { DELETE_PTR(pDb); return false; } CGsPreviewCtrl *pCtrl = CreatePreviewCtrl(this, m_nIDAdd); pCtrl->init(true); pCtrl->SetOrbitFlag(OBF_PAN | OBF_ZOOM | OBF_ORBIT); pCtrl->InitFromCurrentView2D(ext, true); for (int i = 0; i < ptrs.length(); ++i) { pCtrl->Add((AcDbEntity*)ptrs[i]); } pCtrl->view()->invalidate(); pCtrl->Invalidate(); pCtrl->RedrawWindow(); CString sKey; sKey.Format(_T("%p"), pCtrl); m_mapEntPtr2Name.SetAt(sKey, sName); m_arPreViewCtrls.Add(pCtrl); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT, 0, nPages - 1); } else { ShowScrollBar(SB_VERT, FALSE); } DELETE_PTR(pDb); return true; } BOOL CBlkRecsPreviewCtrl::Add(AcDbEntity* pEnt,int nIndex,AcDbExtents* pExtAll) { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { CGsPreviewCtrl* pPreViewCtrl = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(nIndex); if ( pPreViewCtrl != NULL) { pPreViewCtrl->mpView->add(pEnt, pPreViewCtrl->model()); pPreViewCtrl->RefreshView(); } m_nCurSel = 0; return TRUE; } return FALSE; } BOOL CBlkRecsPreviewCtrl::Add(AcDbEntity* pEnt,int nIndex,LPCTSTR pszName,AcDbExtents* pExtAll) { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { CGsPreviewCtrl* pPreViewCtrl = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(nIndex); if ( pPreViewCtrl != NULL) { bool bSuccess = pPreViewCtrl->mpView->add(pEnt, pPreViewCtrl->model()); pPreViewCtrl->RefreshView(); CString sKey; sKey.Format(_T("%p"),pPreViewCtrl); m_mapEntPtr2Name.SetAt(sKey,pszName); } m_nCurSel = 0; return TRUE; } return FALSE; } BOOL CBlkRecsPreviewCtrl::Add(LPCTSTR pszDwgFile,LPCTSTR pszName) { AcDbDatabase *pDb = new AcDbDatabase(false); Acad::ErrorStatus es = pDb->readDwgFile(pszDwgFile); if (es != Acad::eOk) { AfxMessageBox(CString(_T("读取文件失败 \"")) + pszDwgFile + _T("\"")); DELETE_PTR(pDb); return FALSE; } // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb); #ifndef ZWCAD #if ARX>=20 pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #else pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #endif #endif CString sKey; sKey.Format(_T("%p"), pPreViewCtrl); m_mapEntPtr2Name.SetAt(sKey, pszName); m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); m_arDbPtrs.Add(pDb); m_arPreViewCtrls.Add(pPreViewCtrl); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT,0,nPages - 1); } else { ShowScrollBar(SB_VERT,FALSE); } return TRUE; } BOOL CBlkRecsPreviewCtrl::Add(AcDbDatabase* pDb,LPCTSTR pszName) { // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb); #ifndef ZWCAD #if ARX>=20 pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #else pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszName);//?? m_arDbPtrs.Add(pDb); m_arPreViewCtrls.Add(pPreViewCtrl); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT,0,nPages - 1); } else { ShowScrollBar(SB_VERT,FALSE); } return TRUE; } BOOL CBlkRecsPreviewCtrl::Add(LPCTSTR pszDwgFile,LPCTSTR pszShowRc,LPCTSTR pszName) { AcDbDatabase *pDb = new AcDbDatabase(false); Acad::ErrorStatus es = pDb->readDwgFile(pszDwgFile); if (es != Acad::eOk) { AfxMessageBox(CString(_T("读取文件失败 \"")) + pszDwgFile + _T("\"")); DELETE_PTR(pDb); return FALSE; } // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb,pszShowRc); #ifndef ZWCAD #if ARX>=20 pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #else pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::kGouraud); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); m_arDbPtrs.Add(pDb); m_arPreViewCtrls.Add(pPreViewCtrl); int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT,0,nPages - 1); } else { ShowScrollBar(SB_VERT,FALSE); } return TRUE; } Acad::ErrorStatus CBlkRecsPreviewCtrl::InitDrawingControl (CGsPreviewCtrl* pPreViewCtrl,AcDbDatabase *pDb, const TCHAR *space) { // have we got a valid drawing if (pDb == NULL) { pDb = acdbCurDwg(); } AcDbBlockTableRecordPointer spaceRec(space, pDb, AcDb::kForRead); // if ok if (spaceRec.openStatus() == Acad::eOk) { // initialize the preview control pPreViewCtrl->init(true); // set the view to the *Active* AutoCAD view AcGeMatrix3d xform; SetViewTo(pPreViewCtrl->mpView, pDb, xform); // tell the view to display this space //不显示当前模型空间记录的现有实体!!!![lfy-2013-2-20] //pPreViewCtrl->view()->add(spaceRec.object(), pPreViewCtrl->model()); } return spaceRec.openStatus(); } void CBlkRecsPreviewCtrl::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 // if exmax,exmin too larg or small , view show error!!!! AcGePoint3d extMax(500,500,500);// = pDb->extmax(); AcGePoint3d extMin(-500,-500,-500);// = pDb->extmin(); //AcGePoint3d extMax = pDb->extmax(); //AcGePoint3d extMin = 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. // set to -1,-1,1 viewDir.set(-1,-1,1); 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 CBlkRecsPreviewCtrl::RefreshView(AcGsView *pView) { if (pView != NULL) { pView->invalidate(); //pView->update(); } } bool CBlkRecsPreviewCtrl::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(); ////将导致渲染错误,文件保存,核查错误提示 LFY 2019-6-3 // 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 //将导致渲染错误,文件保存,核查错误提示 LFY 2019-6-3 //acdbHostApplicationServices()->setWorkingDatabase(workingDataBase); return (true); } void CBlkRecsPreviewCtrl::Redraw(AcDbExtents* pExtAll,int nGsViewIndex) { if (pExtAll != NULL && nGsViewIndex != -1) { ZoomExtent(nGsViewIndex,pExtAll); } if (::IsWindow(m_hWnd)) { if (nGsViewIndex > -1) { CGsPreviewCtrl *pCtrl = (CGsPreviewCtrl *)m_arPreViewCtrls.GetAt(nGsViewIndex); pCtrl->view()->invalidate(); pCtrl->Invalidate(); pCtrl->RedrawWindow(); } Invalidate(); } } BOOL CBlkRecsPreviewCtrl::PreViewNamedRecs(LPCTSTR pszDwgFile,LPCTSTR pszHead) { AcDbDatabase * pDb = new AcDbDatabase(false); if (Acad::eOk == pDb->readDwgFile(pszDwgFile)) { m_arDbPtrs.Add(pDb); m_arRecNames.Add(pszHead); m_arDwgFiles.Add(pszDwgFile); // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrl* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrl; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb,pszHead); m_arPreViewCtrls.Add(pPreViewCtrl); //scrbar int nCount = (int)m_arPreViewCtrls.GetSize(); int nShows = m_nRows * m_nCols; if (nCount - nShows > 0) { int nRes = (nCount % nShows) ? 1 : 0; int nPages = nCount / nShows + nRes; SetScrollRange(SB_VERT,0,nPages); SCROLLINFO info; info.cbSize = sizeof(SCROLLINFO); info.fMask = SIF_ALL; info.nMin = 0; info.nMax = nPages; info.nPage = 2; info.nPos = 0; info.nTrackPos = 0; SetScrollInfo(SB_VERT,&info); EnableScrollBarCtrl(SB_VERT); } else { ShowScrollBar(SB_VERT,FALSE); } m_nCurSel = 0; return TRUE; } else { DELETE_PTR(pDb); } return FALSE; } BOOL CBlkRecsPreviewCtrl::GetCurSelRec(CString& sRecName) { if (m_nCurSel != -1) { int nTrueSel = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueSel != -1 ) //view rec { sRecName = m_arRecNames.GetAt(nTrueSel); return TRUE; } } return FALSE; } BOOL CBlkRecsPreviewCtrl::GetCurSelRec(CString& sDwgFile,CString& sRecName) { if (m_nCurSel != -1) { int nTrueSel = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueSel != -1 ) //view rec { sRecName = m_arRecNames.GetAt(nTrueSel); sDwgFile = m_arDwgFiles.GetAt(nTrueSel); return TRUE; } } return FALSE; } int CBlkRecsPreviewCtrl::GetCurSelIndex() { if (m_nCurSel != -1) { int nTrueSel = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueSel != -1) //view rec { return nTrueSel; } } return -1; } void CBlkRecsPreviewCtrl::Clear(int nIndex) { CGsPreviewCtrl* pView = NULL; if (nIndex == -1) { int i = 0; for (i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(i); if (pView != NULL) { //pView->mpView->eraseAll(); //pView->DestroyWindow(); pView->clearAll(); DELETE_PTR(pView); } } m_arPreViewCtrls.RemoveAll(); m_arRecNames.RemoveAll(); AcDbDatabase* pDb = NULL; for (i = 0;i < m_arDbPtrs.GetSize();i++) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); if (pDb != NULL) { DELETE_PTR(pDb); } } m_arDbPtrs.RemoveAll(); } else { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(nIndex); if (pView != NULL) { pView->mpView->eraseAll(); pView->DestroyWindow(); DELETE_PTR(pView); } m_arPreViewCtrls.RemoveAt(nIndex); if (nIndex > -1 && nIndex < m_arRecNames.GetSize()) { m_arRecNames.RemoveAt(nIndex); } AcDbDatabase* pDb = NULL; if (nIndex > -1 && nIndex < m_arDbPtrs.GetSize()) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(nIndex); if (pDb != NULL) { DELETE_PTR(pDb); } m_arDbPtrs.RemoveAt(nIndex); } } } } void CBlkRecsPreviewCtrl::DestroyAll() { CGsPreviewCtrl* pView = NULL; int i = 0; for (i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(i); if (pView != NULL) { pView->mpView->eraseAll(); pView->DestroyWindow(); DELETE_PTR(pView); } } m_arPreViewCtrls.RemoveAll(); m_arRecNames.RemoveAll(); AcDbDatabase* pDb = NULL; for (i = 0;i < m_arDbPtrs.GetSize();i++) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); if (pDb != NULL) { DELETE_PTR(pDb); } } m_arDbPtrs.RemoveAll(); } void CBlkRecsPreviewCtrl::OnPaint() { CPaintDC dc(this); if (m_bInit) return; //获取每页单元位置 CArray arCells; DrawGridCell(&dc,arCells); //设置当前可见视的单元位置 SetShowViewPort(&dc,arCells); DrawCurselCell(&dc); //显示当前可见视 CGsPreviewCtrl* pView = NULL; for (int i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(i); if (pView != NULL) { pView->RefreshView(); } } } void CBlkRecsPreviewCtrl::DrawCurselCell(CDC* pDC) { int nIndex = -1; CRect rc,rcClient; GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); int nWidth = (rcClient.Width() - (m_nCols - 1) * s_nSpace ) / m_nCols; int nHeight = (rcClient.Height() - (m_nRows - 1) * s_nSpace) / m_nRows; int nCurCell = m_nCurSel % (m_nCols * m_nRows); for (int i = m_nRows - 1;i > -1;i--) { for (int j = 0;j < m_nCols;j++) { nIndex = i * m_nCols + j; if (nIndex == nCurCell) { //超出 int nTrueSel = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueSel > m_arPreViewCtrls.GetSize() - 1) { return; } rc.top = rcClient.top + i * (nHeight + s_nSpace); rc.bottom = rc.top + nHeight; rc.left = rcClient.left + j * (nWidth + s_nSpace); rc.right = rc.left + nWidth; CPen pen(PS_SOLID | PS_GEOMETRIC,2,RGB(255,0,0)); CPoint pt[5]; rc.DeflateRect(-1,-1,-1,-1); pt[0] = rc.TopLeft(); pt[2] = rc.BottomRight(); pt[1] = rc.TopLeft();pt[1].x = rc.right; pt[3] = rc.BottomRight();pt[3].x = rc.left; pt[4] = pt[0]; CPen * pOldPen = pDC->SelectObject(&pen); pDC->MoveTo(pt[0]); for (int k = 1;k < 5;k++) { pDC->LineTo(pt[k]); } if (pOldPen != NULL) pDC->SelectObject(pOldPen); break; } } } } void CBlkRecsPreviewCtrl::DrawGridCell(CDC* pDC,CArray& arCells) { int nIndex = -1,nTrueIndex = -1; CRect rc,rcClient; GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); int nWidth = (rcClient.Width() - (m_nCols - 1) * s_nSpace ) / m_nCols; int nHeight = (rcClient.Height() - (m_nRows - 1) * s_nSpace) / m_nRows; COLORREF crOld = RGB(0,0,0); if (pDC != NULL) { crOld = pDC->GetBkColor(); } int nPos = GetScrollPos(SB_VERT); for (int i = 0;i < m_nRows;i++) { for (int j = 0;j < m_nCols;j++) { nIndex = i * m_nCols + j; rc.top = rcClient.top + i * (nHeight + s_nSpace); rc.bottom = rc.top + nHeight; rc.left = rcClient.left + j * (nWidth + s_nSpace); rc.right = rc.left + nWidth; arCells.Add(rc); nTrueIndex = nIndex + nPos * (m_nRows * m_nCols); if (nTrueIndex <= m_arPreViewCtrls.GetSize() - 1) { if (pDC != NULL) pDC->FillSolidRect(&rc,RGB(0,0,0)); } else { if (pDC != NULL) pDC->FillSolidRect(&rc,crOld); } } } if (pDC != NULL) pDC->SetBkColor(crOld); } void CBlkRecsPreviewCtrl::SetShowViewPort(CDC* pDC,CArray& arCells) { CGsPreviewCtrl* pView = NULL; AcDbExtents exts; AcGsDCRect dcRc; AcDbDatabase* pDb = NULL; int nShows = m_nCols * m_nRows; int nCount = (int)m_arPreViewCtrls.GetSize(); if (nCount > nShows) { int nPagePos = GetScrollPos(SB_VERT); int nFrom = nPagePos * nShows; int nTo = nFrom + nShows - 1; if (nTo > nCount - 1) nTo = nCount - 1; int nRcIndex = 0,nOld = 0; CRect rc,rcLable; CString sName,sKey; CFont *pFont = NULL; CFont font; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = s_nSpace - 2; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfWeight = FW_NORMAL; _tcscpy(lf.lfFaceName, _T("宋体")); if (m_bLfFont) { memcpy(&lf,&m_lfFont,sizeof(LOGFONT)); } VERIFY(font.CreateFontIndirect(&lf)); pFont = pDC->SelectObject(&font); for (int i = 0;i < nCount;i++) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(i); if (m_arDbPtrs.GetSize() == m_arPreViewCtrls.GetSize()) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); } if (i >= nFrom && i <= nTo) { nRcIndex = i % (m_nRows * m_nCols); rc = arCells.GetAt(nRcIndex); pView->MoveWindow(rc); //写文字标题 rcLable = rc; rcLable.top = rc.bottom; rcLable.bottom = rcLable.top + s_nSpace; sKey.Format(_T("%p"),pView); if (m_mapEntPtr2Name.Lookup(sKey,sName)) { rcLable.DeflateRect(0,1,0,1); nOld = pDC->SetBkMode(TRANSPARENT); pDC->DrawText(sName,rcLable,DT_CENTER); pDC->SetBkMode(nOld); } if (m_arDbPtrs.GetSize() == m_arPreViewCtrls.GetSize()) { pView->OnZoomExtents(pDb); } } else { pView->MoveWindow(CRect(0,0,1,1)); } } pDC->SelectObject(pFont); } else { int nOld = 0; CString sName,sKey; CFont *pFont = NULL; CFont font; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = s_nSpace - 2; lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfWeight = FW_NORMAL; _tcscpy(lf.lfFaceName, _T("宋体")); if (m_bLfFont) { memcpy(&lf,&m_lfFont,sizeof(LOGFONT)); } VERIFY(font.CreateFontIndirect(&lf)); pFont = pDC->SelectObject(&font); //if (m_arDbPtrs.GetSize() == nCount) { CRect rc(0,0,0,0),rcLable; for (int i = 0;i < nCount;i++) { pView = (CGsPreviewCtrl*)m_arPreViewCtrls.GetAt(i); rc = arCells.GetAt(i); pView->MoveWindow(rc); //写文字标题 //写文字标题 rcLable = rc; rcLable.top = rc.bottom; rcLable.bottom = rcLable.top + s_nSpace; sKey.Format(_T("%p"),pView); if (m_mapEntPtr2Name.Lookup(sKey,sName)) { rcLable.DeflateRect(0,1,0,1); nOld = pDC->SetBkMode(TRANSPARENT); pDC->DrawText(sName,rcLable,DT_CENTER); pDC->SetBkMode(nOld); } if ( m_arDbPtrs.GetSize() == m_arPreViewCtrls.GetSize() ) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); pView->OnZoomExtents(pDb); } } } pDC->SelectObject(pFont); } } void CBlkRecsPreviewCtrl::OnLButtonDown(UINT nFlags, CPoint point) { CArray arCells; DrawGridCell(NULL,arCells); int nLastSel = m_nCurSel; m_nCurSel = HitViewCell(point); CRect rcLast = GetCellIndexRect(nLastSel); CRect rcCurs = GetCellIndexRect(m_nCurSel); CRect lastSmall(rcLast), cursSmall(rcCurs); lastSmall.DeflateRect(-2, -2, -2, -2); cursSmall.DeflateRect(-2, -2, -2, -2); // 更新外边框(红变白,白变红) CRgn lastRgn, lastSmlRgn, cursRgn, cursSmlRgn, rgnLast, rgnCurs; lastRgn.CreateRectRgn(rcLast.left, rcLast.top, rcLast.right, rcLast.bottom); cursRgn.CreateRectRgn(rcCurs.left, rcCurs.top, rcCurs.right, rcCurs.bottom); lastSmlRgn.CreateRectRgn(lastSmall.left, lastSmall.top, lastSmall.right, lastSmall.bottom); cursSmlRgn.CreateRectRgn(cursSmall.left, cursSmall.top, cursSmall.right, cursSmall.bottom); rgnLast.CombineRgn(&lastRgn, &lastSmlRgn, RGN_DIFF); rgnCurs.CombineRgn(&cursRgn, &cursSmlRgn, RGN_DIFF); InvalidateRgn(&rgnLast); InvalidateRgn(&rgnCurs); ::DeleteObject(lastRgn); ::DeleteObject(cursRgn); ::DeleteObject(lastSmall); ::DeleteObject(cursSmall); ::DeleteObject(rgnLast); ::DeleteObject(rgnCurs); CWnd *pParent = GetParent(); if (pParent) { ::SendMessage(pParent->GetSafeHwnd(), WM_CELL_SELECT_CHANGE, m_nCurSel, NULL); } } void CBlkRecsPreviewCtrl::OnLButtonUp(UINT nFlags, CPoint point) { if (GetParent() != NULL) { int nId = GetDlgCtrlID(); GetParent()->SendMessage(WM_COMMAND,MAKEWPARAM(nId,BN_CLICKED),(LPARAM)m_hWnd); } } CRect CBlkRecsPreviewCtrl::GetCellIndexRect(int nIndex) { int nIndex2 = -1; CRect rc,rcClient; GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); int nWidth = (rcClient.Width() - (m_nCols - 1) * s_nSpace ) / m_nCols; int nHeight = (rcClient.Height() - (m_nRows - 1) * s_nSpace) / m_nRows; int nCurCell = m_nCurSel % (m_nCols * m_nRows); for (int i = m_nRows - 1;i > -1;i--) { for (int j = 0;j < m_nCols;j++) { nIndex2 = i * m_nCols + j; if (nIndex == nIndex2) { rc.top = rcClient.top + i * (nHeight + s_nSpace); rc.bottom = rc.top + nHeight; rc.left = rcClient.left + j * (nWidth + s_nSpace); rc.right = rc.left + nWidth; return rc; } } } return CRect(0,0,0,0); } void CBlkRecsPreviewCtrl::OnLButtonDblClk(UINT nFlags, CPoint point) { m_nCurSel = HitViewCell(point); if (m_nCurSel != -1) { int nTrueSel = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); GetParent()->SendMessage(WM_VIEWDBLCLKSEL,nTrueSel,0); } } int CBlkRecsPreviewCtrl::HitViewCell(CPoint point) { int nIndex = -1,nTrueIndex = -1; CRect rc,rcClient; GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); int nWidth = (rcClient.Width() - (m_nCols - 1) * s_nSpace ) / m_nCols; int nHeight = (rcClient.Height() - (m_nRows - 1) * s_nSpace) / m_nRows; int nCurCell = m_nCurSel % (m_nCols * m_nRows); for (int i = m_nRows - 1;i > -1;i--) { for (int j = 0;j < m_nCols;j++) { nIndex = i * m_nCols + j; rc.top = rcClient.top + i * (nHeight + s_nSpace); rc.bottom = rc.top + nHeight; rc.left = rcClient.left + j * (nWidth + s_nSpace); rc.right = rc.left + nWidth; if (rc.PtInRect(point)) { nTrueIndex = nIndex + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueIndex > m_arPreViewCtrls.GetSize() -1) { return -1; } return nIndex; } } } return -1; } BOOL CBlkRecsPreviewCtrl::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); COLORREF cr = RGB(192,192,192); pDC->FillSolidRect(&rc,cr); return FALSE; } void CBlkRecsPreviewCtrl::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); } void CBlkRecsPreviewCtrl::OnDestroy() { DestroyAll(); CWnd::OnDestroy(); } void CBlkRecsPreviewCtrl::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { switch (nSBCode) { case SB_LINEUP: case SB_PAGEUP: { nPos -= 1; int nMin = 0,nMax = 0; GetScrollRange(SB_VERT,&nMin,&nMax); if (int(nPos) < nMin) return; SetScrollPos(SB_VERT,nPos,FALSE); Invalidate(); break; } case SB_PAGEDOWN: case SB_LINEDOWN: { nPos += 1; int nMin = 0,nMax = 0; GetScrollRange(SB_VERT,&nMin,&nMax); if (int(nPos) > nMax) return; SetScrollPos(SB_VERT,nPos,FALSE); Invalidate(); break; } case SB_THUMBTRACK: { SetScrollPos(SB_VERT,nPos,FALSE); Invalidate(); break; } default: break; } } BOOL CBlkRecsPreviewCtrl::Create(const RECT& rect, CWnd* pParentWnd, UINT nID) { LPCTSTR pszClass = AfxRegisterWndClass( CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS, ::LoadCursor(NULL, IDC_ARROW), (HBRUSH) ::GetStockObject(WHITE_BRUSH), ::LoadIcon(NULL, IDI_APPLICATION)); DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL; return CWnd::Create(pszClass,_T("BlkRecsPreviewCtrl"),dwStyle,rect,pParentWnd,nID); } void CBlkRecsPreviewCtrl::ZoomExtent(AcGsView* pView,AcDbExtents* pExtAll) { if (pView != NULL && pExtAll != NULL) { pView->zoomExtents(pExtAll->minPoint(), pExtAll->maxPoint()); } } void CBlkRecsPreviewCtrl::ZoomExtent(int nGsViewIndex,AcDbExtents* pExtAll) { if (pExtAll != NULL) { CGsPreviewCtrl *pCtrl = (CGsPreviewCtrl *)m_arPreViewCtrls.GetAt(nGsViewIndex); pCtrl->view()->zoomExtents(pExtAll->minPoint(), pExtAll->maxPoint()); } }