Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > RichEdit. Форматирован ли текст.


Автор: Snowy 1.3.2006, 18:57
Есть RichEdit. Пользователь набил в нем текст.
Как узнать, использовал ли он форматирование или весь текст набит одним форматом.
Мне нужен просто текст, если форматирование не использовалось и RTF, если использовалось.
Не могу отличить...

Автор: Yanis 1.3.2006, 19:01
Цитата(Snowy @ 1.3.2006, 18:57 Найти цитируемый пост)
Как узнать, использовал ли он форматирование или весь текст набит одним форматом.

Текст может быть форматированым и иметь один формат. Поясни...
Добавлено @ 19:10
Может быть через http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/richeditcontrolreference/richeditmessages/em_getcharformat.asp и http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/richeditcontrolreference/richeditmessages/em_getcharformat.asp можно узнать.

Автор: Snowy 1.3.2006, 19:23
Цитата(Yanis @ 1.3.2006, 19:01 Найти цитируемый пост)
Может быть через EM_GETCHARFORMAT и EM_SETCHARFORMAT можно узнать.
Нет. Это я и так могу узнать.
Мне нужно, к примеру: если в тексте пользователь хотя бы одну буковку сделал наклонной или другого цвета, то текст считается, использующим форматирование. Если на протяжении всего текста, его оформление остается постоянным, то такой тест считать неформатированным.
Смысл этого:
Если пользователь просто пишет текст, считать, что его интересует только текст.
Если он использует элементы оформления (жирный, наклонный, цвет, шрифт, размер), то считать, что ему нужен и текст и оформление.
Исходя из этого я должен брать либо RTF, либо PlainText.
Приоритетный PlainText. Но, если вдруг пользователю захочется... Тогда нужно брать RTF.
У пользователя спрашивать нельзя - программа должна сама понимать, что если пользователь меняет оформление, значит оно ему нужно.

Автор: Snowy 1.3.2006, 20:11
Пока придумал только такой вариант:
Смотреть RTF текст и искать в нем теги форматирования (\b\ и т.п.).
Еще есть мысль пробежаться курсором по всем позициям и сравнивать текущий аттрибут с аттрибутом первой позиции. Но сравнить аттрибуты не так просто.
Вероятно все же буду просматривать на наличие тегов.
Если никто более умного не подскажет...

Автор: DemoCode 1.3.2006, 20:38
Цитата(Snowy @ 1.3.2006, 21:11 Найти цитируемый пост)
Если никто более умного не подскажет...

Могу подсказать более глупого smile способа:

Создаёшь второй невидимый richedit со свойством plaintext:=true. Когда надо проверить. Текст из первого (твоего) richedit'а копируешь во второй. И далее, если длина строки первого едита равна длине строки второго, то форматирования не использовалось, иначе оно использовалось. smile Можно ещё и хэши этих строк сравнивать например.

Автор: Демо 1.3.2006, 20:52
Цитата(Snowy @ 1.3.2006, 18:57 Найти цитируемый пост)
если форматирование не использовалось


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

Автор: Quadr0 1.3.2006, 21:06
...

Автор: Snowy 2.3.2006, 00:02
Цитата(DemoCode @ 1.3.2006, 20:38 Найти цитируемый пост)
екст из первого (твоего) richedit'а копируешь во второй. И далее, если длина строки первого едита равна длине строки второго, то форматирования не использовалось
Не понял твоей мысли. Если мы один и тот же текст сконвертим в plain, оба варианта будут равны. А сравнивать RTF и Plain по длине бессмысленно.

Цитата(Демо @ 1.3.2006, 20:52 Найти цитируемый пост)
Каким образом пользователь форматирует текст?
Практически 2 варианта: ввод текста с клавиатуры и оформление кнопочками и хоткеями. Второй - вставка из буфера обмена.

Цитата(Quadr0 @ 1.3.2006, 21:06 Найти цитируемый пост)
RTF - закрытый формат
Это ты зачем так сказал?
Вот описание на русском: http://grandad.by.ru/rtf.html
А также можно найти полное описание на сайте M$. Причем версий вплоть до Office2003.

Цитата(Quadr0 @ 1.3.2006, 21:06 Найти цитируемый пост)
не превращаются в escape-символы
Там бэкслаш символы. Они превращаются \\.

Цитата(Quadr0 @ 1.3.2006, 21:06 Найти цитируемый пост)
Проверяем аттрибуты форматирования
Думаю можно попробовать упростить этот процесс при помощи сериализации объекта TTextAttributes.

Все же мне кажется, что быстрее и разумней будет искать по формату. Завтра поэксперементирую.
(точнее уже сегодня).
Добавлено @ 00:03
А вот и http://www.microsoft.com/downloads/details.aspx?familyid=AC57DE32-17F0-4B46-9E4E-467EF9BC5540&displaylang=en

Автор: Snowy 2.3.2006, 00:27
Цитата(Quadr0 @ 1.3.2006, 21:06 Найти цитируемый пост)
Вот это уже получше вариант. Я пробовал его. Попробуй так:
Попробовал. Перестает работать сразу после того, как появляется форматированный текст. После этого всегда говорит, что форматирован.
Хотя можно пролечить, если пойти по моей схеме - отталкиваться не от эталона, а от первой позиции.
Но тогда не покажет, если весь текст форматирован.
В принципе это уже не так важно. Но вариант с тэгами тут лучше.
С другой стороны, можно всегда сбрасывать на дефолтовое значение.
Но остается проблема со вставкой из буфера - там может быть обычный текст, просто фонт не ариал, а таймс, например...
Все же теги надежней.
Ладно, будем думать и копать...

Автор: Quadr0 2.3.2006, 00:47
...

Автор: DemoCode 2.3.2006, 17:15
Цитата(Snowy @ 2.3.2006, 01:02 Найти цитируемый пост)
Не понял твоей мысли. Если мы один и тот же текст сконвертим в plain, оба варианта будут равны. А сравнивать RTF и Plain по длине бессмысленно.


Имеем два ричедита.
С первым работает пользователь
Второй - невидимый.

Когда натсупает момент проверить использовано ли форматирование. Копируем содержимое первого ричедита во второй. Во втором его конвертируем в plain text. Сохраняям оба. Сравниваем. Если размер первого больше, второго, значит форматирование использовано, иначе нет.

Автор: Snowy 2.3.2006, 17:24
Здрасте, приехали. Я тебе без сравнивания скажу, что RTF будет длинее, чем plain text.
Независимо от форматирования.

Автор: DemoCode 2.3.2006, 17:35
Цитата(Snowy @ 2.3.2006, 18:24 Найти цитируемый пост)
Здрасте, приехали. Я тебе без сравнивания скажу, что RTF будет длинее, чем plain text.
Независимо от форматирования.

Но можно из RTF'a перед сравнением вырезать то, что он пихает туда по-умолчанию.
Добавлено @ 17:42
Проверил так, работает только с латинницей.

Автор: Snowy 2.3.2006, 17:59
В таком случае получается еще более сложный вариант, чем определение наличия тегов.
Хотя... В эту сторону тоже можно подумать.
Кирилицу легко можно законвертить в RTF.
Но! Проблема появится, когда строк будет несколько, а не одна - в RTF это новые параграфы.

Автор: Yanis 4.3.2006, 10:07
2 Snowy
Посмотри, пожалуйста мой вариант. Он основывается на сверке первого символа с остальными. Что скажешь?

Автор: Snowy 6.3.2006, 10:31
Yanis, смотрел. Реагирует даже на смену руской/английской раскладки. Это уж слишком.

Автор: Quadr0 6.3.2006, 13:52
...

Автор: RA 6.3.2006, 20:35
Совсем не обязательно делать это автоматических, пусть юзер сам выбирает какой тип хранения ему нужен.

Что сложно лишний чекбокс прикрутить куданить smile .

Я конечно понимаю, что автоматичность это удобно, а если слишком большой текст то в ручном режыме на много быстрее.

Автор: Yanis 7.3.2006, 10:19
Цитата(Snowy @ 6.3.2006, 10:31 Найти цитируемый пост)
Yanis, смотрел. Реагирует даже на смену руской/английской раскладки. Это уж слишком.

Думаю эту проблему можно решить если вместо
Код

CompareMem(@cf1, @cf, SizeOf(cf))
написать свою функцию, которая будет проверять все поля кроме bCharSet структуры TCharFormat<2>.

Автор: Snowy 7.3.2006, 10:48
Цитата(Quadr0 @ 6.3.2006, 13:52 Найти цитируемый пост)
А чем же сравнение с эталоном не подходит?
Потому что остается копирование из буфера обмена. Текст, скопированный из вордпада уже не считается форматированным только потому, что шрифт другой.

Цитата(Quadr0 @ 6.3.2006, 13:52 Найти цитируемый пост)
Искать форматирование в тэгах беполезно в том виде, в котором мы получаем выходной текст. Это тебе придётся собственный парсёр rtf-а писать.
Это не так сложно. Я ж не текст разбираю, а ищу наличие тэгов. А это не намного сложней, чем с html.

Цитата(Quadr0 @ 6.3.2006, 13:52 Найти цитируемый пост)
Работает!
Проверь вставку из ворда.

Цитата(RAdmin @ 6.3.2006, 20:35 Найти цитируемый пост)
Совсем не обязательно делать это автоматических, пусть юзер сам выбирает какой тип хранения ему нужен.
Это не хранение, это отправка по сети. В 95% долен отправляться plain text. RTF будет отправляться только, когда юзверь захочит разукрасить текст.
Наличие разукраски и будет этим флагом.
Зачем мне лепить чекбокс, который в интерфейс у меня просто не вписывается, когда можно сделать автодетект.
У меня везде в проекте автодетект, а тут я буду чекбоксы лепить. Некрасиво.

Ладно. Значит кроме этих двух идей других нет...

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

Автор: Quadr0 7.3.2006, 22:31
...

Автор: Snowy 9.3.2006, 16:41
Цитата(Quadr0 @ 7.3.2006, 22:31 Найти цитируемый пост)
Да ну, у меня всё нормально. Или я как-то не так тебя понял?
Я имею ввиду, что текст, скорированный из вордпада всегда считается форматированным, низависимо ни от чего.

Цитата(Quadr0 @ 7.3.2006, 22:31 Найти цитируемый пост)
Я уже говорил и по прежнему уверен, что у MS, у их контролла вордовского видимо немного другая реализация.
В Delphi используется тот же самый контрол.
RxRichEdit также построен на том же самом контроле, просто расширен функционал кода.
Реально у нас вовсе не 1.0. Просто юзать выше стандартно не можем, т.к. нет реализации.
Но на уровне WinAPI можно туда и картинки и таблицы вставлять.


Цитата(Quadr0 @ 7.3.2006, 22:31 Найти цитируемый пост)
Что там со вставкой?Набрал в Word 2003 текст, сделал часть курсивным, часть жирным, подчёркнутым, разным шрифтом и размером. Вставил, всё работало как и прежде.
Угу. А если не делать форматирование... Делай, не делай - все равно детектит, что есть.

Ну хоть какой-то результат есть в наличии.
Наконец-то дошли руки. Вот, доработал немножко:
Код
function IsRichFormated(RE: TRichEdit): boolean;
var
  i: integer;
begin
  result := false;
  Re.SelStart := 0;
  Re.DefAttributes.Assign(Re.SelAttributes);
  for i := 0 to Length(Re.Text) do
  begin
    Re.SelStart := i;
    if (Re.SelAttributes.Name  <> Re.DefAttributes.Name) or
       (Re.SelAttributes.Color <> Re.DefAttributes.Color) or
       (Re.SelAttributes.Size  <> Re.DefAttributes.Size) or
       (fsBold in Re.SelAttributes.Style) or
       (fsItalic in Re.SelAttributes.Style) or
       (fsUnderline in Re.SelAttributes.Style) or
       (fsStrikeOut in Re.SelAttributes.Style) or
       (Re.Paragraph.Numbering <> nsNone) or
       (Re.Paragraph.Alignment <> taLeftJustify) then
     begin
       result := true;
       Break;
     end;
  end;
end;
Пока у меня не получилось найти вариантов, где бы это не сработало.
Если артифакты не попадутся, то пожалуй остановлюсь на этом варианте.
Раз уж он работает, то незачем тэги ковырять.

Бонус в этом топике уходит Quadr0

Автор: Yanis 10.3.2006, 15:02
Цитата(Snowy @ 9.3.2006, 16:41 Найти цитируемый пост)
Пока у меня не получилось найти вариантов, где бы это не сработало.
Если артифакты не попадутся, то пожалуй остановлюсь на этом варианте.
Раз уж он работает, то незачем тэги ковырять.

Сдаётся мне, что мой варинт работает быстрее.

Автор: Snowy 10.3.2006, 15:11
Логично. Но не настолько, чтобы это было заметно.
А если в него добавить исключения, то больше заморочек.
А суть все та же.

Автор: Quadr0 11.3.2006, 20:06
...

Автор: Snowy 11.3.2006, 20:20
Цитата(Quadr0 @ 11.3.2006, 20:06 Найти цитируемый пост)
Ты размер шрифта в 11 и имя на Arial не забыл поменять? Просто там по дефолту Times New Roman с 12 размером. Вот он и копируется.
smile в том-то и дело, что пользователь этого делать не будет.
Приоритет должен быть у plain text, а не у RTF.
Код, который я нарисовал, делает точно так, как мне нужно.
Уже его воткнул в проект. Работает без нареканий.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)