先看一下效果:
右侧的8个小黑块,都是由dwg图纸构成。
具体用法如例:
CString strPath;//dwg图纸的全路径
AcDbDatabase mDb(false, true);
CDrawDWG draw();
if (_taccess(strPath, 0) == 0)
{
if (mDb.readDwgFile(strPath) == Acad::eOk && draw.Open(&mDb))
{
draw.ZoomE();
draw.UpdataView();
}
}
然后看一下CDrawDWG类的实现
.h
#include "HHDef.h"
#include "MouseBase.h"
#include "constname.h"
class CMouseMG;
class __declspec(dllexport) CDrawDWG: public CWnd
{
DECLARE_MESSAGE_MAP()
public:
// 传入要绘制的窗体
CDrawDWG(Adesk::Boolean bBuildDefaultDrawing,Adesk::Boolean bNoDocument);
CDrawDWG();
virtual ~CDrawDWG(void);
protected:
CMouseMG* m_pMouse;
CString m_strDWGPath ;// 当前DWG路径
AcDbExtents m_PExtents;// 图纸范围
AcGsView *m_pView ;// 图形系统中的视图,用来绘制图形的区域
AcGsDevice *m_pDevice;// 图形系统中的设备,
AcGsModel *m_pModel ;
AcDbDatabase*m_pDb ;// 图形库
std::vector<CString> m_arrFilePath;// 保存要加密的文件路径
double m_dWheelScale ;// 鼠标中键缩放比例,此值只可为正值,即 > 0
AcGeVector3d m_MoveVector;//view平移的矩阵
std::map<AcDbEntity*, AcDbEntity*> m_arr;// 保存拷贝出来的实体,找机会释放掉
Adesk::Boolean m_bBuildDefaultDrawing; //数据创建时的参数
Adesk::Boolean m_bNoDocument; //数据创建时的参数
AcDbObjectId m_visualStyleId; //控制显示样式
bool m_bIsBlockDisp;//!< 是否整体显示
CString m_strLineName;//因导出多个dwg分幅文件命名需要,所以添加了线路名
public:
// 设置整体显示
virtual void setBlockDisp(bool bIsBlockDisp);
// 是否整体显示
virtual bool isBlockDisp();
//数据创建时的参数
virtual void SetNewDataBaseParams(Adesk::Boolean bBuildDefaultDrawing,Adesk::Boolean bNoDocument);
//-----------------------------------------------------------------------------------
// 函 数 名:Open
// 函数介绍:打开DWG文件
// 参数介绍:LPCTSTR lpDWGFn DWG文件名
// 返 回 值:bool
//-----------------------------------------------------------------------------------
virtual bool Open(LPCTSTR lpDWGFn);
virtual bool Open(LPCTSTR lpDWGFn, double dMaxLength, double dMaxWidth, const AcGePoint3d& origin, double dAngle = 0.0, int iColor = -1);
//-----------------------------------------------------------------------------------
// 函 数 名:Open
// 函数介绍:传入数据指针进行构造
// 参数介绍:AcDbDatabase *pDb
// 返 回 值:bool
//-----------------------------------------------------------------------------------
virtual bool Open( AcDbDatabase *pDb);
// 快速显示图形,此函数适合多次显示不同数据库内容
virtual bool QuickOpen( AcDbDatabase *pDb );
// 关闭文件
virtual void Close();
// 清空DWG路径
__inline void EmptyDWGPath(){m_strDWGPath.Empty();}
//! 创建默认数据库(绘制使用)
AcDbDatabase* CreateDefault();
// 得到DWG路径
const CString& GetDWGPath()const;
//设置线路名
void SetLineName(const CString& strLineName){m_strLineName = strLineName;}
AcGsView* GetView(){return m_pView;}
//获取当前视图的范围
//double dRatio为预览控件的长高比
bool GetCurViewExtens(double dRatio, AcDbExtents& curExtens);
public:
// 添加一个鼠标方法
template<class _MStyle>
_MStyle* AddItem(UINT uID)
{
return m_pMouse->AddItem<_MStyle>(uID, this);
}
//-----------------------------------------------------------------------------------
// 函 数 名:SetNormal
// 函数介绍:设置鼠标为正常模式
//-----------------------------------------------------------------------------------
void SetNormal();
// 设置鼠标方法
void SetCurMouse(UINT uId);
// 判断指定ID,是否为当前ID
bool IsCurMouse(UINT uId)const{return m_pMouse->GetCurID()==uId;}
bool SetCurMouseShowRightMenu(UINT uMenuId);
// 删除所有鼠标样式
void RemoveAllMouse();
// 删除一个鼠标样式
void RemoveMouse(UINT uId);
public:
//-----------------------------------------------------------------------------------
// 函 数 名:ViewAddEntity
// 函数介绍:添加一个实体到视图,视图不负责实体指针的释放
// 参数介绍:AcDbEntity* pEntity
// bool bIsReSetView=true 是否重设置视窗,一般添加完毕,得设置一下
//-----------------------------------------------------------------------------------
void ViewAddEntity(AcDbEntity* pEntity, bool bIsReSetView=true,bool bUpdateView = true);
//-----------------------------------------------------------------------------------
// 函 数 名:ViewEreaseEntity
// 函数介绍:从视图移去一个实体
// 参数介绍:AcDbEntity* pEntity
//-----------------------------------------------------------------------------------
void ViewEreaseEntity(AcDbEntity* pEntity);
public:
//-----------------------------------------------------------------------------------
// 函 数 名:SaveDWG
// 函数介绍:保存文件
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool SaveDWG();
//-----------------------------------------------------------------------------------
// 函 数 名:SaveDWG
// 函数介绍:保存文件
// 参数介绍:LPCTSTR lpDWGFn
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool SaveDWG(LPCTSTR lpDWGFn);
//将特定数据库中的arrSaveId对象保存为dwg文件
static bool SSSaveDwg(AcDbDatabase* pDataBase, AcDbObjectIdArray& arrSaveId, const CString& strDesFile);
//-----------------------------------------------------------------------------------
// 函 数 名:cloneDBase
// 函数介绍:由当前图形克隆一个数据库,克隆出的指针需要在外部释放
// 返 回 值:AcDbDatabase*
//-----------------------------------------------------------------------------------
AcDbDatabase* cloneDBase();
// 得到当前图纸范围
const AcDbExtents& GetGraphExtents()const{return m_PExtents;}
void SetGraphExtents(const AcDbExtents& dbExt);
//-----------------------------------------------------------------------------------
// 函 数 名:ReLoadDWG
// 函数介绍:重新读取DWG文件
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool ReLoadDWG();
void SetDwgFileName(CString propVal)
{
SetProperty(0x3, VT_BSTR, propVal);
}
CString GetDwgFileName()
{
CString result;
GetProperty(0x3, VT_BSTR, (void*)&result);
return result;
}
void Refresh()
{
InvokeHelper(DISPID_REFRESH, DISPATCH_METHOD, VT_EMPTY, NULL, NULL);
}
public:
// 取得0,0点在图上的坐标
AcGeVector3d GetOxy()const;
// 取得当前数据库
AcDbDatabase* GetCurDataBase(){return m_pDb;}
public:
// 缩放到整个图纸可见
afx_msg virtual void ZoomE();
//-----------------------------------------------------------------------------------
// 函 数 名:MoveAndScaleView
// 函数介绍:缩放并移动图形
// 参数介绍:short zDelta
// CPoint point
// 返 回 值:virtual
//-----------------------------------------------------------------------------------
virtual void MoveAndScaleView(short zDelta, CPoint point);
//-----------------------------------------------------------------------------------
// 函 数 名:Move
// 函数介绍:移动图形
// 参数介绍:CPoint p1 开始点
// CPoint p2 终止点
// 返 回 值:virtual void
//-----------------------------------------------------------------------------------
virtual void Move(CPoint p1, CPoint p2);
public:
// 设置滚轮缩放速度
void SetWheelScale(double dWheelScale){m_dWheelScale = dWheelScale;}
// CPoint中的X转成图上坐标Y
double Pt2ViewX(int nPtX)const;
// CPoint中的Y转成图上坐标Y
double Pt2ViewY(int nPtY)const;
//-----------------------------------------------------------------------------------
// 函 数 名:ToPt
// 函数介绍:鼠标坐标转视图坐标
// 参数介绍:CPoint pt
// 返 回 值:AcGePoint3d
//-----------------------------------------------------------------------------------
AcGePoint3d ToPt(CPoint pt)const;
protected:
// 中键滚动缩放图形
afx_msg virtual BOOL OnMouseWheel (UINT nFlags, short zDelta, CPoint pt);
// 左键双击
afx_msg virtual void OnLButtonDblClk(UINT nFlags, CPoint point);
// 左键按下
afx_msg virtual void OnLButtonDown(UINT nFlags, CPoint point);
// 左键弹起
afx_msg virtual void OnLButtonUp (UINT nFlags, CPoint point);
// 中键按下
afx_msg virtual void OnMButtonDown(UINT nFlags, CPoint point);
// 中键弹起
afx_msg virtual void OnMButtonUp (UINT nFlags, CPoint point);
// 鼠标移动
afx_msg virtual void OnMouseMove (UINT nFlags, CPoint point);
afx_msg virtual void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg virtual void OnRButtonUp(UINT nFlags, CPoint point);
// 双击中键
afx_msg virtual void OnMButtonDblClk(UINT nFlags, CPoint point);
afx_msg virtual void OnPaint();
afx_msg virtual void OnSize(UINT nType, int cx, int cy);
afx_msg LRESULT virtual OnNcHitTest(CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnDestroy();
public:
//-----------------------------------------------------------------------------------
// 函 数 名:UpdataView
// 函数介绍:更新视图,在图形有变化时刷新屏幕
// 返 回 值:void
//-----------------------------------------------------------------------------------
void UpdataView();
//! 删除所有图形
void EraseAllEntity();
// 从视图上移除某些实体
void EraseEntitys(const AcDbObjectIdArray& arr);
void EraseEntity(const AcDbObjectId& mId);
void EraseEntityP(AcDbEntity* pEntity);
// 设置菜单
void SetShowMenu(int nMenuId = -1);
public:
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshView 创建者:
// 函数介绍:刷新视图,在数据库增加或删除实体后要调用此函数刷新
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool RefreshView();
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshView
// 函数介绍:刷新视图 中的部分数据
// 参数介绍:const AcDbObjectIdArray& arr
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool RefreshView(const AcDbObjectIdArray& arr);
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshId
// 函数介绍:刷新视图中的某个元素
// 参数介绍:const AcDbObjectId& mId
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool RefreshId(const AcDbObjectId& mId);
bool RefreshIdP(AcDbEntity* pEntity, AcDbExtents* pExtents = NULL);// 是否扩展 李金涛 2011.7.11.9.54
bool RefereshEntity(AcGiDrawable * pDrawable);
//得到当前显示范围 从上到下的中线 sty-Add 2001-3-7
bool GetUpDownMidLine(AcGeLine3d& mLine);
bool GetUpDownMidLine(AcGePoint3d& ptUp,AcGePoint3d& ptDown);
//-----------------------------------------------------------------------------------
// 函 数 名:ReSetView
// 函数介绍:重新设置视窗
//-----------------------------------------------------------------------------------
void ReSetView();
//改变了访问权限
bool GetActiveViewPortInfo (ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, AcDbObjectId ¤tVsId, bool getViewCenter);
//从外部的数据库中复制至当前库,并刷新视图
bool CopyAndRefresh(AcDbDatabase* pDb, bool bIsUpdata = true);
//-----------------------------------------------------------------------------------
// 函 数 名:GetMid
// 函数介绍:取2点的中点
// 参数介绍:const AcGePoint3d& pt1 点1
// const AcGePoint3d& pt2 点2
// AcGePoint3d& ptMid 返回值
// 返 回 值:static void
//-----------------------------------------------------------------------------------
static AcGePoint3d GetMidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2);
protected:
//-----------------------------------------------------------------------------------
// 函 数 名:InitPtr
// 函数介绍:初始化其它设备指针
// 返 回 值:bool
//-----------------------------------------------------------------------------------
virtual bool InitPtr();
//-----------------------------------------------------------------------------------
// 函 数 名:AfterInitPtr
// 函数介绍:初始化指针完毕
// 返 回 值:virtual bool
//-----------------------------------------------------------------------------------
virtual bool AfterInitPtr();
virtual BOOL PreTranslateMessage(MSG* pMsg);
protected:
virtual void PreSubclassWindow();
private:
// 如果从DWG文件里面读取实体调用这个来改变实体的颜色并移动和缩放
bool Transform(const AcGeMatrix3d& matrix,const AcGeMatrix3d& matrixAngle, int iColor = -1);
};
.cpp
#include "StdAfx.h"
#include "resource.h"
#include "DrawDWG.h"
#include <axlock.h>
#include "QuickQuery.h"
#include "templatefun.h"
#include "ShareFun.h"
#include "CommonSDK\encdec.h"
#include "ComVar.h"
#include "SSGetTools.h"
#include "GraTools.h"
// 添加实体到视图
bool addEntity(AcDbEntity* pEntity, AcGsView *pView, AcGsModel *pModel)
{
if (NULL == pView)
return false;
pView->add(pEntity, pModel);
return true;
}
// 鼠标的常规模式
// #ifndef IDC_CURSOR
// #define IDC_CURSOR 434
// #endif
// #ifndef IDI_PAN
// #define IDI_PAN 435
// #endif
CDrawDWG::CDrawDWG(Adesk::Boolean bBuildDefaultDrawing,Adesk::Boolean bNoDocumen):
m_bBuildDefaultDrawing(bBuildDefaultDrawing),
m_bNoDocument(bNoDocumen),
m_pView(NULL),
m_pDevice(NULL),
m_pModel(NULL),
m_pDb(NULL),
m_dWheelScale(1),
m_bIsBlockDisp(true)
{
m_pMouse = new CMouseMG;
}
CDrawDWG::CDrawDWG():
m_pView(NULL),
m_pDevice(NULL),
m_pModel(NULL),
m_pDb(NULL),
m_dWheelScale(1),
m_bIsBlockDisp(true)
{
m_pMouse = new CMouseMG;
m_bBuildDefaultDrawing=Adesk::kFalse;
m_bNoDocument=Adesk::kTrue;
}
CDrawDWG::~CDrawDWG(void)
{
Close();
if (NULL != m_pMouse)
delete m_pMouse;
m_pMouse = NULL;
// 加密dwg文件
//for(int i=0; i<m_arrFilePath.size(); ++i)
// encDec::enctryptFile(m_arrFilePath[i]);
}
BEGIN_MESSAGE_MAP(CDrawDWG, CWnd)
//{{AFX_MSG_MAP(CDrawDWG)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_MOUSEWHEEL()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_RBUTTONDOWN()
ON_WM_RBUTTONUP()
ON_WM_NCHITTEST()
ON_WM_SETFOCUS()
//}}AFX_MSG_MAP
ON_WM_SETCURSOR()
ON_WM_DESTROY()
ON_COMMAND(ID_ZOOM_E, &CDrawDWG::ZoomE)
ON_WM_MBUTTONDBLCLK()
ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()
//
//!
//! @brief 获取真实显示style,解决只显示2dframe的问题
//!
//! @param pDb
//! @param realisticVsId 输出的 visualStyleId
//!
//! @returns (Acad::ErrorStatus)
//!
//! detailed description here.
//!
//!
// ---------------------------------------------------------------------
//
// 版本: 1.0
// ---------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-07-28 1.0
//
Acad::ErrorStatus getRealisticVisualStyleId(AcDbDatabase *pDb, AcDbObjectId& realisticVsId)
{
if (NULL == pDb)
return Acad::eWasErased;
Acad::ErrorStatus es;
const ACHAR* styleName = _T("Realistic");
AcDbDictionary * pVsDict = NULL;
es = pDb->getVisualStyleDictionary(pVsDict,AcDb::kForRead);
if ( es != Acad::eOk || pVsDict == NULL )
return es;
es = pVsDict->getAt(styleName,realisticVsId);
pVsDict->close();
return es;
}
//-----------------------------------------------------------------------------------
// 函 数 名:Open
// 函数介绍:打开DWG文件
// 参数介绍:LPCTSTR lpDWGFn DWG文件名
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::Open(LPCTSTR lpDWGFn)
{
// 先关闭
Close();
m_pDb = new AcDbDatabase(false,true);
if (NULL == m_pDb)
return false;
// 如果已加密,则不再加了
encDec::CEncDec ed;
bool bIsEncrypt = false;
if (ed.wasEncrypted(lpDWGFn) )
{
encDec::decipherFile(lpDWGFn);
bIsEncrypt = true;
}
Acad::ErrorStatus es = m_pDb->readDwgFile(lpDWGFn, _SH_DENYRW);
if (bIsEncrypt)
encDec::enctryptFile(lpDWGFn);
m_arrFilePath.push_back(lpDWGFn);
setTextStyleFont(m_pDb);
if (es != Acad::eOk)
{
delete m_pDb;
m_pDb = NULL;
return false;
}
// 获取真实显示 style id
getRealisticVisualStyleId(m_pDb,m_visualStyleId);
m_pDb->closeInput(true);
// 初始化指针
if ( !InitPtr() )
return false;
AfterInitPtr();
m_strDWGPath = lpDWGFn;
return true;
}
void CDrawDWG::SetNewDataBaseParams(Adesk::Boolean bBuildDefaultDrawing,Adesk::Boolean bNoDocument)
{
m_bBuildDefaultDrawing=bBuildDefaultDrawing;
m_bNoDocument=bNoDocument;
}
//
//! @brief
//! @param LPCTSTR lpDWGFn
//! @param double dMaxLength 最大长度
//! @param double dMaxWidth 最大宽度
//! @param int iColor
//! @exception
//! @return bool
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-7-13 1.0
//
bool CDrawDWG::Open(LPCTSTR lpDWGFn, double dMaxLength, double dMaxWidth, const AcGePoint3d& ptOrigin, double dAngle, int iColor)
{
// 先关闭
Close();
m_pDb = new AcDbDatabase(false,true);
if (NULL == m_pDb)
return false;
// 如果已加密,则不再加了
encDec::CEncDec ed;
bool bIsEncrypt = false;
if (ed.wasEncrypted(lpDWGFn) )
{
encDec::decipherFile(lpDWGFn);
bIsEncrypt = true;
}
Acad::ErrorStatus es = m_pDb->readDwgFile(lpDWGFn, _SH_DENYRW);
if (bIsEncrypt)
encDec::enctryptFile(lpDWGFn);
m_arrFilePath.push_back(lpDWGFn);
setTextStyleFont(m_pDb);
if (es != Acad::eOk)
{
delete m_pDb;
m_pDb = NULL;
return false;
}
// 通过要求尺寸及实际尺寸得到比例
HHVerifyErr(m_pDb->updateExt());
AcGePoint3d p1(m_pDb->extmin());
AcGePoint3d p2(m_pDb->extmax());
double dWScale = dMaxLength / (p2.x - p1.x);
double dHScale = dMaxWidth / (p2.y - p1.y);
double dScale = min(dWScale, dHScale);
AcGeMatrix3d matrixS = matrixS.setCoordSystem(origin, xAxis, yAxis, zAxis);
matrixS = matrixS.scaling(dScale, origin);
AcGePoint3d pt = p2;
pt.x -= ( pt.x - p1.x ) / 2.0;
pt.y -= ( pt.y - p1.y ) / 2.0;
AcGeVector3d vecDist = ptOrigin*dScale - pt*dScale;
AcGeMatrix3d matrix = matrix.translation(vecDist);
for (int i=0; i<3; i++)
{
matrix.entry[i][i] = matrixS.entry[i][i];
}
AcGeMatrix3d matrixAngle = matrix.rotation(dAngle,zAxis,ptOrigin);
Transform(matrix, matrixAngle, iColor);
getRealisticVisualStyleId(m_pDb,m_visualStyleId);
m_pDb->closeInput(true);
// 初始化指针
if ( !InitPtr() )
return false;
AfterInitPtr();
m_strDWGPath = lpDWGFn;
return true;
}
bool CDrawDWG::Transform(const AcGeMatrix3d& matrix, const AcGeMatrix3d& matrixAngle, int iColor)
{
Acad::ErrorStatus es = Acad::eOk;
// 打开块表
AcDbBlockTable *pBlkTbl;
es = m_pDb->getSymbolTable(pBlkTbl, AcDb::kForRead);//取得块表
if(es != Acad::eOk)
{
return false;
}
// 打开模型空间块表记录
AcDbBlockTableRecord *pBlkTblRcd;
es = pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
pBlkTbl->close();//关闭块表
if(es != Acad::eOk)
{
return false;
}
//创建模型空间的遍历器
AcDbBlockTableRecordIterator *pBlkTblRcdItr;
es = pBlkTblRcd->newIterator(pBlkTblRcdItr);//创建遍历器
if(es != Acad::eOk)
{
delete pBlkTblRcdItr;
return false;
}
pBlkTblRcd->close();
// 遍历模型空间块表记录
AcDbEntity *pEntity=NULL;
for(pBlkTblRcdItr->start(); !pBlkTblRcdItr->done(); pBlkTblRcdItr->step())
{
es = pBlkTblRcdItr->getEntity(pEntity, AcDb::kForWrite);//得到实体指针
if (iColor != -1)
{
pEntity->setColorIndex(iColor);
}
pEntity->transformBy(matrix);
pEntity->transformBy(matrixAngle);
pEntity->close();
}
delete pBlkTblRcdItr;
pBlkTblRcdItr = NULL;
return true;
}
//-----------------------------------------------------------------------------------
// 函 数 名:Open
// 函数介绍:传入数据指针
// 参数介绍:AcDbDatabase *pDb
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::Open( AcDbDatabase *pDb )
{
// 先关闭
Close();
m_pDb = CQKQuery::cloneDBase(pDb);
if (NULL == m_pDb)
return false;
getRealisticVisualStyleId(m_pDb,m_visualStyleId);
// 初始化指针
if ( !InitPtr() )
return false;
AfterInitPtr();
m_strDWGPath = _T("");
return true;
}
//
//! @brief
//! @param AcDbDatabase *pDb
//! @exception
//! @return bool
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-3-7 1.0
//
bool CDrawDWG::QuickOpen( AcDbDatabase *pDb )
{
if ( m_pDb==NULL )
{
return Open(pDb);
}
// 数据库指针不为空,则删除所有实体,重新加载新数据库实体
CQKQueryAppVar mSrc(NULL, NULL, pDb);
CQKQueryAppVar mQkq(NULL, NULL, m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.DelAllEntity());
HHVerify(mQkq.CloneAddEntitys(AcGeMatrix3d::kIdentity, mSrc.GetAllIds()));
HHVerify(mQkq.UnLockDoc());
return RefreshView(mQkq.GetAllIds());
}
//-----------------------------------------------------------------------------------
// 函 数 名:SaveDoc
// 函数介绍:保存文件
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::SaveDWG()
{
return SaveDWG(m_strDWGPath);
}
//-----------------------------------------------------------------------------------
// 函 数 名:SaveDWG
// 函数介绍:保存文件
// 参数介绍:LPCTSTR lpDWGFn
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::SaveDWG(LPCTSTR lpDWGFn)
{
if ( NULL != m_pDb )
{
Acad::ErrorStatus acadRet = m_pDb->saveAs(lpDWGFn);
if ( acadRet == Acad::eOk )
{
return true;
}
// 保存出错
HHAssert(false);
return false;
}
return false;
}
//将特定数据库中的arrSaveId对象保存为dwg文件
//pDataBase会在外部删除
bool CDrawDWG::SSSaveDwg(AcDbDatabase* pDataBase, AcDbObjectIdArray& arrSaveId, const CString& strDesFile)
{
if (NULL == pDataBase)
return false;
AcDbBlockTable *pBT = NULL;
Acad::ErrorStatus es = pDataBase->getSymbolTable(pBT,AcDb::kForRead);
if(es != Acad::eOk)
{
//delete pDataBase;
return FALSE;
}
AcDbBlockTableRecord *pBTR = NULL;
es = pBT->getAt(ACDB_MODEL_SPACE,pBTR,AcDb::kForRead);
pBT->close();
if(es != Acad::eOk)
{
//delete pDataBase;
return FALSE;
}
AcDbBlockTableRecordIterator *pIterator;
pBTR->newIterator(pIterator);
pBTR->close();
for(pIterator->start();!pIterator->done();pIterator->step())
{
AcDbEntity *pEnt = NULL;
es = pIterator->getEntity(pEnt,AcDb::kForWrite);
if(es != Acad::eOk)
{
delete pIterator;
return FALSE;
}
AcDbHandle handle;
pEnt->getAcDbHandle(handle);
bool bDelete = true;
for (int i = 0; i < arrSaveId.length(); i++)
{
AcDbHandle hd = arrSaveId[i].handle();
if (hd == handle)
{
bDelete = false;
}
}
if (bDelete)
{
pEnt->erase();
}
pEnt->close();
}
delete pIterator;
es = pDataBase->saveAs(strDesFile);
if (es != Acad::eOk)
return false;
return true;
}
//-----------------------------------------------------------------------------------
// 函 数 名:cloneDBase
// 函数介绍:由当前图形克隆一个数据库,克隆出的指针需要在外部释放
// 返 回 值:AcDbDatabase*
//-----------------------------------------------------------------------------------
AcDbDatabase* CDrawDWG::cloneDBase()
{
return CQKQuery::cloneDBase(m_pDb);
}
//-----------------------------------------------------------------------------------
// 函 数 名:ReLoadDWG
// 函数介绍:重新读取DWG文件
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::ReLoadDWG()
{
if (NULL != m_pView)
m_pView->eraseAll();
delete m_pDb;
m_pDb = new AcDbDatabase(false,true);
// 如果已加密,则不再加了
encDec::CEncDec ed;
bool bIsEncrypt = false;
if (ed.wasEncrypted(m_strDWGPath) )
{
encDec::decipherFile(m_strDWGPath);
bIsEncrypt = true;
}
Acad::ErrorStatus es = m_pDb->readDwgFile(m_strDWGPath, _SH_DENYRW);
if (bIsEncrypt)
encDec::enctryptFile(m_strDWGPath);
m_arrFilePath.push_back(m_strDWGPath);
if (es != Acad::eOk)
{
assert(false);
delete m_pDb;
m_pDb = NULL;
return false;
}
getRealisticVisualStyleId(m_pDb,m_visualStyleId);
RefreshView();
return true;
}
// 关闭文件
void CDrawDWG::Close()
{
AcGsManager *pGsManager = acgsGetGsManager();
HHAssert(pGsManager);
if (NULL == pGsManager)
return;
if (m_pView)
{
m_pView->eraseAll();
if (m_pDevice)
{
bool b = m_pDevice->erase(m_pView);
HHAssert(b);
}
AcGsClassFactory *pFactory = pGsManager->getGSClassFactory();
HHAssert(pFactory);
pFactory->deleteView(m_pView);
m_pView = NULL;
}
if (m_pModel)
{
pGsManager->destroyAutoCADModel(m_pModel);
m_pModel = NULL;
}
if (m_pDevice)
{
pGsManager->destroyAutoCADDevice(m_pDevice);
m_pDevice = NULL;
}
if (m_pDb)
{
delete m_pDb;
m_pDb = NULL;
}
m_strDWGPath.Empty();
}
// 缩放到整个图纸可见
void CDrawDWG::ZoomE()
{
if (NULL == m_pView)
return;
AcGePoint3d ptTargetView = GetMidPoint(m_PExtents.maxPoint(), m_PExtents.minPoint());
double dLenght = m_PExtents.maxPoint().x - m_PExtents.minPoint().x;
double dWidth = m_PExtents.maxPoint().y - m_PExtents.minPoint().y;
m_pView->setView(ptTargetView + AcGeVector3d::kZAxis,ptTargetView,AcGeVector3d::kYAxis,dLenght*1.05,dWidth*1.05);
UpdataView();
}
//-----------------------------------------------------------------------------------
// 函 数 名:AfterInitPtr
// 函数介绍:初始化指针完毕
// 返 回 值:virtual bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::AfterInitPtr()
{
if ( NULL == m_pDb )
{
HHAssert(false);
return false;
}
// 视图与数据库绑定
HHVerifyErr(m_pDb->updateExt());
CQKQuery mQkq(m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.UpdataView(m_pView, m_pModel, &m_PExtents, m_bIsBlockDisp));
HHVerify(mQkq.UnLockDoc());
ZoomE();
return true;
}
//-----------------------------------------------------------------------------------
// 函 数 名:InitPtr
// 函数介绍:初始化其它设备指针
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::InitPtr()
{
// 获得图形系统管理器
AcGsManager *pGsManager = acgsGetGsManager();
HHAssert(pGsManager);
// 获得图形系统类工厂
AcGsClassFactory *pFactory = pGsManager->getGSClassFactory();
HHAssert(pFactory);
// 创建图形系统设备
m_pDevice = pGsManager->createAutoCADDevice(m_hWnd);
HHAssert(m_pDevice);
CRect rect;
GetClientRect(&rect);
m_pDevice->onSize(rect.Width(), rect.Height());
// 创建图形系统视图
m_pView = pFactory->createView();
HHAssert(m_pView);
m_pDevice->add(m_pView);
//m_pView->setMode(AcGsView::k2DOptimized);
m_pView->setVisualStyle(AcGiVisualStyle::kRealistic);
m_pModel = pGsManager->createAutoCADModel();
HHAssert(m_pModel);
ReSetView();
// 加载鼠标样式
m_pMouse->AddItem<CMouseStyleNormal>(IDC_CURSOR, this);
// 设置当前鼠标样式
SetNormal();
return true;
}
//-----------------------------------------------------------------------------------
// 函 数 名:SetNormal
// 函数介绍:设置鼠标为正常模式
//-----------------------------------------------------------------------------------
void CDrawDWG::SetNormal()
{
if (NULL == m_pMouse)
return;
m_pMouse->SetCurID(IDC_CURSOR);
m_pMouse->SetCurMouseShowRightMenu(IDR_MENU_DEF_GRAPH);
}
//函数功能:获得当前视口的信息。
//输出参数:height 视口高度,width 视口宽度,target 视口中心点,viewDir 视口的观察向量,twist 扭曲的视口
bool CDrawDWG::GetActiveViewPortInfo ( ads_real &height, ads_real &width,
AcGePoint3d &target, AcGeVector3d &viewDir,
ads_real &viewTwist, AcDbObjectId ¤tVsId, bool getViewCenter)
{
// if not ok
if (m_pDb == NULL)
return false;
// get the current working database as a backup
//AcDbDatabase *workingDataBase = acdbHostApplicationServices()->workingDatabase();
// now set the working database
//acdbHostApplicationServices()->setWorkingDatabase(m_pDb);
// make sure the active view port is uptodate
acedVports2VportTableRecords();
// open the view port records
AcDbViewportTablePointer pVTable(m_pDb->viewportTableId(), AcDb::kForRead);
// if we opened them ok
if (pVTable.openStatus() == Acad::eOk)
{
AcDbViewportTableRecord *pViewPortRec = NULL;
Acad::ErrorStatus 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 viewport's 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 ();
// return the current Visual Style
currentVsId = pViewPortRec->visualStyle();
}
// close after use
if (NULL != pViewPortRec)
pViewPortRec->close();
}
// now restore the original working database
// acdbHostApplicationServices()->setWorkingDatabase(workingDataBase);
return (true);
}
//-----------------------------------------------------------------------------------
// 函 数 名:GetMidPoint
// 函数介绍:取2点的中点
// 参数介绍:const AcGePoint3d& pt1 点1
// const AcGePoint3d& pt2 点2
// 返 回 值:static AcGePoint3d
//-----------------------------------------------------------------------------------
AcGePoint3d CDrawDWG::GetMidPoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2)
{
AcGePoint3d ptMid;
ptMid.x = 0.5 *(pt1.x + pt2.x);
ptMid.y = 0.5 *(pt1.y + pt2.y);
ptMid.z = 0.5 *(pt1.z + pt2.z);
return ptMid;
}
void CDrawDWG::OnPaint()
{
__super::OnPaint();
UpdataView();
}
void CDrawDWG::OnSize(UINT nType, int cx, int cy)
{
if (!m_pDevice)
return;
CRect rect;
GetClientRect(&rect);
m_pDevice->onSize(rect.Width(), rect.Height());
}
//-----------------------------------------------------------------------------------
// 函 数 名:MoveAndScaleView
// 函数介绍:缩放并移动图形
// 参数介绍:short zDelta
// CPoint point
// 返 回 值:virtual
//-----------------------------------------------------------------------------------
void CDrawDWG::MoveAndScaleView(short zDelta, CPoint point)
{
if ( !m_pView)
return;
// 1.将鼠标点转成视图坐标
// double dX1 = Pt2ViewX(point.x);
// double dY1 = Pt2ViewY(point.y);
// 2.移动图形
if (zDelta < 0)
{
m_pView->zoom(0.5);
m_dWheelScale *= 0.5;
}
else
{
m_pView->zoom(1.5);
m_dWheelScale *= 1.5;
}
// 3.将鼠标点再次转成视图坐标
// double dX2 = Pt2ViewX(point.x);
// double dY2 = Pt2ViewY(point.y);
// // 4.根据2次坐标差值,移动图形
// AcGeVector3d pan_vec(dX1-dX2, dY1-dY2, 0.0);
// m_pView->dolly(pan_vec);
UpdataView();
}
//-----------------------------------------------------------------------------------
// 函 数 名:Move
// 函数介绍:移动图形
// 参数介绍:CPoint p1 开始点
// CPoint p2 终止点
// 返 回 值:virtual void
//-----------------------------------------------------------------------------------
void CDrawDWG::Move(CPoint p1, CPoint p2)
{
if ( NULL == m_pView )
return;
//完成从设备坐标系统到世界坐标系统的转换
AcGeVector3d pan_vec(-(p2.x-p1.x),p2.y-p1.y,0);
pan_vec.transformBy(m_pView->viewingMatrix() * m_pView->worldToDeviceMatrix().inverse());
m_pView->dolly(pan_vec);
//调整平移的矩阵
m_MoveVector += pan_vec;
UpdataView();
}
BOOL CDrawDWG::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
{
m_pMouse->OnMouseWheel(nFlags, zDelta, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_MOUSEWHEEL, MAKEWPARAM(nFlags, zDelta), MAKELPARAM(point.x, point.y));
return TRUE;
}
void CDrawDWG::OnLButtonDown(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnLButtonDown(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_LBUTTONDOWN, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
void CDrawDWG::OnLButtonUp(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnLButtonUp(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_LBUTTONUP, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
void CDrawDWG::OnMButtonDown(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnMButtonDown(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_MBUTTONDOWN, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
void CDrawDWG::OnMButtonUp(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnMButtonUp(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_MBUTTONUP, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
//函数功能:鼠标滚轮放大缩小视图
void CDrawDWG::OnMouseMove(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnMouseMove(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
{
//pWnd->SetFocus();
pWnd->PostMessage(WM_MOUSEMOVE, nFlags, MAKEWPARAM(point.x, point.y));
}
SetFocus();
}
void CDrawDWG::OnRButtonDown(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnRButtonDown(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_RBUTTONDOWN, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
void CDrawDWG::OnRButtonUp(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnRButtonUp(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_RBUTTONUP, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
void CDrawDWG::OnMButtonDblClk( UINT nFlags, CPoint point )
{
if (NULL == m_pMouse)
return;
m_pMouse->OnMButtonDblClk(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_MBUTTONDBLCLK, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
//
//! @brief
//! @param UINT nFlags
//! @param CPoint point
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-5-16 1.0
//
void CDrawDWG::OnLButtonDblClk(UINT nFlags, CPoint point)
{
if (NULL == m_pMouse)
return;
m_pMouse->OnLButtonDblClk(nFlags, point);
// 给父窗口发鼠标消息
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
pWnd->PostMessage(WM_LBUTTONDBLCLK, nFlags, MAKEWPARAM(point.x, point.y));
SetFocus();
}
//-----------------------------------------------------------------------------------
// 函 数 名:UpdataView
// 函数介绍:更新视图,在图形有变化时刷新屏幕
// 返 回 值:void
//-----------------------------------------------------------------------------------
void CDrawDWG::UpdataView()
{
if ( NULL == m_pView )
return;
m_pView->invalidate();
m_pView->update();
}
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshId
// 函数介绍:刷新视图中的某个元素
// 参数介绍:const AcDbObjectId& mId
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool CDrawDWG::RefreshId(const AcDbObjectId& mId)
{
if ( NULL == m_pView )
return false;
AcDbEntity* pEntity=NULL;
HHVerifyErr2(acdbOpenObject(pEntity, mId,AcDb::kForWrite, true), return false;);
HHVerify(RefreshIdP(pEntity));
HHVerifyErr(pEntity->close());
return true;
}
bool CDrawDWG::RefreshIdP( AcDbEntity* pEntity, AcDbExtents* pExtents)
{
if ( NULL == m_pView )
return false;
m_pView->erase(pEntity);
if ( !pEntity->isErased() && pEntity->visibility()== AcDb::kVisible )
{
if (pExtents)
{
m_PExtents.addExt(*pExtents);
}
addEntity(pEntity, m_pView, m_pModel);
}
return true;
}
//-----------------------------------------------------------------------------------
// 函 数 名:ReSetView
// 函数介绍:重新设置视窗
//-----------------------------------------------------------------------------------
void CDrawDWG::ReSetView()
{
// 张战运 2015/12/18 16:33
if (NULL == m_pView)
return;
double height = 0.0, width = 0.0, viewTwist = 0.0;
AcGePoint3d ptTargetView;
AcGeVector3d vecViewDir;
AcDbObjectId currentVsId;
GetActiveViewPortInfo (height, width, ptTargetView, vecViewDir, viewTwist, currentVsId, true);
vecViewDir[X] = -1;
m_pView->setView(ptTargetView + vecViewDir, ptTargetView,
AcGeVector3d(0.0, 1.0, 0.0), 1.0, 1.0);
m_pView->setVisualStyle(m_visualStyleId);
UpdataView();
}
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshView
// 函数介绍:刷新视图 中的部分数据
// 参数介绍:const AcDbObjectIdArray& arr
// 返 回 值:bool true:成功,false:失败
//-----------------------------------------------------------------------------------
bool CDrawDWG::RefreshView(const AcDbObjectIdArray& arr)
{
// 张战运 2015/12/18 16:33
if (NULL == m_pDb)
return false;
CQKQueryIds mQkq(arr, m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.OpEntity(arr, HHstd::PtrMemFun_1<CDrawDWG>(this,&CDrawDWG::RefreshId)) );
HHVerify(mQkq.UnLockDoc());
HHVerifyErr(m_pDb->updateExt());
HHVerifyErr(m_PExtents.set(m_pDb->extmin(), m_pDb->extmax()));
return true;
}
void CDrawDWG::EraseAllEntity()
{
if ( m_pView != NULL )
m_pView->eraseAll();
}
//-----------------------------------------------------------------------------------
// 函 数 名:RefreshView
// 函数介绍:刷新视图,在数据库增加或删除实体后要调用此函数刷新
// 返 回 值:bool
//-----------------------------------------------------------------------------------
bool CDrawDWG::RefreshView()
{
if ( m_pView == NULL )
return false;
HHVerifyErr(m_pDb->updateExt());
CQKQuery mQKQuery(m_pDb);
HHVerify(mQKQuery.LockDoc());
HHVerify(mQKQuery.UpdataView(m_pView, m_pModel, &m_PExtents, m_bIsBlockDisp));
HHVerify(mQKQuery.UnLockDoc());
ReSetView();
ZoomE();
return true;
}
// 取得0,0点在图上的坐标
AcGeVector3d CDrawDWG::GetOxy()const
{
if ( NULL == m_pView )
return AcGeVector3d (0.0,0.0,0.0);;
AcGeMatrix3d matrix(m_pView->screenMatrix());
AcGeVector3d mPt(0.0,0.0,0.0);
mPt.transformBy(matrix);
return mPt;
}
// CPoint中的X转成图上坐标Y
double CDrawDWG::Pt2ViewX(int nPtX)const
{
double dX = 0.0;
if (m_pView)
{
m_pView->endInteractivity();
AcGeMatrix3d matrix = m_pView->worldToDeviceMatrix();
AcGePoint3d pt(nPtX,0.0,0.0);
pt = pt.transformBy(matrix.inverse());
dX = pt[X];
}
return dX;
}
// CPoint中的Y转成图上坐标Y
double CDrawDWG::Pt2ViewY(int nPtY)const
{
CPoint pt(0,nPtY);
//ScreenToClient(&pt);
CRect rect;
GetClientRect(rect);
pt.y = rect.bottom - pt.y;
AcGeVector3d mPt(0.0,pt.y,0.0);
double dY = 0.0;
if (m_pView)
{
m_pView->endInteractivity();
AcGeMatrix3d matrix = m_pView->worldToDeviceMatrix();
AcGePoint3d pt(0.0,pt.y,0.0);
pt = pt.transformBy(matrix.inverse());
dY = pt[Y];
}
return dY;
}
//-----------------------------------------------------------------------------------
// 函 数 名:ToPt
// 函数介绍:鼠标坐标转视图坐标
// 参数介绍:CPoint pt
// 返 回 值:AcGePoint3d
//-----------------------------------------------------------------------------------
AcGePoint3d CDrawDWG::ToPt(CPoint pt)const
{
return AcGePoint3d(Pt2ViewX(pt.x), Pt2ViewY(pt.y), 0.0);
}
BOOL CDrawDWG::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
HCURSOR hCur = m_pMouse->GetCursorHandle();
if ( NULL != hCur )
{
SetCursor(hCur);
return TRUE;
}
return CWnd::OnSetCursor(pWnd, nHitTest, message);
}
LRESULT CDrawDWG::OnNcHitTest(CPoint point)
{
return HTCLIENT;
}
BOOL CDrawDWG::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN )
{
// 如果鼠标事件处理了键盘按下消息,则不传递给父类了
if ( m_pMouse->OnProcKeyDown(pMsg->wParam) )
{
return TRUE;
}
CWnd* pWnd = GetParent();
if ( NULL != pWnd )
{
pWnd->PostMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
return TRUE;
}
}
return CWnd::PreTranslateMessage(pMsg);
}
void CDrawDWG::OnDestroy()
{
CWnd::OnDestroy();
Close();
}
//-----------------------------------------------------------------------------------
// 函 数 名:ViewAddEntity
// 函数介绍:添加一个实体到视图,视图不负责实体指针的释放
// 参数介绍:AcDbEntity* pEntity
// bool bIsReSetView=true 是否重设置视窗,一般添加完毕,得设置一下
//-----------------------------------------------------------------------------------
void CDrawDWG::ViewAddEntity(AcDbEntity* pEntity, bool bIsReSetView/*=true*/,bool bUpdateView /*= true*/)
{
// 张战运 2015/12/18 16:33
if (NULL == m_pView)
return;
HHAssert(m_pView);
addEntity(pEntity, m_pView, m_pModel);
CQKQuery mQkq(m_pDb);
HHVerify(mQkq.LockDoc());
AcDbExtents extents;
mQkq.GetEntExtent(pEntity, extents);
HHVerify(mQkq.UnLockDoc());
// 判断一下新得到的实体坐标
m_PExtents.addExt(extents);
if ( bIsReSetView )
ReSetView();
else if (bUpdateView)
UpdataView();
}
//-----------------------------------------------------------------------------------
// 函 数 名:ViewEreaseEntity
// 函数介绍:从视图移去一个实体
// 参数介绍:AcDbEntity* pEntity
//-----------------------------------------------------------------------------------
void CDrawDWG::ViewEreaseEntity(AcDbEntity* pEntity)
{
if (NULL == m_pView)
return;
HHAssert(m_pView);
m_pView->erase(pEntity);
}
void CDrawDWG::PreSubclassWindow()
{
CWnd::PreSubclassWindow();
InitPtr();
}
//
//! @brief
//! @param UINT uId
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-2-22 1.0
//
void CDrawDWG::SetCurMouse( UINT uId )
{
// 张战运 2015/12/18 16:33
if (NULL == m_pMouse)
return;
m_pMouse->SetCurID(uId);
}
//
//! @brief
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-2-23 1.0
//
void CDrawDWG::RemoveAllMouse()
{
if (NULL == m_pMouse)
return;
m_pMouse->DelAll();
}
//
//! @brief
//! @param UINT uId
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-2-23 1.0
//
void CDrawDWG::RemoveMouse( UINT uId )
{
// 张战运 2015/12/18 16:33
if (NULL == m_pMouse)
return;
m_pMouse->DelItem(uId);
}
bool CDrawDWG::GetUpDownMidLine(AcGeLine3d& mLine)
{
if(m_pDb==NULL)
return false;
HHVerifyErr(m_pDb->updateExt());
CQKQuery mQkq(m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.UpdataView(m_pView, m_pModel, &m_PExtents, m_bIsBlockDisp));
HHVerify(mQkq.UnLockDoc());
double dMinX=m_PExtents.minPoint().x;
double dMinY=m_PExtents.minPoint().y;
double dMaxX=m_PExtents.maxPoint().x;
double dMaxY=m_PExtents.maxPoint().y;
AcGePoint3d pt1((dMinX+dMaxX)/2,dMaxY,0);
AcGePoint3d pt2((dMinX+dMaxX)/2,dMinY,0);
mLine.set(pt1,pt2);
return true;
}
bool CDrawDWG::GetUpDownMidLine(AcGePoint3d& ptUp,AcGePoint3d& ptDown)
{
if(m_pDb==NULL)
return false;
HHVerifyErr(m_pDb->updateExt());
CQKQuery mQkq(m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.UpdataView(m_pView, m_pModel, &m_PExtents, m_bIsBlockDisp));
HHVerify(mQkq.UnLockDoc());
double dMinX=m_PExtents.minPoint().x;
double dMinY=m_PExtents.minPoint().y;
double dMaxX=m_PExtents.maxPoint().x;
double dMaxY=m_PExtents.maxPoint().y;
ptUp.x=(dMinX+dMaxX)/2;
ptUp.y=dMaxY;
ptDown.x=(dMinX+dMaxX)/2;
ptDown.y=dMinY;
return true;
}
//
//! @brief
//! @param UINT uMenuId
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-3-18 1.0
//
bool CDrawDWG::SetCurMouseShowRightMenu( UINT uMenuId )
{
if (NULL == m_pMouse)
return false;
return m_pMouse->SetCurMouseShowRightMenu(uMenuId);
}
//
//! @brief 设置菜单
//! @param int nMenuId
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-4-26 1.0
//
void CDrawDWG::SetShowMenu( int nMenuId )
{
if (NULL == m_pMouse)
return;
m_pMouse->SetCurMouseShowRightMenu(nMenuId==-1?IDR_MENU_DEF_GRAPH:nMenuId);
}
//
//! @brief
//! @param const AcDbObjectIdArray& arr
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-4-26 1.0
//
void CDrawDWG::EraseEntitys( const AcDbObjectIdArray& arr )
{
if (NULL == m_pDb)
return;
CQKQueryIds mQkq(arr, m_pDb);
HHVerify(mQkq.LockDoc());
HHVerify(mQkq.OpEntity(arr, HHstd::PtrMemFun_1<CDrawDWG>(this,&CDrawDWG::EraseEntity)) );
HHVerify(mQkq.UnLockDoc());
HHVerifyErr(m_pDb->updateExt());
HHVerifyErr(m_PExtents.set(m_pDb->extmin(), m_pDb->extmax()));
}
//
//! @brief
//! @param const AcDbObjectId& mId
//! @exception
//! @sa
// -----------------------------------------------------------------------
// 作者:
// 版本: 1.0
// -----------------------------------------------------------------------
// 修改记录:
// 日 期 版本 修改人 修改内容
// 2011-4-26 1.0
//
void CDrawDWG::EraseEntity( const AcDbObjectId& mId )
{
if ( mId.isNull() || !mId.isValid() )
return;
AcDbEntity* pEntity=NULL;
HHVerifyErr2(acdbOpenObject(pEntity, mId,AcDb::kForWrite, true), return;);
if (NULL == pEntity)
return;
ViewEreaseEntity(pEntity);
//m_pView->erase(pEntity);
HHVerifyErr(pEntity->close());
}
/**
* @brief 更新实体,但不刷新视图
*
* @param pDrawable
*
* @returns (bool)
*/
bool CDrawDWG::RefereshEntity(AcGiDrawable * pDrawable )
{
if (pDrawable == NULL) return true;
AcDbEntity * p = AcDbEntity::cast(pDrawable);
if ( p == NULL )
return false;
ViewEreaseEntity(p);
addEntity(p, m_pView, m_pModel);
return true;
}
void CDrawDWG::EraseEntityP( AcDbEntity* pEntity )
{
if ( NULL == pEntity )
return;
ViewEreaseEntity(pEntity);
}
void CDrawDWG::SetGraphExtents(const AcDbExtents& dbExt)
{
m_PExtents = dbExt;
}
const CString& CDrawDWG::GetDWGPath() const
{
return m_strDWGPath;
}
AcDbDatabase* CDrawDWG::CreateDefault()
{
m_pDb = new AcDbDatabase(false,true);
return m_pDb;
}
void CDrawDWG::setBlockDisp(bool bIsBlockDisp)
{
m_bIsBlockDisp = bIsBlockDisp;
}
bool CDrawDWG::isBlockDisp()
{
return m_bIsBlockDisp;
}
//获取当前视图的范围
bool CDrawDWG::GetCurViewExtens(double dRatio, AcDbExtents& curExtens)
{
if (NULL == m_pView)
return false;
AcGePoint3d ptTarget(m_pView->target());
double dHeight = m_pView->fieldHeight();
double dWidth = m_pView->fieldWidth();
//注,宽度与高度可能有当前预览的实体有关,而不是完全根据当前窗口决定,
// 故在此根据预览窗口的长高比进行调整
double dMax = dHeight;
if (dMax < dWidth)
dMax = dWidth;
if (dRatio > 1)
{
dWidth = dMax;
dHeight = dMax / dRatio;
}
else
{
dWidth = dMax * dRatio;
dHeight = dMax;
}
AcGePoint3d minPoint(ptTarget);
AcGePoint3d maxPoint(ptTarget);
minPoint.x -= dWidth/2;
minPoint.y -= dHeight/2;
minPoint.z = 0.0;
maxPoint.x += dWidth/2;
maxPoint.y += dHeight/2;
maxPoint.z = 0.0;
if (Acad::eOk != curExtens.set(minPoint, maxPoint))
return false;
else
return true;
}
//从外部的数据库中复制至当前库,并刷新视图
bool CDrawDWG::CopyAndRefresh(AcDbDatabase* pDb, bool bIsUpdata/* = true*/)
{
if (NULL == pDb || NULL == m_pDb)
return false;
AcDbObjectIdArray arrNewIds;
if (!CGraBasicTools::GetDataBaseAllIds(pDb, arrNewIds))
return false;
//清空数据库中所有对象
AcDbObjectIdArray arrAllIds;
CGraBasicTools::GetDataBaseAllIds(m_pDb, arrAllIds);
CQKQueryLayer mQkq(m_pDb);
mQkq.SetIds(arrAllIds);
mQkq.DelAllEntity();
//拷贝实体
AcDbObjectIdArray arrIdCloned;
mQkq.cloneOids(arrNewIds,ACDB_MODEL_SPACE,arrIdCloned);
RefreshView();
if (bIsUpdata)
{
m_pView->zoom(m_dWheelScale);
m_pView->dolly(m_MoveVector);
UpdataView();
}
return true;
}