首页 ObjectARX-光标提示实体信息

ObjectARX-光标提示实体信息

小白鼠 2019-04-04 12:51:38 0 3579

基本思路:

20180924080839917.jpg


(1) 创建一个新工程EntInfoTip.

添加一个从AcEdInputPointMonitor类继承的类CEntInfoTipHandler.

类CEntInfoTipHandler的头文件实现代码:


class CEntInfoTipHandler :
	public AcEdInputPointMonitor
{
public:
	CEntInfoTipHandler(const bool storeInDocVars = true,AcApDocument* pDoc
	 = curDoc());
	virtual ~CEntInfoTipHandler();
 
	//计算需要从自动捕捉中排除的实体
	virtual bool excludeFromOsnapCalculation(const AcArray<AcDbObjectId>&
		nestedEntity, int gsSelectionMark);
 
	//监控输入点信息
	virtual Acad::ErrorStatus monitorInputPoint(
		bool& bAppendToTooltipStr,
		TCHAR*& pAdditionalTooltipString,
		AcGiViewportDraw* pDrawContext,
		AcApDocument* pDocument,
		bool pointComputed,
		int history,
		const AcGePoint3d& lastPoint,
		const AcGePoint3d& rawPoint,
		const AcGePoint3d& grippedPoint,
		const AcGePoint3d& cartesianSnappendPoint,
		const AcGePoint3d& osnapppendPoint,
		AcDb::OsnapMask osnapMask,
		const AcArray<AcDbCustomOsnapMode*>& customOsnapModes,
		AcDb::OsnapMask osnapOverrides,
		const AcArray<AcDbObjectId>& customOsnapOverrides,
		const AcArray<AcDbObjectId>& apertureEntitise,
		const AcArray<AcDbObjectIdArray,
		AcArrayObjectCopyReallocator<AcDbObjectIdArray>>&
		nestedApertureEntities,
		const AcArray<int>& gsSelectionMark,
		const AcArray<AcDbObjectId>& keyPointEntities,
		const AcArray<AcDbObjectIdArray,
		AcArrayObjectCopyReallocator<AcDbObjectIdArray>>&nestedKeyPointEntities,
		const AcArray<int>& keyPointGetSelectionMark,
		const AcArray<AcGeCurve3d*>& aligmentPaths,
		const AcGePoint3d& computedPoint,
		const TCHAR* pTooltipString);
 
private:
	//指向这个对象所属的文档
	AcApDocument* m_pDoc;
};


(2)在类CDocData的声明中添加CEntInfoTipHandler类型的成员变量:



class CDocData {
 
	//----- TODO: here you can add your variables
 
public:
	CDocData () ;
	CDocData (const CDocData &data) ;
	~CDocData () ;
 
	CEntInfoTipHandler* m_pIPM;
} ;


需要添加头文件:


#include "EntInfoTipHandler.h"



(3)CDocDate类的实现代码:


AsdkDataManager<CDocData> DocVars;
//----- Implementation of the document data class.
CDocData::CDocData ():m_pIPM(NULL) {
}
 
//-----------------------------------------------------------------------------
CDocData::CDocData (const CDocData &data):m_pIPM(NULL){
}
 
//-----------------------------------------------------------------------------
CDocData::~CDocData () {
	if (m_pIPM)
	{
		delete m_pIPM;
	}
}


注意:AsdkDataManager需要添加头文件:


#include "AdskDMgr.h" 


注意:要是 StdAfx.h 文件中已经定义 extern AcApDataManager<CDocData> DocVars ;  此时,DocVars已经被定义,所以你需要将 AsdkDataManager<CDocData> DocVars; 的变量名更换。

(4)在CEntInfoTipHandler类的构造函数中,为当前的图形文件添加输入点监视器:

CEntInfoTipHandler::CEntInfoTipHandler(const bool storeInDocVars /*= true*/,
	AcApDocument* pDoc/*= curDoc()*/)
{
	if (storeInDocVars)
	{
		assert(DocVars.docData(pDoc).m_pIPM == NULL);
 
		//添加输入点监视器
		m_pDoc->inputPointManager()->addPointMonitor(this);
		DocVars.docData().m_pIPM = this;
	}
	else
	{
		m_pDoc = NULL;
	}
}

在当前cpp文件的开头添加下面的语句:



extern AsdkDataManager<CDocData> DocVars;


(5)在CEntInfoTipHandler类的构造函数中,删除当前文档的输入点监视器:


CEntInfoTipHandler::~CEntInfoTipHandler()
{
	if (m_pDoc)
	{
		if (DocVars.docData(m_pDoc).m_pIPM)
		{
			//删除输入点监视器
			m_pDoc->inputPointManager()->removePointMonitor(this);
			DocVars.docData(m_pDoc).m_pIPM = NULL;
		}
	}
}


(6)excludeFromOsnapCalculation函数的实现代码:


bool CEntInfoTipHandler::excludeFromOsnapCalculation(
	const AcArray<AcDbObjectId>& nestedEntity, int gsSelectionMark)
{
	return false;
}


(7)monitorInputPoint函数的实现代码:


Acad::ErrorStatus CEntInfoTipHandler::monitorInputPoint(
	bool& bAppendToTooltipStr,
	TCHAR*& pAdditionalTooltipString,
	AcGiViewportDraw* pDrawContext,
	AcApDocument* pDocument,
	bool pointComputed,
	int history,
 
	const AcGePoint3d& lastPoint,
	const AcGePoint3d& rawPoint,
	const AcGePoint3d& grippedPoint,
	const AcGePoint3d& cartesianSnappendPoint,
	const AcGePoint3d& osnapppendPoint,
 
	AcDb::OsnapMask osnapMask,
	const AcArray<AcDbCustomOsnapMode*>& customOsnapModes,
	AcDb::OsnapMask osnapOverrides,
	const AcArray<AcDbObjectId>& customOsnapOverrides,
	const AcArray<AcDbObjectId>& apertureEntities,
	const AcArray<AcDbObjectIdArray,
	AcArrayObjectCopyReallocator<AcDbObjectIdArray>>&
	nestedApertureEntities,
 
	const AcArray<int>& gsSelectionMark,
	const AcArray<AcDbObjectId>& keyPointEntities,
	const AcArray<AcDbObjectIdArray,
	AcArrayObjectCopyReallocator<AcDbObjectIdArray>>&nestedKeyPointEntities,
	const AcArray<int>& keyPointGetSelectionMark,
	const AcArray<AcGeCurve3d*>& aligmentPaths,
	const AcGePoint3d& computedPoint,
	const TCHAR* pTooltipString)
{
	//一定要注意检查缓冲区的大小,避免越界导致的Acad直接跳出
	TCHAR mtooltipStr[1024], tempStr[1024];
	mtooltipStr[0] = '\0';
 
	Acad::ErrorStatus es;
	AcDbEntity* pEnt;
	AcDbObjectId highlightId = AcDbObjectId::kNull;
 
	if (pointComputed)
	{
		//分析光标所覆盖的实体
		if (apertureEntities .length() > 0)
		{
			for (int i = 0; i < apertureEntities.length(); i++)
			{
				//避免显示更多的实体(根据需要确定是否需要)
				if (i > 0)
				{
					break;
				}
 
				if (Acad::eOk != (acdbOpenAcDbEntity(pEnt, apertureEntities[i],
					AcDb::kForRead)))
				{
					continue;
				}
 
				if (pEnt->isKindOf(AcDbLine::desc()))
				{
					//实体类型信息
					if (_tcslen(mtooltipStr) > 0)
					{
						_tcscpy(mtooltipStr, TEXT("直线:"));
					}
					else
					{
						_tcscpy(mtooltipStr, TEXT("\n直线:"));
					}
 
					//实体详细信息
					AcDbLine* pLine = AcDbLine::cast(pEnt);
					double length = pLine->startPoint.distanceTo(pLine->
						endPoint());
					AcGeVector3d vec = pLine->endPoint() - pLine->startPoint();
					double angle = vec.convert2d(AcGePlane::kXYPlane).angle();
					_stprintf(tempStr, TEXT("\n 长度: %.2f \n 倾角 : %.2f"),
						length, RadianToAngle(angle));
				}
				else if (pEnt->isKindOf(AcDbCircle::desc()))
				{
					//实体类型信息
					if (_tcslen(mtooltipStr) > 0)
					{
						_tcscpy(mtooltipStr, TEXT("\n圆:"));
					}
					else
					{
						_tcscpy(mtooltipStr, TEXT("\n圆:"));
					}
 
					//实体详细信息
					AcDbCircle* pCircle = AcDbCircle::cast(pEnt);
					double radius = pCircle->radius();
					double area = PI() * radius * radius;
					_stprintf(tempStr, TEXT("\n 半径: %.2f \n面积: %.2f"),
						radius, area);
					_tcscat(mtooltipStr, tempStr);
					
				}
				pEnt->close();
			}
			highlightId = apertureEntities[0];
		}
		
	}
 
	//执行高亮显示,只有在显示最顶层的实体会被高亮显示
	static AcDbObjectId oldHighlightId = AcDbObjectId::kNull;
	if (highlightId != oldHighlightId)
	{
		if (AcDbObjectId::kNull != oldHighlightId)
		{
			es = acdbOpenAcDbEntity(pEnt, oldHighlightId, AcDb::kForRead);
			if (es == Acad::eOk)
			{
				es = pEnt->unhighlight();
				pEnt->close();
				oldHighlightId = AcDbObjectId::kNull;
			}
			
		}
		es = acdbOpenAcDbEntity(pEnt, highlightId, AcDb::kForRead);
		if (es == Acad::eOk)
		{
			es = pEnt->highlight();
			pEnt->close();
			oldHighlightId = highlightId;
		}
		//显示其他提示内容
		bAppendToTooltipStr = true;
		pAdditionalTooltipString = mtooltipStr;
 
		return Acad::eOk;
	}
}


RadianToAngle函数的实现:


double CEntInfoTipHandler::RadianToAngle(double radian)
{
	return radian * 180 / CEntInfoTipHandler::PI();
}
 
double CEntInfoTipHandler::PI()
{
	return atan(1.0) * 4;
}


(8)注册新命令 EntTipOn


if (!DocVars.docData().m_pIPM)
{
			new CEntInfoTipHandler;
}


添加头文件:


#include "EntInfoTipHandler.h"


别忘了声明DocVars:


// 声明这个全局函数的定义在其他的obj中
extern AsdkDataManager<CDocData> DocVars;


添加AsdkDataManager的头文件:


#include "AdskDMgr.h"


(9)注册新命令EntTipOff,关闭当前文档中实体信息动态显示的功能:


if (DocVars.docData().m_pIPM)
{
	delete DocVars.docData().m_pIPM;
	DocVars.docData().m_pIPM = NULL;
}



(10)完整项目源代码

https://pan.baidu.com/s/1GteHb7AKZiK_FSGVna35Iw


发表评论