找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 835|回复: 1

[分享] 光标提示实体信息(EntInfoTip)

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2019-1-21 09:15:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 LoveArx 于 2019-1-21 09:15 编辑

基本思路:

光标提示实体信息(EntInfoTip)-1.jpg


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

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

类CEntInfoTipHandler的头文件实现代码:




[C++] 纯文本查看 复制代码
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类型的成员变量:

[C++] 纯文本查看 复制代码
class CDocData {

        //----- TODO: here you can add your variables

public:
        CDocData () ;
        CDocData (const CDocData &data) ;
        ~CDocData () ;

        CEntInfoTipHandler* m_pIPM;
} ;

需要添加头文件:

[C++] 纯文本查看 复制代码
#include "EntInfoTipHandler.h"

3)CDocDate类的实现代码:

[C++] 纯文本查看 复制代码
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;
        }
}

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

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

[C++] 纯文本查看 复制代码
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类的构造函数中,删除当前文档的输入点监视器:

[C++] 纯文本查看 复制代码
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函数的实现代码:

[C++] 纯文本查看 复制代码
bool CEntInfoTipHandler::excludeFromOsnapCalculation(
        const AcArray<AcDbObjectId>& nestedEntity, int gsSelectionMark)
{
        return false;
}

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

[C++] 纯文本查看 复制代码
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函数的实现:

[C++] 纯文本查看 复制代码
double CEntInfoTipHandler::RadianToAngle(double radian)
{
        return radian * 180 / CEntInfoTipHandler::PI();
}
 
double CEntInfoTipHandler::PI()
{
        return atan(1.0) * 4;
}

(8)注册新命令 EntTipOn

[C++] 纯文本查看 复制代码
if (!DocVars.docData().m_pIPM)
{
                        new CEntInfoTipHandler;
}

添加头文件:

[C++] 纯文本查看 复制代码
#include "EntInfoTipHandler.h"

别忘了声明DocVars:

[C++] 纯文本查看 复制代码
// 声明这个全局函数的定义在其他的obj中
extern AsdkDataManager<CDocData> DocVars;

添加AsdkDataManager的头文件:

[C++] 纯文本查看 复制代码
#include "AdskDMgr.h"

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

[C++] 纯文本查看 复制代码
if (DocVars.docData().m_pIPM)
{
        delete DocVars.docData().m_pIPM;
        DocVars.docData().m_pIPM = NULL;
}

(10)完整项目源代码


请点击此处下载

请先注册会员后在进行下载

已注册会员,请先登录后下载

文件名称:代码(提取码:dsiw) 
下载次数:12  文件大小:0 Bytes  售价:1D豆 [记录]
下载权限: 不限 以上  [免费赚D豆]


Reference:

张帆《AutoCAD ObjectARX(VC)开发基础与实例教程》


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2019-3-19 20:44:08 | 显示全部楼层
本帖最后由 edata 于 2019-3-19 21:15 编辑

前天有个网友刚好问到我这个问题,就是用的这个源码,我发现高版本(CAD2008及其以上版本开始)更改了一个函数的参数类型
monitorInputPoint的const AcArray<int>& gsSelectionMark,和const AcArray<int>& keyPointGetSelectionMark,中的int类型均改为了Adesk::GsMarker,否则无法触发反应器,
我记得自定义实体中也有几处改成了Adesk::GsMarker的地方,我记得好像是捕捉的函数参数。


  1. #if _MSC_VER>1400
  2. Acad::ErrorStatus CEntInfoTipHandler::monitorInputPoint(
  3.         bool& bAppendToTooltipStr,
  4.         TCHAR*& pAdditionalTooltipString,
  5.         AcGiViewportDraw* pDrawContext,
  6.         AcApDocument* pDocument,
  7.         bool pointComputed,
  8.         int history,
  9.         const AcGePoint3d& lastPoint,
  10.         const AcGePoint3d& rawPoint,
  11.         const AcGePoint3d& grippedPoint,
  12.         const AcGePoint3d& cartesianSnappedPoint,
  13.         const AcGePoint3d& osnappedPoint,
  14.         AcDb::OsnapMask osnapMask,
  15.         const AcArray<AcDbCustomOsnapMode*>& customOsnapModes,
  16.         AcDb::OsnapMask osnapOverrides,
  17.         const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides,
  18.         const AcArray<AcDbObjectId>& apertureEntities,
  19.         const AcArray< AcDbObjectIdArray,
  20.         AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedApertureEntities,
  21.         const AcArray<Adesk::GsMarker>& gsSelectionMark,
  22.         const AcArray<AcDbObjectId>& keyPointEntities,
  23.         const AcArray< AcDbObjectIdArray,
  24.         AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities,
  25.         const AcArray<Adesk::GsMarker>& keyPointGsSelectionMark,
  26.         const AcArray<AcGeCurve3d*>& alignmentPaths,
  27.         const AcGePoint3d& computedPoint,
  28.         const TCHAR* pTooltipString)
  29. #else
  30. Acad::ErrorStatus CEntInfoTipHandler::monitorInputPoint(
  31.         bool& bAppendToTooltipStr,
  32.         TCHAR*& pAdditionalTooltipString,
  33.         AcGiViewportDraw* pDrawContext,
  34.         AcApDocument* pDocument,
  35.         bool pointComputed,
  36.         int history,
  37.         const AcGePoint3d& lastPoint,
  38.         const AcGePoint3d& rawPoint,
  39.         const AcGePoint3d& grippedPoint,
  40.         const AcGePoint3d& cartesianSnappedPoint,
  41.         const AcGePoint3d& osnappedPoint,
  42.         AcDb::OsnapMask osnapMask,
  43.         const AcArray<AcDbCustomOsnapMode*>& customOsnapModes,
  44.         AcDb::OsnapMask osnapOverrides,
  45.         const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides,
  46.         const AcArray<AcDbObjectId>& apertureEntities,
  47.         const AcArray< AcDbObjectIdArray,
  48.         AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedApertureEntities,
  49.         const AcArray<int>& gsSelectionMark,
  50.         const AcArray<AcDbObjectId>& keyPointEntities,
  51.         const AcArray< AcDbObjectIdArray,
  52.         AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities,
  53.         const AcArray<int>& keyPointGsSelectionMark,
  54.         const AcArray<AcGeCurve3d*>& alignmentPaths,
  55.         const AcGePoint3d& computedPoint,
  56.         const TCHAR* pTooltipString)
  57. #endif
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-11-14 21:52 , Processed in 0.323201 second(s), 34 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表