| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > GetKeyword + InitializeUserInput + VB.Net = проблема

GetKeyword + InitializeUserInput + VB.Net = проблема

Ответ
Поиск в этой теме
Непрочитано 12.07.2010, 07:36 #1
GetKeyword + InitializeUserInput + VB.Net = проблема
huckleberry
 
Регистрация: 12.07.2010
Сообщений: 6

Уважаемые коллеги.

Пишу я, значит, на vb.net-е (версия 2-я) библиотечку для работы с автокад (пока стоит 2008-й). Почему VB? Потому, что он обладает очень подходящим свойством позднего связывания. Почему библиотечку? Потому, что остальная часть на C#, который мне нравится значительно больше, но свойством позднего связывания он не обладает. Изюм в том, что я смею надеться избежать пересборки при изменении версии AutoCAD. Ну разве что произойдет полный отказ от COM. Это было вступление. Теперь по сути.

Вот кусок кода №раз:
Код:
[Выделить все]
    Shared AcadApp As Object

    Public Function Connect() As Boolean Implements TSInt.iTSAcad.Connect
        AcadApp = GetObject(, "AutoCAD.Application")
        Dim ver As String
        ver = AcadApp.Version

    End Function
Вот кусок кода №два:
Код:
[Выделить все]
    Public Function GetKeyword(ByVal prompt As String, ByVal keywords As String) As String Implements TSInt.iTSAcad.GetKeyword

        Dim doc = AcadApp.ActiveDocument
        Dim utl = doc.Utility
        Dim word
        Try
            utl.InitializeUserInput(1, keywords)
            word = utl.GetKeyword(prompt)

        Catch ex As Exception
            If (ex.Message.Contains("0x80020009")) Then
                Return ""
            Else
                Throw ex
            End If
        End Try

        Return word
    End Function
При попытке работать успешно проглатывается InitializeUserInput (например, keywords = "Asd Zxc"), затем происходит вход в GetKeyword и... и при вводе слова "Asd" вылезает "Введено неправильное ключевое слово". То же самое с любым набором слов или букв.

Однако. Если вместо строчки
Код:
[Выделить все]
            utl.InitializeUserInput(1, keywords)
поставить
Код:
[Выделить все]
            utl.InitializeUserInput(1, "Asd Zxc")
ТО ВСЕ РАБОТАЕТ!!!

Меня это не устраивает - мне крайне желательно передавать набор слов как параметр. Я много чего попробовал, чтобы добиться этого, но результат пока нулевой. Специально не буду перечислять, что я попробовал, дабы не ограничивать Вас в фантазиях. С вниманием слушаю Ваши советы.

ЗЫ Кстати, тот пример в хелпе по GetKeyword при исполнении его из MS Word тоже не работает...
Просмотров: 3719
 
Непрочитано 12.07.2010, 10:12
1 | #2
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Это известная проблема
Вместо этого нужно использовать метод GetKeyWords:

Код:
[Выделить все]
        [CommandMethod("CLE")]

        public void ChooseLetter()
        {
            Document doc =  Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            PromptKeywordOptions opts = new PromptKeywordOptions("\nChoose From Alphabet: ");
            opts.AllowNone = true;
            opts.Keywords.Add("Alpha");
            opts.Keywords.Add("Bravo");
            opts.Keywords.Add("Charlie");
            opts.Keywords.Add("Delta");
            opts.Keywords.Default = "Alpha";
            PromptResult kres = ed.GetKeywords(opts);
            if (kres.Status != PromptStatus.OK)
                return;
            Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog(kres.StringResult);
        }
~'J'~
Олег (jr.) вне форума  
 
Непрочитано 12.07.2010, 10:26
#3
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


Цитата:
Изюм в том, что я смею надеться избежать пересборки при изменении версии AutoCAD.
Это врядли.
Sleekka вне форума  
 
Непрочитано 12.07.2010, 10:31
#4
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от huckleberry Посмотреть сообщение
остальная часть на C#, который мне нравится значительно больше, но свойством позднего связывания он не обладает
Ой ли? А поиск по гуглу не судьба попробовать, прежде чем такое утверждать?

Цитата:
Для использования позднего связывания Visual C# необходимо применить метод System.Type.InvokeMember. Этот метод вызывает методы IDispatch::GetIDsOfNames и IDispatch::Invoke для привязки к методам и свойствам сервера автоматизации.
Offtop: VB.Net может что-то такое, чего не может C# (наследник C++ и Java) - прямо таки анекдот какой-то...
hwd вне форума  
 
Автор темы   Непрочитано 12.07.2010, 10:35
#5
huckleberry


 
Регистрация: 12.07.2010
Сообщений: 6


Олег, я рад, что Вы обратили внимание на мой пост.
Однако предлагаемое Вами решение для меня не подходит по двум причинам:

1) Это, насколько я понимаю, предполагает написание модуля, встраиваемого в автокад (может, тут я ошибаюсь), ну а я подсоединяюсь к автокаду параллельно.

2) Где-то вначале такого кода подразумевается вставить примерно следующее:
Код:
[Выделить все]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;
Именно от этого я пытался уйти, создавая сборку на бейсике - я СПЕЦИАЛЬНО использовал позднее связывание, ни одного референса у меня пока нет.

Можно ли этого достичь как-то иначе, без референсов?
huckleberry вне форума  
 
Автор темы   Непрочитано 12.07.2010, 10:39
#6
huckleberry


 
Регистрация: 12.07.2010
Сообщений: 6


hwd, уточним, да, обладает, но, насколько я помню, только с 3-ей версии фреймворка. Я же написал, что у меня 2-й, не хочу пока ставить 3-й фреймворк. Да, через Invoke вполне реально. Но в бейсике придется написать меньше кода, который будет выглядеть лучше и его будет проще поддерживать. Можете считать меня аппологетом 3-го фреймворка и этой его фичи, которую все ругают

Sleekka, почему Вы так считаете?

Олег, к сожалению, мое сообщение не отобразилось (типа ушло на модерацию), поэтому напишу кратко - я бы не хотел добавлять референсы, в этом для меня весь смысл сборки на бейсике.
huckleberry вне форума  
 
Непрочитано 12.07.2010, 11:00
#7
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от huckleberry Посмотреть сообщение
hwd, уточним, да, обладает, но, насколько я помню, только с 3-ей версии фреймворка. Я же написал, что у меня 2-й, не хочу пока ставить 3-й фреймворк. Да, через Invoke вполне реально.
Во первых - плохо помните (во 2-м фрэйме System.Type.InvokeMember имеется). Во вторых - это не сложно было проверить и самому.

Цитата:
Но в бейсике придется написать меньше кода, который будет выглядеть лучше и его будет проще поддерживать.
Даже комментировать не хочется....

Цитата:
и этой его фичи, которую все ругают
Какой "фичи" и кто "все"? Все те, кто до сих пор не знает, что 2-й фрэймворк имеет System.Type.InvokeMember? Ну так это не та публика, мнение которой имеет вес.

Цитата:
Изюм в том, что я смею надеться избежать пересборки при изменении версии AutoCAD
ObjectARX 2009:
Цитата:
Binary compatibility between AutoCAD 2008 and AutoCAD 2009 has been maintained. Applications built with ObjectARX for AutoCAD 2008, ObjectARX for AutoCAD 2007, and ObjectARX for AutoCAD 2008 will continue to run in AutoCAD 2009, but applications built using ObjectARX for AutoCAD 2009 may not work with previous releases.
А вот в 2010-й версии .Net API AutoCAD произошли очень сильные изменения (очень много не только добавлено, но и удалено). Полный перечень изменений смотрите в ObjectARX 2010.

Последний раз редактировалось hwd, 12.07.2010 в 11:22.
hwd вне форума  
 
Автор темы   Непрочитано 12.07.2010, 11:24
#8
huckleberry


 
Регистрация: 12.07.2010
Сообщений: 6


hwd, честно, я не хочу спорить. Более того, результат спора никак не относится к решению возникшей у меня проблемы - что через Invoke, что через механизмы бейсика - проблема таким образом не решится.

Позднее связывание - это довольно широкий термин. Чем лично мне (заметьте, лично мне) приятен бейсик - это тем, что операции Invoke (по несколько штук для каждого обращения к методу объекта) он выполняет сам, так сказать, инлайн. Достаточно просто написать "AcadApp.Documents" вместо пары строк с Invoke'м. В С# в 3-м фреймворке это, кажется, тоже есть (не проверял, но журнальчики читал). Во 2-м же - надо делать Invoke. Вариант "инлайн" мне нравится больше. Я не настаиваю, у Вас может быть иное мнение по этому поводу. Вы, вероятно, будете говорить про производительность, контроль кода и "неуловимые" ошибки, возникающие в ситуации с неуправляемым приведением типов. Да, все это так (я, между прочим, когда-то начинал с чистого С, dll-hell'а, MFC, gcc и прочих приятных вещей), но меня это устраивает, потому что я имею иллюзию, что контролирую процесс расползания этого подхода по остальным модулям системы. Поэтому предлагаю не спорить, а сосредоточиться на решении конкретной проблемы.

По поводу ObjectARX конкретизирую более внятно - я не делаю arx. Если бы делал - вопроса о бейсике и не стояло бы. Я, наиболее вероятно, писал бы это на сях.
huckleberry вне форума  
 
Непрочитано 12.07.2010, 12:32
#9
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от huckleberry Посмотреть сообщение
По поводу ObjectARX конкретизирую более внятно - я не делаю arx. Если бы делал - вопроса о бейсике и не стояло бы. Я, наиболее вероятно, писал бы это на сях.
При чём здесь arx или не arx... Вы ведь хотите с помощью позднего связывания работать с объектами AutoCAD, которые по факту являются компонентами библиотеки ObjectARX, ибо на нём написан AutoCAD. Если в очередной версии продукта Autodesk удалит/изменит из ObjectARX используемый вами в коде класс, (не важно позднее связывание это или обёртка), то вносить изменения в код для следующей версии AutoCAD всё равно придётся.

Наиболее полную информацию о произведённых модификациях в составе библиотеки очередной версии AutoCAD можно почерпнуть как раз-таки только из документации самого ObjectARX.

Т.о. полная совместимость кода с новыми версиями AutoCAD не гарантируется (к сожалению), и для очередной версии AutoCAD придётся проверять, на месте ли те классы, которыми вы пользуетесь. Сие касается любых плагинов AutoCAD и написал я это применительно к вашей фразе:
Цитата:
я смею надеться избежать пересборки при изменении версии AutoCAD
Не факт, что модификация коснётся используемых вами в коде классов, но перечень изменений весьма велик, поэтому, если вам, как вы пишете, не безразлична совместимость без переписывания кода - лучше предварительно посмотреть список изменений в составе библиотеки. Я не настаиваю конечно, просто если вы пишете под 2008-й, а по факту уже есть 2011-й, то проследить изменения не составит труда и вы будете точно знать, придётся ли вам что-то переписывать в своём коде.

п.с. На мой взгляд Олег (jr.) предлагает наиболее оптимальный вариант.

п.с.2 А чем вас не устроил .Net API AutoCAD? Autodesk его довольно таки интенсивно расширяет от версии к версии. Работа с подшивкой, к примеру, вообще осуществляется через библиотеку, написанную на .Net (т.е. это не обёртка).

Последний раз редактировалось hwd, 12.07.2010 в 12:52.
hwd вне форума  
 
Автор темы   Непрочитано 12.07.2010, 15:37
#10
huckleberry


 
Регистрация: 12.07.2010
Сообщений: 6


Цитата:
При чём здесь arx или не arx... Вы ведь хотите с помощью позднего связывания работать с объектами AutoCAD, которые по факту являются компонентами библиотеки ObjectARX, ибо на нём написан AutoCAD. Если в очередной версии продукта Autodesk удалит/изменит из ObjectARX используемый вами в коде класс, (не важно позднее связывание это или обёртка), то вносить изменения в код для следующей версии AutoCAD всё равно придётся.
Не совсем так. Это произойдет только, если будет изменен COM-интерфейс. Но это происходит реже (есть такая надежда), чем изменение библиотеки ObjectARX. Пример - да, отличия в объектной модели COM у Excel 2010 и Excel 2003 имеются, но они не столь значительны, чтобы это потребовало полной переработки имеющихся макросов. А вот 95-й офис от 2003-го отличается значительно. Понятно, гарантий нет никаких; более того, когда происходит эволюционный скачок, изменений не избежать. Ну вот тогда и будем шевелиться. За этот код мне никто не платит, я надеюсь на нем зарабатывать сам -> минимум телодвижений, красивых кнопок с анимацией, но максимум результата.

Еще раз повторюсь - у меня не плагин. Он работает во внешней относительно автокада памяти и внутрь не лезет.

.Net API... Наеврное, хорошая штука. Скажу честно, не пробовал. Опять же вопрос по "раннему/позднему связыванию" - оно там как? Чисто интерфейсы? Или все-таки придется шевелить ручками для каждой версии автокада? Я, конечно, поищу. Спасибо за подсказку, как это называется.

Вариант Олега я, безусловно, поставил для себя в верхние строчки списка (даже спасибо сказал ). И все же - почему не срабатывает нормально InitializeUserInput? Ему статик нужен на вход? Можно ли как-то это победить малой кровью?

Последний раз редактировалось huckleberry, 12.07.2010 в 16:10.
huckleberry вне форума  
 
Непрочитано 12.07.2010, 16:24
1 | #11
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от huckleberry Посмотреть сообщение
.Net API... Наеврное, хорошая штука. Скажу честно, не пробовал. Опять же вопрос по "раннему/позднему связыванию" - оно там как? Чисто интерфейсы? Или все-таки придется шевелить ручками для каждой версии автокада? Я, конечно, поищу. Спасибо за подсказку, как это называется.

Вариант Олега я, безусловно, поставил для себя в верхние строчки списка. И все же - почему не срабатывает нормально InitializeUserInput? Ему статик нужен на вход? Можно ли как-то это победить малой кровью?
"раннее/позднее связывание" я использовал всего несколько раз, да и то очень давно и применительно к MS Office... Поэтому на тему связывания применительно к AutoCAD ничего подсказать не смогу (не использую этот способ). Свои приложения оформляю в виде плагинов, поскольку при работе с AutoCAD использую только .Net API AutoCAD. Дело в том, что этот интерфейс, к сожалению, можно использовать только при написании плагинов, а в отдельном приложении заюзать не удастся.
Официальный мануал по .Net API здесь, так же интерес представляют следующие ресурсы:
1. тынц
2. тынц
Вообще .Net API AutoCAD использовать гораздо удобней, если не принципиально, чтобы ваше приложение работало не как плагин, а как внешний "аппликэйшен".

Вообще по тематике .Net программирования имеет смысл задавать вопросы на англоязычных форумах. На dwg.ru и caduser.ru вероятность получения ответа значительно ниже, поскольку основная масса форумчан пишут на Lisp.
Из зарубежных форумов могу посоветовать этот и этот. Там шансов на ответ больше.

Хороших русскоязычных ресурсов по .Net API AutoCAD, я не встречал (да и объём официального английского мануала, честно говоря, оставляет желать лучшего)... На буржуйских сайтах встречаются монстры программирования вроде Tony Tonzillo.
На этом сайте по .Net (применительно к AutoCAD) лучше всех разбирается Александр Ривилис, но его, к сожалению, с некоторых пор не видно (предполагаю, что он в отпуске).

Последний раз редактировалось hwd, 12.07.2010 в 16:30.
hwd вне форума  
 
Непрочитано 12.07.2010, 17:51
#12
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


В справке по AutoCAD ActiveX вторым аргументом должен быть variant, ссылающийся на массив строк. Вот выдержка из справки (см. выделенное оранжевым цветом):
Код:
[Выделить все]
Signature 

object.InitializeUserInput Bits[, Keyword] 

Object

Utility
The object this method applies to. 

Bits

Integer; input-only
To set more than one condition at a time, add the values together in any combination. If this value is not included or is set to 0, none of the control conditions apply.
1 
 Disallows NULL input. This prevents the user from responding to the request by entering only [Return] or a space.
2
 Disallows input of zero (0). This prevents the user from responding to the request by entering 0.
4
 Disallows negative values. This prevents the user from responding to the request by entering a negative value. 
8
 Does not check drawing limits, even if the LIMCHECK system variable is on. This enables the user to enter a point outside the current drawing limits. This condition applies to the next user-input function even if the AutoCAD LIMCHECK system variable is currently set.
16
 Not currently used.
32
 Uses dashed lines when drawing rubber-band lines or boxes. This causes the rubber-band line or box that AutoCAD displays to be dashed instead of solid, for those methods that let the user specify a point by selecting a location on the graphics screen. (Some display drivers use a distinctive color instead of dashed lines.) If the POPUPS system variable is 0, AutoCAD ignores this bit. 
64
 Ignores Z coordinate of 3D points (GetDistance method only). This option ignores the Z coordinate of 3D points returned by the GetDistance method, so an application can ensure this function returns a 2D distance.
128
 Allows arbitrary input—whatever the user types.
 
Keyword

Variant (array of strings); input-only; optional
The keywords that the following user-input method will recognize.
У вас же переменная keywords объявлена как String. Может это должен быть массив String[] ?
Имеется ввиду, сделать массив из одной строки "Asd Zxc" ! Возможно в случае с литералом компилятор именно это и делает втихую.
Подозреваю, что метод utl.InitializeUserInput(1, keywords) в качестве второго аргумента ожидает Object. И если ему передать строку а не массив строк,то ошибки компиляции не будет, но и смысл исказится. Нужен массив из одной строки!
__________________
...в шее моей жилы железные, и лоб мой - медный...

Последний раз редактировалось Pastor, 12.07.2010 в 18:07.
Pastor вне форума  
 
Автор темы   Непрочитано 13.07.2010, 08:23
#13
huckleberry


 
Регистрация: 12.07.2010
Сообщений: 6


Цитата:
Сообщение от Pastor Посмотреть сообщение
У вас же переменная keywords объявлена как String. Может это должен быть массив String[] ?
Имеется ввиду, сделать массив из одной строки "Asd Zxc" ! Возможно в случае с литералом компилятор именно это и делает втихую.
Подозреваю, что метод utl.InitializeUserInput(1, keywords) в качестве второго аргумента ожидает Object. И если ему передать строку а не массив строк,то ошибки компиляции не будет, но и смысл исказится. Нужен массив из одной строки!
Хорошая была идейка... не помогло
код был такой:
Код:
[Выделить все]
Dim kw1() As String = {"Word Aord"}
utl.InitializeUserInput(1,kw1)
и такой:
Код:
[Выделить все]
Dim kw1() As String = {"Word", "Aord"}
utl.InitializeUserInput(1,kw1)
Вылетает с исключением "Неверный параметр KeyWordList"

hwd, за ссылки ОГРОМНОЕ спасибо. Активно изучаю.
huckleberry вне форума  
 
Непрочитано 13.07.2010, 14:44
#14
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


А как выглядит прототип (сигнатура) метода utl.InitializeUserInput(...)?

И ещё.
Раз уж была просьба в фантазиях себя не ограничивать, то предлагаю проверить следующее.
Перед тем, как передать keywords в utl.InitializeUserInput(1, keywords) выполнить следующее:
keywords = String.Intern( keywords ).
__________________
...в шее моей жилы железные, и лоб мой - медный...

Последний раз редактировалось Pastor, 13.07.2010 в 15:43.
Pastor вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > GetKeyword + InitializeUserInput + VB.Net = проблема

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с пространством листа и ограничением печати Мысь AutoCAD 27 14.09.2018 13:13
Проблема с выводом на печать чертежей, содержащийх подрезанные растровые изображения (AutoCAD 2009LT) GazRust AutoCAD 13 27.06.2014 10:51
Проблема с файлом после импорта из Компас Alex 166 AutoCAD 7 22.08.2008 10:33
проблема экспорта файлов по IFC из ADT в лиру и ревит thygank Revit 1 03.08.2008 18:08
Проблема с ксероксом Canon PC860 _Oleg_ Разное 5 26.12.2007 10:18