#include "StdAfx.h" #include "BlkRecsPreviewList.h" #include "math.h" #include "GsPreviewCtrl.h" #include "dbobjptr.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define ID_PREVIEWCTRL 401 int CBlkRecsPreviewList::s_nSpace = 2; #define WM_VIEWDBLCLKSEL (WM_USER + 0x1200) 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); } CBlkRecsPreviewList::CBlkRecsPreviewList() { m_pManager = NULL; m_pFactory = NULL; m_pDevice = NULL; m_nRows = 1; m_nCols = 1; m_nCurSel = -1; m_bInit = FALSE; } CBlkRecsPreviewList::~CBlkRecsPreviewList() { } BEGIN_MESSAGE_MAP(CBlkRecsPreviewList, CWnd) //{{AFX_MSG_MAP(CBlkRecsPreviewList) 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() BOOL CBlkRecsPreviewList::Init(HMODULE hRes,int nRows,int nCols,int nCount) { if (nRows * nCols <= 0) return FALSE; DestroyAll(); m_bInit = TRUE; m_nRows = nRows; m_nCols = nCols; CRect rcClient; if (m_pManager == NULL) { m_pManager = acgsGetGsManager(); #if (ARX >= 20) AcGsKernelDescriptor desc; desc.addRequirement(AcGsKernelDescriptor::k3DDrawing); m_pFactory = AcGsManager::acquireGraphicsKernel(desc); if (!m_pFactory) return FALSE; m_pDevice = m_pManager->createAutoCADDevice(*m_pFactory, m_hWnd); #else m_pFactory = m_pManager->getGSClassFactory(); m_pDevice = m_pManager->createAutoCADDevice(m_hWnd); #endif GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); m_pDevice->onSize(rcClient.Width(), rcClient.Height()); if (nCount > 0) { // 根据nCount创建view AcGsView* pView = NULL; AcGsModel* pModel = NULL; for (int i = 0;i < nCount;i++) { pView = m_pFactory->createView(); m_arViewPtrs.Add(pView); m_pDevice->add(pView); pView->setView( AcGePoint3d(0.0, 0.0, 1.0), AcGePoint3d(0.0, 0.0, 0.0), AcGeVector3d(0.0, 1.0, 0.0), 1.0, 1.0); #if (ARX >= 20) pModel = m_pManager->createAutoCADModel(*m_pFactory); #else pModel = m_pManager->createAutoCADModel(); #endif m_arModelPtrs.Add(pModel); } 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); } else { ShowScrollBar(SB_VERT,FALSE); } } } m_bInit = FALSE; return TRUE; } BOOL CBlkRecsPreviewList::Add(AcDbEntity* pEnt,int nIndex,AcDbExtents* pExtAll) { if (nIndex > -1 && nIndex < m_arViewPtrs.GetSize()) { AcGsView* pView = (AcGsView*)m_arViewPtrs.GetAt(nIndex); AcGsModel* pModel = (AcGsModel*)m_arModelPtrs.GetAt(nIndex); AcDbExtents extent; pEnt->getGeomExtents(extent); double dH = pView->fieldHeight(); double dW = pView->fieldWidth(); double dH1 = fabs(extent.maxPoint().y - extent.minPoint().y) + 4; double dW1 = fabs(extent.maxPoint().x - extent.minPoint().x) + 4; if (dH1 - dH < 1.e-10) dH1 = dH; if (dW1 - dW < 1.e-10) dW1 = dW; if (pExtAll != NULL) { ZoomExtent(pView,pExtAll); pView->setView( AcGePoint3d(0.0, 0.0, 1.0), AcGePoint3d(0,0,0), AcGeVector3d(0.0, 1.0, 0.0), fabs(pExtAll->maxPoint().x - pExtAll->minPoint().x) + 100, fabs(pExtAll->maxPoint().y - pExtAll->minPoint().y) + 100); } else { ZoomExtent(pView,&extent); } pView->add(pEnt,pModel); return TRUE; } return FALSE; } BOOL CBlkRecsPreviewList::Add(LPCTSTR pszDwgFile,LPCTSTR pszName) { if (pszDwgFile == NULL || pszName == NULL) return FALSE; BOOL bSuccess = FALSE; AcDbDatabase* pDb = new AcDbDatabase(false); if (Acad::eOk == pDb->readDwgFile(pszDwgFile)) { m_arDbPtrs.Add(pDb); AcDbBlockTable* pTable = NULL; pDb->getBlockTable(pTable,AcDb::kForRead); if (pTable != NULL) { AcDbObjectId id; if (Acad::eOk == pTable->getAt(pszName,id)) { AcDbBlockTableRecord* pRec = NULL; pTable->getAt(ACDB_MODEL_SPACE,pRec,AcDb::kForRead); if (pRec != NULL) { AcDbBlockTableRecordIterator* pIt = NULL; pRec->newIterator(pIt); int i = 0; AcDbExtents exts,ext1; if (pIt != NULL) { //Create View AcGsView* pView = NULL; AcGsModel* pModel = NULL; pView = m_pFactory->createView(); m_arViewPtrs.Add(pView); m_pDevice->add(pView); #if (ARX >= 20) pModel = m_pManager->createAutoCADModel(*m_pFactory); #else pModel = m_pManager->createAutoCADModel(); #endif AcDbEntity* pEnt = NULL; for (pIt->start();!pIt->done();pIt->step()) { pIt->getEntity(pEnt,AcDb::kForRead); if (i == 0) { pEnt->getGeomExtents(exts); } else { pEnt->getGeomExtents(ext1); exts.addExt(ext1); } pView->add(pEnt,pModel); pEnt->close(); } delete pIt; ZoomExtent(pView,&exts); m_arModelPtrs.Add(pModel); m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); bSuccess = TRUE; } pRec->close(); } } pTable->close(); } } else { delete pDb; } return bSuccess; } BOOL CBlkRecsPreviewList::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 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::k2DWireframe); #else pPreViewCtrl->mpView->setMode(AcGsView::k2DOptimized); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::k2DOptimized); #else pPreViewCtrl->mpView->setVisualStyle(AcGiVisualStyle::k2DWireframe); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); m_arDbPtrs.Add(pDb); m_arViewPtrs.Add(pPreViewCtrl); int nCount = (int)m_arViewPtrs.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 CBlkRecsPreviewList::InitDrawingControl (CGsPreviewCtrl* pPreViewCtrl,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 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 pPreViewCtrl->view()->add(spaceRec.object(), pPreViewCtrl->model()); } return spaceRec.openStatus(); } void CBlkRecsPreviewList::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 = 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 (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 CBlkRecsPreviewList::RefreshView(AcGsView *pView) { if (pView != NULL) { pView->invalidate(); //pView->update(); } } bool CBlkRecsPreviewList::GetActiveViewPortInfo (ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter) { // make sure the active view port is uptodate acedVports2VportTableRecords(); // get the working db AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase(); // if not ok if (pDb == NULL) return false; // 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(); } return (true); } void CBlkRecsPreviewList::Redraw(AcDbExtents* pExtAll,int nGsViewIndex) { if (pExtAll != NULL && nGsViewIndex != -1) { ZoomExtent(nGsViewIndex,pExtAll); } if (::IsWindow(m_hWnd)) { Invalidate(); } } BOOL CBlkRecsPreviewList::PreViewNamedRecs(LPCTSTR pszDwgFile,LPCTSTR pszHead) { AcDbDatabase db(false); if (Acad::eOk == db.readDwgFile(pszDwgFile)) { AcDbBlockTable* pTable = NULL; db.getBlockTable(pTable,AcDb::kForRead); if (pTable != NULL) { AcDbBlockTableIterator* pIter = NULL; pTable->newIterator(pIter); if (pIter != NULL) { BOOL bAdd = FALSE; CString sName; const TCHAR* pszName = NULL; AcDbBlockTableRecord* pRec = NULL; AcGsView* pView = NULL; AcGsModel* pModel = NULL; for (pIter->start();!pIter->done();pIter->step()) { if (Acad::eOk == pIter->getRecord(pRec,AcDb::kForRead)) { pRec->getName(pszName); sName = pszName; bAdd = FALSE; if (pszHead == NULL) { bAdd = TRUE; } else { if (sName.Find(pszHead) == 0) { bAdd = TRUE; } } if (bAdd) { AcDbExtents extent; extent.addBlockExt(pRec); //Create View pView = m_pFactory->createView(); m_arViewPtrs.Add(pView); m_pDevice->add(pView); #if (ARX >= 20) pModel = m_pManager->createAutoCADModel(*m_pFactory); #else pModel = m_pManager->createAutoCADModel(); #endif m_arModelPtrs.Add(pModel); pView->add(pRec,pModel); m_arRecNames.Add(sName); ZoomExtent(pView,&extent); } pRec->close(); } } //scrbar int nCount = (int)m_arViewPtrs.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); } delete pIter; m_nCurSel = 0; } pTable->close(); } return TRUE; } return FALSE; } BOOL CBlkRecsPreviewList::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 CBlkRecsPreviewList::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 CBlkRecsPreviewList::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 CBlkRecsPreviewList::Clear(int nIndex) { AcGsView* pView = NULL; if (nIndex == -1) { for (int i = 0;i < m_arViewPtrs.GetSize();i++) { pView = (AcGsView*)m_arViewPtrs.GetAt(i); if (pView != NULL) { pView->eraseAll(); if (m_pDevice != NULL) m_pDevice->erase(pView); if (m_pFactory != NULL) m_pFactory->deleteView(pView); } } m_arViewPtrs.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 pDb; } } m_arDbPtrs.RemoveAll(); } else { if (nIndex > -1 && nIndex < m_arViewPtrs.GetSize()) { pView = (AcGsView*)m_arViewPtrs.GetAt(nIndex); if (pView != NULL) { pView->eraseAll(); } 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 pDb; } m_arDbPtrs.RemoveAt(nIndex); } } } } void CBlkRecsPreviewList::DestroyAll() { AcGsView* pView = NULL; for (int i = 0;i < m_arViewPtrs.GetSize();i++) { pView = (AcGsView*)m_arViewPtrs.GetAt(i); if (pView != NULL) { pView->eraseAll(); if (m_pDevice != NULL) m_pDevice->erase(pView); if (m_pFactory != NULL) m_pFactory->deleteView(pView); } } m_pFactory = NULL; m_arViewPtrs.RemoveAll(); AcGsModel* pModel = NULL; if (m_pManager != NULL) { for (i = 0;i < m_arModelPtrs.GetSize();i++) { pModel = (AcGsModel*)m_arModelPtrs.GetAt(i); if (pModel != NULL) { m_pManager->destroyAutoCADModel(pModel); } } if (m_pDevice != NULL) { m_pManager->destroyAutoCADDevice(m_pDevice); m_pDevice = NULL; } m_pManager = NULL; } m_arModelPtrs.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 pDb; } } m_arDbPtrs.RemoveAll(); } void CBlkRecsPreviewList::OnPaint() { CPaintDC dc(this); if (m_bInit) return; //获取每页单元位置 CArray arCells; DrawGridCell(&dc,arCells); //设置当前可见视的单元位置 SetShowViewPort(arCells); if (m_arViewPtrs.GetSize() > 1) DrawCurselCell(&dc); //显示当前可见视 AcGsView* pView = NULL; for (int i = 0;i < m_arViewPtrs.GetSize();i++) { pView = (AcGsView*)m_arViewPtrs.GetAt(i); if (pView != NULL) { pView->invalidate(); pView->update(); } } } void CBlkRecsPreviewList::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_arViewPtrs.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 CBlkRecsPreviewList::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 = 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; arCells.Add(rc); nTrueIndex = nIndex + nPos * (m_nRows * m_nCols); if (nTrueIndex < m_arViewPtrs.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 CBlkRecsPreviewList::SetShowViewPort(CArray& arCells) { AcGsView* pView = NULL; int nShows = m_nCols * m_nRows; int nCount = (int)m_arViewPtrs.GetSize(); AcDbExtents exts; AcDbDatabase* pDb = NULL; 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; CRect rc; for (int i = 0;i < nCount;i++) { pView = (AcGsView*)m_arViewPtrs.GetAt(i); if (m_arDbPtrs.GetSize() == m_arViewPtrs.GetSize()) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); exts.set(pDb->extmin(),pDb->extmax()); } if (i >= nFrom && i <= nTo) { nRcIndex = i % (m_nRows * m_nCols); rc = arCells.GetAt(nRcIndex); pView->setViewport(AcGsDCRect(rc.left,rc.right,rc.top,rc.bottom)); if (m_arDbPtrs.GetSize() == m_arViewPtrs.GetSize()) { ZoomExtent(pView,&exts); } } else { pView->setViewport(AcGsDCRect(0,1,0,1)); } } } else { CRect rc(0,0,0,0); AcGsDCRect dcRc; for (int i = 0;i < nCount;i++) { pView = (AcGsView*)m_arViewPtrs.GetAt(i); rc = arCells.GetAt(i); if (m_arDbPtrs.GetSize() == m_arViewPtrs.GetSize()) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); exts.set(pDb->extmin(),pDb->extmax()); } dcRc.m_min.x = rc.left; dcRc.m_min.y = rc.top; dcRc.m_max.x = rc.right; dcRc.m_max.y = rc.bottom; pView->setViewport(dcRc); if (m_arDbPtrs.GetSize() == m_arViewPtrs.GetSize()) { ZoomExtent(pView,&exts); } } } } void CBlkRecsPreviewList::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); rcLast.DeflateRect(-2,-2,-2,-2); InvalidateRect(rcLast); rcCurs.DeflateRect(-2,-2,-2,-2); InvalidateRect(rcCurs); } void CBlkRecsPreviewList::OnLButtonUp(UINT nFlags, CPoint point) { if (GetParent() != NULL) { int nId = GetDlgCtrlID(); GetParent()->SendMessage(WM_COMMAND,MAKEWPARAM(nId,BN_CLICKED),(LPARAM)m_hWnd); } } CRect CBlkRecsPreviewList::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 CBlkRecsPreviewList::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 CBlkRecsPreviewList::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_arViewPtrs.GetSize() -1) { return -1; } return nIndex; } } } return -1; } BOOL CBlkRecsPreviewList::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); COLORREF cr = RGB(192,192,192); pDC->FillSolidRect(&rc,cr); return FALSE; } void CBlkRecsPreviewList::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); } void CBlkRecsPreviewList::OnDestroy() { DestroyAll(); CWnd::OnDestroy(); } void CBlkRecsPreviewList::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 CBlkRecsPreviewList::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 CBlkRecsPreviewList::ZoomExtent(AcGsView* pView,AcDbExtents* pExtAll) { if (pExtAll != NULL) { ads_real height = 0.0, width = 0.0, viewTwist = 0.0; AcGePoint3d targetView; AcGeVector3d viewDir; GetActiveViewPortInfo (height, width, targetView, viewDir, viewTwist, true); viewDir = viewDir.normal(); AcGeVector3d viewXDir = viewDir.perpVector ().normal(); viewXDir = viewXDir.rotateBy (viewTwist, -viewDir); AcGeVector3d viewYDir = viewDir.crossProduct (viewXDir); AcGePoint3d boxCenter = pExtAll->minPoint() + 0.5 * ( pExtAll->maxPoint() - pExtAll->minPoint() ); AcGeMatrix3d viewMat; viewMat = AcGeMatrix3d::alignCoordSys ( boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis, boxCenter, viewXDir, viewYDir, viewDir).inverse(); AcDbExtents wcsExtents(pExtAll->minPoint(), pExtAll->maxPoint()); AcDbExtents viewExtents = wcsExtents; viewExtents.transformBy (viewMat); double xMax = fabs(viewExtents.maxPoint ().x - viewExtents.minPoint ().x); double yMax = fabs(viewExtents.maxPoint ().y - viewExtents.minPoint ().y); AcGePoint3d eye = boxCenter + viewDir; AcGePoint3d ptCen = pExtAll->minPoint() + 0.5 * (pExtAll->maxPoint() - pExtAll->minPoint()); pView->setView( eye, boxCenter, viewYDir, xMax, yMax); } } void CBlkRecsPreviewList::ZoomExtent(int nGsViewIndex,AcDbExtents* pExtAll) { int nSize = (int)m_arViewPtrs.GetSize(); if (nGsViewIndex > -1 && nGsViewIndex < nSize) { AcGsView* pView = (AcGsView*)m_arViewPtrs.GetAt(nGsViewIndex); ZoomExtent(pView,pExtAll); } }