1 说明

  1. AutoCAD中有一个非常实用的功能,当光标移动到一个实体上时,它会显示一个动态的信息空间,光标离开这个实体,信息控件就会隐藏起来。这种显示方式非常便于用户获取图形中不容易得到的实体信息,如下图所示。
  2. 本文使用两个简单的例子来说明实现这个功能的方法,在这两个例子中将分别使用AcEdInputPointFilter和AcEdInputPointMonitor反应器来重载AutoCAD鼠标点处实体的提示信息。
  3. 环境配置:
    AutoCAD2016 64位;
    Vs2012;
    ObjectARX2015 SDK。

2 思路

在ObjectARX中,这个效果是通过点输入处理机制来实现的,有以下两种实现方式。

2.1 使用AcEdInputPointFilter实现

使用AcEdInputPointFilter完成这个功能需要的基本流程包括:

  1. 创建一个从AcEdInputPointFilter类继承的子类,重写processInputPoint函数;
  2. 需要启动实体信息动态提示时,为当前文档添加输入点过滤器,处理的对象就是从AcEdInputPointFilter类继承的子类;
  3. 需要关闭实体动态提示时,为当前的文档删除输入点过滤器。

2.1.1 创建工程

在VS2012中创建一个名为FilterTest的工程,并添加一个名为CPointFilterSample的类。

2.1.2 改写CPointFilterSample类

将CPointFilterSample类改写为一个从AcEdInputPointFilter类继承的子类,并添加和重写成员函数。
头文件CPointFilterSample.h的内容为:

#pragma once
class CPointFilterSample : public AcEdInputPointFilter
{public:virtual Acad::ErrorStatus processInputPoint(bool& changedPoint, AcGePoint3d& newPoint, bool& displayOsnapGlyph, bool& changedTooltipStr, ACHAR*& newTooltipString, bool& retry, AcGiViewportDraw* drawContext, AcApDocument* document, bool pointComputed, int history, const AcGePoint3d& lastPoint, const AcGePoint3d& rawPoint, const AcGePoint3d& grippedPoint, const AcGePoint3d& cartesianSnappedPoint, const AcGePoint3d& osnappedPoint, AcDb::OsnapMask osnapMask, const AcArray<AcDbCustomOsnapMode*>& customOsnapModes, AcDb::OsnapMask osnapOverrides, const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides, const AcArray<AcDbObjectId>& pickedEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedPickedEntities, const AcArray<Adesk::GsMarker>& gsSelectionMark, const AcArray<AcDbObjectId>& keyPointEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities, const AcArray<Adesk::GsMarker>& keyPointGsSelectionMark, const AcArray<AcGeCurve3d*>& alignmentPaths, const AcGePoint3d& computedPoint, const ACHAR* tooltipString);public:// 弧度转角度static double RadianToAngle(double radian);// 获得PI的值static double PI();};

源文件CPointFilterSample.cpp的内容为:

#include "stdafx.h"
#include "PointFilterSample.h"
Acad::ErrorStatus CPointFilterSample::processInputPoint(bool& changedPoint, AcGePoint3d& newPoint, bool& displayOsnapGlyph, bool& changedTooltipStr, ACHAR*& newTooltipString, bool& retry, AcGiViewportDraw* drawContext, AcApDocument* document, bool pointComputed, int history, const AcGePoint3d& lastPoint, const AcGePoint3d& rawPoint, const AcGePoint3d& grippedPoint, const AcGePoint3d& cartesianSnappedPoint, const AcGePoint3d& osnappedPoint, AcDb::OsnapMask osnapMask, const AcArray<AcDbCustomOsnapMode*>& customOsnapModes, AcDb::OsnapMask osnapOverrides, const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides, const AcArray<AcDbObjectId>& pickedEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedPickedEntities, const AcArray<Adesk::GsMarker>& gsSelectionMark, const AcArray<AcDbObjectId>& keyPointEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities, const AcArray<Adesk::GsMarker>& keyPointGsSelectionMark, const AcArray<AcGeCurve3d*>& alignmentPaths, const AcGePoint3d& computedPoint, const ACHAR* tooltipString)
{// 一定要注意检查缓冲区的大小,避免越界导致的Acad直接跳出TCHAR mtooltipStr[1024], tempStr[1024];mtooltipStr[0] = '\0';Acad::ErrorStatus es;AcDbEntity* pEnt;AcDbObjectId highlightId = AcDbObjectId::kNull;if (pointComputed){// 分析光标所覆盖的实体if (pickedEntities.length() > 0){for (int i = 0; i < pickedEntities.length(); ++i){// 避免显示更多的实体(根据需要确定是否需要)if (i > 0){break;}if (Acad::eOk != (acdbOpenAcDbEntity(pEnt, pickedEntities[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, CPointFilterSample::RadianToAngle(angle));_tcscat(mtooltipStr, tempStr);}else if (pEnt->isKindOf(AcDbCircle::desc())){// 实体类型信息if (_tcslen(mtooltipStr) > 0){_tcscpy(mtooltipStr, TEXT("圆:"));}else{_tcscpy(mtooltipStr, TEXT("\n圆:"));}// 实体详细信息AcDbCircle* pCircle = AcDbCircle::cast(pEnt);double radius = pCircle->radius();double area =CPointFilterSample::PI() * radius * radius;_stprintf(tempStr, TEXT("\n 半径: %.2f \n 面积: %.2f"), radius, area);_tcscat(mtooltipStr, tempStr);}pEnt->close();}highlightId = pickedEntities[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;}}// 显示其他的提示内容changedTooltipStr = true;newTooltipString = mtooltipStr;return Acad::eOk;
}double CPointFilterSample::RadianToAngle(double radian)
{return radian * 180 / CPointFilterSample::PI();
}double CPointFilterSample::PI()
{return atan(1.0) * 4;
}

2.1.3 改写入口点函数

在入口点函数acrxEntryPoint.cpp中分别注册两个命令AddFilterRemoveFilter,分别用于在文档中添加和移除输入点过滤器。入口点函数acrxEntryPoint.cpp的文件内容为:

//-----------------------------------------------------------------------------
//----- acrxEntryPoint.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"
#include "PointFilterSample.h"CPointFilterSample MyFilter;//-----------------------------------------------------------------------------
#define szRDS _RXST("")//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CFilterTestApp : public AcRxArxApp {public:CFilterTestApp () : AcRxArxApp () {}virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {// TODO: Load dependencies here// You *must* call On_kInitAppMsg hereAcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;// TODO: Add your initialization code herereturn (retCode) ;}virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {// TODO: Add your code here// You *must* call On_kUnloadAppMsg hereAcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;// TODO: Unload dependencies herereturn (retCode) ;}virtual void RegisterServerComponents () {}// The ACED_ARXCOMMAND_ENTRY_AUTO macro can be applied to any static member // function of the CFilterTestApp class.// The function should take no arguments and return nothing.//// NOTE: ACED_ARXCOMMAND_ENTRY_AUTO has overloads where you can provide resourceid and// have arguments to define context and command mechanism.// ACED_ARXCOMMAND_ENTRY_AUTO(classname, group, globCmd, locCmd, cmdFlags, UIContext)// ACED_ARXCOMMAND_ENTRYBYID_AUTO(classname, group, globCmd, locCmdId, cmdFlags, UIContext)// only differs that it creates a localized name using a string in the resource file//   locCmdId - resource ID for localized command// Modal Command with localized name// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyCommand, MyCommandLocal, ACRX_CMD_MODAL)static void MyGroupMyCommand () {// Put your command code here}// Modal Command with pickfirst selection// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET)static void MyGroupMyPickFirst () {ads_name result ;int iRet =acedSSGet (ACRX_T("_I"), NULL, NULL, NULL, result) ;if ( iRet == RTNORM ){// There are selected entities// Put your command using pickfirst set code here}else{// There are no selected entities// Put your command code here}}// Application Session Command with localized name// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MySessionCmd, MySessionCmdLocal, ACRX_CMD_MODAL | ACRX_CMD_SESSION)static void MyGroupMySessionCmd () {// Put your command code here}//添加输入点过滤器static void MyGroupAddFilter(){curDoc()->inputPointManager()->registerPointFilter( &MyFilter);acutPrintf( _T("输入点过滤器已添加到本文档中.\n") );}//移除输入点过滤器static void MyGroupRemoveFilter(){if ( NULL != curDoc()->inputPointManager()->currentPointFilter() ){curDoc()->inputPointManager()->revokePointFilter();acutPrintf( _T("输入点过滤器已从本文档中移除.\n") );}}// The ACED_ADSFUNCTION_ENTRY_AUTO / ACED_ADSCOMMAND_ENTRY_AUTO macros can be applied to any static member // function of the CFilterTestApp class.// The function may or may not take arguments and have to return RTNORM, RTERROR, RTCAN, RTFAIL, RTREJ to AutoCAD, but use// acedRetNil, acedRetT, acedRetVoid, acedRetInt, acedRetReal, acedRetStr, acedRetPoint, acedRetName, acedRetList, acedRetVal to return// a value to the Lisp interpreter.//// NOTE: ACED_ADSFUNCTION_ENTRY_AUTO / ACED_ADSCOMMAND_ENTRY_AUTO has overloads where you can provide resourceid.//- ACED_ADSFUNCTION_ENTRY_AUTO(classname, name, regFunc) - this example//- ACED_ADSSYMBOL_ENTRYBYID_AUTO(classname, name, nameId, regFunc) - only differs that it creates a localized name using a string in the resource file//- ACED_ADSCOMMAND_ENTRY_AUTO(classname, name, regFunc) - a Lisp command (prefix C:)//- ACED_ADSCOMMAND_ENTRYBYID_AUTO(classname, name, nameId, regFunc) - only differs that it creates a localized name using a string in the resource file// Lisp Function is similar to ARX Command but it creates a lisp // callable function. Many return types are supported not just string// or integer.// ACED_ADSFUNCTION_ENTRY_AUTO(CFilterTestApp, MyLispFunction, false)static int ads_MyLispFunction () {//struct resbuf *args =acedGetArgs () ;// Put your command code here//acutRelRb (args) ;// Return a value to the AutoCAD Lisp Interpreter// acedRetNil, acedRetT, acedRetVoid, acedRetInt, acedRetReal, acedRetStr, acedRetPoint, acedRetName, acedRetList, acedRetValreturn (RTNORM) ;}} ;//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CFilterTestApp)ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyCommand, MyCommandLocal, ACRX_CMD_MODAL, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MySessionCmd, MySessionCmdLocal, ACRX_CMD_MODAL | ACRX_CMD_SESSION, NULL)
ACED_ADSSYMBOL_ENTRY_AUTO(CFilterTestApp, MyLispFunction, false)//向CAD中注册“AddFilter”命令
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, AddFilter, AddFilter, ACRX_CMD_MODAL, NULL)//向CAD中注册“RemoveFilter”命令
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, RemoveFilter,RemoveFilter, ACRX_CMD_MODAL, NULL)

2.1.4 实现效果

编译运行程序,启动AutoCAD2016,在窗口中绘制直线和园,并添加生成的FilterTest.arx文件。执行AddFilter命令,将光标移动到直线和圆附近,就能在图形窗口中看到如图下所示的提示。执行RemoveFilter命令,将光标移动到直线和圆附近,提示恢复原状。

2.2 使用AcEdInputPointFilter实现

使用AcEdInputPointMonitor完成这个功能需要的基本流程包括:

  1. 创建一个从AcEdInputPointMonitor类继承的子类,重写monitorInputPoint函数;
  2. 需要启动实体信息动态提示时,为当前文档添加输入点监视器,处理的对象就是从AcEdInputPointMonitor类继承的子类;
  3. 需要关闭实体动态提示时,为当前的文档删除输入点监视器。

2.2.1 创建工程

在VS2012中创建一个名为MonitorTest的工程,并添加一个名为CPointMonitorSample的类。

2.2.2 改写CPointMonitorSample类

将CPointMonitorSample类改写为一个从AcEdInputPointMonitor类继承的子类,并添加和重写成员函数。
头文件CPointMonitorSample.h的内容为:

#pragma once
class CPointMonitorSample : public AcEdInputPointMonitor
{virtual Acad::ErrorStatus monitorInputPoint(bool& appendToTooltipStr, ACHAR*& additionalTooltipString, AcGiViewportDraw* drawContext, AcApDocument* document, bool pointComputed, int history, const AcGePoint3d& lastPoint, const AcGePoint3d& rawPoint, const AcGePoint3d& grippedPoint, const AcGePoint3d& cartesianSnappedPoint, const AcGePoint3d& osnappedPoint, AcDb::OsnapMask osnapMask, const AcArray<AcDbCustomOsnapMode*>& customOsnapModes, AcDb::OsnapMask osnapOverrides, const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides, const AcArray<AcDbObjectId>& apertureEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedApertureEntities, const AcArray<Adesk::GsMarker>& gsSelectionMark, const AcArray<AcDbObjectId>& keyPointEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities, const AcArray<Adesk::GsMarker>& keyPointGsSelectionMark, const AcArray<AcGeCurve3d*>& alignmentPaths, const AcGePoint3d& computedPoint, const ACHAR* tooltipString);
public:// 弧度转角度static double RadianToAngle(double radian);// 获得PI的值static double PI();};

源文件CPointMonitorSample.cpp的内容为:

#include "stdafx.h"
#include "PointMonitorSample.h"Acad::ErrorStatus CPointMonitorSample::monitorInputPoint(bool& appendToTooltipStr, ACHAR*& additionalTooltipString, AcGiViewportDraw* drawContext, AcApDocument* document, bool pointComputed, int history, const AcGePoint3d& lastPoint, const AcGePoint3d& rawPoint, const AcGePoint3d& grippedPoint, const AcGePoint3d& cartesianSnappedPoint, const AcGePoint3d& osnappedPoint, AcDb::OsnapMask osnapMask, const AcArray<AcDbCustomOsnapMode*>& customOsnapModes, AcDb::OsnapMask osnapOverrides, const AcArray<AcDbCustomOsnapMode*>& customOsnapOverrides, const AcArray<AcDbObjectId>& apertureEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedApertureEntities, const AcArray<Adesk::GsMarker>& gsSelectionMark, const AcArray<AcDbObjectId>& keyPointEntities, const AcArray< AcDbObjectIdArray, AcArrayObjectCopyReallocator< AcDbObjectIdArray > >& nestedKeyPointEntities, const AcArray<Adesk::GsMarker>& keyPointGsSelectionMark, const AcArray<AcGeCurve3d*>& alignmentPaths, const AcGePoint3d& computedPoint, const ACHAR* tooltipString)
{// 一定要注意检查缓冲区的大小,避免越界导致的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, CPointMonitorSample::RadianToAngle(angle));_tcscat(mtooltipStr, tempStr);}else if (pEnt->isKindOf(AcDbCircle::desc())){// 实体类型信息if (_tcslen(mtooltipStr) > 0){_tcscpy(mtooltipStr, TEXT("圆:"));}else{_tcscpy(mtooltipStr, TEXT("\n圆:"));}// 实体详细信息AcDbCircle* pCircle = AcDbCircle::cast(pEnt);double radius = pCircle->radius();double area = CPointMonitorSample::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;}}// 显示其他的提示内容appendToTooltipStr = true;additionalTooltipString = mtooltipStr;return Acad::eOk;
}double CPointMonitorSample::RadianToAngle(double radian)
{return radian * 180 / CPointMonitorSample::PI();
}double CPointMonitorSample::PI()
{return atan(1.0) * 4;
}

2.2.3 改写入口点函数

在入口点函数acrxEntryPoint.cpp中分别注册两个命令AddMonitorRemoveMonitor,分别用于在文档中添加和移除输入点过滤器。入口点函数acrxEntryPoint.cpp的文件内容为:

//-----------------------------------------------------------------------------
//----- acrxEntryPoint.cpp
//-----------------------------------------------------------------------------
#include "StdAfx.h"
#include "resource.h"
#include "PointMonitorSample.h"CPointMonitorSample MyMonitor;//-----------------------------------------------------------------------------
#define szRDS _RXST("")//-----------------------------------------------------------------------------
//----- ObjectARX EntryPoint
class CFilterTestApp : public AcRxArxApp {public:CFilterTestApp () : AcRxArxApp () {}virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {// TODO: Load dependencies here// You *must* call On_kInitAppMsg hereAcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;// TODO: Add your initialization code herereturn (retCode) ;}virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {// TODO: Add your code here// You *must* call On_kUnloadAppMsg hereAcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;// TODO: Unload dependencies herereturn (retCode) ;}virtual void RegisterServerComponents () {}// The ACED_ARXCOMMAND_ENTRY_AUTO macro can be applied to any static member // function of the CFilterTestApp class.// The function should take no arguments and return nothing.//// NOTE: ACED_ARXCOMMAND_ENTRY_AUTO has overloads where you can provide resourceid and// have arguments to define context and command mechanism.// ACED_ARXCOMMAND_ENTRY_AUTO(classname, group, globCmd, locCmd, cmdFlags, UIContext)// ACED_ARXCOMMAND_ENTRYBYID_AUTO(classname, group, globCmd, locCmdId, cmdFlags, UIContext)// only differs that it creates a localized name using a string in the resource file//   locCmdId - resource ID for localized command// Modal Command with localized name// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyCommand, MyCommandLocal, ACRX_CMD_MODAL)static void MyGroupMyCommand () {// Put your command code here}// Modal Command with pickfirst selection// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET)static void MyGroupMyPickFirst () {ads_name result ;int iRet =acedSSGet (ACRX_T("_I"), NULL, NULL, NULL, result) ;if ( iRet == RTNORM ){// There are selected entities// Put your command using pickfirst set code here}else{// There are no selected entities// Put your command code here}}// Application Session Command with localized name// ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MySessionCmd, MySessionCmdLocal, ACRX_CMD_MODAL | ACRX_CMD_SESSION)static void MyGroupMySessionCmd () {// Put your command code here}//添加输入点监视器static void MyGroupAddMonitor(){curDoc()->inputPointManager()->addPointMonitor( &MyMonitor);acutPrintf( _T("输入监视器已添加到本文档中.\n") );}//移除输入点监视器static void MyGroupRemoveMonitor(){curDoc()->inputPointManager()->removePointMonitor( &MyMonitor);acutPrintf( _T("输入点监视器已从本文档中移除.\n") );}// The ACED_ADSFUNCTION_ENTRY_AUTO / ACED_ADSCOMMAND_ENTRY_AUTO macros can be applied to any static member // function of the CFilterTestApp class.// The function may or may not take arguments and have to return RTNORM, RTERROR, RTCAN, RTFAIL, RTREJ to AutoCAD, but use// acedRetNil, acedRetT, acedRetVoid, acedRetInt, acedRetReal, acedRetStr, acedRetPoint, acedRetName, acedRetList, acedRetVal to return// a value to the Lisp interpreter.//// NOTE: ACED_ADSFUNCTION_ENTRY_AUTO / ACED_ADSCOMMAND_ENTRY_AUTO has overloads where you can provide resourceid.//- ACED_ADSFUNCTION_ENTRY_AUTO(classname, name, regFunc) - this example//- ACED_ADSSYMBOL_ENTRYBYID_AUTO(classname, name, nameId, regFunc) - only differs that it creates a localized name using a string in the resource file//- ACED_ADSCOMMAND_ENTRY_AUTO(classname, name, regFunc) - a Lisp command (prefix C:)//- ACED_ADSCOMMAND_ENTRYBYID_AUTO(classname, name, nameId, regFunc) - only differs that it creates a localized name using a string in the resource file// Lisp Function is similar to ARX Command but it creates a lisp // callable function. Many return types are supported not just string// or integer.// ACED_ADSFUNCTION_ENTRY_AUTO(CFilterTestApp, MyLispFunction, false)static int ads_MyLispFunction () {//struct resbuf *args =acedGetArgs () ;// Put your command code here//acutRelRb (args) ;// Return a value to the AutoCAD Lisp Interpreter// acedRetNil, acedRetT, acedRetVoid, acedRetInt, acedRetReal, acedRetStr, acedRetPoint, acedRetName, acedRetList, acedRetValreturn (RTNORM) ;}} ;//-----------------------------------------------------------------------------
IMPLEMENT_ARX_ENTRYPOINT(CFilterTestApp)ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyCommand, MyCommandLocal, ACRX_CMD_MODAL, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MyPickFirst, MyPickFirstLocal, ACRX_CMD_MODAL | ACRX_CMD_USEPICKSET, NULL)
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, MySessionCmd, MySessionCmdLocal, ACRX_CMD_MODAL | ACRX_CMD_SESSION, NULL)
ACED_ADSSYMBOL_ENTRY_AUTO(CFilterTestApp, MyLispFunction, false)//向CAD中注册“AddMonitor”命令
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, AddMonitor, AddMonitor, ACRX_CMD_MODAL, NULL)//向CAD中注册“RemoveMonitor”命令
ACED_ARXCOMMAND_ENTRY_AUTO(CFilterTestApp, MyGroup, RemoveMonitor,RemoveMonitor, ACRX_CMD_MODAL, NULL)

2.2.4 实现效果

编译运行程序,启动AutoCAD2016,在窗口中绘制直线和园,并添加生成的MonitorTest.arx文件。执行AddMonitor命令,将光标移动到直线和圆附近,就能在图形窗口中看到如图下所示的提示。执行RemoveMonitor命令,将光标移动到直线和圆附近,提示恢复原状。

3 总结

  • 使用AcEdInputPointFilter和AcEdInputPointMonitor反应器,都能实现光标提示功能,二者的功能类似,不同之处在于AcEdInputPointMonitor无法更改点,工具提示字符串,或要求系统重试。
  • 在新版本的ObjectARX SDK中,AcEdInputPointFilter和AcEdInputPointMonitor分别增加了一种重载形式,并定义了3个类。使用新的重载形式可以更加简便地(篇幅上)实现以上功能。
//新增的重载形式
ACAD_PORT virtual Acad::ErrorStatus monitorInputPoint(const AcEdInputPoint& input, AcEdInputPointMonitorResult& output);
ACAD_PORT virtual Acad::ErrorStatus processInputPoint(const AcEdInputPoint& input, AcEdInputPointFilterResult& output);//新增的3个类
class AcEdInputPoint;
class AcEdInputPointFilterResult;
class AcEdInputPointMonitorResult;

4 源代码

链接: https://pan.baidu.com/s/1FvaCZeszoTDZmTWO80Rp7w
提取码:uj7l

参考文档
[1]:Autodesk ObjectARX for AutoCAD 2015: Developer Guide.
[2]:AutoCAD ObjectARX(VC) 开发基础与实例教程.

ObjectARX开发笔记(一)——分别使用AcEdInputPointFilter和AcEdInputPointMonitor实现光标提示功能相关推荐

  1. ObjectArx开发笔记(二)---命令注册、表结构

    目录 一.注册AutoCAD命令 二.CAD表结构 2.1 ObjectARX类 三.常见类库初识 3.1 AcRx库 3.2 AcEd库 3.3 AcDb库 3.4 AcGi库 3.5 AcGe库 ...

  2. 【unity 保卫星城】--- 开发笔记04(武器管理系统)

    [unity 保卫星城]--- 开发笔记 六.完善类图中的类的功能 3.武器管理的类 4.武器抽象类 六.完善类图中的类的功能 3.武器管理的类 using System.Collections; u ...

  3. 【unity 保卫星城】--- 开发笔记03(飞机类第一版)

    [unity 保卫星城]--- 开发笔记 六.完善类图中的类的功能 2.飞机的类 六.完善类图中的类的功能 2.飞机的类 先放到这后面再慢慢完善~ using System.Collections; ...

  4. 【unity 保卫星城】--- 开发笔记02(陀螺仪移动)

    [unity 保卫星城]--- 开发笔记 六.完善类图中的类的功能 1.飞机移动模块 第二版(完善了陀螺仪移动) 六.完善类图中的类的功能 1.飞机移动模块 第二版(完善了陀螺仪移动) using S ...

  5. 运维开发笔记整理-前后端分离

    运维开发笔记整理-前后端分离 作者:尹正杰  版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.为什么要进行前后端分离 1>.pc, app, pad多端适应 2>.SPA开发式的流 ...

  6. iOS开发笔记-两种单例模式的写法

    iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h"st ...

  7. 【Visual C++】游戏开发笔记十三 游戏输入消息处理(二) 鼠标消息处理

    本系列文章由zhmxy555编写,转载请注明出处. http://blog.csdn.net/zhmxy555/article/details/7405479 作者:毛星云    邮箱: happyl ...

  8. 【Visual C++】游戏开发笔记二十七 Direct3D 11入门级知识介绍

    游戏开发笔记二十七 Direct3D 11入门级知识介绍 作者:毛星云    邮箱: happylifemxy@163.com    期待着与志同道合的朋友们相互交流 上一节里我们介绍了在迈入Dire ...

  9. Android移动APP开发笔记——最新版Cordova 5.3.1(PhoneGap)搭建开发环境

    引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地AP ...

最新文章

  1. referer 访问控制
  2. python就业方向有哪些-Python如何零基础入门?就业方向有哪些?
  3. 四川启动西南知识产权大数据中心合作共建工作
  4. @Value获取值和@ConfigurationProperties获取值比较||配置文件注入值数据校验
  5. Nginx负载均衡常用配置
  6. 首帧秒开+智能鉴黄+直播答题,阿里云直播系统背后技术大起底
  7. StretchDIBits速度测试(COLORONCOLOR)
  8. 高效工作-使用石墨文档进行信息收集
  9. 酸性溶液中HER动力学分析
  10. 成人大专计算机试题,2021成人大专数学模拟试题及参考答案
  11. 清火茶疗方 食疗灭四火
  12. 对比学习(contrastive learning)
  13. 九个Web开发者必备的软技能
  14. 信息系统项目管理师核心考点(五十五)配置管理员(CMO)的工作
  15. PS练习2——相扣的五环
  16. 爬虫----dex2jar工具的安装与使用
  17. atoi和itoa的模拟实现
  18. ABA-->狸猫换太子之法
  19. 奇点临近:互联网经济的供给侧革命和全球货币政策的新格林斯潘之谜
  20. 【史上最骚爬虫|疯狂爬取中国大学mooc】太燃了,爬虫vs慕课反爬世纪大战|No.1

热门文章

  1. BIOS INT 10中断功能详解
  2. 网易云热歌榜评论(爬虫项目)
  3. qemu-system-x86_64: warning: host doesn‘t support requested feature: CPUID.80000001H:ECX.svm [bit 2]
  4. 蚂蚁金服副总谈区块链
  5. Table里td中的文本过长,设置不换行,随内容同行显示
  6. VR和AR可以怎样干掉智能手机
  7. 课程设计 齿轮油泵泵体的机械加工工艺规程及工艺夹具装备设计
  8. 免费好用的APP你值得一试
  9. 莫纳什大学计算机工程,莫纳什大学计算机系统工程专业本科.pdf
  10. [java] JavaMail发送邮件