#include "StdAfx.h" #include "BlkRecsPreviewCtrlEx.h" #include "GsPreviewCtrlEx.h" #include "math.h" #include "dbobjptr.h" #include "EarThwormDef.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif int CBlkRecsPreviewCtrlEx::s_nSpace = 16; #define WM_VIEWDBLCLKSEL (WM_USER + 0x1200) #define WM_TRUERELOAD (WM_USER + 0x1201) #define WM_ONITEMSEL (WM_USER + 0x1202) 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); } CBlkRecsPreviewCtrlEx::CBlkRecsPreviewCtrlEx() { m_nRows = 1; m_nCols = 1; m_nCurSel = -1; m_bInit = FALSE; m_hRes = NULL; m_bLfFont = FALSE; } CBlkRecsPreviewCtrlEx::~CBlkRecsPreviewCtrlEx() { Clear(); } BEGIN_MESSAGE_MAP(CBlkRecsPreviewCtrlEx, CWnd) ON_WM_PAINT() ON_WM_LBUTTONDOWN() ON_WM_LBUTTONUP() ON_WM_LBUTTONDBLCLK() ON_WM_ERASEBKGND() ON_WM_SIZE() ON_WM_DESTROY() ON_WM_VSCROLL() END_MESSAGE_MAP() #define ID_PREVIEWCTRL 401 void CBlkRecsPreviewCtrlEx::SetLogFont(LOGFONT* plf) { if (plf != NULL) { memcpy(&m_lfFont,plf,sizeof(LOGFONT)); m_bLfFont = TRUE; } } BOOL CBlkRecsPreviewCtrlEx::Init(HMODULE hRes,int nRows,int nCols,int nCount,AcDbDatabase* pDb,bool b3D/* = true*/) { m_hRes = hRes; if (nRows * nCols <= 0) return FALSE; DestroyAll(); m_bInit = TRUE; m_nRows = nRows; m_nCols = nCols; CRect rcClient; AcGsDCRect dcRc; GetClientRect(&rcClient); rcClient.DeflateRect(s_nSpace,s_nSpace,s_nSpace,s_nSpace); 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; CGsPreviewCtrlEx* pPreViewCtrl = NULL; for (int i = 0;i < nCount;i++) { pPreViewCtrl = new CGsPreviewCtrlEx; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + i); m_nIDAdd = i; InitDrawingControl(pPreViewCtrl,pDb,ACDB_MODEL_SPACE,b3D); #ifndef ZWCAD #if ARX <= 19 pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #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 CBlkRecsPreviewCtrlEx::Add(AcDbEntity* pEnt,int nIndex,AcDbExtents* pExtAll) { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { CGsPreviewCtrlEx* pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(nIndex); if ( pPreViewCtrl != NULL) { pPreViewCtrl->mpView->add(pEnt, pPreViewCtrl->model()); AcDbPoint* pPt = AcDbPoint::cast(pEnt); if (pPt != NULL) { m_mapViewCtrl2Pt.SetAt(pPreViewCtrl,1); } else { m_mapViewCtrl2Pt.SetAt(pPreViewCtrl,0); } pPreViewCtrl->RefreshView(); } m_nCurSel = 0; return TRUE; } return FALSE; } BOOL CBlkRecsPreviewCtrlEx::Add(AcDbEntity* pEnt,int nIndex,LPCTSTR pszName,AcDbExtents* pExtAll) { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { CGsPreviewCtrlEx* pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(nIndex); if ( pPreViewCtrl != NULL) { bool bSuccess = pPreViewCtrl->mpView->add(pEnt, pPreViewCtrl->model()); pPreViewCtrl->RefreshView(); AcDbPoint* pPt = AcDbPoint::cast(pEnt); if (pPt != NULL) { m_mapViewCtrl2Pt.SetAt(pPreViewCtrl,1); } else { m_mapViewCtrl2Pt.SetAt(pPreViewCtrl,0); } CString sKey; sKey.Format(_T("%p"),pPreViewCtrl); m_mapEntPtr2Name.SetAt(sKey,pszName); } m_nCurSel = 0; return TRUE; } return FALSE; } BOOL CBlkRecsPreviewCtrlEx::Add(LPCTSTR pszDwgFile,LPCTSTR pszName) { Acad::ErrorStatus es; AcDbDatabase *pDb = NULL; bool bNewDb = false; if ( !m_mapDwgFile2Db.Lookup(pszDwgFile,(void*&)pDb) ) { bNewDb = true; pDb = new AcDbDatabase(false); 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; CGsPreviewCtrlEx* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrlEx; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb,pszName); #ifndef ZWCAD #if ARX <= 19 pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); if (!bNewDb) { m_arDbPtrs.Add(pDb); m_mapDwgFile2Db.SetAt(pszDwgFile,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 CBlkRecsPreviewCtrlEx::Add(AcDbDatabase* pDb,LPCTSTR pszName) { // 根据nCount创建viewCtrl DWORD dwStyle = WS_CHILD | WS_VISIBLE; CGsPreviewCtrlEx* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrlEx; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb,pszName); #ifndef ZWCAD #if ARX <= 19 pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraudWithEdges); pPreViewCtrl->mpView->setVisualStyle(style); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszName);//?? m_arDbPtrs.Add(pDb); m_mapDwgFile2Db.SetAt(pszName,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 CBlkRecsPreviewCtrlEx::Add(LPCTSTR pszDwgFile,LPCTSTR pszShowRc,LPCTSTR pszName,bool bIs3D/* = true*/) { Acad::ErrorStatus es; AcDbDatabase *pDb = NULL; bool bNewDb = false; if ( !m_mapDwgFile2Db.Lookup(pszDwgFile,(void*&)pDb) ) { bNewDb = true; pDb = new AcDbDatabase(false); 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; CGsPreviewCtrlEx* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrlEx; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); InitDrawingControl(pPreViewCtrl,pDb,pszShowRc,bIs3D); #ifndef ZWCAD #if ARX <= 19 pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraud); pPreViewCtrl->mpView->setVisualStyle(style); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraud); pPreViewCtrl->mpView->setVisualStyle(style); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); if (!bNewDb) { m_arDbPtrs.Add(pDb); m_mapDwgFile2Db.SetAt(pszDwgFile,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 CBlkRecsPreviewCtrlEx::PreviewWinDoor(LPCTSTR pszDwgFile,LPCTSTR pszShowRc,LPCTSTR pszName,bool bIsDoor,bool bIs3D/* = true*/) { Acad::ErrorStatus es; AcDbDatabase *pDb = NULL; bool bNewDb = false; if ( !m_mapDwgFile2Db.Lookup(pszDwgFile,(void*&)pDb) ) { bNewDb = true; pDb = new AcDbDatabase(false); 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; CGsPreviewCtrlEx* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrlEx; pPreViewCtrl->Create(_T("PreView"),dwStyle,rc,this,ID_PREVIEWCTRL + m_nIDAdd); if (Acad::eOk != InitDrawingControlWinDoor(pPreViewCtrl, pDb, pszName, bIsDoor, bIs3D)) { return FALSE; } #ifndef ZWCAD #if ARX <= 19 pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraud); pPreViewCtrl->mpView->setVisualStyle(style); #endif #else #if defined(R24) pPreViewCtrl->mpView->setMode(AcGsView::kGouraudShaded); #else AcGiVisualStyle style; style.setType(AcGiVisualStyle::kGouraud); pPreViewCtrl->mpView->setVisualStyle(style); #endif #endif m_arRecNames.Add(pszName); m_arDwgFiles.Add(pszDwgFile); if (bNewDb) { m_arDbPtrs.Add(pDb); m_mapDwgFile2Db.SetAt(pszDwgFile,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 CBlkRecsPreviewCtrlEx::InitDrawingControlWinDoor(CGsPreviewCtrlEx* pPreViewCtrl,AcDbDatabase *pDb, LPCTSTR space,bool bIsDoor,bool b3D/* = true*/) { // 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(m_hRes,true); // set the view to the *Active* AutoCAD view AcGeMatrix3d xform; SetViewTo(pPreViewCtrl->mpView, pDb, xform,b3D); // tell the view to display this space //不显示当前模型空间记录的现有实体? //pPreViewCtrl->view()->add(spaceRec.object(), pPreViewCtrl->model()); AcDbBlockReference *pRef = new AcDbBlockReference(); pRef->setBlockTableRecord(spaceRec->objectId()); pRef->setPosition(AcGePoint3d::kOrigin); pRef->setRotation(0.0); 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()); } return spaceRec.openStatus(); } Acad::ErrorStatus CBlkRecsPreviewCtrlEx::InitDrawingControl (CGsPreviewCtrlEx* pPreViewCtrl,AcDbDatabase *pDb, const TCHAR *space,bool b3D/* = true*/) { // 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(m_hRes,true); // set the view to the *Active* AutoCAD view AcGeMatrix3d xform; SetViewTo(pPreViewCtrl->mpView, pDb, xform,b3D); // tell the view to display this space //不显示当前模型空间记录的现有实体? pPreViewCtrl->view()->add(spaceRec.object(), pPreViewCtrl->model()); } return spaceRec.openStatus(); } void CBlkRecsPreviewCtrlEx::SetViewTo(AcGsView *pView, AcDbDatabase *pDb, AcGeMatrix3d& viewMat,bool b3D) { // 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(); // 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 if (b3D) { 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 CBlkRecsPreviewCtrlEx::RefreshView(AcGsView *pView) { if (pView != NULL) { pView->invalidate(); //pView->update(); } } bool CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::Redraw(AcDbExtents* pExtAll,int nGsViewIndex) { if (pExtAll != NULL && nGsViewIndex != -1) { ZoomExtent(nGsViewIndex,pExtAll); } if (::IsWindow(m_hWnd)) { Invalidate(); } } BOOL CBlkRecsPreviewCtrlEx::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; CGsPreviewCtrlEx* pPreViewCtrl = NULL; CRect rc; GetClientRect(rc); m_nIDAdd += 1; pPreViewCtrl = new CGsPreviewCtrlEx; 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 CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::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; } BOOL CBlkRecsPreviewCtrlEx::SetCurSelRec(CString &sDwgFile, CString &sRecName) { CString sRecName2, sDwgFile2; //仅仅限于当前页 int nIndex = -1, nTrueIndex = -1; for (int i = m_nRows - 1; i > -1; i--) { for (int j = 0; j < m_nCols; j++) { nIndex = i * m_nCols + j; nTrueIndex = nIndex + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueIndex < m_arPreViewCtrls.GetSize() - 1) { sRecName2 = m_arRecNames.GetAt(nTrueIndex); sDwgFile2 = m_arDwgFiles.GetAt(nTrueIndex); if (sRecName.CompareNoCase(sRecName2) == 0 && sDwgFile.CompareNoCase(sDwgFile2) == 0) { int nLastSel = m_nCurSel; m_nCurSel = nIndex; 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); if (m_nCurSel > -1 && m_nCurSel < m_arPreViewCtrls.GetSize()) { int nTrueIndex = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueIndex > -1 && nTrueIndex < m_arPreViewCtrls.GetSize()) { GetParent()->SendMessage(WM_ONITEMSEL, nTrueIndex, 0); CGsPreviewCtrlEx *pPreViewCtrl = (CGsPreviewCtrlEx *)m_arPreViewCtrls.GetAt(nTrueIndex); WORD nFlag = 0; if (m_mapViewCtrl2Pt.Lookup(pPreViewCtrl, nFlag)) { if (nFlag == 1)//point default { GetParent()->SendMessage(WM_TRUERELOAD, nTrueIndex, 0); } } } } rcCurs.DeflateRect(-2, -2, -2, -2); InvalidateRect(rcCurs); return TRUE; } } } } return FALSE; } int CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::Clear(int nIndex) { CGsPreviewCtrlEx* pView = NULL; if (nIndex == -1) { int i = 0; for (i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrlEx*)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(); m_mapViewCtrl2Pt.RemoveAll(); } else { if (nIndex > -1 && nIndex < m_arPreViewCtrls.GetSize()) { pView = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(nIndex); if (pView != NULL) { pView->mpView->eraseAll(); pView->DestroyWindow(); DELETE_PTR(pView); } m_arPreViewCtrls.RemoveAt(nIndex); m_mapViewCtrl2Pt.RemoveKey((void*)pView); 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 CBlkRecsPreviewCtrlEx::DestroyAll() { CGsPreviewCtrlEx* pView = NULL; int i = 0; for (i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrlEx*)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 CBlkRecsPreviewCtrlEx::OnPaint() { CPaintDC dc(this); if (m_bInit) return; //获取每页单元位置 CArray arCells; DrawGridCell(&dc,arCells); //设置当前可见视的单元位置 SetShowViewPort(&dc,arCells); DrawCurselCell(&dc); //显示当前可见视 CGsPreviewCtrlEx* pView = NULL; for (int i = 0;i < m_arPreViewCtrls.GetSize();i++) { pView = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); if (pView != NULL) { pView->RefreshView(); } } } void CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::SetShowViewPort(CDC* pDC,CArray& arCells) { CGsPreviewCtrlEx* 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 = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); if (m_arDbPtrs.GetSize() == m_arPreViewCtrls.GetSize()) { pDb = (AcDbDatabase*)m_arDbPtrs.GetAt(i); } else { CString sDwgFile = m_arDwgFiles.GetAt(i); if (pDb) pView->OnZoomExtents(pDb); } if (i >= nFrom && i <= nTo) { nRcIndex = i % (m_nRows * m_nCols); rc = arCells.GetAt(nRcIndex); if (pView->GetMaxFlag() == 0) { pView->MoveWindow(rc); } pView->SetCellRect(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 { CString sDwgFile = m_arDwgFiles.GetAt(i); m_mapDwgFile2Db.Lookup(sDwgFile,(void*&)pDb); if (pDb) 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 = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); rc = arCells.GetAt(i); if (pView->GetMaxFlag() == 0) { pView->MoveWindow(rc); } pView->SetCellRect(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); } else { CString sDwgFile = m_arDwgFiles.GetAt(i); if (pDb) pView->OnZoomExtents(pDb); } } } pDC->SelectObject(pFont); } } void CBlkRecsPreviewCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) { //判断当前是否有最大化 for (int i = 0;i < m_arPreViewCtrls.GetSize();i++) { CGsPreviewCtrlEx* pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); if ( pPreViewCtrl != NULL) { if ( pPreViewCtrl->GetMaxFlag() )//max { return; } } } 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); if (m_nCurSel > -1 && m_nCurSel < m_arPreViewCtrls.GetSize()) { int nTrueIndex = m_nCurSel + GetScrollPos(SB_VERT) * (m_nRows * m_nCols); if (nTrueIndex > -1 && nTrueIndex < m_arPreViewCtrls.GetSize()) { GetParent()->SendMessage(WM_ONITEMSEL,nTrueIndex,0); CGsPreviewCtrlEx* pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(nTrueIndex); WORD nFlag = 0; if ( m_mapViewCtrl2Pt.Lookup(pPreViewCtrl,nFlag) ) { if (nFlag == 1)//point default { GetParent()->SendMessage(WM_TRUERELOAD,nTrueIndex,0); } } } } rcCurs.DeflateRect(-2,-2,-2,-2); InvalidateRect(rcCurs); } void CBlkRecsPreviewCtrlEx::OnLButtonUp(UINT nFlags, CPoint point) { if (GetParent() != NULL) { int nId = GetDlgCtrlID(); GetParent()->SendMessage(WM_COMMAND,MAKEWPARAM(nId,BN_CLICKED),(LPARAM)m_hWnd); } } CRect CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::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); CGsPreviewCtrlEx* pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(nTrueSel); if ( pPreViewCtrl != NULL) { CRect rcClient; GetClientRect(&rcClient); CRect rcCtrl; pPreViewCtrl->GetWindowRect(&rcCtrl); ScreenToClient(&rcCtrl); if ( pPreViewCtrl->GetMaxFlag() == 0 )//不同 { pPreViewCtrl->MoveWindow(rcClient); pPreViewCtrl->SetMaxFlag(TRUE); pPreViewCtrl->InvalidateRect(rcClient); } else //返回小格 { pPreViewCtrl->SetMaxFlag(FALSE); } Invalidate(); } } else //外部点击 { CRect rcClient; GetClientRect(&rcClient); CGsPreviewCtrlEx* pPreViewCtrl = NULL; for (int i = 0;i < m_arPreViewCtrls.GetSize();i++) { pPreViewCtrl = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); if ( pPreViewCtrl->GetMaxFlag() == 1 )//不同 { CRect rcCtrl; pPreViewCtrl->GetWindowRect(&rcCtrl); ScreenToClient(&rcCtrl); if (rcCtrl.PtInRect(point)) { pPreViewCtrl->SetMaxFlag(FALSE); break; } } } Invalidate(); } } int CBlkRecsPreviewCtrlEx::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; } } } //当最大化时,点击框外 CGsPreviewCtrlEx* pEx = NULL; for (int i = 0;i < m_arPreViewCtrls.GetSize();i++) { pEx = (CGsPreviewCtrlEx*)m_arPreViewCtrls.GetAt(i); if (pEx->GetMaxFlag() == 1) { pEx->GetWindowRect(&rc); ScreenToClient(&rc); if (rc.PtInRect(point)) { return i; } } } return -1; } BOOL CBlkRecsPreviewCtrlEx::OnEraseBkgnd(CDC* pDC) { CRect rc; GetClientRect(&rc); COLORREF cr = RGB(192,192,192); pDC->FillSolidRect(&rc,cr); return FALSE; } void CBlkRecsPreviewCtrlEx::OnSize(UINT nType, int cx, int cy) { CWnd::OnSize(nType, cx, cy); } void CBlkRecsPreviewCtrlEx::OnDestroy() { DestroyAll(); CWnd::OnDestroy(); } void CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::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 CBlkRecsPreviewCtrlEx::ZoomExtent(AcGsView* pView,AcDbExtents* pExtAll) { } void CBlkRecsPreviewCtrlEx::ZoomExtent(int nGsViewIndex,AcDbExtents* pExtAll) { }