设为首页收藏本站

中国膜结构网

 找回密码
 立即注册
膜结构车棚
膜结构车棚膜结构资质国产膜材 膜结构网中国膜结构协会
查看: 105|回复: 0

arx的一些心得

[复制链接]
  • TA的每日心情
    开心
    2020-10-20 17:08
  • 签到天数: 1320 天

    连续签到: 3 天

    [LV.10]以坛为家III

    发表于 2020-9-20 17:57 | 显示全部楼层 |阅读模式


    Arx学习心得
    1.  2009年5月14日星期四
    ACHAR的初始化应该采用
    ACHAR char1[] =  _T( "初始化");
    ACHAR *char2;
    char2 = _T( "初始化");
    的格式,其中因为AutoCAD定义的ACHAR为
              typedef wchar_t ACHAR;
    因此ACHAR就具备了wchar_t的属性了,根据这点,有以下函数可以调用,分别是:
         WCSCAT------------------------ACHAR的合并
         WCSCPY------------------------ACHAR的复制
         WCSLEN------------------------ACHAR的长度
         _tcscmp------------------------代替strcmp,比较ACHAR
         StrCpy---------------------------代替strcpy,跟WCSCPY一样

    2.  2009年5月15日星期五
    对于vlsip中的getpoint来说,可以提示一些东西,比如:
              (setq ptInsert (getpoint (strcat “\n输入下一点/或S进行字高设定” (atoi zigao)))
    来提示在获取点的等待中的字高值,但是在ObjectArx中,却不能这么做,这里牵涉到一个非常好用,但上手有点模糊的东西——格式说明符。
         之前模仿过一个
              acutPrintf( _T(“\n当前的字高是:%.2f”, zigao);
    我以为这个可以在acedGetPoint中用到,
              Retcode = acedGetPoint( NULL, ( _T(“\n当前的字高是:%d”, zigao), ptInsert);
    但上面的代码是错误的,总是提示不能转换。相关的资料也没有说对arx08等支持UNICODE的格式说明。
         我用
              ACHAR prompt[] = ( _T(“\n当前的字高是:%.2f”, zigao);
              Retcode = acedGetPoint( NULL, prompt, ptInsert);
    这样也是不行的。
         幸亏有人帮忙,指出合适的操作方法,方法如下
                  CString str;
              str.Format(_T("\n指定一点或输入<S>设置字高:%.2f"), scaleFactor);
              Retcode = acedGetPoint( NULL, str, ptInsert);
    这样就可以了,看来arx的文字格式说明符的确用途很广。
    3.  2009年5月25日星期一
    关于默认输入的问题
    本来在lisp中,一个变量可以在内存中存在是很简单就可以实现的,如以下的内容就很简单:
    (setq aaa ‘1.0)
    这样aaa变量就可以在这个图形中存在,直到这个图形关闭为止。
    可是在ObjectARX中,如何实现倒是个非常麻烦的事情,因为我不知道怎么搞。在摸索一段时间后,终于明白和实现这部分内容了。以下是步骤:
    在CDocData类的头文件中加入一个变量,这里我以ads_real为例。
    class CDocData {
    public:
         ads_real myReal;
         CDocData () ;
         CDocData (const CDocData &data) ;
         ~CDocData () ;
    } ;
             然后在CDocData类的实现文件中添加默认值:
    CDocData::CDocData(const CDocData &data) {
         ads_real myReal = 1.5;
    }
                      这样就可以用这个全局变量了,下面是测试的函数:
         static voidralftt_rrr(void)
         {
             ads_real oldReal;
             ads_real newReal;
             ads_real inputReal;
             int retcode;
             oldReal = DocVars.docData().myReal; //这里获取了在CDocData中的MyReal值。
             
             if ( oldReal < 0.00000000001 ) //这里实际就是确认原始数是否为0
             {
                  oldReal = 1.5;
             }
             CString prompt;
             prompt.Format(_T( "\n当前的real是:%.2f,\n输入新的real:"), oldReal );
             retcode = acedGetReal( prompt,&newReal );
             if ( retcode == RTNORM )
             {
                  DocVars.docData().myReal = newReal;//这里将参数返回到全局变量中。
             }
             
         }

    4.  2009年5月26日星期二
    关于使用acdbOpenObject
    今天想使用acdbOpenObject来打开一个AcDbObjectId,但是怎么编译都不成功,原来是在说明指针的时候不对。
    AcDbBlockReference blkRef;
    acdbOpenObject( blkRef, blkId, AcDb::kforWrite );
    blkRef->erase( true );
    上面的代码怎么看都是对的,但就是不能被编译,最后查明问题,就是在说明指针的时候没有使用间接引用,将第一句改为
         AcDbBlockReference *blkRef;
    这样就可以了,指针虽然是C++里面最好的东西,但掌握的时候却非常麻烦,学习的时候已经异常花时间去掌握,可是在使用的时候总是忽略,这是亟待解决的问题。
    5.  2009年6月15日星期一
    如何统计曲线长度的问题
    关于曲线长度的计算,原以为有相关函数可以用来直接获得,但查阅了ARX的参考手册,却并没有发现这“应该有”的函数。如果是线段倒是简单,先获得起点坐标,再获得终点的坐标,然后利用distance函数来计算线段的长度。可是对于圆弧、多线段等几何图形来讲,却不能用此方法,因为这些图形的长度跟平面中的路径有关。以下是解决方法:
    圆弧、多线段、线段等都属于acdbcurve类,这个类里面几个函数:
    pCurve->getEndParam( endParam );
    pCurve->getDistAtParam( endParam, length );
    上面第一句是获得曲线终点的参数endParam,根据参考的描述,就是:
    The implementation of thisfunction in derived classes should return with endParam set to the parameter ofthe endpoint of the curve.
    即是:在衍生类中使用这个函数,可以返回这曲线的终点参数。其实点在本段曲线的参数实际上就是从本段起点到参考点的长度与曲线总长的比。如果是复杂曲线,就以像2.50形式存在,其中2表示该段在曲线中是第三段曲线,0.50表示该段起点到参考点的长度与该段曲线长度的比为0.50。(线段的参数就是从起点到该参考点的长度)
    第二句是获得曲线的长度,endParam是终点参数,length是曲线长度。
    file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
    getDistAtParam是获得曲线起点至参考点间的曲线长度,也就是说,当refParam与endParam为同一点时,将获得曲线的全部长度。获得指定一点的曲线上点的参数可使用函数getParamAtPoint来获取。
    6.  2010年7月9日星期五
    使用sendStringtoExecute(pDoc, _T(“\003”) )可以清除当前已经选中的实体。
    7. 2010年10月10日星期日
    使用钩子
    使用钩子关键是灵活使用ARX提供的2个函数acedRegisterFilterWinMsg及acedRemoveFilterWinMsg
    以下是基本代码:
    H
    static BOOL registerHook();                //这里是注册钩子
        static BOOL removeHook();                 //这里是移除钩子
        static BOOL callback( MSG *msg );         //这里是回调函数

    CPP
    BOOL rLockLayerHook::registerHook()
    {
        return acedRegisterFilterWinMsg(rLockLayerHook::callback);
    }
    BOOL rLockLayerHook::removeHook()
    {
        return acedRemoveFilterWinMsg(rLockLayerHook::callback);
    }
    BOOL rLockLayerHook::callback(MSG *msg )
    {
        if ( msg->message != WM_KEYDOWN)  //WM_KEYDOWN为需要监视消息
        {
           return FALSE;                   //这里FALSE,表示钩子不会再发送这个消息到cad那里去
        }
        return TRUE;                       //TRUE,钩子失效,发送监视消息到cad那里去
    }
    8. 2012年4月20日星期五
    file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image003.png
    这个其实就是个comboBox,mfc ex的基类就是CacUiColorComboBox或者是CacUiTrueColorComboBox,区别在于后者在选其他颜色的时候,会出现一个真彩色的选项。弄好基类后,就要在comboBox上设置属性,其中style是droplist,owner draw是fixed,has string是true,之后就OK了
    9. 2012年4月27日星期五
        使用 objectARX 函数 acedGetRGB(int color) 可以将cad的颜色索引(ACI)转换成对应的RGB颜色值。
        也可以通过使用AcCmEntityColor来进行转换。
    10.2012年9月27日星期四
    在各vs版本中,为保持项目工程的一致性,可以将各版本的源文件放置与同一个文件夹里面,这样可以在vs编译的时候迅速优化各个工程,但是必须手动在各个vs版本中添加各个新建的项目,及新的资源h和脚本文件
    11.2012年11月23日星期五
    从网站上抄的,移除xdata
    Thefollowing ObjectARX / Lisp code removes XData that is attached to an entityregardless of the APPNAME. Use it with caution and only if you need to do this,since removing XData from an entity without considering the appname may cause plug-insthat rely on them to misbehave.
    Hereis the ObjectARX code :
    staticvoid AdskTestCommand(void)
    {
       ads_name eNam;
       ads_point pt;
        intret;
        ret =acedEntSel(ACRX_T("\nPick an entity :"), eNam, pt);
        if(RTNORM != ret)
           return;

       AcDbObjectId ObjId;
       acdbGetObjectId(ObjId, eNam);

       AcDbEntity *pEnt = NULL;
       Acad::ErrorStatus es
               =acdbOpenAcDbEntity(pEnt, ObjId, AcDb::kForWrite);

       resbuf *xdata = pEnt->xData(NULL);
        if(xdata)
        {
            xdata->rbnext= NULL;
           pEnt->setXData(xdata);
           acutRelRb(xdata);
        }
       pEnt->close();
    }
    Hereis the Lisp code:
    (defun celXdata()
    (setq l (car (entsel "ick object:")))
    (if l (progn
         (redraw l 3)
         (setq le (entget l '("*")) )
         (setq xdata (assoc '-3 le))
         (setq le
               (subst (cons (car xdata) (list (list (car (car (cdr xdata))))))
    xdata le))
         (entmod le)
         (redraw l 4)
         le
        )
    )

    12.2012年11月23日星期五
    如何炸开文字
    Q:
    How to explode SHX based AcDbText entities to itsconstituent lines?
    A:
    You can “explode” or tessellate the text entity using theAcGiTextEngine::tessellate() method. But the method returns raw pointinformation which can be used to create individual lines. The method does nothonor the text style table properties and the text height, width are assumed tobe of one unit.
    To get the exact representation of an AcDbText entity, weneed to transform this raw point information depending upon the attributes ofthe text and its text style. In the attached sample, the functionfGeneratematrix() creates a transformation matrix which will place the linesdrawn using the points exactly at the text location. This transformation matrixwill take care of oblique angle, upside down, backward text properties.
    NOTE: the true type fonts are not supported.

    13.2012年12月19日星期三
    获取命令行的文字串
    // get the command line CWnd container
    CWnd* pDock =(CWnd*)acedGetAcadTextCmdLine();   
    // get the child window
    CWnd* pChild =pDock->GetWindow(GW_CHILD);   
    // loop while we have children
    while (pChild!=NULL)
    {      
    CString str;      
    // get thewindow text
    pChild->GetWindowText(str);      
    // if we don'thave any text
    if(str.GetLength() <= 0)
       pChild = pChild->GetNextWindow();   
    else
    {
       // display the text
       MessageBox(NULL, str);
       break;
    }
    }  
    14.2012年12月27日星期四
    创建一个非矩形的视口
    AcDbViewport::setNonRecClipEntityId()can be used to associate aviewport with an entity and enabling non-rectangular clipping is done throughAcDbViewport::setNonRectClipOn()
    For a clipping entity to be valid, itmust be contained in the same paperspace as the viewport entity and should beone of the entities as explained with ObjectARX help file. Please see thedocumentation for AcDbViewport::setNonRecClipEntityId() method for moredetails.
    The sample code snippet below creates anon-rectangular viewport of type circle and assign a specified view to thesame:
    void fCreateNonRectangularViewPort()
    {
    //____create thecircle
    ads_point centerPoint;
    if(RTNORM !=acedGetPoint(NULL,
    L"\nEnterthe Viewport center point:",centerPoint))
    return;
    ads_real radius;
    if(RTNORM !=acedGetDist(centerPoint,
    L"\nEnterthe radius of the Viewport:",&radius))
    return;
    ACHAR viewName[133];
       if (RTNORM != ads_getstring(0,
    L"\nEntername of view to use: ", viewName))
           return;
    AcDbCircle* pCircle = new AcDbCircle;
    //____assigningthe center point
    pCircle->setCenter(AcGePoint3d(centerPoint[X],centerPoint[Y],0));
    pCircle->setRadius(radius);
    AcDbBlockTable *pTable;
    AcDbBlockTableRecord *pRecord;
    if (Acad::eOk !=acdbHostApplicationServices()->
    workingDatabase()->getBlockTable(pTable, AcDb::kForRead)) {
    acutPrintf(L"\nCannot get block table.");
    delete pCircle;
    return;
    }
    if (Acad::eOk !=pTable->getAt(ACDB_PAPER_SPACE,
    pRecord,AcDb::kForWrite)) {
    acutPrintf(L"\nCannot access paper space.");
    pTable->close();
    delete pCircle;
    return;
    }
    pTable->close();
    AcDbObjectId circleId;
    if (Acad::eOk !=pRecord->appendAcDbEntity(circleId, pCircle)) {
    acutPrintf(L"\nCannot append circle to paper space.");
    pRecord->close();
    delete pCircle;
    return;
    }
    pRecord->close();
    pCircle->close();
    //____create theviewport entity
    AcDbViewport *pViewport = newAcDbViewport;
    //___assign thecenter point of circle
    //(since thevalue is known directly assigning)
    pViewport->setCenterPoint(AcGePoint3d(centerPoint[X],
    centerPoint[Y],0));   
    //___Append newviewport to the paper space
    if (Acad::eOk !=acdbHostApplicationServices()->
    workingDatabase()->getBlockTable(pTable, AcDb::kForRead)) {
    acutPrintf(L"\nCannot get block table.");
    deletepViewport;
    return;
    }
    if (Acad::eOk !=pTable->getAt(ACDB_PAPER_SPACE,
    pRecord,AcDb::kForWrite)) {
    acutPrintf(L"\nCannot access paper space.");
    pTable->close();
    deletepViewport;
    return;
    }
    pTable->close();
    AcDbObjectId viewportId;
    if (Acad::eOk !=pRecord->appendAcDbEntity(viewportId,
    pViewport)) {
    acutPrintf(L"\nCannot append viewport to paper space.");
    pRecord->close();
    deletepViewport;
    return;
    }
    pRecord->close();
    pViewport->setNonRectClipEntityId(circleId);
    pViewport->setNonRectClipOn();
    //___set theview
    AcDbViewTable *pViewTable;
    AcDbViewTableRecord *pView;
    if (Acad::eOk !=acdbHostApplicationServices()->
    workingDatabase()->getViewTable(pViewTable,
    AcDb::kForRead)) {
    acutPrintf(L"\nCannot get view table.");
    pViewport->close();
    return;
    }
    if (Acad::eOk !=pViewTable->getAt(viewName,
    pView,AcDb::kForRead)) {
    acutPrintf(L"\nCannot access view '%s'.", viewName);
    pViewport->close();
    pViewTable->close();
    return;
    }
    pViewTable->close();
    if(acedSetCurrentView(pView, pViewport)!=Acad::eOk)
    acutPrintf(L"\nFailed to set view");
    pViewport->setOn();
    pView->close();
    pViewport->close();
    //update thescreen such the viewport is updated
    acedCommand(RTSTR,L"_REGEN",RTNONE,0);
    }
    15.2012年12月27日星期四
    创建有端点导航的OPM
    The following snippets of code can be used to implement apolyline-like vertex edit in OPM (Object Property Manager) usingIOPMPropertyExpander interface for a custom entity.
    Lets assume the custom object (called AsDkRings) has twonew variables to reflect an array of vertices:
    AcGePoint3dm_polyline[5];  
    intm_numbervertices;
    For simplicity, lets say the custom entity has a maximum offive vertices.
    The custom class also has two corresponding accessfunctions. (Note the vertex number parameter):
    Acad::ErrorStatusAsDkRings::polyline(AcGePoint3d& vertex,
    intvertexNumber)
    Acad::ErrorStatusAsDkRings::setPolyline(AcGePoint3d vertex,
    intvertexNumber)
    In AsDkRings:: subWoldDraw(), we draw a polyline connectingthe five vertices.
    The key to getting a spin control in OPM is to return agrouping number. This number will determine the number of elements to grouptogether.
    //IOPMPropertyExpander
    STDMETHODIMPCRings::GetElementGrouping(
    /* [in] */ DISPIDdispID,
    /* [out] */ short *groupingNumber)
    {
    .............
      .............
    } else if (dispID ==5)
    {
      *groupingNumber= 4;
      return S_OK;
    }
    return E_NOTIMPL;
    }
    A grouping number of 4 means there is one entry (called"Vertex") plus 3 entries (Vertex X, Y and Z) to group together intoone property. What this would do is put a spin control into the first item(vertex in this case), so that this could be used to traverse an array of 3remaining grouped items (which is Vertex X, Y and Z).
    Next, we should specify the number of items that the propertyis going to display. Here this would be the number of vertices  = 5. Thiswould mean that the spin contol can go up to a maximum of 5 steps, for fivevertices.
    //IOPMPropertyExpander
    STDMETHODIMPCRings::GetGroupCount(
    /* [in] */ DISPIDdispID,
    /* [out] */ long*nGroupCnt)
    {
    ................
      ...............
    } else if (dispID ==5)
    {
      *nGroupCnt =m_numbervertices; // Number of vertices
      return S_OK;
    }
    return E_NOTIMPL;
    }
    Next, we set the string to display in the OPM.
    //IOPMPropertyExpander
    STDMETHODIMPCRings::GetElementStrings(
    /* [in] */ DISPIDdispID,
    /* [out] */OPMLPOLESTR __RPC_FAR *pCaStringsOut,
    /* [out] */ OPMDWORD__RPC_FAR *pCaCookiesOut)
    {
    ................................
    ................................
    } else if (dispID ==5)
    {
      // For theVertices
    pCaStringsOut->cElems = 4;
    pCaStringsOut->pElems = (LPOLESTR*)CoTaskMemAlloc(sizeof(LPOLESTR)*4);
    pCaStringsOut->pElems[0] = SysAllocString(L"Vertex");
    pCaStringsOut->pElems[1] = SysAllocString(L"Vertex X");
      pCaStringsOut->pElems[2]= SysAllocString(L"Vertex Y");
    pCaStringsOut->pElems[3] = SysAllocString(L"Vertex Z");
    pCaCookiesOut->cElems = 4;
    pCaCookiesOut->pElems = (DWORD*)CoTaskMemAlloc(sizeof(DWORD)*4);

    pCaCookiesOut->pElems[0] = 10;
    pCaCookiesOut->pElems[1] = 1;
    pCaCookiesOut->pElems[2] = 2;
    pCaCookiesOut->pElems[3] = 3;
      return S_OK;
    }
    return E_NOTIMPL;
    }
    The cookies count is the unique identifier for eachproperty item that will be used to get and set values. The table below willgive you an idea of cookie value for each vertex value. Please remember thatvertex entry has a spin control that goes like 1, 2, 3, 4.........and so on.
    Property String  CookieValue      
                    Vertex = 1    Vertex = 2   Vertex = 3  Vertex = 4  ....and so on        
    Vertex             0            4           8          12        ....and so on        
    Vertex X           1            5           9          13        ....and so on        
    Vertex Y           2            6          10           14       ....and so on        
    Vertex Z           3            7          11          15        ....and so on
    So just by using the cookie values, you must get the vertexnumber and find out if it is an x, y, or z coordinate. The following code doesthat.
    // Get the coordinateindex (x=0, y= 1, z=2) from dwCookie
    for (int i = 1; i< 4; i++) {
    vertex = (double(dwCookie)- i) / 4;
    if( vertex ==(double(dwCookie) - i) / 4) {
      index = i -1;
      break;
    }
    }

    indexwill return 0 for vertex X, 1 for vertex Y and 2 for vertex Z for thecorrosponding cookie values.
    So this is allthat is needed to implement a poly-line vertex edit.
    16.2012年12月27日星期四
    为实体创建一个自定义的捕捉点
    You can define a custom osnap like this:
    //-------------------------------------------------------------------
    // Osnap classes

    class MkrInfo : publicAcDbCustomOsnapInfo
    {
    public:
       ACRX_DECLARE_MEMBERS(MkrInfo);

        Acad::ErrorStatus  getOsnapInfo(
        AcDbEntity*          pickedObject,
        Adesk::GsMarker       gsSelectionMark,
        constAcGePoint3d&    pickPoint,
        constAcGePoint3d&    lastPoint,
        constAcGeMatrix3d&   viewXform,
        AcArray<AcGePoint3d>& snapPoints,
        AcDbIntArray &     geomIdsForPts,
        AcArray<AcGeCurve3d*>& snapCurves,
        AcDbIntArray &     geomIdsForLines);
    };



    ACRX_CONS_DEFINE_MEMBERS(MkrInfo,AcDbCustomOsnapInfo, 1);


    Acad::ErrorStatus
    MkrInfo::getOsnapInfo(
    AcDbEntity*          pickedObject,
    Adesk::GsMarker      gsSelectionMark,
    constAcGePoint3d&    pickPoint,
    constAcGePoint3d&    lastPoint,
    constAcGeMatrix3d&   viewXform,
    AcArray<AcGePoint3d>&snapPoints,
    AcDbIntArray&     geomIdsForPts,
    AcArray<AcGeCurve3d*>&snapCurves,
    AcDbIntArray&     geomIdsForLines
    )
    {
       AsDkCurve *p = AsDkCurve::cast(pickedObject);
        if (NULL !=p)
        {
           AcGeLineSeg3d *pls1 = new AcGeLineSeg3d;
      AcGePoint3dstartP, endP;
    p->startPoint(startP);
    p->m_endPoint(endP);
           pls1->set(startP, (endP - startP));
           snapCurves.append(pls1);

           AcGeLineSeg3d *pls2 = new AcGeLineSeg3d;
           pls2->set(endP, (endP - startP));
           snapCurves.append(pls2);
        }
        return Acad::eOk;
    }


    //static
    MkrInfo _mkrInfo;


    class MkrMode : publicAcDbCustomOsnapMode
    {
    public:
        const TCHAR*localModeString() const;
        const TCHAR*globalModeString() const;
        const AcRxClass*entityOsnapClass() const;
       AcGiGlyph* glyph() const;
        constTCHAR*              tooltipString() const;
    };

    const TCHAR*
    MkrMode::localModeString()const
    {
        return _T("XTNd");
    }

    const TCHAR*
    MkrMode::globalModeString()const
    {
        return _T("_XTNd");
    }

    const AcRxClass*
    MkrMode::entityOsnapClass()const
    {
        return MkrInfo::desc();
    }

    class MyGlyph : public AcGiGlyph
    {
    public:
       Acad::ErrorStatus setLocation(const AcGePoint3d& dcsPoint);
        voidsubViewportDraw(AcGiViewportDraw* vportDrawContext);
    private:
       AcGePoint3d m_point;
    };

    Acad::ErrorStatus
    MyGlyph::setLocation(constAcGePoint3d& dcsPoint)
    {
       m_point = dcsPoint;
        return Acad::eOk;
    }


    void
    MyGlyph::subViewportDraw(AcGiViewportDraw*p)
    {
        // notneeded for ext-like snaps
    }

    AcGiGlyph*
    MkrMode::glyph() const
    {
        static MyGlyphmg;
        return &mg;
    }

    const TCHAR*
    MkrMode::tooltipString()const
    {
        return _T("CustomExtend");
    }

    MkrMode _mkrMode;
    And you can register a custom osnap to associate with withan entity as follows:
    //Register protocolextension object (customOsnapInfo)
    MkrInfo::rxInit();
    acrxBuildClassHierarchy();
    AcDbEntity::desc()->addX(MkrInfo::desc(),&_mkrInfo);
    acdbCustomOsnapManager()->addCustomOsnapMode(&_mkrMode);
    And unregister as follows:
    //Remove protocolextension object
    acdbCustomOsnapManager()->removeCustomOsnapMode(&_mkrMode);
    AcDbEntity::desc()->delX(MkrInfo::desc());
    deleteAcRxClass(MkrInfo::desc());
    17.2013年1月16日星期三
    Jig多个实体
    Jig more than one entity with AcEdJig class in ObjectARXThe AcEdJig class only supports the update of one entityat a time. However, there is a useful trick you can use to jig more than oneentity in ObjectARX.
    To do this, you need to define a custom entity class anduse it as a *temporary* jig entity which will be used with to maintaina list of real entities that need to be jigged. You will use this custom entitywith your custom AcEdJig class to update your list of Jigged entities.Following this, you simply need to override the *temporary* jig entity'ssubWorldDraw() and inside it,  you can iterate through your recordedentities and call worldDraw() on each. This will give the impression ofmultiple entity update.
    Please find herea sample application (available for download and migrated to use ARX 2013libraries) which has been written in such a way that it will Jig any number ofentities. You can also provide your own input and update functions for entitythat is required to be jigged. Here is the relevant source:
    Header for Jig custom entity and and custom jigdeclaration:
    #ifndefASDKMULTIJIG__H
    #defineASDKMULTIJIG__H

    #endif //ASDKMULTIJIG__H

    ////////////////////////////////////////////////////////
    classasdkEntityList : public AcDbEntity
    {
    public:

    //constructor
    asdkEntityList ();
    //destructor
    ~asdkEntityList ();

    // flag toindicate that we have
    // assignedsome entities to the entity list
    boolm_calledSetEntityList;

    // array ofAcDbEntities
    AcDbVoidPtrArraym_entities;


    typedefAdesk::Boolean (*updateFunction) (int mode,
      asdkEntityList&entityList);
    // array ofupdate Functions
    AcArray<updateFunction>m_updateFuncs;

    // entityinput data
    AcArray<AcGePoint3d>m_pnts;

    // setswhat entities are to be jigged
    Acad::ErrorStatussetEntityList(
      constAcDbVoidPtrArray &entities);

    // loopthrough m_entities and display the data
    virtualAdesk::Boolean subWorldDraw(AcGiWorldDraw *wd);
    };

    /////////////////////////////////////////////////////////////
    classasdkMultiJig : public AcEdJig
    {
    public:
    //constructor
    asdkMultiJig ();
    //destructor
    ~asdkMultiJig ();

    // mode ofinput, starts at 0 then
    //increments until all entities have been
    // input,indexes m_entityList
    int m_mode;

    // classcontaining the list of entities to jig
    asdkEntityListm_entityList;
    ads_real m_distance;
    AcGePoint3dm_originalPnt;

    typedefAcEdJig:ragStatus
      (*inputFunction)(asdkMultiJig &jig);
    // array ofinput Functions
    AcArray<inputFunction>m_inputFuncs;

    // get thejig data
    virtualAcEdJig:ragStatus sampler();
    // returnthe jig entity
    virtual AcDbEntity*entity() const;
    // updatethe sampler data to the jig entity
    virtualAdesk::Boolean update();
    // add theobject to the space
    AcDbObjectIdappend(AcDbDatabase *dwg=NULL,
      const ACHAR*requiredSpace = ACDB_MODEL_SPACE);

    private:
    };

    Implementation of the custom jig and jig custom entity:
    #include "StdAfx.h"
    #include "StdArx.h"

    ///////////////////////////////////////////////////////
    Acad::ErrorStatuspostToDwg (AcDbEntity *pEnt,
    AcDbDatabase*pDb=NULL,
    const ACHAR*requiredSpace=ACDB_MODEL_SPACE);

    ///////////////////////////////////////////////////////
    // constructor
    asdkMultiJig::asdkMultiJig()
    {
    m_mode = 0;
    m_distance = 0.0;
    }
    ///////////////////////////////////////////////////////
    // destructor
    asdkMultiJig::~asdkMultiJig()
    {
    }
    ///////////////////////////////////////////////////////
    // get the jig data
    AcEdJig:ragStatusasdkMultiJig::sampler()
    {
    // set thecursor to invisible
    setSpecialCursorType(AcEdJig::kInvisible);

    // call theupdate function
    return ((*this->m_inputFuncs[m_mode])(*this));
    }
    ///////////////////////////////////////////////////////
    // return the jigentity
    AcDbEntity*asdkMultiJig::entity() const
    {
    // check tomake sure we called setEntityList
    if(!m_entityList.m_calledSetEntityList)
      AfxMessageBox(L"Error - You must call setEntityList \
      beforecalling asdkMultiJig::drag()");

    return (const_cast<asdkEntityList*>(&m_entityList));
    }

    ///////////////////////////////////////////////////////
    // update the samplerdata to the jig entity
    Adesk::BooleanasdkMultiJig::update()
    {
    // call theupdate function
    return ((*m_entityList.m_updateFuncs[m_mode])
      (m_mode, this->m_entityList));
    }
    ///////////////////////////////////////////////////////
    // add the object tothe space
    AcDbObjectIdasdkMultiJig::append(AcDbDatabase *dwg,
    const ACHAR*requiredSpace)
    {
    // get thetotal number of entities registered
    int length =m_entityList.m_entities.length ();
    // loopround the registered
    // entitiesand add the to the space
    for (int i=0;i<length; ++i)
    {
      postToDwg((AcDbEntity *)m_entityList.m_entities,
       dwg,requiredSpace);
    }

    // get theid of the first entity drawn
    AcDbObjectId id =
      ((AcDbEntity*)m_entityList.m_entities[0])->id ();

    // closethe entities added
    for (int i=0;i<length; ++i)
      ((AcDbEntity*)m_entityList.m_entities)->close ();
    // returnthe object id
    return (id);
    }
    ///////////////////////////////////////////////////////
    // constructor
    asdkEntityList::asdkEntityList()
    {
    m_calledSetEntityList= false;
    }
    ///////////////////////////////////////////////////////
    // destructor
    asdkEntityList::~asdkEntityList()
    {
    }
    ///////////////////////////////////////////////////////
    // set what entitiesare to be jigged
    Acad::ErrorStatusasdkEntityList::setEntityList (
    constAcDbVoidPtrArray &entities)
    {
    // recordthat we have called this function correctly
    m_calledSetEntityList= true;
    // setupour entity list
    m_entities = entities;
    // ifnothing in there then lets say!
    if(m_entities.length() == 0)
      returnAcad::eInvalidInput;
    // setupour point storage
    m_pnts.setLogicalLength(m_entities.length());
    // all ok
    return Acad::eOk;
    }
    ///////////////////////////////////////////////////////
    Adesk::BooleanasdkEntityList::subWorldDraw (AcGiWorldDraw * wd)
    {
    int length =m_entities.length ();
    // loop thenumber of entities in the entity list
    for (int i=0;i<length; ++i)
    {
      // lets getthe entity out
      AcDbEntity *ent= (AcDbEntity *)m_entities;
      // if ok
      if (ent !=NULL)
      {
       // thendraw it
      wd->geometry ().draw (ent);
      }
    }
    return(Adesk::kTrue);
    }
    ///////////////////////////////////////////////////////
    // adds an entity tothe required space...
    // default is currentdwg and ACDB_MODEL_SPACE.
    Acad::ErrorStatuspostToDwg (AcDbEntity *pEnt, AcDbDatabase *pDb,
    const ACHAR*requiredSpace)
    {
    // if thedefault database is to be used
    if (pDb ==NULL)
      pDb =acdbHostApplicationServices()->workingDatabase ();
    AcDbBlockTable*blockTable = NULL;
    // get apointer to the block table
    Acad::ErrorStatus es =pDb->getBlockTable (blockTable,
    AcDb::kForRead);
    // if itfailed then abort
    if (es !=Acad::eOk)
      return (es);
    AcDbBlockTableRecord*blockTableRecord = NULL;
    // now geta pointer to the model space entity records
    es =blockTable->getAt (requiredSpace,
    blockTableRecord, AcDb::kForWrite);
    // canclose the block table
    // itselfas we don't need it anymore
    blockTable->close();
    // if itfailed then abort
    if (es !=Acad::eOk)
      return (es);
    //otherwise put the entity into the model space
    es =blockTableRecord->appendAcDbEntity (pEnt);
    // nowclose it up
    blockTableRecord->close();
    return (es);
    }
    18.2013年1月31日星期四
    用ObjectARX取得当cad 截屏
    Capturinga Screen Shot using ObjectARXBy Fenton Webb
    Issue

    How to capture the screen shot of     a Viewport to save it to an image file?
    Is it possible to temporarily     display an image over the Viewport or alter the Viewport display?
    Solution
    There are two AcGs functions in ObjectARX SDK that can beused to get the screen shot of the specified Viewport in AutoCAD and also toset an image to be displayed in a specified Viewport.
    The functions are:

    acgsGetScreenShot()
    acgsDisplayImage()
    The function acgsGetScreenShot() will get you the pointerto an AcGsScreenShot object for the specified viewport number. When in TILEMODE1, just specify the Viewport that you are interested in or just specify “0” toget the entire ModelSpace (and same is the case with PaperSpace). Similarlyjust specify the Viewport number you are interested in if the TILEMODE is 0(i.e. in PaperSpace). Also if you specify viewport number of 1 in TILEMODE 0then you will get only the entities that exist in the PaperSpace.
    You can get the image data using the method getScanline()of the AcGsScreenShot class. Using this you can fill in an array of truecolorlong words which essentially will be the ARBG data. This data can be used tocreate an image file. You can use the ATIL SDK to create a bitmap or JPG easilyfrom the image data.
    The function acgsDisplayImage() on the other hand takes anarray of truecolor long words and displays the image at the specified locationon a specified Viewport. The image will stay till a redraw is called.
    This function can be used to:

    Show a temporary external image     quickly.
    Blank the entire view port     temporarily.
    Change the colors of the Viewport.     Say inverting the colors of the Viewport.
    Note:The acgsGetScreenShot() does not get you the shaded orrendered view.
    Here’s some code which shows how to use the functions, touse the Atil libs you need to link with the headers and libs in the Atil folderof the ObjectARX SDK:
    // by Fenton Webb,DevTech, 1/30/2013
    // screen shoots theview details as a BMP
    bool RecordViewDetails(double &fieldWidth, double &fieldHeight, AcGePoint3d &position, AcGePoint3d &target, AcGeVector3d &upVector, const TCHAR *imagePath)
    {
      int iVP = getCVPort();

      // Computethe viewport dimensions.
      int nLeft, nBottom, nRight, nTop;
      int iImageWidth, iImageHeight;
      acgsGetViewportInfo (iVP, nLeft, nBottom, nRight, nTop);

      iImageWidth  = nRight - nLeft + 1;
      iImageHeight = nTop - nBottom + 1;
      Atil::Size size(iImageWidth, iImageHeight);
      int nBytesPerRow = Atil:ataModel::bytesPerRow(iImageWidth,
                                   Atil:ataModelAttributes::k32);
      unsigned long nBufferSize = iImageHeight * nBytesPerRow;

      // Createan ATIL image for accepting the rendered image.
      std::auto_ptr<char> autoBuff = std::auto_ptr<char>(new char[nBufferSize]);
      char *pSnapshotData = autoBuff.get();  
      Atil::Image * pImage = NULL;
      // see ifthere is a GS view created
      AcGsView *pView = acgsGetGsView(iVP, false);
      // if not
      if (NULL == pView)
      {
        // then wemust be in 2D wireframe mode, so use acgsGetScreenShot
        std::auto_ptr<AcGsScreenShot> autoScreenShot(acgsGetScreenShot(iVP));
        AcGsScreenShot* screenShot = autoScreenShot.get(); // auto_ptrstill owns the pointer.
        if (screenShot)
        {
         int w = 0, h = 0, d = 0;
         screenShot->getSize(w, h, d);

         char* pBufTemp = pSnapshotData;
         for (int row = 0; row < h; row++)
         {
           memcpy(pBufTemp, screenShot->getScanline(0, row), nBytesPerRow);

           //convert from RGBA to BGRA
           char* pColor = pBufTemp;
           for (int i = 0; i < w; i++)   //Slow but it works
           {
             char temp = *pColor;
             *pColor = *(pColor + 2);
             *(pColor + 2) = temp;
             pColor += 4;
           }
           pBufTemp += nBytesPerRow;
         }
         pImage = constructAtilImg(reinterpret_cast<char*>(pSnapshotData),
                       nBufferSize, nBytesPerRow, w, h, 32, 0);
         std::auto_ptr<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage); // auto_ptrnow owns the image

         if (!writeImageFile(pImage, kBMP, imagePath))
         {
           acutPrintf(_T("\nFailedto write image file %s"), imagePath);
           return false;
         }
         else
           acutPrintf(_T("\nSuccessfullywritten %s"), imagePath);

        }

        return true;
      }
      else
      {
        return snapGSView(pView, iImageWidth, iImageHeight, fieldHeight, fieldWidth, position, target, upVector, imagePath);
      }
    }

    bool snapGSView(AcGsView *pView, int width, int height, double &fieldWidth, double &fieldHeight, AcGePoint3d &position, AcGePoint3d &target, AcGeVector3d &upVector, const TCHAR *imagePath)
    {
      Atil::Size size(width, height);
      int nBytesPerRow = Atil:ataModel::bytesPerRow(width, Atil:ataModelAttributes::k32);
      unsigned long nBufferSize = height * nBytesPerRow;

      // Createan ATIL image for accepting the rendered image.
      std::auto_ptr<char> apCharBuffer = std::auto_ptr<char>(new char[nBufferSize]);
      char *pSnapshotData = apCharBuffer.get();  // auto_ptr still owns the buffer.

      // inshaded mode (from GS)
      Atil::Image * pImage = NULL;
      pImage = constructAtilImg(pSnapshotData, nBufferSize, nBytesPerRow, width, height, 32, 0);
      std::auto_ptr<Atil::Image> autodeleter = std::auto_ptr<Atil::Image>(pImage); // auto_ptrnow owns the image
      pView->getSnapShot(pImage, AcGsDCPoint(0, 0));

      // add atemp image to invert the image. do we have a better way to turn an imagearound?
      Atil::Image imgTempForInverted(pImage->read(pImage->size(), Atil::Offset(0, 0), Atil::kBottomUpLeftRight));
      *pImage = imgTempForInverted;

      if (!writeImageFile(pImage, kBMP, imagePath))
      {
        acutPrintf(_T("\nFailedto write image file %s"), imagePath);
        return false;
      }
      else
        acutPrintf(_T("\nSuccessfullywritten %s"), imagePath);

      // recordthe view data
      fieldHeight = pView->fieldHeight();
      fieldWidth = pView->fieldWidth();
      position = pView->position();
      target = pView->target();
      upVector = pView->upVector();

      return true;
    }

    bool writeImageFile (Atil::Image *pImageSource, eFormatType formatType,
      wchar_t const *pFileName)
    {
      _ASSERT(NULL != pImageSource);
      if(NULL == pImageSource)
        return false;

      _ASSERT(pImageSource->isValid());
      if(!pImageSource->isValid())
        return false;

      if(PathFileExists(pFileName))
        DeleteFile(pFileName);

      /*if(PathFileExists(pFileName)){
    if(IsFileReadOnly(pFileName)) {
    RemoveReadonlyAttribute(pFileName);
    DeleteFile(pFileName);
      }
      }*/

      if(PathFileExists(pFileName))
        return false;

      Atil::RowProviderInterface* pPipe = pImageSource->read(pImageSource->size(),
        Atil::Offset(0,0));
      _ASSERTE(NULL != pPipe);
      if(!pPipe)
        return false;

      Atil::FileWriteDescriptor  *pFWD = NULL;
      Atil::ImageFormatCodec    *pCodec = NULL;

      if (formatType == kJPG)
        pCodec = new JfifFormatCodec();
      else if (formatType == kPNG)
        pCodec = new PngFormatCodec();
      else if (formatType == kTIF)
        pCodec = new TiffFormatCodec();
      else if (formatType == kBMP)
        pCodec = new BmpFormatCodec();

      _ASSERTE(NULL != pCodec);
      if(NULL == pCodec)
        return false;

      if(!Atil::FileWriteDescriptor::isCompatibleFormatCodec(pCodec,
       &(pPipe->dataModel()), pPipe->size())) {
         delete pCodec;
         return false;
      }

      pFWD = new Atil::FileWriteDescriptor(pCodec);
      _ASSERTE(NULL != pFWD);

    #ifdef UNICODE
    #ifndef _ADESK_MAC_
      Atil::FileSpecifier fs(Atil::StringBuffer((lstrlen(pFileName) + 1) * sizeof(TCHAR),
        (const Atil::Byte *) pFileName, Atil::StringBuffer::kUTF_16),
        Atil::FileSpecifier::kFilePath);
    #else
      Atil::FileSpecifier fs(Atil::StringBuffer((lstrlen(pFileName) + 1) * sizeof(TCHAR),
        (const Atil::Byte *) pFileName, Atil::StringBuffer::kUTF_32),
        Atil::FileSpecifier::kFilePath);

    #endif
    #else
      Atil::FileSpecifier fs(Atil::StringBuffer(lstrlen(pFileName) + 1,
        (const Atil::Byte *) pFileName, Atil::StringBuffer::kASCII),
        Atil::FileSpecifier::kFilePath);
    #endif

      if (!pFWD->setFileSpecifier(fs))
        return false;

      pFWD->createImageFrame(pPipe->dataModel(), pPipe->size());

      if (formatType == kPNG) {
        Atil::FormatCodecPropertyInterface* pProp = pFWD->getProperty(Atil::FormatCodecPropertyInterface::kCompression);
        if (pProp != NULL) {
         PngCompression* pPngComp = (PngCompression*)(pProp);
         if ( pPngComp != NULL ) {
           //Why not compress all we can?
           pPngComp->selectCompression(PngCompressionType::kHigh);
           pFWD->setProperty(pPngComp);
         }
         delete pProp;
         pProp = NULL;
        }
      }
      else if (formatType == kTIF) {
        Atil::FormatCodecPropertyInterface* pProp = pFWD->getProperty(Atil::FormatCodecPropertyInterface::kCompression);
        if (pProp != NULL) {
         TiffCompression* pComp = (TiffCompression*)(pProp);
         if ( pComp != NULL ) {
           //G4 is only valid for 1 bit images.
           if ( pComp->selectCompression(TiffCompressionType::kCCITT_FAX4) == false ) {
             //So if that fails, resort to LZW now that it is patent free
             if ( pComp->selectCompression(TiffCompressionType::kLZW) == false ) {
               //If that fails (and is shouldn't, be) then set none.
               pComp->selectCompression(TiffCompressionType::kNone);
             }
           }
           pFWD->setProperty(pComp);
         }
         delete pProp;
         pProp = NULL;
        }
      }
    // get the current vp
    int getCVPort()
    {
      struct resbuf rb;
      ads_getvar(_T("CVPORT"), &rb);
      return rb.resval.rint;
    }

    Atil:ataModel* colorSpace (char *&pRGBData, int colorDepth, int paletteSize)
    {
      _ASSERT(NULL != pRGBData);

      // Setup acolor space, with palette if needed
      Atil:ataModel *pDm = NULL;
      if (colorDepth == 8) {
        Atil::RgbColor space[256];

        Atil::RgbPaletteModel *pPM = new Atil::RgbPaletteModel();
        _ASSERT(NULL != pPM);
        if(!pPM)
         return NULL;

        pDm = pPM;
        char *palette = pRGBData;
        pRGBData += paletteSize;
        for (int i = 0; i < paletteSize; i += 4)
         space[i / 4] = Atil::RgbColor(palette[i+2],palette[i+1],palette, 255);
        pPM->setEntries(0, 256, (Atil::RgbColor *)&space);
      } else
        pDm = new Atil::RgbModel(32);


      _ASSERT(NULL != pDm);
      return pDm;
    }

    Atil::Image *constructAtilImg(char *pRGBData,
      unsigned long bufferSize, unsigned long rowBytes,
      unsigned long xSize, unsigned long ySize, int colorDepth, int paletteSize)
    {
      if ((8 != colorDepth)&& (32 != colorDepth))
      {
        return NULL;
      }

      if (paletteSize)
      {
        if ((paletteSize < 0) ||(paletteSize > 255))
        {
         return NULL;
        }
      }

      if ((xSize <= 0)|| (ySize <= 0))
      {
        return NULL;
      }

      Atil::Image *pImg = NULL;
      Atil::Size size(xSize, ySize);

      //construct the Atil::Image object
      if (pRGBData) {

        // Checkthe buffer for size and definition
        if (bufferSize) {
         if (!rowBytes) {
           return NULL;
         }

         //did they allocate enough?
         if (rowBytes * ySize > bufferSize) {
           return NULL;
         }
        }
        else {
         return NULL;
       }        

        Atil:ataModel *pM = colorSpace(pRGBData, colorDepth, paletteSize);
        _ASSERT(NULL != pM);
        if(NULL == pM)
         return NULL;

        try {
         //BEWARE: pRGBData may be moved in colorSpace
         pImg = new Atil::Image(pRGBData, bufferSize,
           rowBytes, size, pM);  
        } catch (Atil::ATILException* pExpCon) {
         //image construction failure
         delete pExpCon;
         delete pM;
         pImg = NULL;
         _ASSERT(FALSE);
         return NULL;
        }

        delete pM;
      }
      else {
        Atil::RgbModel    rgbM(32);
        Atil::RgbGrayModel gM;

        Atil::ImagePixel initialColor(colorDepth == 32 ?
         Atil:ataModelAttributes::kRgba :
        Atil:ataModelAttributes::kGray);
        initialColor.setToZero();

        try {
         pImg = new Atil::Image(size,
           colorDepth == 32 ?&rgbM : &gM,
           initialColor);
        } catch (Atil::ATILException* pExpCon) {
         //image construction failure
         delete pExpCon;
         pImg = NULL;
         _ASSERT(FALSE);
         return NULL;
        }
      }

      _ASSERT(NULL != pImg);
      return pImg;
    }

    bool getTempImgFile(TCHAR * fileName)
    {
      // Here wecreate a temp bmp file as a transitional file
      TCHAR tempDic[MAX_PATH];
      ::memset(tempDic,0,MAX_PATH);
      DWORD nRetSize = ::GetTempPath(MAX_PATH,tempDic);
      if (nRetSize > MAX_PATH || nRetSize == 0)
      {
        const TCHAR * tempStr = _T("C:\\temp");
        if (wcscpy_s(tempDic,tempStr) != 0)
        {
         return false;
        }

        if (:athFileExists(tempStr) == FALSE &&
         ::CreateDirectory(tempStr,NULL) == FALSE)
        {
         return false;
        }
      }

      // createthe temp file whose prefix is "img"
      if (::GetTempFileName(tempDic,_T("tmp"),0,fileName) == 0)
      {
        return false;
      }

      // now splitthe filepath into its individual components
      TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
      _tsplitpath (fileName, drive, dir, fname, ext);
      _stprintf(fileName, _T("%s%s%s.bmp"), drive, dir, fname);

      return true;
    }
    19.2013年6月8日星期六
    在文件搜索路径添加指定的目录
    void CRInit::addSupportPath(const CString&szNewPath )
    {
         const ACHAR* libPath= acdbHostApplicationServices()->getEnv( L"ACAD" );
         CString sysPath;
         sysPath.Format( libPath);
         if ( sysPath.Find( szNewPath ) != -1 )
         {
             acutPrintf(L"已经存在指定路径!\n");
             return;
         }
         sysPath+= L";";
         sysPath+= szNewPath;
         int retcode;
         retcode= acedSetEnv( L"ACAD", sysPath);
         return;
    }
    20.2013年9月3日星期二
    AcAdDoubleClickEdit 在 arx2010 中 变到哪里了?
    Solution
    The AcDbDoubleClickEdit functionality that was exposed in AcDblClkEditPE.arx isnow rolled up in AcApp.arx and acad.lib.
    For AutoCAD 2010 to make double click extension protocol to work.…
    1. Remove any loadModule() calls to AcDblClkEditPE.arx
    2. Remove any calls to AcDbDoubleClickEdit::rxinit() as this is now doneautomatically for us.
    3. Include the AcDblClkEdit.h
    4. Add ACRX_DEFINE_MEMBERS(AcDbDoubleClickEdit); in one of your .cpp modules
    For AutoCAD2007~2009
    file:///C:/Users/ADMINI~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg
    21.2014年1月23日星期四
    以下代码获取lsp中的变量值:
    static void RALFHCDev_pp(void)
        {
            // Add yourcode for command RALFHCDev._pp here
            int i = 0;
            CString str;
            int retcode = RTNORM;
            struct resbuf *result = NULL;
            retcode= acedGetSym( _T("kkk"), &result);
            if ( retcode != RTNORM)
            {
                acutRelRb(result);
                str.Format( _T("Error [%d]"),retcode);
                AfxMessageBox(str );
                return;
            }
            i = result->resval.rint;
            acutRelRb(result);
            str.Format( _T("kkk所ù属?的?值μ为a[%d]"),i);
            AfxMessageBox( str);
        }
    22.2016年1月21日 10:05:21
    以下代码禁止选择AcDbLine
    //AcEdSSGetFilterEx.h
    #pragma once
    class AcEdSSGetFilterEx:public AcEdSSGetFilter
    {
    virtual void ssgetAddFilter(
    int ssgetFlags,
    AcEdSelectionSetService &service,
    const AcDbObjectIdArray& selectionSet,
    const AcDbObjectIdArray& subSelectionSet);
    virtual void
    endSSGet(
    Acad:romptStatus returnStatus,
    int ssgetFlags,
    AcEdSelectionSetService &service,
    const AcDbObjectIdArray&selectionSet);
    virtual void
    endEntsel(
    Acad:romptStatus      returnStatus,
    const AcDbObjectId&     pickedEntity,
    const AcGePoint3d&      pickedPoint,
    AcEdSelectionSetService& service);
    //是否可以选中
    virtual bool CanBeSelect(AcDbObjectId id);
    //是否可以选中
    virtual bool CanBeSelect(AcDbEntity* pEnt);
    };
    //AcEdSSGetFilterEx.cpp
    #include"StdAfx.h"
    #include "AcEdSSGetFilterEx.h"
    void
    AcEdSSGetFilterEx::ssgetAddFilter(
    int ssgetFlags,
    AcEdSelectionSetService &service,
    const AcDbObjectIdArray& selectionSet,
    const AcDbObjectIdArray& subSelectionSet)
    {
    acutPrintf(_T("\r\nAcEdSSGetFilterEx::ssgetAddFilter\r\n"));
    for(int i=subSelectionSet.logicalLength()-1;i>=0;i--)
    {
    if(CanBeSelect(subSelectionSet.at(i)))
    {
    continue;
    }
    service.remove(i);
    }
    }
    void AcEdSSGetFilterEx::endSSGet(
    Acad:romptStatus returnStatus,
    int ssgetFlags,
    AcEdSelectionSetService &service,
    const AcDbObjectIdArray& selectionSet)
    {
    acutPrintf(_T("\r\nAcEdSSGetFilterEx::endSSGet\r\n"));
    for(int i=selectionSet.logicalLength()-1;i>=0;i--)
    {
    if(CanBeSelect(selectionSet.at(i)))
    {
    continue;
    }
    service.remove(i);
    }
    }
    void AcEdSSGetFilterEx::endEntsel(
    Acad:romptStatus       returnStatus,
    const AcDbObjectId&      pickedEntity,
    const AcGePoint3d&       pickedPoint,
    AcEdSelectionSetService& service)
    {
    acutPrintf(_T("\r\nAcEdSSGetFilterEx::endEntsel\r\n"));
    if(CanBeSelect(pickedEntity))
    {
    return;
    }
    service.remove(0);
    }
    //是否可以选中
    bool AcEdSSGetFilterEx::CanBeSelect(AcDbObjectId id)
    {
    AcDbEntity* pEnt=NULL;
    Acad::ErrorStatus es=acdbOpenAcDbEntity(pEnt,id,AcDb::kForRead);
    if(es!=Acad::eOk)
    {
    return false;
    }
    bool rc=CanBeSelect(pEnt);
    pEnt->close();
    return rc;
    }
    //是否可以选中
    bool AcEdSSGetFilterEx::CanBeSelect(AcDbEntity* pEnt)
    {
    return true;
    }
    //MySSGetFilter.h
    #pragma once
    #include "AcEdSSGetFilterEx.h"
    class MySSGetFilter: public AcEdSSGetFilterEx
    {
    public:
    //是否可以选中
    virtual bool CanBeSelect(AcDbEntity* pEnt);
    };
    //MySSGetFilter.cpp
    #include"StdAfx.h"
    #include "MySSGetFilter.h"
    //是否可以选中
    bool MySSGetFilter::CanBeSelect(AcDbEntity* pEnt)
    {
    if(pEnt->isKindOf(AcDbLine::desc()))
    {
    return false;
    }
    else
    {
    return true;
    }
    }
    //acrxEntryPoint.cpp
    #include"StdAfx.h"
    #include "resource.h"
    #include "MySSGetFilter.h"
    MySSGetFilter m_filter;
    //-----------------------------------------------------------------------------
    #define szRDS _RXST("")
    //-----------------------------------------------------------------------------
    //----- ObjectARX EntryPoint
    class CSSGetFilterTestApp : public AcRxArxApp {
    public:
    CSSGetFilterTestApp () : AcRxArxApp () {}
    virtualAcRx::AppRetCode On_kInitAppMsg (void *pkt) {
    // TODO: Load dependencies here
    // You *must* callOn_kInitAppMsg here
    AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;
    addSSgetFilterInputContextReactor(curDoc(),&m_filter);
    // TODO: Add yourinitialization code here
    return (retCode) ;
    }
    virtualAcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
    // TODO: Add your code here
    // You *must* callOn_kUnloadAppMsg here
    AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;
    removeSSgetFilterInputContextReactor(curDoc(),&m_filter);
    // TODO: Unloaddependencies here
    return (retCode) ;
    }
    virtual voidRegisterServerComponents () {
    }
    } ;
    //-----------------------------------------------------------------------------
    IMPLEMENT_ARX_ENTRYPOINT(CSSGetFilterTestApp)

    23.
    http://www.mjgw.org/ 专业从事膜结构设计、制作加工、施工安装的膜结构咨询服务,能够为客户提供专业的膜结构整体解决方案。做中国最好的膜结构综合服务平台。欢迎大家联系QQ:463017170.
    回复

    使用道具 举报

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

    本版积分规则

    关闭

    推荐膜材品牌上一条 /5 下一条

    进口膜材 国产膜材 pvdf膜材ptfe膜材ETFE膜材
    最好的膜结构公司 一级膜结构资质 膜结构一级资质
    膜结构设计-膜结构十大品牌-etfe设计-充气膜结构
    诺科膜结构
    遨都膜结构设计
    中国膜结构网
    中国空间膜结构协会

    QQ|申请友链|Archiver|手机版|中国膜结构论坛

    GMT+8, 2020-10-21 23:35 , Processed in 0.304751 second(s), 23 queries .

    Powered by 中国膜结构网->膜材采购->膜结构设计->膜结构安装->膜结构维修

    © 2014-2020 膜结构协会->进口膜材->国产膜材->PVDF膜材->PTFE膜材->ETFE膜材.

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