Страниц: [1] 2
  Печать  
Автор Тема: очистка текста в PtMultiText  (Прочитано 1485 раз)
Дмитрий
Участник
*
Offline Offline

Сообщений: 38


Просмотр профиля
« : Мая 17, 2017, 02:09:33 pm »

Здравствуйте!

Очень нужна Ваша помощь!!!

Есть виджет PtMultiText, созданный при помощи меню виджетов на экране.

В программе к нему обращаюсь как MTex1=ApGetWidgetPtr(wSe,ABN_PtMTevents);// где wSe - виджет окна.
Текст в программе добавляется только в конец позиции виджета MTex1.
Я же хочу очищать виджет перед записью нового текста, но почему-то не получается.
Код:
Код:
memset(&buffer2,0,sizeof(buffer2));
PtTextModifyText(MTex1,0,sizeof(buffer2),-1,buffer2,sizeof(buffer2)); // очистка виджета

 while( fgets( buffer, 128, fj ) != NULL )
  {  
   PxTranslateToUTF(trans,buffer,strlen(buffer),
            &srctaken,buffer1,sizeof(buffer1),
    &dstmade);
   PtMultiTextModifyText(MTex1,NULL,NULL,-1,buffer1,strlen(buffer1),NULL,
                 Pt_MT_FONT|Pt_MT_FOREGROUND|Pt_MT_TEXT_COLOR|Pt_MT_BACKGROUND|
                 Pt_MT_BACKGROUND_COLOR); //добавляем текст
   memset(&buffer,0,sizeof(buffer));
   memset(&buffer1,0,sizeof(buffer1));          
  }
Текст виджета не очищается...
Подскажите, в чем дело!
« Последнее редактирование: Мая 17, 2017, 02:18:37 pm от Дмитрий » Записан
GrayCat
Full Member
***
Offline Offline

Сообщений: 121


Gray©at


Просмотр профиля
« Ответ #1 : Мая 17, 2017, 09:25:30 pm »

А кто такой у вас "buffer2" ? Если это имя массива, то выражение "memset( &buffer2,0,sizeof(buffer2));" пытается обнулить указатель на массив. Иногда такое тоже нужно, но тут вы, скорее всего, имели в виду совсем другое ;-) .
Записан

Gray©at
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #2 : Мая 18, 2017, 08:18:02 am »

А кто такой у вас "buffer2" ? Если это имя массива, то выражение "memset( &buffer2,0,sizeof(buffer2));" пытается обнулить указатель на массив. Иногда такое тоже нужно, но тут вы, скорее всего, имели в виду совсем другое ;-) .

Это неверно - в C buffer2 и &buffer2 в данном случае абсолютно эквивалентны.

Код:
Код:
memset(&buffer2,0,sizeof(buffer2));
PtTextModifyText(MTex1,0,sizeof(buffer2),-1,buffer2,sizeof(buffer2)); // очистка виджета

А каков размер массива buffer2? В вашем варианте он должен быть заведомо больше длины очищаемого текста.
Но вообще-то массив buffer2 здесь вовсе не обязателен. Достаточно задать третий параметр PtTextModifyText() заведомо бОльшим, чем длина текста, а последние два параметра - NULL, 0.
« Последнее редактирование: Мая 18, 2017, 09:06:01 am от A_O » Записан
Дмитрий
Участник
*
Offline Offline

Сообщений: 38


Просмотр профиля
« Ответ #3 : Мая 18, 2017, 04:16:00 pm »

Вот я затуркался, болван!
Я указал буфер в 16 байт Cheesy
Ваш пример более правильный, я думаю!
Только вопрос еще такой:
Как в виджете считается количество байт в буфере, по количеству символов на экране?
А символы перевода строки наверное тоже учитываются?
И да, наверное, глупый вопрос.
Т. е. как правильно посчитать размер текста, у меня, например, список....

P.S. Было бы удобно, если бы была бы реализована функция PtSetResourse CLEAR_ALL_TEXT
« Последнее редактирование: Мая 18, 2017, 04:24:36 pm от Дмитрий » Записан
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #4 : Мая 18, 2017, 06:03:09 pm »

Попробуйте поиграть с ресурсом Pt_ARG_TEXT_STRING. С его помощью можно и очистить виджет (через PtSetResources), и получить указатель на текст (через PtGetResources). Не знаю, правда, что выдаст PtGetResources в случае наличия нескольких сегментов текста с разным форматированием, но, скорее всего, это предусмотрено. В общем, надо пробовать.
Что касается длины текста, то она складывается из длины всех сегментов, которые вы туда пишете, и больше ни из чего (если, конечно, у вас не предусмотрено редактирование текста пользователем). Следует только различать длину текста в байтах и в символах - в кодировке UTF это не одно и то же.
Записан
da-nie
Full Member
***
Offline Offline

Сообщений: 167



Просмотр профиля
« Ответ #5 : Мая 18, 2017, 07:05:08 pm »

Цитировать
Это неверно - в C buffer2 и &buffer2 в данном случае абсолютно эквивалентны.

А вот это интересно.  Cool
Правильно я понимаю, что написав:
unsigned char buffer[100];

Оказывается, что &buffer=buffer? Это в Си такое работает? В Си++ не работает?
Мой компилятор VC6 (в проекте для Си++) такую строку не принимает:

if (buffer==(&buffer)) MessageBox(NULL,"!!!!","",MB_OK);

У него к ней идиосинкразия "error C2446: '==' : no conversion from 'unsigned char (*)[100]' to 'unsigned char *'" И я с ним полностью согласен. Честно говоря, не вижу причин, по которым &buffer должен быть равен buffer.  Roll Eyes
« Последнее редактирование: Мая 18, 2017, 07:09:50 pm от da-nie » Записан

И день и ночь в пути
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #6 : Мая 18, 2017, 07:14:56 pm »

Причин вы можете не видеть, но в C (не C++) это действительно так.
Записан
da-nie
Full Member
***
Offline Offline

Сообщений: 167



Просмотр профиля
« Ответ #7 : Мая 18, 2017, 07:20:13 pm »

На всё есть свои причины. Smiley Дело в том, что будет очень интересно, если вдруг buffer станет определяться через new. В этом случае программа просто рассыплется. Поэтому крайне интересно, зачем в Си сделано так. По логике, имя массива есть указатель на первый элемент. А взятие адреса от указателя должно давать адрес указателя. А тут получается зоопарк. Я про такой фокус не знал.
И действительно, если тип привести, то получится так:
Код:
unsigned char *p1=buffer;
unsigned char *p2=(unsigned char*)(&buffer);
if (p1==p2) MessageBox(NULL,"!!!!","",MB_OK);
И оно действительно выдаёт "!!!!". И в Си++. Smiley

Оказывается, и статья была на хабре с этим моментом: https://habrahabr.ru/post/251091/
Записан

И день и ночь в пути
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #8 : Мая 18, 2017, 07:39:58 pm »

1. В Си нет new.
2. Имя массива есть ссылка на первый элемент, но не объект типа "указатель". Такой объект в данном случае не создается.
« Последнее редактирование: Мая 18, 2017, 07:41:53 pm от A_O » Записан
da-nie
Full Member
***
Offline Offline

Сообщений: 167



Просмотр профиля
« Ответ #9 : Мая 18, 2017, 07:44:30 pm »

В Си есть malloc. И ваш пример в Си++ тоже работает. А это уже хреново.

Цитировать
Имя массива есть ссылка на первый элемент, но не объект типа "указатель".

Судя по статье с хабра - массив он свой собственный мальчик, и имя его в указатель преобразуется, но им не является, как не является и ссылкой.
« Последнее редактирование: Мая 18, 2017, 07:47:18 pm от da-nie » Записан

И день и ночь в пути
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #10 : Мая 18, 2017, 08:04:18 pm »

В случае malloc есть явный объект - указатель. Со всеми вытекающими.
Если вы напишете
Код:
char *buffer = malloc (16);
то buffer никак не будет равно &buffer.
А в случае
Код:
char buffer[16];
такое равенство будет. Но не будет объекта типа "указатель".
По крайней мере, компилятор Watcom в QNX 4.25 спокойно кушает оператор
Код:
if (buffer == &buffer) ...
Он выдает только туманное предупреждение "&array may not produce intended result", но результат сравнения при этом true.
Интересно проверить, что будет при арифметических операциях с этим указателем. Но в данной теме это значения не имеет - использование &buffer2 вместо buffer2 в обращении к функции ошибкой никоим образом не является.
« Последнее редактирование: Мая 18, 2017, 08:24:33 pm от A_O » Записан
da-nie
Full Member
***
Offline Offline

Сообщений: 167



Просмотр профиля
« Ответ #11 : Мая 18, 2017, 08:21:27 pm »

Вроде бы я об этом и пишу? Wink

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

И день и ночь в пути
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #12 : Мая 18, 2017, 08:25:50 pm »

Если поменять массивы на динамические, компилятор как раз наверняка возмутится.
Записан
da-nie
Full Member
***
Offline Offline

Сообщений: 167



Просмотр профиля
« Ответ #13 : Мая 18, 2017, 09:29:50 pm »

Не-а. Во всех местах, где вы будете задавать указатель, как &buffer, вы его будете приводить к типу указателя на тип буфера (иначе работать не будет так же, как у меня в VC6 в примере). А это значит, что компилятор подмены не заметит.
Записан

И день и ночь в пути
A_O
Full Member
***
Offline Offline

Сообщений: 205


Просмотр профиля
« Ответ #14 : Мая 18, 2017, 09:33:22 pm »

Ну это ж надо вставлять явное приведение. Так вредить неинтересно - возни больно много.
« Последнее редактирование: Мая 18, 2017, 09:34:56 pm от A_O » Записан
Страниц: [1] 2
  Печать  
 
Перейти в: