ACD_把dwg像控件一样放到界面

先看一下效果:

右侧的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 &currentVsId, 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 &currentVsId, 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;
}

 

转载于:https://my.oschina.net/u/2930533/blog/1826934

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值