ACD_把dwg像控件同樣放到界面

先看一下效果:數據庫

右側的8個小黑塊,都是由dwg圖紙構成。函數

具體用法如例:ui

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類的實現this

.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);
};

.cpp3d

#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;
}
相關文章
相關標籤/搜索