Тема: Немогу изменить текст...
Не могу изменить текст.
Если кому не жалко покажите кусочек кода где реально выполняется замена свойств (в частности текста) с помощью функции acdbEntMod(...).
Благодарю
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Программирование → ObjectARX → Немогу изменить текст...
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Не могу изменить текст.
Если кому не жалко покажите кусочек кода где реально выполняется замена свойств (в частности текста) с помощью функции acdbEntMod(...).
Благодарю
Не могу с помощью acdbEntMode(...) изменить текст.
Вопрос №1:
Можно ли использовать операторы new и delete для перераспределения памяти? Или здесь необходимо использовать только realloc(...)?
Вопрос №2:
Как преобразовывать ACHAR* к char* и наоборот
Если это где-то уже обсуждалось, направьте меня пожалуйста туда.
Буду очень признателен.
По первому вопросу: new и delete использовать не рекомендуют. Рекомендуют использовать:
acutNewString acutDelString acutUpdString acutNewBuffer acad_calloc acad_malloc acad_free acad_realloc acad__strdup
По второму вопросу: http://www.private.peterlink.ru/poleshc … String.htm
Спасибо, Александр.
По первому вопросу сейчас буду пробовать.
А по второму вопросу у меня вопрос:
Мне нужно преобразовать ACHAR* именно к char* но не к const char*.
Будет ли корректным следующие определения:
ACHAR*pastr=[инициализация];
char*pstr=(char*)pastr;
.....
что - то сотворили с буфером...
funcMem(...,pstr);
.....
pastr=(ACHAR*)pstr;
Понятно, если функция в качестве аргумента принимает указатель для изменения буфера, то, естественно const здесь неуместен.
И еще. Если не сложно приведи, пожалуйста, фрагмент реального кода с изменением свойств примитива, в частности текста. Если есть ссылка, буду очень благодарен.
Документации нет, попробовал пример из электронной документации, но очевидно он написан под более старые версии студии и Акада,
Сделал по своему разумению, компилятор согласился, но acdbEntMod(...) не отработал с кодом завершения RTNORM :(
Александр Ривилис (2008-10-21 09:56:36)
Вот фрагмент моего кода с учетом твоей подсказки но модификации текста не происходит, прости за элементарные вопросы.
resbuf*ptemp,pres; acad_name anm; ptemp=pres=acdbEntGet(anm); while(pres) { if(pres->restype==1) { st=pres->resval.rstring; len=st.GetLength(); pres->resval.rstring=(ACHAR*)acad_realloc(pres->resval.rstring,100); acutUpdString(L"sss",(ACHAR*&)pres->resval.rstring); break; } pres=pres->rbnext; } pres=ptemp; if (acdbEntMod(pres) != RTNORM) { acutRelRb(ptemp); return 0; }
Что-то я здесь пропускаю? или делаю не так?
Снимаю второй вопрос, похоже, он не уместен. Преобразования выполняются как обычно.
Посмотри для какого указателя ты делаешь acdbEntMod(pres). Вместо того чтобы указать на "голову" списка, ты указываешь на тот элемент у которого группа 1
А это TEXT или MTEXT? Если MTEXT, то необходимо работать еще и с группой 3. Хотя я не понимаю зачем все эти сложности если можно воспользоваться методами AcDbText (для TEXT) или AcDbMtext (для MTEXT)
static void ChTxtStr(void) { ACHAR buf[512]; ads_name en; ads_point p; if (acedEntSel(_T("\nВыберите текстовый примитив: "),en,p) == RTNORM) { if (acedGetString(TRUE,_T("\nВведите новую текстовую строку: "),buf) == RTNORM) { resbuf *rb = acdbEntGet(en), *rbstart = rb; for (; rb; rb=rb->rbnext) { if (rb->restype == 1) { acutUpdString(buf,rb->resval.rstring); break; } } acdbEntMod(rbstart); acdbEntUpd(en); acutRelRb(rbstart); } } }
Проверь еще что выбран действительно текст, что слой на котором этот текст не заблокирован. И еще по твоему коду не понятно откуда ты получил anm, Это случайно не примитив внутри блока? Если да, то тогда все понятно. Тебе после замены текста необходимо найти все вставки этого блока и обновить их.
ACHAR * в char*
Попробуйте так (к сожалению, негде проверить)
ACHAR * acharStr; acutNewString(acharStr,1000); //Присвоить значение ........... char *psz; acutNewBuffer(psz,1000); wcstombs(psz,acharStr,1000);acutDelString(acharStr);
///Обратно:
wchar_t *pwsz; acutNewString(pwsz,1000); mbstowcs(pwsz,psz,1000); acutDelString(psz);
Спасибо всем! В общем-то я разобрался.
Во первых - я наступил на старые грабли, и не заблокировал документ. Об этом много раз и многих предупреждал Александр.
Во вторых - я решил список (resbuf) разматывать до конца и только после этого возвращать ему голову. Может дело и не в этом, но так работает.
С текстовыми функциями непременно ознакомлюсь, огромное спасибо тебе, Александр, за консультацию. Я преследовал еще одну цель, ведь таким образом можно менять и другие свойства примитивов? Возможно это понадобится мне в дальнейшем.
Ниже привожу код. Особенность его его заключается, в том, что эта функция загружается в параллельном процессе, и в фоне просматривая БД, корректирует надписи в чертеже.
UINT UpdateValuesThread(LPVOID WinObjPtr) { CLibData lib; CDataObjects v; CMSTools t; resbuf*pres,*ptemp; AcDbHandle hd; ads_name anm; CString s,sv,sl,st; int len, N=5000; AcString sb; while(1) { if(nFlaEndThread==1) return 1; Sleep(N); if(lib.GetStatusEvent(v)) { sv=v.GetString(_DATA_RANGE_EXT_DATA); s=t.GetItem(sv,0,'('); s.TrimLeft(); s.TrimRight(); sl=s; s=t.GetItem(sv,1,'('); s.TrimLeft(L" ()"); s.TrimRight(L" ()"); AcAxDocLock lock(acdbCurDwg()); if((lock.lockStatus() == Acad::eOk) && (hd=acdbHandEnt(sl,anm)==RTNORM)) { [b] ptemp=pres=acdbEntGet(anm); while(pres) { if(pres->restype==1) { len=s.GetLength(); pres->resval.rstring=(ACHAR*)acad_realloc(pres->resval.rstring,len*2+1); acutUpdString(((AcString)s).kACharPtr(),(ACHAR*&)pres->resval.rstring); } pres=pres->rbnext; } pres=ptemp; if (acdbEntMod(pres) != RTNORM) { acutRelRb(ptemp); return 0; }[/b] acutRelRb(ptemp); v.m_ObjStatus=0; lib.SetStatusEvent(v); } } } return 1; }
Жирным выделен фрагмент непосредственно выполняющий изменение текста.
Что касается этого фрагмента, то его можно смело использовать, что касается функции в целом, то тут требуется определенная аккуратность. Это связано в первую очередь с процессом загрузки новых документов и доступа к ним в фоновом режиме. Эта функция может бестактно подступиться к документу который находится в процессе загрузки и соответственно от Акада получить по полной. Здесь отстуствует масса проверок указателей всех уровней.
Еще раз спасибо Александр и Зигмус. Вы мне здорово помогли.
> alex
Я не буду говорить что всего этого делать не следует. Внимание! Функции acdbEntMod и acdbHandEnt, как и ряд других работают только с текущей (активной) базой.
Для моих текущих нужд работы с активной базой пока достаточно.
Но тем не менее постараюсь быть весьма осторожным при работе с множеством документов.
В приведенном выше коде выставлен период опроса аж 5 сек. Это то время в течении которого вероятность выполнения запроса к активной базе при загрузке документа достаточно мал. Когда контекст полностью переместится на текущий документ (вновь открытый документ), я думаю, все будет в порядке, или я не прав?
Какие средства для безопасного доступа к данным вообще предусмотрены в ARXe?
Спасибо, Александр.
Можно запретить на это время возможность переключения документов:
if (acDocManagerPtr()->isDocumentActivationEnabled()) { acDocManagerPtr()->disableDocumentActivation(); // Здесь твой код acDocManagerPtr()->enableDocumentActivation(); }
Спасибо, Александр, непременно этим фрагментом воспользуюсь.
Вот только не приведет ли это к потере команды?
А то пользователь решит открыть документ, а система спокойно проигнорирует его желание только потому, что в этот момент она занята просмотром какой-то базы данных и ей нежелательно оторваться от текущего документа?
Впрочем, это легко проверить...
Спасибо!
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Программирование → ObjectARX → Немогу изменить текст...
Форум работает на PunBB, при поддержке Informer Technologies, Inc