Тема: Управление свойствами главного окна AutoCAD при раннем связывании

Всем доброго времени суток!

Передо мной, была поставлена задача, реализовать на VB пользовательское приложение с использованием раннего связывания, в котором по ходу сценария необходимо управлять видимостью AutoCAD на экране, изменять высоту/ширину главного окна приложения, положение левого/верхнего края окна приложения. Управлять свойствами окна приложения надо, используя интерфейс API COM. Вроде бы все просто, но в процессе работы столкнулся с тем, что, например, при  раннем связывании после установки Application.Visible = False AutoCAD остается виден на экране, а после установки Application.Visible = True – запускается второй экземпляр AutoCAD.
При использовании позднего связывания все работает как и планировалось, т.е. после установки Application.Visible = False AutoCAD ‘исчезает’ с экрана, а после установки Application.Visible = True – появляется, и он остается в единственном числе.

Набросал простейшие тесты свойства Application.Visible, управляющего видимостью окна приложенияс при раннем и позднем связывании, которые создают описанные ваше ситуации.

<CommandMethod("TestComVisibleEarly")> _
  Public Sub TestComVisibleEarly()
    '' При раннем связывании после установки app.Visible = False AutoCAD остается виден на экране, 
    '' а после установки app.Visible = True – запускается второй экземпляр AutoCAD.

    Me.msgDoc.Editor.WriteMessage(vbLf & " Тест свойства Application.Visible, управляющего видимостью окна приложенияс при раннем связывании")

    Dim app As AcadApplication = CreateObject("AutoCAD.Application")

    app.Visible = False

    Dim answer As String = Nothing

    answer = MsgBox("Если в данный момент окно приложения на экране не видно - ответьте 'Да', в противном случае 'Нет'.", vbYesNo + vbQuestion, "Подтверждение результата")

    If answer = vbYes Then
      Me.msgDoc.Editor.WriteMessage(vbLf & "   =====> Окно приложения на экране НЕ видно.")
    Else
      Me.msgDoc.Editor.WriteMessage(vbLf & "   =====> Окно приложения на экране осталось видимым.")
    End If

    app.Visible = True

  End Sub
 

Function GetApplicationDispatch()
  GetApplicationDispatch = Application.AcadApplication()
End Function

<CommandMethod("TestComVisibleLater")> _
  Public Sub TestComVisibleLater()

    Me.msgDoc.Editor.WriteMessage(vbLf & " Тест свойства Application.Visible, управляющего видимостью окна приложенияс при позднем связывании")

    Dim app As Object = GetApplicationDispatch()

    app.Visible = False

    Dim answer As String

    answer = MsgBox("Если в данный момент окно приложения на экране не видно - ответьте 'Да', в противном случае 'Нет'.", vbYesNo + vbQuestion, "Подтверждение результата")

    If answer = vbYes Then
      Me.msgDoc.Editor.WriteMessage(vbLf & "   =====> Окно приложения на экране НЕ видно.")
    Else
      Me.msgDoc.Editor.WriteMessage(vbLf & "   =====> Окно приложения на экране осталось видимым.")
    End If

    app.Visible = True

  End Sub

Аналогичная ситуация при использовании свойств Application.Height,  Application.WindowLeft при раннем связывании. При позднем связывании все работает нормально.

Коллеги, подскажите, что надо сделать, чтобы при раннем связывании главное окно AutoCAD, как положено, становилось невидимым при Application.Visible = False и не продились экземпляры AutoCAD.

Заранее благодарю за помощь.

С уважением,
Андрей

(изменено: Александр Ривилис, 27 апреля 2014г. 20:40:08)

Re: Управление свойствами главного окна AutoCAD при раннем связывании

Вот этот код у тебя запускает второй экземпляр AutoCAD:

Dim app As AcadApplication = CreateObject("AutoCAD.Application") 

И определись с терминами "раннее" и "позднее" связывание. Похоже у тебя с ними путаница.
Если есть еще вопросы - смотри мою подпись.

Re: Управление свойствами главного окна AutoCAD при раннем связывании

Андрей Дудинский пишет:

в котором по ходу сценария необходимо управлять видимостью AutoCAD на экране, изменять высоту/ширину главного окна приложения, положение левого/верхнего края окна приложения. Управлять свойствами окна приложения надо, используя интерфейс API COM.

Зачем?

Похоже у тебя с ними путаница.

Да похоже не только с ними - в коде вообще полная белиберда.

реализовать на VB пользовательское приложение с использованием раннего связывания

Внешнее приложение или же плагин автокада?

Re: Управление свойствами главного окна AutoCAD при раннем связывании

Александр, Андрей, здравствуйте!

Спасибо, что оперативно откликнулись на мой вопрос. Александр, Вы наверное как всегда правы, Что-то я тоже засомневался, правильно ли толкую термины “раннее” и “позднее” связывание. Поэтому еще раз обратился к различным источникам информации. С одной стороны, согласно MSDN:
“Объект является объектом с ранней привязкой, если он присвоен переменной определенного типа объекта.
Объект является объектом с поздней привязкой, если он присвоен переменной, имеющей тип Object. . . По возможности следует использовать объекты с ранней привязкой. Они позволяют компилятору производить важные преобразования, повышающие эффективность приложений. У объектов с ранней привязкой быстродействие существенно выше, чем у объектов с динамической привязкой.” Тогда, в части подключения приложения AutoCAD, по-моему, у меня все правильно.
Другие источники (AutoCAD 2007 и Auto CAD LT 2007 : библия пользователя  Авторы: Эллен Финкельштейн...) говорят: “Существует два различных подхода к созданию объектов автоматизации – раннее связывание и позднее связывание. При раннем связывании Вы используете ключевое слово New для ссылки на библиотеку типов во время разработки. При позднем связывании нужно объявить переменную типа Object, а затем применить функцию CreateObject или GetObject для создания объекта нужного типа во время выполнения. Раннее связывание имеет определенные преимущества перед поздним, включая скорость, проверку синтаксиса при разработке и оперативную подсказку. . . И пример обращения к Excel с ранним и поздним связыванием“.

В тесте с моей интерпретацией ‘раннего’ связывания заменил строку кода
Dim app As AcadApplication = CreateObject("AutoCAD.Application")
На
Dim app As AcadApplication = New AcadApplication
Результат тот же - после установки Application.Visible = False AutoCAD остается виден на экране, а после установки Application.Visible = True – запускается второй экземпляр AutoCAD.
Еще замечено, что в обоих случаях быстродействие существенно ниже, чем у теста, в котором использую Dim app As Object = GetApplicationDispatch()

Что-то не так. . .
Коллеги, подскажите, где я накуралесил?

Андрей, если не брать во внимание ‘постановку’ задачи (в общем это будет приложение, выполняемое только под управлением самого AutoCAD, т.е. dll-сборка), то, подскажите, где  в коде вообще полная белиберда?  Код то вроде простой?
И еще, в данные тесты, для отработки решений, добавил код, создающий объект пользователя (документ) и добавляющий его в соответствующую коллекцию методом Documents.Add (app.Documents.Add(templatePath), где templatePath - название шаблона), проверку числа элементов в коллекции через свойство Documents.Count (app.Documents.Count), открытия существующего файла чертежа (DWG) методом Documents.Open (app.Documents.Open(pathFile, True), где pathFile – путь к файлу чертежа) и  в конце пытаюсь закрыть все открытые документы коллекции методом Documents.Close (app.Documents.Close ).
Так вот, в тесте с ‘ранним’ связыванием, пока в моей интерпретации, после закрытия всех документов AutoCAD остается открытым, но и остается открыт один документ “Чертеж1.dwg”, хотя в тоже время счетчик открытых документов app.Documents.Count равен 0:  (Фрагмент журнала сообщений в командной строке  “Закрываются все документы коллекции. Было 3 открытых документов. Стало 0”. Хочу уточнить, при этом AutoCAD функционирует в многодокументном режиме. Системная переменная SDI = 0.
Андрей, на Вашем сайте https://sites.google.com/site/bushmansn … h-otkrytia я встречал такую фразу: “ Количество документов, после закрытия последнего документа будет равным 1 [а почему не ноль?]*”. По идее должны быть закрыты все документы, а AutoCAD оставаться открытым. Это баг в AutoCAD или так он и должен работать?
А вот в тесте с ‘поздним’ связыванием, пока в моей интерпретации, при закрытии всех документов коллекции вылетает ошибка “Чертеж занят”. Использование   <CommandMethod("TestComVisibleLater", CommandFlags.Session)>_ вместо <CommandMethod("TestComVisibleLater")> _ , как Вы советуете в http://forum.dwg.ru/showthread.php?t=99386
- не помогает. Посоветуйте, что надо сделать, чтобы все документы коллекции, желательно в обоих случаях закрылись.

Ребята, буду искренне рад Вашей помощи. Просто очень хочется понять и разобраться как следует работать с интерфейсом API COM в различных ситуациях.

С уважением,
Андрей

(изменено: Андрей, 26 мая 2014г. 23:42:30)

Re: Управление свойствами главного окна AutoCAD при раннем связывании

Предлагаю перенести обсуждение темы в эту ветку. Там, по мере свободного времени, всё и разберём детально. На кадюзер я редко захожу (имхо - мёртвый форум).