Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1399 lines
33 KiB
C++

#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<CRect, CRect> 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<CRect,CRect> 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<CRect,CRect> 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<CRect,CRect>& 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<CRect,CRect>& 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<CRect,CRect> 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());
}
}