Коды Служебного бита Ввода пользователя
Коды служебного бита ввода пользователя, перечисленные в следующей таблице пропускают как первый параметр к acedInitGet () функция, чтобы управлять поведение функций ввода пользователя acedGetxxx, acedEntSel, acedNEntSelP, acedNEntSel, и acedDragGen:
Коды служебного бита Ввода пользователя
Код | Описание |
RSG_NONULL | Отвергают нулевой{*пустой*} ввод |
RSG_NOZERO | Отвергают нулевые значения |
RSG_NONEG | Отвергают отрицательные значения |
RSG_NOLIM | Не проверяют{*отмечают*} пределы рисунка, даже если LIMCHECK включен |
RSG_DASH | Пунктирные линии Использования при рисунке резиновой полосы выравнивают или поле |
RSG_2D | Игнорируют координату Z трехмерных точек (acedGetDist () только) |
RSG_OTHER | Позволяют произвольный ввод (безотносительно типов пользователя) |
Списки и другие динамически размещенные данные
Структура resbuf включает поле указателя, rbnext, для соединения буферов результатов в список. Буфера Результатов могут быть размещены статически, объявляя их в приложении. Вы делаете это, когда только единственный буфер результатов используется (например, acedGetVar () и acedSetVar ()) или когда, только короткий список необходим. Но более длинные списки проще, чтобы обработать, размещая их динамически, и списки, возвращенные функциями ObjectARX всегда размещаются динамически. Один из наиболее часто используемые функции, который возвращает список связей - acedGetArgs ().
“ Оценка Внешних Функций ” на странице 526 показывает AutoLISP, запрашивающий внешней подпрограммы, которая берет параметры трех отличных типов: строка, целое число, и реальное значение:
( Doit pstr iarg rarg)
Следующий код сегментирует показы, как осуществить функцию с такой последовательностью запроса. Типовая функция проверяет, чтобы список параметров был правилен и сохранил значения в местном масштабе перед действием на них (операции не показываются). Пример предполагает, что предыдущий запрос к acedDefun () назначил внешнюю подпрограмму функциональный код 0, и что все функции, определенные этим приложением берут по крайней мере один параметр:
// Выполнить определенную функцию.
int dofun()
{
struct resbuf *rb;
char str[64];
int ival, val;
ads_real rval;
ads_point pt;
// Get the function code.
if ((val = acedGetFuncode()) == RTERROR)
return BAD; // Indicate failure.
// Get the arguments passed in with the function.
if ((rb = acedGetArgs()) == NULL)
return BAD;
switch (val) { // Which function is called?
case 0: // (doit)
if (rb->restype!= RTSTR) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a string.");
return BAD;
}
// Save the value in local string.
strcpy(str, rb->resval. rstring);
// Advance to the next result buffer.
rb = rb->rbnext;
if (rb == NULL) {
acutPrintf("\nDOIT: Insufficient number of arguments.");
return BAD;
}
if (rb->restype!= RTSHORT) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a short integer.");
return BAD;
}
// Save the value in local variable.
ival = rb->resval. rint;
// Advance to the last argument.
rb = rb->rbnext;
if (rb == NULL) {
acutPrintf("\nDOIT: Insufficient number of arguments.");
return BAD;
}
if (rb->restype!= RTREAL) {
acutPrintf("\nDOIT called with %d type.", rb->restype);
acutPrintf("\nExpected a real.");
return BAD;
}
// Save the value in local variable.
rval = rb->resval. rreal;
// Check that it was the last argument.
if (rb->rbnext!= NULL) {
acutPrintf("\nDOIT: Too many arguments.");
return BAD;
}
// Operate on the three arguments.
. . .
return GOOD; // Indicate success
break;
case 1:
// Execute other functions.
. . .
}
}
ОБРАТИТЕ ВНИМАНИЕ, что этот пример исключителен в одном отношении: acedGetArgs () - единственная ObjectARX глобальная функция, которая возвращает список связей, который приложение должно явно не выпустить. Следующая секция описывает обычный путь управления памятью, необходимой для списков.
Управление памятью Буфера результата
Основное различие между списками буфера результата и сопоставимыми списками результата AutoLISP - то, что ObjectARX-приложение должно явно управлять списками, которые это создает и использования. Создает ли приложение список или имеет тот, пропускал к этому, это - ответственность приложения выпустить буфера результатов, которые это размещает. ObjectARX не имеет никакой автоматической сборки "мусора", поскольку AutoLISP делает. Приложение должно вызвать библиотечную функцию acutRelRb () чтобы выпустить динамически размещенные буфера результатов, когда приложение закончено с ними.
AcutRelRb () функция выпускает полный список, который следует за указанным буфером результатов, включая указанный (главный) буфер, непосредственно и любая строка оценивает это буфера в точке списка к. Чтобы выпускать строку без того, чтобы удалить буфер непосредственно, или выпускать строку, принадлежащую на статический буфер результатов, приложение должно вызвать функцию стандартной библиотеки C free().
ПРЕДУПРЕЖДЕНИЕ! Не запишите данные к динамическому местоположению, которое не было размещено с прямым, вызывает к malloc () или с ObjectARX библиотекой (включая acutNewRb ()). Это может разрушать данные в памяти. Наоборот, вызывая free() или acutRelRb() чтобы выпустить данные, который был размещен статически — в статическом или объявлении — динамической локальной переменной также, может разрушать память. Вставка статически размещенной переменной, типа строки, в список буфера результата заставляет вашу программу терпеть неудачу, когда Вы выпускаете список с acutRelRb ().
Выборка вызывает к acutRelRb() появляются в нескольких из примеров кода в следующих секциях.
Создание и cтирание cписка
ObjectARX-приложение может динамически размещать единственный буфер результатов, вызывая acutNewRb (). Запрос к acutNewRb () должен определить тип буфера, чтобы разместить; acutNewRb () автоматически инициализирует restype поле буфера, чтобы содержать указанный код типа.
Следующий типовой кодовый фрагмент размещает буфер результатов, чтобы содержать трехмерную точку и затем инициализирует значение точки:
struct resbuf *head;
if ((head=acutNewRb(RT3DPOINT)) == NULL) {
acdbFail("Unable to allocate buffer\n");
return BAD;
}
head->resval. rpoint[X] = 15.0;
head->resval. rpoint[Y] = 16.0;
head->resval. rpoint[Z] = 11.18;
Если новый буфер результатов должен содержать строку, приложение должно явно разместить память, чтобы содержать строку:
struct resbuf *head;
if ((head=acutNewRb(RTSTR)) == NULL) {
acdbFail("Unable to allocate buffer\n");
return BAD;
}
if ((head->resval. rstring = malloc(14)) == NULL) {
acdbFail("Unable to allocate string\n");
return BAD;
}
strcpy(head->resval. rstring, "Hello, there.");
Память, размещенная для строк, которые связаны с динамическим списком, выпущена, когда список выпущен, так что следующий запрос выпускает всю память, размещенную в предыдущем примере:
acutRelRb(head);
Чтобы выпускать строку без того, чтобы выпустить буфер, вызовите свободным () и установите строковый указатель на NULL как показано в следующем примере:
free(head->resval. rstring);
head->resval. rstring = NULL;
Установка resval. rstring к NULL предотвращает последующий запрос к acutRelRb () из попытки выпустить строку второй раз.
Если элементы списка известны заранее, более быстрый способ создавать это состоит в том, чтобы вызвать acutBuildList (), который берут переменное число пар параметра (с исключениями типа RTLB, RTLE, -3, и других) и возвращают указатель на список буферов результатов, который содержит указанные типы и значения, связанные вместе в порядке, в котором их пропускали к acutBuildList (). Эта функция размещает память как требовано и инициализирует все значения. Последний параметр к acutBuildList () должен быть единственный параметр, чей значение является или нулем или RTNONE.
Следующий типовой кодовый фрагмент создает список, который состоит из трех буферов результатов. Они содержат реальное значение, строку, и точку, в том порядке:
struct resbuf *result;
ads_point pt1 = {1.0, 2.0, 5.1};
result = acutBuildList(
RTREAL, 3.5,
RTSTR, "Hello, there.",
RT3DPOINT, pt1,
0 );
Если это не может создавать список, acutBuildList () возвращает NULL; иначе, это размещает пространство, чтобы содержать список. Этот список должен быть выпущен последующим запросом к acutRelRb ():
if (result!= NULL)
acutRelRb(result);
Списки AutoLISP
AcutBuildList() функция вызвана в сочетании и с acedRetList(), который возвращает структуру списка AutoLISP.
Следующий типовой кодовый фрагмент передает список четырех точек:
struct resbuf *res_list;
ads_point ptarray[4];
// Initialize the point values here.
.
.
.
res_list = acutBuildList(
RT3DPOINT, ptarray[0],
RT3DPOINT, ptarray[1],
RT3DPOINT, ptarray[2],
RT3DPOINT, ptarray[3], 0);
if (res_list == NULL) {
acdbFail("Couldn’t create list\n");
return BAD;
}
acedRetList(res_list);
acutRelRb(res_list);
Точечные пары и вложенные списки могут быть возвращены AutoLISP, вызывая acutBuildList () чтобы формировать список, созданный со специальными кодами типа строительства списка. Эти коды необходимы только для сложных списков. Для обычного (то есть одномерный) списки, acedRetList () можно пропускать простой список буферов результатов, как показано в предыдущем примере.
ОБРАТИТЕ ВНИМАНИЕ список, возвращенный AutoLISP acedRetList () может включать только следующие коды типа результата: RTREAL, RTPOINT, RTSHORT, RTANG, RTSTR, RTENAME, RTPICKS, RTORINT, RT3DPOINT, RTLB, RTLE, RTDOTE, RTNIL, и RTT. (Хотя имеется RTNIL код возврата, если Вы возвращаете только список ноля, Вы можете вызывать acedRetNil ()). Это может содержать типы результата RTLONG, если список возвращается другому ObjectARX-приложению.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |


