Тема: Немогу изменить текст...

Не могу изменить текст.
Если кому не жалко покажите кусочек кода где реально выполняется замена свойств (в частности текста) с помощью функции acdbEntMod(...).
Благодарю

Re: Немогу изменить текст...

Не могу с помощью acdbEntMode(...) изменить текст.
Вопрос №1:
Можно ли использовать операторы new и delete для перераспределения памяти? Или здесь необходимо использовать только realloc(...)?
Вопрос №2:
Как преобразовывать ACHAR* к char* и наоборот
Если это где-то уже обсуждалось, направьте меня пожалуйста туда.
Буду очень признателен.

Re: Немогу изменить текст...

По первому вопросу: new и delete использовать не рекомендуют. Рекомендуют использовать:

acutNewString
acutDelString
acutUpdString
acutNewBuffer
acad_calloc
acad_malloc
acad_free
acad_realloc
acad__strdup

По второму вопросу: http://www.private.peterlink.ru/poleshc … String.htm

Re: Немогу изменить текст...

Спасибо, Александр.
По первому вопросу сейчас буду пробовать.
А по второму вопросу у меня вопрос:
Мне нужно преобразовать ACHAR* именно к char* но не к const char*.
Будет ли корректным следующие определения:

ACHAR*pastr=[инициализация];
char*pstr=(char*)pastr;
.....
что - то сотворили с буфером...
funcMem(...,pstr);
.....
pastr=(ACHAR*)pstr;

Понятно, если функция в качестве аргумента принимает указатель для изменения буфера, то, естественно const здесь неуместен.
И еще. Если не сложно приведи, пожалуйста, фрагмент реального кода с изменением свойств примитива, в частности текста. Если есть ссылка, буду очень благодарен.
Документации нет, попробовал пример из электронной документации, но очевидно он написан под более старые версии студии и Акада,
Сделал по своему разумению, компилятор согласился, но acdbEntMod(...) не отработал с кодом завершения RTNORM :(

Re: Немогу изменить текст...

Александр Ривилис (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;
}

Что-то я здесь пропускаю? или делаю не так?
Снимаю второй вопрос, похоже, он не уместен. Преобразования выполняются как обычно.

Re: Немогу изменить текст...

Посмотри для какого указателя ты делаешь acdbEntMod(pres). Вместо того чтобы указать на "голову" списка, ты указываешь на тот элемент у которого группа 1

Re: Немогу изменить текст...

Стоп. Я проглядел. Дело не в этом.

Re: Немогу изменить текст...

А это TEXT или MTEXT? Если MTEXT, то необходимо работать еще и с группой 3. Хотя я не понимаю зачем все эти сложности если можно воспользоваться методами AcDbText (для TEXT) или AcDbMtext (для MTEXT)

Re: Немогу изменить текст...

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, Это случайно не примитив внутри блока? Если да, то тогда все понятно. Тебе после замены текста необходимо найти все вставки этого блока и обновить их.

Re: Немогу изменить текст...

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);

Re: Немогу изменить текст...

Спасибо всем! В общем-то я разобрался.
Во первых - я наступил на старые грабли, и не заблокировал документ. Об этом много раз и многих предупреждал Александр.
Во вторых - я решил список (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;
}

Жирным выделен фрагмент непосредственно выполняющий изменение текста.
Что касается этого фрагмента, то его можно смело использовать, что касается функции в целом, то тут требуется определенная аккуратность. Это связано в первую очередь с процессом загрузки новых документов и доступа к ним в фоновом режиме. Эта функция может  бестактно подступиться к документу который находится в процессе загрузки и соответственно от Акада получить по полной. Здесь отстуствует масса проверок указателей всех уровней.
Еще раз спасибо Александр и Зигмус. Вы мне здорово помогли.

Re: Немогу изменить текст...

> alex
Я не буду говорить что всего этого делать не следует. Внимание! Функции acdbEntMod и acdbHandEnt, как и ряд других работают только с текущей (активной) базой.

Re: Немогу изменить текст...

Для моих текущих нужд работы с активной базой пока достаточно.
Но тем не менее постараюсь быть весьма осторожным при работе с множеством документов.
В приведенном выше коде выставлен период  опроса аж 5 сек. Это то время в течении которого вероятность выполнения запроса к активной базе при загрузке документа достаточно мал. Когда контекст полностью переместится на текущий документ (вновь открытый документ), я думаю, все будет в порядке, или я не прав?
Какие средства для безопасного доступа к данным вообще предусмотрены в ARXe?
Спасибо, Александр.

Re: Немогу изменить текст...

Можно запретить на это время возможность переключения документов:

if (acDocManagerPtr()->isDocumentActivationEnabled()) {
  acDocManagerPtr()->disableDocumentActivation();
  // Здесь твой код
  acDocManagerPtr()->enableDocumentActivation();
}

Re: Немогу изменить текст...

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