ADN Open CIS
Сообщество программистов Autodesk в СНГ

23/12/2015

Получение доступа к каталогам поддержки и проекта

Я получил недавно запрос о том, как програмно получить доступ к каталогам поддержки и файлам проекта, которые доступны на вкладке Свойства/Файлы.

Мы можем воспользоваться ActiveX API  AcadPreferences.Files для получения доступа к каталогам поддержки и файлам проекта.

Чтобы получить информацию о каталогах поддержки можно также прочитать системную переменную «ACADPREFIX» или выполнить следующий код:

Код - C++: [Выделить]
  1. void TestProj()
  2. {
  3.   HRESULT hr;
  4.   try
  5.   {
  6.     AutoCAD::IAcadApplication *pAcad =NULL;
  7.     hr = NOERROR;
  8.     LPUNKNOWN pUnk = NULL;
  9.     LPDISPATCH pAcadDisp = acedGetIDispatch(TRUE);
  10.  
  11.     if(pAcadDisp==NULL)
  12.       return ;
  13.  
  14.     hr = pAcadDisp->QueryInterface(AutoCAD::IID_IAcadApplication,
  15.       (void**)&pAcad);
  16.  
  17.     pAcadDisp->Release();
  18.  
  19.     if (FAILED(hr))
  20.       return;
  21.  
  22.     if (pAcad)
  23.     {
  24.       AutoCAD::IAcadPreferences* pPreferences  = NULL;
  25.       hr = pAcad->get_Preferences(&pPreferences);
  26.       if(FAILED(hr))  return;
  27.       pAcad->Release();
  28.  
  29.       AutoCAD::IAcadPreferencesFiles* pPreferencesFiles = NULL;
  30.  
  31.       hr = pPreferences->get_Files(&pPreferencesFiles);
  32.       if(FAILED(hr)) return;
  33.  
  34.       if(pPreferencesFiles)
  35.       {
  36.         /* Для доступа к каталогу проекта */
  37.  
  38.         BSTR projectFilePath, supportPath;
  39.  
  40.         /* Создан Testproject и добавлен путь"C:/Temp */
  41.  
  42.         pPreferencesFiles->GetProjectFilePath(_bstr_t("TESTPROJECT"),
  43.           &projectFilePath);
  44.  
  45.         std::wstring ps(projectFilePath,SysStringLen(projectFilePath));
  46.  
  47.         acutPrintf(_T("\nКаталог проекта: %s"), ps.c_str());
  48.  
  49.  
  50.         /* Получаем список каталогов в путях доступа */
  51.  
  52.         pPreferencesFiles->get_SupportPath(&supportPath);
  53.  
  54.         std::wstring ws(supportPath,SysStringLen(supportPath));
  55.  
  56.         acutPrintf(_T("\nПути доступа : %s"),ws.c_str());
  57.  
  58.       }
  59.     }
  60.   }
  61.   catch(...)
  62.   {
  63.     return;
  64.   }
  65. }

Код выше позволяет получить путь к текущему проекту, созданному в Приложении. Но нет API позволяющее получить список всех проектов созданных в приложении. Так что нам придётся воспользоваться чтением из реестра.

Механизм чтения реестра описан здесь.

Код - C++: [Выделить]
  1. /* Перечисляем все доступные проекты в списке */
  2. #define MAX_KEY_LENGTH 255
  3. #define MAX_VALUE_NAME 16383
  4. void QueryKey(HKEY hKey)
  5. {
  6.   TCHAR    achKey[MAX_KEY_LENGTH];   // буфер имени
  7.   DWORD    cbName;                   // размер строки
  8.   TCHAR    achClass[MAX_PATH] = TEXT("");  // буфер класса
  9.   DWORD    cchClassName = MAX_PATH;  // размер строки
  10.   DWORD    cSubKeys = 0;               // число ключей
  11.   DWORD    cbMaxSubKey;              // длина самого длинного ключа
  12.   DWORD    cchMaxClass;              // длина самой длинной строки класса
  13.   DWORD    cValues;              // число значений ключа
  14.   DWORD    cchMaxValue;          // самое длинное значение
  15.   DWORD    cbMaxValueData;       // самое длинное значение данных
  16.   DWORD    cbSecurityDescriptor; // длина дескриптора защиты
  17.   FILETIME ftLastWriteTime;      // дата последнего изменения
  18.  
  19.   DWORD i, retCode;
  20.  
  21.   TCHAR  achValue[MAX_VALUE_NAME];
  22.   DWORD cchValue = MAX_VALUE_NAME;
  23.  
  24.   // Получим имя класса и счетчик значений.
  25.   retCode = RegQueryInfoKey(
  26.     hKey,                    // метка ключа
  27.     achClass,                // буфер имени класса
  28.     &cchClassName,           // длина строки класса
  29.     NULL,                    // зарезервировано
  30.     &cSubKeys,               // число ключей
  31.     &cbMaxSubKey,            // длина самого длинного ключа
  32.     &cchMaxClass,            // длина самой длинной строки класса
  33.     &cValues,                // число значений для ключа
  34.     &cchMaxValue,            // самое длинное значение
  35.     &cbMaxValueData,         // самое длинное значение данных
  36.     &cbSecurityDescriptor,   //  длина дескриптора защиты
  37.     &ftLastWriteTime);       // дата последнего изменения
  38.  
  39.   // Перебираем все ключи до тех пор, пока RegEnumKeyEx не выдаст ошибку.
  40.  
  41.   if (cSubKeys)
  42.   {
  43.     printf("\nЧисло ключей: %d\n", cSubKeys);
  44.  
  45.     for (i = 0; i<cSubKeys; i++)
  46.     {
  47.       cbName = MAX_KEY_LENGTH;
  48.       retCode = RegEnumKeyEx(hKey, i,
  49.         achKey,
  50.         &cbName,
  51.         NULL,
  52.         NULL,
  53.         NULL,
  54.         &ftLastWriteTime);
  55.       if (retCode == ERROR_SUCCESS)
  56.       {
  57.         acutPrintf(TEXT("(%d) %s\n"), i + 1, achKey);
  58.       }
  59.     }
  60.   }
  61.  
  62.   // Перебираем значения ключа.
  63.  
  64.   if (cValues)
  65.   {
  66.     printf("\nЧисло значений: %d\n", cValues);
  67.  
  68.     for (i = 0, retCode = ERROR_SUCCESS; i<cValues; i++)
  69.     {
  70.       cchValue = MAX_VALUE_NAME;
  71.       achValue[0] = '\0';
  72.       retCode = RegEnumValue(hKey, i,
  73.         achValue,
  74.         &cchValue,
  75.         NULL,
  76.         NULL,
  77.         NULL,
  78.         NULL);
  79.  
  80.       if (retCode == ERROR_SUCCESS)
  81.       {
  82.         acutPrintf(TEXT("(%d) %s\n"), i + 1, achValue);
  83.       }
  84.     }
  85.   }
  86. }
  87.  
  88. void TestList()
  89. {
  90.   HKEY hTestKey;
  91.   /* Явно задаём путь, R20.1 - соответствует ACAD версии 2016
  92.   ACAD-F001:419 : Код для "чистого" русского AutoCAD
  93.   */
  94.   /* Для получения полной информации:
  95.   http://adndevblog.typepad.com/autocad/2013/08/registry-values-for-productid-and-localeid-for-autocad.html */
  96.  
  97.  
  98.   if (RegOpenKeyEx(HKEY_CURRENT_USER,
  99.     TEXT("Software\\Autodesk\\AutoCAD\\R20.1\\ACAD-F001:419\\Profiles\\acad\\Project Settings"),
  100.     0,
  101.     KEY_READ,
  102.     &hTestKey) == ERROR_SUCCESS
  103.     )
  104.   {
  105.     QueryKey(hTestKey);
  106.   }
  107.   RegCloseKey(hTestKey);
  108. }

Результат выполнения программы:

 

Можете также посмотреть, как изменить путь к файлу проекта:

http://adndevblog.typepad.com/autocad/2012/12/setting-the-project-file-search-path.html

Аналогичный механизм для изменения пути к каталогам поддержки:

Код - C++: [Выделить]
  1. virtual HRESULT __stdcall put_SupportPath (
  2.     /*[in]*/ BSTR orient ) = 0;

 

Источник: http://adndevblog.typepad.com/autocad/2015/08/accessing-support-files-and-project-files-search-paths.html

 

Автор перевода: Александр Ривилис

Обсуждение: http://adn-cis.org/forum/index.php?topic=3296

Опубликовано 23.12.2015
Отредактировано 23.12.2015 в 14:16:54