Выбор определенных примитивов из набора предварительного выбора
Системная переменная 'PICKFIRST' будучи установленной в '1' позволяет пользователю выбрать примитивы до запуска команды AutoCAD. Это применимо и к командам, созданным при помощи ObjectARX.
Есть две ARX-функции, которые позволяют получить набор предварительного выбора. Это функция acedSSGet() с опцией "_I", и чаще используемая функция acedSSGetFirst(). Это демонстрирует следующий код. Имя команды 'pfss'.
Если пользователь предварительно выберет примитивы и запустит команду 'pfss', эти примитивы попадут в набор 'pfSet'. Проверим , что число элементов в наборе больше нуля и если это так, то выполним цикл 'for'. В цикле 'for' получаем ObjectId каждого примитива и открываем примитив «для чтения». Проверяем примитив при помощи функции 'isA()'. Вы можете аналогично проверить и пользовательские примитивы если замените имя на имя пользовательского класса.
Можно использовать методы 'cast()' или 'isKindOf()'. Обратитесь к документации ObjectARX за описанием этих методов. Если примитив AcDbLine (или пользовательский примитив) переменная 'lineEntCount' увеличивается. Примитив закрывается и переходим к следующему примитиву. Результаты сообщаются пользователю. Функция acedSSGetFirst()
Функция acedSSGetFirst () показана в конце фрагмента кода. Эта функция требует двух указателей на списки буферов результатов, первый 'prbGrip' содержит примитивы, у которых подсвечены «ручки», но не выбраны, а второй 'prbPick' содержит примитивы, которые предварительно выбраны. Если ни один примитив не был предварительно выбран, то поле 'ResType' списка буферов 'prbPick' будет содержать значение 'RTNONE'. Если примитивы были предварительно выбраны то поле 'ResType "поле будет содержать значение 'RTPICKS'. Если это так, то поле resval.rlname буфера результата будет содержать набор объектов. Не забудьте освободить наборы выбора, прежде освободить списки буферов результатов.
- void pfss()
- {
- AcDbEntity *pEnt;
- AcDbObjectId entId;
- Acad::ErrorStatus es;
- int retCode;
- ads_name pfSet; // 'PICKFIRST' набор выбора
- ads_name ename; long pfSetLen;
- // Количество примитивов в наборе 'PICKFIRST'
- long lineEntCount = 0;
- acedSSGet(L"_I", NULL, NULL, NULL, pfSet);
- acedSSLength(pfSet, &pfSetLen);
- // Проверим, что набор не пустой
- if(pfSetLen > 0)
- {
- acutPrintf(L"\nПредварительно выбрано %d примитивов.", pfSetLen);
- // Цикл по примитивам в наборе
- for(long i = 0; i < pfSetLen; i++)
- {
- retCode = acedSSName(pfSet, i, ename);
- if(retCode != RTNORM)
- {
- acutPrintf(L"\nОшибка получения примитива из набора");
- break;
- }
- es = acdbGetObjectId(entId, ename);
- if(es != Acad::eOk)
- {
- acutPrintf(L"\nОшибка получения AcDbObjectId примитива.");
- break;
- }
- es = acdbOpenAcDbEntity(pEnt, entId, AcDb::kForRead);
- if(es != Acad::eOk)
- {
- acutPrintf(L"\nОшибка открытия примитива для операции чтения");
- break;
- }
- // Здесь мы проверяем в точности на примитив AcDbLine.
- // Точно так же мы можем проверить на пользовательский примитив,
- // являющийся элементов в дереве иерархии классов.
- // Мы можем использовать методы cast() и isKindOf()
- // Обратите внимание на идентификацию времени выполнения (RTI)
- // в документации ObjectARX, описывающую эти методы
- if(pEnt->isA() == AcDbLine::desc())
- {
- // Увеличим счетчик отрезков
- lineEntCount++;
- }
- // Не забываем закрывать примитив, когда заканчиваем
- // работать с ним.
- pEnt->close();
- } // for
- acutPrintf(L"\nВсего в наборе %d примитивов класса AcDbLine.", lineEntCount);
- }
- else
- {
- acutPrintf(L"\nНичего не было предварительно выбрано.");
- }
- // Не забываем освободить набор.
- acedSSFree(pfSet);
- // Здесь мы продемонстрируем использование функции acedSSGetFirst()
- // для получения набора предварительного выбора.
- // prbGrip - resbuf содержащий набор примитивов,
- // у кооторого подсвечены ручки, но примитивы не выбраны.
- // prbPick - resbuf содержит набор в resval.rlname
- // предварительно выбранных примитивов.
- // Ручки могут быть, а могут и не быть.
- struct resbuf* prbGrip = NULL;
- struct resbuf* prbPick = NULL;
- // олучаем наборы
- acedSSGetFirst(&prbGrip, &prbPick);
- long gripLen, pickLen;
- acedSSLength(prbPick->resval.rlname, &pickLen);
- acedSSLength(prbGrip->resval.rlname, &gripLen);
- acutPrintf(
- L"\nПредварительно выбрано %d примитивов - результат функци acedSSGetFirst().",
- pickLen);
- // Не забываем освободить наборы.
- acedSSFree(prbPick->resval.rlname);
- acedSSFree(prbGrip->resval.rlname);
- // А также освобождаем списки результатов
- acutRelRb(prbGrip);
- acutRelRb(prbPick);
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=391
Опубликовано 11.12.2013Отредактировано 11.12.2013 в 05:09:52