(изменено: Savka Antonina, 16 сентября 2009г. 12:12:58)

Тема: Перекрытие програмно нарисованого объекта

Столкнулась с такой проблемой: когда пользователь в неком мной созданном диалоге (модальном) делает клик мышки на ветке дерева, то на чертеже рисуется полилиния. Полилиния рисуется правильно и поверх остальных объектов, что уже были на чертеже. Но после того, как я программно прячу диалог (BeginEditorCommand()), чтобы просмотреть чертеж эта полилиния почему-то уходить на задний план, под объекты. Пожалуйста, помогите разобраться в ошибке и в том, как ее исправить.

Re: Перекрытие програмно нарисованого объекта

скорей всего это проблемы с регенерацией чертежа.
попробуй после "прятанья" своего окна выполнить команду _regenall

acedCommand(RTSTR, _T("_regenall"), 0);

изменилось ли отображение полилинии?

Re: Перекрытие програмно нарисованого объекта

Благодарю  :)  Работает

Re: Перекрытие програмно нарисованого объекта

но если честно, то это не выход, т.к. при большом количестве объектов и при слабенькой машинке, пользователь впадает в ступор.
если вспомню, напишу как я эту проблему обходил, а ты пока посмотри по форуму, тут уже подобные проблемы обсуждались.

Re: Перекрытие програмно нарисованого объекта

Ну если уж делать REGEN, то не командой, а функцией ads_regen():

void ads_regen(void);

Но скорее всего должен помочь код:

actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();

Re: Перекрытие програмно нарисованого объекта

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

Но скорее всего должен помочь код:

actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();

К сожалению этот код не работает - все равно моя полилиния уходитьна задний план. Может чтото еще к нему нужно?

(изменено: Николай, 16 сентября 2009г. 14:25:51)

Re: Перекрытие програмно нарисованого объекта

а попробуй acedUpdateDisplay();

или есть еще один вариант
1. отурыть объект для чтения
2. pEnt->draw();
3. pEnt->close();

Re: Перекрытие програмно нарисованого объекта

Николай пишет:

acedUpdateDisplay()

Тоже работоспособний код. Какие преимущества от второй версии?

Николай пишет:

или есть еще один вариант
1. отурыть объект для чтения
2. pEnt->draw();
3. pEnt->close();

Re: Перекрытие програмно нарисованого объекта

ну я так подозреваю, что updatedisplay делает на кучу пробегов по базе чертежа, во всяком случае больше чем pEnt->draw()
:)
вот что написано в хелпе про AcDbEntity::draw()

This function queues up the entity's graphics and flushes the graphics queue, forcing the entity and anything else in the queue to be drawn or re-drawn on-screen

Дословно переводить не буду, но эта функция добавляет объект в стек отрисовки и принудительно перерисовывает всесь стек. Ну где-то так:)

Re: Перекрытие програмно нарисованого объекта

Вопрос к Александру Ривилису относительно его решения:

actrTransactionManager->queueForGraphicsFlush();
actrTransactionManager->flushGraphics();

Я в справке нашел вот что (выделение текста моё):

virtual Acad::ErrorStatus
queueForGraphicsFlush() = 0;

Queues up the graphics changes of all transaction-resident modified entities from any existing transaction. This places these changes on the graphics queue in preparation for a call to AcDbTransactionManager::flushGraphics() to send them to the display.

Т.е. если транзакцию никто не открывал, то и построенный примитив не может быть transaction-resident, а значит и решение это не поможет.

(изменено: Александр Ривилис, 17 сентября 2009г. 15:12:11)

Re: Перекрытие програмно нарисованого объекта

Далеко не все утверждения в справке соответствуют действительности. Если поищешь поиском по этому форумы предложенный мной метод очень часто помогал. Кроме того транзакцию могла открыть и не эта программа. Кстати, стандартные команды AutoCAD часто используют транзакции, так что если использовались функции acedCommand()/acedCmd(), то транзакции могли быть. В общем случае этот вызов не помешает.

Re: Перекрытие програмно нарисованого объекта

Странно как-то. Даже если транзакцию и открыла какая-то внешняя объемлющая процедура, но ведь вновь созданный объект не присоединен к транзакции. Может для пущей верности стоит выяснить, есть ли открытая транзакция например с помощью numActiveTransactions() и если да, то добавить к ней вновь созданный объект с помощью addNewlyCreatedDBRObject(...) и уж тогда вызывать пару flush- функций.
А если numActiveTransactions() говорит, что нет открытых транзакций и при этом пара flush-функций помогает, то получается что в справке о чем-то действительно не договаривают.
Но вот решение Николая

1. открыть объект для чтения
2. pEnt->draw();
3. pEnt->close();

для меня неискушенного выглядит простым и стопроцентно гарантирующим успех. Или что-то все же в нем не так.

Re: Перекрытие програмно нарисованого объекта

скажу честно, чтоб не мучаться постоянно при создании объектов разных типов, например, точек, полилиний, штриховок и др. был написан специальный класс (ну обычно так все и делается, если не хочеться разрастания кода)
так вот, в каждой функции создания любого типа объекта стоит draw(), и вот уже лет 5 проблем точно нет никаких, акад не падает, объекты создаются и отображаются на экране :)
так что думай сама :):):)

Re: Перекрытие програмно нарисованого объекта

Пастух пишет:

для меня неискушенного выглядит простым и стопроцентно гарантирующим успех. Или что-то все же в нем не так.

В действительности метод draw() лишь сообщает подсистеме вывода AutoCAD о необходимости перерисовать примитив, но не отрисовывает его немедленно. И вот тут возможны нюансы. Иногда подсистему вывода "подстегивает" actrTransactionManager->flushGraphics(), чаще acedUpdateDisplay(), еще чаще ads_regen(). И в разных версиях AutoCAD это все по-разному.