ObjectARX学习笔记(十八)---如何给对象添加xData

  1. // (C) Copyright 1996-2008 by Autodesk, Inc.
  2.  
    //
  3.  
    // Permission to use, copy, modify, and distribute this software in
  4.  
    // object code form for any purpose and without fee is hereby granted,
  5.  
    // provided that the above copyright notice appears in all copies and
  6.  
    // that both that copyright notice and the limited warranty and
  7.  
    // restricted rights notice below appear in all supporting
  8.  
    // documentation.
  9.  
    //
  10.  
    // AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
  11.  
    // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
  12.  
    // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
  13.  
    // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
  14.  
    // UNINTERRUPTED OR ERROR FREE.
  15.  
    //
  16.  
    // Use, duplication, or disclosure by the U.S. Government is subject to
  17.  
    // restrictions set forth in FAR 52.227-19 (Commercial Computer
  18.  
    // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
  19.  
    // (Rights in Technical Data and Computer Software), as applicable.
  20.  
    //
  21.  
    // Description:
  22.  
    //
  23.  
    // This program demonstrates the use of the AcDBObject Xdata
  24.  
    // member functions.
  25.  
     
  26.  
    #if defined(_DEBUG) && !defined(AC_FULL_DEBUG)
  27.  
    #error _DEBUG should not be defined except in internal Adesk debug builds
  28.  
    #endif
  29.  
     
  30.  
    #include <stdlib.h>
  31.  
    #include <string.h>
  32.  
    #include <rxobject.h>
  33.  
    #include <rxregsvc.h>
  34.  
    #include <aced.h>
  35.  
    #include <dbsymtb.h>
  36.  
    #include <adslib.h>
  37.  
    #include "tchar.h"
  38.  
     
  39.  
    #include "acestext.h"
  40.  
     
  41.  
     
  42.  
     
  43.  
    void printXdata();
  44.  
    void addXdata();
  45.  
    void printList(struct resbuf* pRb);
  46.  
    AcDbObject* selectObject(AcDb::OpenMode openMode);
  47.  
    void initApp();
  48.  
    void unloadApp();
  49.  
    extern "C"
  50.  
    AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode, void*);
  51.  
     
  52.  
    // THE FOLLOWING CODE APPEARS IN THE SDK DOCUMENT.
  53.  
     
  54.  
    // This function calls the
  55.  
    // selectObject() function to allow the user to pick an
  56.  
    // object; then it accesses the xdata of the object and
  57.  
    // sends the list to the printList() function that lists the
  58.  
    // restype and resval values.
  59.  
    //
  60.  
    void
  61.  
    printXdata()
  62.  
    {
  63.  
    // Select and open an object.
  64.  
    //
  65.  
    AcDbObject *pObj;
  66.  
    if ((pObj = selectObject(AcDb::kForRead)) == NULL) {
  67.  
    return;
  68.  
    }
  69.  
     
  70.  
    // Get the application name for the xdata.
  71.  
    //
  72.  
    TCHAR appname[133];
  73.  
    if (acedGetString(NULL,
  74.  
    _T("\nEnter the desired Xdata application name: "),
  75.  
    appname) != RTNORM)
  76.  
    {
  77.  
    return;
  78.  
    }
  79.  
     
  80.  
    // Get the xdata for the application name.
  81.  
    //
  82.  
    struct resbuf *pRb;
  83.  
    pRb = pObj->xData(appname);
  84.  
     
  85.  
    if (pRb != NULL) {
  86.  
     
  87.  
    // Print the existing xdata if any is present.
  88.  
    // Notice that there is no -3 group, as there is in
  89.  
    // LISP. This is ONLY the xdata, so
  90.  
    // the -3 xdata-start marker isn't needed.
  91.  
    //
  92.  
    printList(pRb);
  93.  
    acutRelRb(pRb);
  94.  
     
  95.  
    } else {
  96.  
    acutPrintf(_T("\nNo xdata for this appname"));
  97.  
    }
  98.  
    pObj->close();
  99.  
    }
  100.  
     
  101.  
    void
  102.  
    addXdata()
  103.  
    {
  104.  
    AcDbObject* pObj = selectObject(AcDb::kForRead);
  105.  
    if (!pObj) {
  106.  
    acutPrintf(_T("Error selecting object\n"));
  107.  
    return;
  108.  
    }
  109.  
     
  110.  
     
  111.  
    // Get the application name and string to be added to
  112.  
    // xdata.
  113.  
    //
  114.  
    TCHAR appName[132], resString[200];
  115.  
    appName[0] = resString[0] = _T('\0');
  116.  
     
  117.  
    acedGetString(NULL, _T("Enter application name: "),
  118.  
    appName);
  119.  
    acedGetString(NULL, _T("Enter string to be added: "),
  120.  
    resString);
  121.  
     
  122.  
     
  123.  
    struct resbuf *pRb, *pTemp;
  124.  
     
  125.  
    pRb = pObj->xData(appName);
  126.  
     
  127.  
    if (pRb != NULL) {
  128.  
     
  129.  
    // If xdata is present, then walk to the
  130.  
    // end of the list.
  131.  
    //
  132.  
    for (pTemp = pRb; pTemp->rbnext != NULL;
  133.  
    pTemp = pTemp->rbnext)
  134.  
    { ; }
  135.  
    } else {
  136.  
    // If xdata is not present, register the application
  137.  
    // and add appName to the first resbuf in the list.
  138.  
    // Notice that there is no -3 group as there is in
  139.  
    // AutoLISP. This is ONLY the xdata so
  140.  
    // the -3 xdata-start marker isn't needed.
  141.  
    //
  142.  
    acdbRegApp(appName);
  143.  
     
  144.  
    pRb = acutNewRb(AcDb::kDxfRegAppName);
  145.  
    pTemp = pRb;
  146.  
    const size_t nSize = _tcslen(appName) + 1;
  147.  
    pTemp->resval.rstring
  148.  
    = (TCHAR*) malloc(nSize * sizeof(TCHAR));
  149.  
    errno_t err = _tcscpy_s(pTemp->resval.rstring, nSize, appName);
  150.  
    assert(err == 0);
  151.  
    }
  152.  
     
  153.  
    // Add user-specified string to the xdata.
  154.  
    //
  155.  
    pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);
  156.  
    pTemp = pTemp->rbnext;
  157.  
    const size_t nSize = _tcslen(resString) + 1;
  158.  
    pTemp->resval.rstring
  159.  
    = (TCHAR*) malloc(nSize * sizeof(TCHAR));
  160.  
    errno_t err = _tcscpy_s(pTemp->resval.rstring, nSize, resString);
  161.  
    assert(err == 0);
  162.  
     
  163.  
    // The following code shows the use of upgradeOpen()
  164.  
    // to change the entity from read to write.
  165.  
    //
  166.  
    pObj->upgradeOpen();
  167.  
    pObj->setXData(pRb);
  168.  
     
  169.  
    pObj->close();
  170.  
    acutRelRb(pRb);
  171.  
    }
  172.  
     
  173.  
    // END CODE APPEARING IN SDK DOCUMENT.
  174.  
     
  175.  
    // This function accepts a linked list of resbufs as it's
  176.  
    // argument and runs through the list printing out the
  177.  
    // restype and resval values one set per line.
  178.  
    //
  179.  
    void
  180.  
    printList(struct resbuf* pRb)
  181.  
    {
  182.  
    int rt, i;
  183.  
    TCHAR buf[133];
  184.  
     
  185.  
    for (i = 0;pRb != NULL;i++, pRb = pRb->rbnext) {
  186.  
    if (pRb->restype < 1010) {
  187.  
    rt = RTSTR;
  188.  
    } else if (pRb->restype < 1040) {
  189.  
    rt = RT3DPOINT;
  190.  
    } else if (pRb->restype < 1060) {
  191.  
    rt = RTREAL;
  192.  
    } else if (pRb->restype < 1071) {
  193.  
    rt = RTSHORT;
  194.  
    } else if (pRb->restype == 1071) {
  195.  
    rt = RTLONG;
  196.  
    } else {// restype is already RTSHORT, RTSTR,...
  197.  
    rt = pRb->restype; // or else it is unknown.
  198.  
    }
  199.  
     
  200.  
    switch (rt) {
  201.  
    case RTSHORT:
  202.  
    if (pRb->restype == RTSHORT) {
  203.  
    acutPrintf(
  204.  
    _T("RTSHORT : %d\n"), pRb->resval.rint);
  205.  
    } else {
  206.  
    acutPrintf(_T("(%d . %d)\n"), pRb->restype,
  207.  
    pRb->resval.rint);
  208.  
    };
  209.  
    break;
  210.  
     
  211.  
    case RTREAL:
  212.  
    if (pRb->restype == RTREAL) {
  213.  
    acutPrintf(_T("RTREAL : %0.3f\n"),
  214.  
    pRb->resval.rreal);
  215.  
    } else {
  216.  
    acutPrintf(_T("(%d . %0.3f)\n"), pRb->restype,
  217.  
    pRb->resval.rreal);
  218.  
    };
  219.  
    break;
  220.  
     
  221.  
    case RTSTR:
  222.  
    if (pRb->restype == RTSTR) {
  223.  
    acutPrintf(_T("RTSTR : %s\n"),
  224.  
    pRb->resval.rstring);
  225.  
    } else {
  226.  
    acutPrintf(_T("(%d . \"%s\")\n"), pRb->restype,
  227.  
    pRb->resval.rstring);
  228.  
    };
  229.  
    break;
  230.  
     
  231.  
    case RT3DPOINT:
  232.  
    if (pRb->restype == RT3DPOINT) {
  233.  
    acutPrintf(
  234.  
    _T("RT3DPOINT : %0.3f, %0.3f, %0.3f\n"),
  235.  
    pRb->resval.rpoint[X],
  236.  
    pRb->resval.rpoint[Y],
  237.  
    pRb->resval.rpoint[Z]);
  238.  
    } else {
  239.  
    acutPrintf(_T("(%d %0.3f %0.3f %0.3f)\n"),
  240.  
    pRb->restype,
  241.  
    pRb->resval.rpoint[X],
  242.  
    pRb->resval.rpoint[Y],
  243.  
    pRb->resval.rpoint[Z]);
  244.  
    }
  245.  
    break;
  246.  
     
  247.  
    case RTLONG:
  248.  
    acutPrintf(_T("RTLONG : %dl\n"), pRb->resval.rlong);
  249.  
    break;
  250.  
    }
  251.  
     
  252.  
    if ((i == 23) && (pRb->rbnext != NULL)) {
  253.  
    i = 0;
  254.  
    acedGetString(0,
  255.  
    _T("Press <ENTER> to continue..."), buf);
  256.  
    }
  257.  
    }
  258.  
    }
  259.  
     
  260.  
    // This function prompts the user to select an entity or
  261.  
    // enter an object's handle. It then proceeds to open the
  262.  
    // object/entity and return a pointer to it.
  263.  
    //
  264.  
    AcDbObject*
  265.  
    selectObject(AcDb::OpenMode openMode)
  266.  
    {
  267.  
    // Allow user to either pick an entity, or type in the
  268.  
    // object handle.
  269.  
    //
  270.  
    int ss;
  271.  
    ads_name en;
  272.  
    ads_point pt;
  273.  
    acedInitGet(RSG_OTHER, _T("Handle _Handle"));
  274.  
    ss = acedEntSel(_T("\nSelect an Entity or enter")
  275.  
    _T(" 'H' to enter its handle: "), en, pt);
  276.  
     
  277.  
    TCHAR handleStr[132];
  278.  
    AcDbObjectId eId;
  279.  
    switch (ss) {
  280.  
    case RTNORM: // got it!
  281.  
    break;
  282.  
    case RTKWORD:
  283.  
    if ((acedGetString(Adesk::kFalse,
  284.  
    _T("Enter Valid Object Handle: "),
  285.  
    handleStr) == RTNORM)
  286.  
    && (acdbHandEnt(handleStr, en) == RTNORM))
  287.  
    {
  288.  
    break;
  289.  
    }
  290.  
    // Fall-through intentional
  291.  
    //
  292.  
    default:
  293.  
    acutPrintf(_T("Nothing Selected, Return Code==%d\n"),ss);
  294.  
    return NULL;
  295.  
    }
  296.  
    // Now, exchange the ads_name for the object Id...
  297.  
    //
  298.  
    Acad::ErrorStatus retStat;
  299.  
    retStat = acdbGetObjectId(eId, en);
  300.  
    if (retStat != Acad::eOk) {
  301.  
    acutPrintf(_T("\nacdbGetObjectId failed"));
  302.  
    acutPrintf(_T("\nen==(%lx,%lx), retStat==%d\n"),
  303.  
    en[0], en[1], eId);
  304.  
    return NULL;
  305.  
    }
  306.  
     
  307.  
    AcDbObject* obj;
  308.  
     
  309.  
    if ((retStat = acdbOpenObject(obj, eId, openMode))
  310.  
    != Acad::eOk)
  311.  
    {
  312.  
    acutPrintf(_T("acdbOpenEntity failed: ename:(%lx,%lx),")
  313.  
    _T(" mode:%d retStat:%d"), en[0], en[1],
  314.  
    openMode, retStat);
  315.  
    return NULL;
  316.  
    }
  317.  
    return obj;
  318.  
    }
  319.  
     
  320.  
     
  321.  
    // Initialization function called from acrxEntryPoint during
  322.  
    // kInitAppMsg case. This function is used to add commands
  323.  
    // to the command stack.
  324.  
    //
  325.  
    void
  326.  
    initApp()
  327.  
    {
  328.  
    acedRegCmds->addCommand(_T("ASDK_XDATA_DEMO"),
  329.  
    _T("ASDK_PRINTX"), _T("PRINTX"), ACRX_CMD_MODAL,
  330.  
    printXdata);
  331.  
    acedRegCmds->addCommand(_T("ASDK_XDATA_DEMO"),
  332.  
    _T("ASDK_ADDXDATA"), _T("ADDXDATA"), ACRX_CMD_MODAL,
  333.  
    addXdata);
  334.  
     
  335.  
    }
  336.  
     
  337.  
     
  338.  
    // Clean up function called from acrxEntryPoint during the
  339.  
    // kUnloadAppMsg case. This function removes this app's
  340.  
    // command set from the command stack.
  341.  
    //
  342.  
    void
  343.  
    unloadApp()
  344.  
    {
  345.  
    acedRegCmds->removeGroup(_T("ASDK_XDATA_DEMO"));
  346.  
    }
  347.  
     
  348.  
     
  349.  
    // ARX entry point
  350.  
    //
  351.  
    AcRx::AppRetCode
  352.  
    acrxEntryPoint(AcRx::AppMsgCode msg, void* appId)
  353.  
    {
  354.  
    switch (msg) {
  355.  
    case AcRx::kInitAppMsg:
  356.  
    acrxDynamicLinker->unlockApplication(appId);
  357.  
    acrxDynamicLinker->registerAppMDIAware(appId);
  358.  
    initApp();
  359.  
    break;
  360.  
    case AcRx::kUnloadAppMsg:
  361.  
    unloadApp();
  362.  
    }
  363.  
    return AcRx::kRetOK;
  364.  
    }
posted @ 2020-03-01 22:49  中国膜结构网mjgou  阅读(600)  评论(0编辑  收藏  举报