Тема: Регистрация команды и функция команды с параметром.

Регистрирую команду через

addCommand(
const char* cmdGroupName,
const char* cmdGlobalName,
const char* cmdLocalName,
Adesk::Int32 commandFlags,
AcRxFunctionPtr FunctionAddr,
AcEdUIContext * UIContext = NULL,
int fcode = -1,
HINSTANCE hResourceHandle = NULL,
AcEdCommand** cmdPtrRet = NULL) = 0;

Возможно ли таким способом поставить команде в соответствие функцию с параметром? При этом значение параметра нужно указывать при регистрации команды.

Re: Регистрация команды и функция команды с параметром.

Возможно ли таким способом поставить команде в соответствие функцию с параметром?

Нет. А зачем?

Re: Регистрация команды и функция команды с параметром.

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

Нет. А зачем?

Сделать свой диспатчер по коду комадны.

Re: Регистрация команды и функция команды с параметром.

Не понял. Поясни подробнее. Может это как-то иначе можно реализовать.

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Как бы это было:
Я регистрирую одну команду с параметром несколько раз, с разным значением параметра.
В результате, при вызове команды все запросы приходят в одну функцию, например, Execute(параметр).
Функция Execute, вызывает, к примеру, функцию Dispatch(параметр), которая по параметру и определит, какой код дальше выполнять.

Re: Регистрация команды и функция команды с параметром.

> equilibrium
Команды предназначены не для этой цели.
А не проще ли тогда регистрировать не команду, а функцию? Посмотри в сторону acedDefun/acedRegFunc

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Спасибо, посмотрю.

Re: Регистрация команды и функция команды с параметром.

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

А не проще ли тогда регистрировать не команду, а функцию? Посмотри в сторону acedDefun/acedRegFunc

acedDefun, на сколько я понял, предназначена для того, чтобы сделать функцию из ARX доступной AutoLISP, а acedRegFunc - чтобы получить доступ к функциям из другого ARX приложения.
Поясните, пожалуйста, каким образом я должен их использовать для реализации своей задумки.

Re: Регистрация команды и функция команды с параметром.

Зарегистрированная таким образом функция может принимать параметры (с использованием функции acedGetArgs) Так что ты сможешь использовать вызов вида:

(Execute <параметр>)

Впрочем я совершенно немогу понять зачем это все нужно. Зачем все вешать на одну команду, чтобы потом пытаться разделить действия в зависимости от параметра? Почему не делать отдельные команды на разные действия? В каком контексте это вообще будет выполняться что необходимо регистрировать команду/функцию?

Re: Регистрация команды и функция команды с параметром.

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

Зарегистрированная таким образом функция может принимать параметры (с использованием функции acedGetArgs) Так что ты сможешь использовать вызов вида:

(Execute <параметр>)

Еще немного поясню и укажу, что мне в данном механизме не понятно.
Допустим, я регистрирую фукнцию Execute<параметр> с помощью функции acedRegFunc.
Каким образом я могу поставить эту функцию в соответствие команде?
Каким образом через поставленную в соответствие команду я могу передать параметр в функцию? (Предложим, я вызываю команду из меню)

Впрочем я совершенно немогу понять зачем это все нужно.

В моем текущем приложении есть некоторое количество команд. Приложение работает с COM-dll. Каждая такая команда может бросить исключение _com_error или одно из определенных мною исключений.
Таким образом в каждой функции, поставленной в соответствие некоторой команде я должен их обработать, повторяется код, что не очень хорошо, если его придется править.
Я сделал коды команд и вызываю функцию Execute(код_команды), где в одном блоке try/catch по коду выбираю нужную функцию. Этот "выбор" вынесен в отдельный метод Dispatch(код_команды).
Таким образом, я имею n(== количество команд) функций + функция Execute(параметр). Хочу вызывать Execute(параметр) непосредственно, избавившись от упомянутых выше n функций.

Re: Регистрация команды и функция команды с параметром.

> equilibrium
Если ты вызываешь из меню, то для каждого пункта можешь написать что-то типа:
^C^C^P(Execute "код1")^P
...
^C^C^P(Execute "кодN")^P
Для любого кода будет вызвана функция
void ads_Execute(void), в которой используя acedGetArgs ты можешь выяснить какой именно "кодI" задан.
P.S.: Хотя вся схема мне не нравится. Не очень понимаю почему нельзя вынести тот код, который будет повторятся в отдельную функцию (один из принципов структурного программирования).

Re: Регистрация команды и функция команды с параметром.

Александр Ривилис пишет:
^C^C^P(Execute "код1")^P

Спасибо, попробую так, будет что-то непонятно - спрошу.

P.S.: Хотя вся схема мне не нравится. Не очень понимаю почему нельзя вынести тот код, который будет повторятся в отдельную функцию (один из принципов структурного программирования).

Видимо, я плохо объяснил. Я именно так и сделал. Повторяющийся код вынесен в Execute(параметр). В результате получилось что-то вроде

void ArxModuleFunc1()
{    
    Execute(FUNC1_INT);
}
...
void ArxModuleFuncN()
{    
    Execute(FUNCN_INT);
}
void Execute(CString commandCode)
{            
    try
        {
        MyCheck();        
        Dispatch(commandCode);                                
    }
    catch(exception &ex)
    {
        ExceptionHandling(ex);
    }    
}
void Dispatch(CString commandCode)
{
    if (CommandCompare(commandCode, FUNC1_INT, FUNC1_LOC))
    {
        Func1();
    }
        else if (...) {...}
    else if (CommandCompare(commandCode, FUNCN_INT, FUNCN_LOC))
    {
                FunN();
        }
}

А избавиться я хочу как раз от функций ArxModuleFunc1...N.

Re: Регистрация команды и функция команды с параметром.

Посмотри пример в ObjectARX SDK samples\misc\fact_dg

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Посмотрел пример, собрал приложение. Загрузил его.
В дебаге проверил, как отбработала функция funcload. acedDefun удачно отработала для обеих функций из func_entry func_table - fact и sqr.
Как я понял, теперь могу использовать данные команды. Хочу вызвать команду fact c параметром из меню:

***MENUGROUP=FACT
***POP1
ID_FACT    [FACT]
ID_FACT_5    [FACT 5]^C^C^P(fact "5")^P

При выборе пунтка "FACT 5" не вызываются функции из приложения.
Поясните, пожалуйста, стоит ли как-то еще регистрировать команду и как ее вызвать.

Re: Регистрация команды и функция команды с параметром.

Что нибудь сообщает?
Попробуй так:

ID_FACT_5  [FACT 5]^C^C^P(fact "5");^P

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Попробовал, результат тотже.
Никаких сообщений в консоли/диалогов нет.
SDK - 2006, MS VS 7.0, AutoCAD 2004.

Re: Регистрация команды и функция команды с параметром.

Попробуй в командной строке:

(fact "5")

Должно быть сообщение в командной строке:

Application ERROR: Argument should be an integer.

А вообще-то для AutoCAD 2004 нужно использовать SDK 2004. Иначе могут быть глюки или приложение вообще не загрузится.

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Спасибо, Александр, команда "^C^C^P(fact "5");^P" работает.
Скорее всего я ошибся, при перегрузке меню, когда менял команду. Правда, старался удадить mnr и mnc файлы..
С SDK 2006 для AutoCAD 2004 в своей небольшой практике проблем пока не встречал. Встречу - буду использовать другую версию. А пока использую SDK 2002 для AutoCAD2000/2002, 2006 - для AutoCAD 2004/2006, 2007 - для AutoCAD 2007/2008.

Re: Регистрация команды и функция команды с параметром.

> equilibrium
Я тоже наткнулся на такой глюк меню. Что касается версии SDK - это конечно твое право, но по правилам:
2000 для 2000,2000i,2002
2004 для 2004,2005,2006
2007 для 2007,2008,2009

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Спасибо, Александр, воспользуюсь SDK по правилам.
У меня возникла проблема при использовании команды, зарегистрированной с помощью acedDefun. Команда, как и в примере fact_dg регистрируется при событии AcRx::kLoadDwgMsg.
Мое приложение, в том числе, может открывать документы.
Вызываю зарегистрированную команду с неким параметром для открытия документа - команда отрабатывает успешно: документ открывается, а функция регистрации команд, которая вызывается по событию AcRx::kLoadDwgMsg выполняется еще раз.
После открытия документа, вызываю команду с тем же параметром (или любым другим) повторно - в консоли получаю

; error: ADS request error

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

; error: no function definition: MYCOMMAND

Выгружается ли команда, зарегистрированная с помощью acedDefun, после каждого ее вызова?
Когда мне следует регистрировать команду?

Re: Регистрация команды и функция команды с параметром.

> equilibrium
А вот с открытием документа у тебя могут быть проблемы. Главная из них та, что функции зарегистрированные через acedDefun выполняются в контексте документа и при открытии другого документа ее выполнение приостанавливается и завершается только тогда, когда ты вернешься к документу, в котором эта функция была запущена.

Выгружается ли команда, зарегистрированная с помощью acedDefun, после каждого ее вызова?

Нет. Но она должна быть зарегистрирована в каждом открытом документе.

Re: Регистрация команды и функция команды с параметром.

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

Но она должна быть зарегистрирована в каждом открытом документе.

Регистрирую команду на событии AcRx::kLoadDwgMsg. При вызове команды во вновь открытом документе получаю в консоли:

; error: ADS request error

Re: Регистрация команды и функция команды с параметром.

> equilibrium
Это происходит всегда или только тогда, когда новый документ открывается при помощи твоей функции? Если всегда, то это глюк твоего AutoCAD. Во втором случае внимательно читай > Александр Ривилис (2008-04-29 00:44:16)
Реальная регистрация произойдет только тогда, когда твоя функция завершится, т.е. тебе нужно вернутся к тому документу из которого ты открыл другой.

Re: Регистрация команды и функция команды с параметром.

> Александр Ривилис
Спасибо.