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.   }
上一篇:ObjectArx圆角功能代码


下一篇:矩阵树定理 学习笔记