Работа с графикой и интерфейсная форма

Автор Тема: Работа с графикой и интерфейсная форма  (Прочитано 6600 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн JohnLenninАвтор темы

  • .Net Teapot
  • ADN OPEN
  • Сообщений: 49
  • Карма: 1
Коллеги!

Честно скажу - где-то я про это читал, но к сожалению не могу теперь найти на просторах интернета где именно, может подскажете. :'(
Проблема следующая - чего-то накодил, все работает нормально, когда команды вызваются из командной строки автокада.
Однако, необходимо, чтобы они вызвались из формы с кнопочками, списками, которые генерятся из СУБД и т.п.
Форму слава богу нарисовал и даже вызываю ее, она показывается, кнопочки нажимаются, списки заполняются, однако, когда на форме нажимаю кнопочку вставить объект в чертеж и вызываю команду этой самой вставки - необходимо точку вставки вместе с объектом выбрать на чертеже и тут вываливается ошибка eLockViolation.
При этом если эту команду вызвать руками например из командной строки или отдельно компильнуть без формы - все замечатльно работает.
Где-то я что-то читал по поводу того, что надо что-то с формой делать и штуки типа Form1.ActiveForm.Show() Form1.ActiveForm.Hide() недостаточно чтобы все нормально заработало, но к сожалению, сейчас не могу найти где именно это было написано с подробностями и как с этим бороться.
Ошибка вываливается на строке (4) в котрой делаю запись в таблицу с блоками.
Код - vb.net [Выбрать]
  1. If sampstatus = "OK" Then
  2.    Using myT As Transaction = tm.StartTransaction()
  3.      Dim bt As BlockTable = DirectCast(tm.GetObject(db.BlockTableId, OpenMode.ForRead, False), BlockTable)
  4.      Dim btr As BlockTableRecord = DirectCast(tm.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite, False), BlockTableRecord)
  5.      btr.AppendEntity(mvb)
  6.      tm.AddNewlyCreatedDBObject(mvb, True)
  7.      myT.Commit()
  8.    End Using
  9. End If

UPD: Нашел где это было
http://forums.autodesk.com/t5/NET/eLockViolation-when-trying-to-draw-from-a-command-on-a-form/td-p/1348038
Исправляется путем Lock'а активного документа, перед всем этим безобразием надо написать:
Код - vb.net [Выбрать]
  1.  Dim doc1 As Document = Application.DocumentManager.MdiActiveDocument
  2.  Dim dl As DocumentLock = doc1.LockDocument
И тогда все заработало.
Стоит оставить эту тему, т.к. с этим часто все кто начинает писать в таблицы через интерфейсные формы сталкивается.
« Последнее редактирование: 20-11-2013, 05:00:59 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Правильнее было бы использовать такой код:
Код - vb.net [Выбрать]
  1. Dim doc As Document = Application.DocumentManager.MdiActiveDocument
  2. Using acLckDoc As DocumentLock = doc.LockDocument()
  3.  '  здесь код который модифицирует документ
  4. End Using
Этот код гарантирует то, что документ будет разблокирован даже если возникнет исключение.

P.S.: Кстати на нашем сайте есть такая переводная статья: В каких случаях следует блокировать документ
« Последнее редактирование: 20-11-2013, 05:02:20 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн JohnLenninАвтор темы

  • .Net Teapot
  • ADN OPEN
  • Сообщений: 49
  • Карма: 1
Спасибо Александр!
Действительно так будет вернее. И за ссылку на статью спасибо!
Скорее всего я ее и читал когда-то, просто голова в последнее время совсем дырявая стала, слишком много в ней приходится держать оперативной информации, а времени чтобы систематизировать и структурировать долгосрочные знания как всегда не хватает. Все приходится делать "галопом по Европам". Вот и выпадают фрагменты из памяти  :o

Оффлайн JohnLenninАвтор темы

  • .Net Teapot
  • ADN OPEN
  • Сообщений: 49
  • Карма: 1
И еще такой вопросик - как обычно принято делать переключение между диалоговым окном и рабочим пространством autocad? В том смысле, чтобы диалоговое окно не мешало тыкать мышкой в пространство модели.
Просто сворачивать? а если например надо поменять какие-то параметры в диалоговом окне - его опять разворачивать?
Может тупо  Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView()?
« Последнее редактирование: 20-11-2013, 11:45:59 от JohnLennin »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Обычно принято (на этом форуме) один вопрос - одна тема.  :)
А если серьезно, то всё зависит от того какая форма и что от неё требуется. Если форма модальная, то она должна быть закрыта в любом случае. Если форма немодальная и небольшая, то может оставаться на экране. Если большая, то нужно скрывать/восстанавливать, так как она будет закрывать кусок рабочего пространства.
Может тупо  Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView()?
Вопрос только где это делать? Нужно же оставить возможность переключиться на эту форму.
« Последнее редактирование: 21-11-2013, 10:52:24 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Anton

  • One Breath
  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
  • Endless possibilities
Присоединяюсь ко второй части вопроса про Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView.
Как вернуть фокус обратно на форму?
Смысл примерно такой-же - есть форма, в ней произвели какие-то манипуляции, дальше вызываем команду Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView, опять производим манипуляции, а затем надо сделать фокус обратно на форму, вопрос какой командой?


Оффлайн Anton

  • One Breath
  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
  • Endless possibilities
Спасибо большое Дмитрий за линк. Эта штука в принципе мне подходит, хотя и работает только с модальными формами. Вполне допускаю что переделать немного интерфейс и сделать вызывающее окно модальным будет правильнее.
Выделю здесь основные моменты, чтобы другим времени зря не терять

Код - vb.net [Выбрать]
  1.         Dim doc As Autodesk.AutoCAD.ApplicationServices.Document = _
  2.                   Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument
  3.         Dim ed As Autodesk.AutoCAD.EditorInput.Editor = doc.Editor
  4.         ' Активируем editor
  5.         Using UI As Autodesk.AutoCAD.EditorInput.EditorUserInteraction = ed.StartUserInteraction(Me)
  6.              ' Здесь производим все необходимые нам манипуляции в редакторе AutoCAD
  7.          End Using ' возвращаемся обратно в модальное окно
  8.  
Да еще, при миграции на 2013-2014 надо в 5 строке Me дополнить Me.Handle
Код - vb.net [Выбрать]
  1. Using UI As Autodesk.AutoCAD.EditorInput.EditorUserInteraction = ed.StartUserInteraction(Me.Handle)
  2.  
Напеределали они в 2013 немного, часть функционала перекидали в accoremgd.dll, чтобы не скучно жить было, а то расслабились понимаешь с 2007 версии никаких кардинальных изменений  ;)
« Последнее редактирование: 06-02-2014, 23:30:48 от Anton »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Как вернуть фокус обратно на форму?
Смысл примерно такой-же - есть форма, в ней произвели какие-то манипуляции, дальше вызываем команду Autodesk.AutoCAD.Internal.Utils.SetFocusToDwgView, опять производим манипуляции, а затем надо сделать фокус обратно на форму, вопрос какой командой?
1. http://www.pinvoke.net/default.aspx/user32.setfocus - это как записать P/Invoke для функции SetFocus из Windows API. Ей требуется один параметр - HWND формы.
2. Чтобы найти HWND для твоей формы используй метод Form.Handle
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
P.S.: Кстати на нашем сайте есть такая переводная статья: В каких случаях следует блокировать документ
Такой момент: предположим, что изначально метод был написан со значением Session (помимо прочих) в атрибуте, и в коде использовалась блокировка (LockDocument в блоке using) некоторого документа, с которым выполнялась работа.

Позднее разработчик вдруг решает, мол пусть этот метод будет работать лишь с текущим документом и изменил код так, что работа ведётся в MdiActiveDocument. В свете оного программист убирает в атрибуте значение Session, но забывает удалить обозначенный выше блок кода, который на некоторое время блокирует документ. Получается, что автокад сам блокирует документ, а тут ещё и программист пытается сделать то же самое, т.е. блокировать уже блокированный документ... В подобной ситуации я бы ожидал генерации исключения (Exception) , но оно не происходит и код, на котором я моделировал обозначенную ситуацию, работает как нужно.

Могут ли в обозначенной мною ситуации всё же возникать какие-либо проблемы?

Небольшое замечания по ссылке.
Цитата: Александр Ривилис
// изменим значение 'TILEMODE ' одного из документов
Не "одного", а всех кроме текущего (комментарий не соответствует коду).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Небольшое замечания по ссылке.
Цитата: Александр Ривилис

    // изменим значение 'TILEMODE ' одного из документов

Не "одного", а всех кроме текущего (комментарий не соответствует коду).
Согласен. Исправил. В оригинальной статье таже неточность.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Позднее разработчик вдруг решает, мол пусть этот метод будет работать лишь с текущим документом и изменил код так, что работа ведётся в MdiActiveDocument. В свете оного программист убирает в атрибуте значение Session, но забывает удалить обозначенный выше блок кода, который на некоторое время блокирует документ. Получается, что автокад сам блокирует документ, а тут ещё и программист пытается сделать то же самое, т.е. блокировать уже блокированный документ... В подобной ситуации я бы ожидал генерации исключения (Exception) , но оно не происходит и код, на котором я моделировал обозначенную ситуацию, работает как нужно.

Могут ли в обозначенной мною ситуации всё же возникать какие-либо проблемы?

Никаких проблем. Просто если в команде нет атрибута Session, то она выполняется в контексте документа и Application.DocumentManager.MdiActiveDocument.LockDocument просто игнорируется.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Значит можно везде писать блокировку документа на всякий случай, чтобы если в будущем вдруг потребуется работать в контексте приложения,  то не приходилось бы судорожно перелопачивать код и добавлять необходимые юзинги. Можно будет просто добавлять атрибут и не беспокоиться о том, что у юзера "вдруг" всё встанет на уши.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13177
  • Карма: 1701
  • Рыцарь ObjectARX
  • Skype: rivilis
Да. Во всяком случае во всех существующих версиях AutoCAD .NET API "лишний" вызов LockDocument в контексте документа не приводит ни к каким отрицательным последствиям.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение