Тема: Интерактивный выбор + ввод с клавиатуры

Спецы! Как реализовать такой сценарий - предоставить пользователю или выбрать элемент(AcDbEntity) на рабочем поле или возможность ввести строку в Command Window, т.е. что-то типа acedEntSel и acedGetString вместе взятых? Думал сначала, что поможет acedInitGet() с флагом RSG_OTHER, но для acedEntSel он игнорируется. Как быть?

Re: Интерактивный выбор + ввод с клавиатуры

Как вариант acedInitGet() с флагом RSG_OTHER и acedGetPoint. Если введена точка, то acedNEntSelP, в которую передаётся введенная точка.

Re: Интерактивный выбор + ввод с клавиатуры

Пока нашел только такое решение. Подскажите насколько оно адекватно?

...
ads_name entRes;
ads_point ptRes;
ads_matrix xformres;
int res;
struct resbuf * refstkres;

acedInitGet(RSG_OTHER, NULL);

res = acedGetPoint(NULL, NULL, ptRes);

if ( res == RTKWORD ) { // Ввели строку в Command Window
    acutPrintf(L"User Input!");
    ...
}
else { // Выбрали точку на рабочем поле
    acedNEntSelP(NULL, entRes, ptRes, TRUE, xformres, &refstkres);
    ...
}
...

Re: Интерактивный выбор + ввод с клавиатуры

Спасибо, Александр. Как только добавил свой пост - увидел ваш. Значит я правильно подумал  :D

Re: Интерактивный выбор + ввод с клавиатуры

S P пишет:

Пока нашел только такое решение. Подскажите насколько оно адекватно?

Ну собственно говоря это я и предложил.

Re: Интерактивный выбор + ввод с клавиатуры

Я просто не увидел, что вы ответили - страницу не обновил.  ;) Спасибо.

Re: Интерактивный выбор + ввод с клавиатуры

А еще вопрос.  Вот такой код

...
acedInitGet(RSG_OTHER, NULL);
res = acedGetPoint(NULL, NULL, ptRes);

switch ( res ) {
   case RTCAN:
    return false;
   case RTKWORD:
    res = acedGetInput(textString);
    ...
    break;
   case RTNORM :
       ...
  

дает возможность ввести текст, но без пробелов в вызове acedGetPoint.
Как получить строку с прбелами?

(изменено: Александр Ривилис, 5 сентября 2011г. 08:51:01)

Re: Интерактивный выбор + ввод с клавиатуры

S P пишет:

Как получить строку с прбелами?

Думаю что никак. Разве что переписать всё на acedGrRead.

(изменено: S P, 5 сентября 2011г. 10:37:16)

Re: Интерактивный выбор + ввод с клавиатуры

Почитал из документации, что эта функция позволяет делать ввод из разных источников, идентифицируемых параметром type, а результат находится в связанном списке структур resbuf. Но извлекать из этого списка весь нужный текст - еще одна большая проблема. В частности если пользователь указал на рабочем поле многострострочный текст - то он будет разбит на несколько блоков resbuf, эти блоки могут идти не один за другим по порядку, иметь разные значения restype и плюс ко всему прочему такой текст будет "сырым", т.е. содержать все символы редактирования - переводов строки (\n), новый абзац (\P), заголовок (\H1,\H2, ...), специальные последовательности фигурных скобок, точек с запятой и т.п. Да, жаль, что не все так, как хотелось бы  :(

(изменено: S P, 5 сентября 2011г. 10:46:55)

Re: Интерактивный выбор + ввод с клавиатуры

Хотя я наверное поторопился - по параметру type = 3 можно получить координаты точки выбора и передать их в acedNEntSelP. Попробую что нибудь наваять.

Александр, спасибо за подсказку.

(изменено: S P, 12 сентября 2011г. 13:26:23)

Re: Интерактивный выбор + ввод с клавиатуры

Снова вопрос. Возникли проблемы при вызове функции acedGrRead несколько раз. В первом вызове все проходит нормально, но в последующих вызовах функция как бы срабатывает сама без участия пользователя, возвращая в параметре type=26. В документации в описании значится "AUX1 menu button number". Почему так происходит?

P.S. Между вызовами acedGrRead открывается другой документ и активируется.

Re: Интерактивный выбор + ввод с клавиатуры

Наверное регистрируется вызов из меню открытие нового документа.

(изменено: S P, 12 сентября 2011г. 13:46:16)

Re: Интерактивный выбор + ввод с клавиатуры

Ok. А как тогда, так сказать, "очистить" ввод от этого вызова, чтобы функция не срабатывала на него?

P.S. Кстати другой документ открывается и активируется программно

(изменено: S P, 13 сентября 2011г. 11:34:48)

Re: Интерактивный выбор + ввод с клавиатуры

Оказалось, что проблема не ограничивается функцией acedGrRead. Проблема, как оказалось, не в открытии документов. После ряда экспериментов обнаружил, что, если перед вызовом функции из семейства acedGetXxx производить манипуляции с окном документа, то функции сразу же дают RTCAN в своем вызове. К примеру

...
ads_point ptRes;
acedGetAcadFrame()->MDIGetActive()->MDIMaximize();   // полностью раскрываем текущее окно
acedInitGet(RSG_OTHER, NULL);
switch ( acedGetPoint(NULL, NULL, ptRes) ) {                    // Получаем точку
   case RTNORM:
      ...
      break;
   case RTNONE:
      ...
      break;
   case RTKWORD:
      ...
      break;
   case RTCAN:                                                               // Но сразу же попадаем сюда!!!
     ...
     break;
   case RTERROR:
     ...
     break;
}

Почему так работают эти функции? Как этого избежать?

Re: Интерактивный выбор + ввод с клавиатуры

Эти функции работают только в контексте документа.

(изменено: S P, 13 сентября 2011г. 16:10:16)

Re: Интерактивный выбор + ввод с клавиатуры

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

Эти функции работают только в контексте документа.

Было бы очень странно, если бы они работали НЕ в контексте документа  ;)

Насколько я понял, манипуляции с окном в контексте приложения (изменения размеров к примеру):

acedGetAcadFrame()->MDIGetActive()->MDIMaximize();

тоже "оставляют свой след" в контексте документа. И следующий за этим вызов функции

acedGetXxx(...)

сразу же реагирует на эти "следы", если конечно был предварительно сделан вызов

acedInitGet(RSG_OTHER, NULL);

Re: Интерактивный выбор + ввод с клавиатуры

Тот код, который ты показал работает в каком контексте? С какими флагами зарегистрирована команда?

Re: Интерактивный выбор + ввод с клавиатуры

В контексте приложения. Флаги такие ACRX_CMD_MODAL | ACRX_CMD_SESSION

Re: Интерактивный выбор + ввод с клавиатуры

Не понял. Так чего ты хочешь? В команде работающей в контексте приложения функции acedGetXXX работать не должны.

(изменено: S P, 14 сентября 2011г. 13:00:41)

Re: Интерактивный выбор + ввод с клавиатуры

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

Не понял. Так чего ты хочешь? В команде работающей в контексте приложения функции acedGetXXX работать не должны.

Э-э-э... Теперь я не понял. Что значит не должны? В принципе, если "не трогать" окно, то эти функции отрабатывают нормально в команде с флагами ACRX_CMD_MODAL | ACRX_CMD_SESSION. Единственное - переключение между документами блокируется, т.е. работать можно только с документом, который был активным на момент вызова (меня это устраивает).

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

Re: Интерактивный выбор + ввод с клавиатуры

S P пишет:

Единственное - переключение между документами блокируется, т.е. работать можно только с документом, который был активным на момент вызова (меня это устраивает).

Зачем тебе ACRX_CMD_SESSION?

(изменено: S P, 14 сентября 2011г. 17:06:31)

Re: Интерактивный выбор + ввод с клавиатуры

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

Единственное - переключение между документами блокируется, т.е. работать можно только с документом, который был активным на момент вызова (меня это устраивает).

Зачем тебе ACRX_CMD_SESSION?

Ну для разных вещей... Основное - это открытие и закрытие документов. Мы это обсуждали здесь

Блокирование переключения документов меня не смущает. Прерывание ввода при изменении размеров окна, в принципе - тоже. Любая нативная команда AutoCAD, взаимодействующая с пользователем через командную строку (например КРУГ), работает также, т.е. прерывается.

(изменено: S P, 21 сентября 2011г. 01:13:32)

Re: Интерактивный выбор + ввод с клавиатуры

В продолжение темы. Предположим, что в методе acedInitGet() указаны ключевые слова. Как в последующих вызовах acedGetXxx() acedEntSel(), acedNEntSelP(), acedNEntSel(), и т.д. сделать так, чтобы эти ключевые слова можно было выбрать из контекстного меню по правой клавише мыши? Возможно ли настроить как-либо автозавершение для ключевых слов, если они вводятся вручную пользователем в командную строку?

Re: Интерактивный выбор + ввод с клавиатуры

лень выбирать куски. кидаю пример целиком

static void gnnLesson2gnn_multi(void)
{
    bool next = true;
    ACHAR szBuffer[255];
    ACHAR userstring[133];
    int i = 1;
    AcGePoint3d pt;
    AcGePoint3dArray ptArray;
    ptArray.removeAll();

    while (next) 
    {
        _tcsncpy(userstring,_T("\0"),133);
        acutPrintf(_T("\n"));
        _tcsncpy(szBuffer,_T("\0"),255);
        _itot(i,szBuffer,10);
        _tcscat(szBuffer, _T("-я точка или [Отменить]: "));
        acedInitGet( RSG_NOZERO | RSG_NONEG | RSG_OTHER, _T("О")); 
        switch(acedGetPoint(NULL,szBuffer,asDblArray(pt)))
        {
            case RTERROR:
            case RTCAN:
            case RTNONE:
                next = false;
                break;    

            case RTKWORD:
            {
                acedGetInput(userstring);
                if (userstring[0] == _T('О'))
                {
                    if (!ptArray.isEmpty())
                    {
                        ptArray.removeLast();
                        i--;
                        break;
                    }
                    else
                    {
                        acutPrintf(_T("\nДа собственно нечего отменять"));
                        break;
                    }
                }
                else
                {
                    acutPrintf(_T("\nUser error. Replase user :):):)"));
                    break;
                }
            }

            case RTNORM:
            {
                ptArray.append(pt);
                i++;
            }
        }
    }

    acutPrintf(_T("\nВсего точек: %d"), ptArray.length());
    for (int a = 0; a < ptArray.length(); a++)
        acutPrintf(_T("\n%d-я точка: %.2f,%.2f,%.2f"),a+1, ptArray.at(a).x, ptArray.at(a).y, ptArray.at(a).z);
}

тут ключевое слово только одно, но для примера хватит

(изменено: S P, 21 сентября 2011г. 12:26:28)

Re: Интерактивный выбор + ввод с клавиатуры

Супер! Николай, огромное спасибо!