Помощь - Поиск - Пользователи - Календарь
Полная версия: Изображение и RichEdit
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
Unconnected
Допустим, имеется изображение(оно может быть разное) в RichEdit. Как его можно преобразовать в текст, чтобы для каждой картинки был свой "идентефикатор"? Помимо картинки в RichEdite может быть ещё и текст.
volvo
Цитата
Допустим, имеется изображение(оно может быть разное) в RichEdit
А ты попробовал в стандартный TRichEdit запихать изображение, прежде, чем такое допускать? Код приведи, который добавляет к текущему содержимому TRichEdit (допустим, там только текст) снизу картинку 'A.GIF'... А потом будешь допускать что-то...
Unconnected
Картинка в RichEdit уже добавляется, в том и дело, модуль прикрепил (в сети нашёл его). Правда, я использую не TRichEdit, а TsRichEdit, из пакета AlphaControls, ну это роли не играет в принципе.
volvo
Насколько я понимаю, это для твоего ICQ-клиента, чтоб передавать и хранить в истории что-то типа : COOL : для отображения cool.bmp? Тогда можно сделать так: не преобразовывать изображение в текст, а наоборот. Смотри: заводишь переменную типа TStringList, которая будет хранить текст, отрисовываемый в RichEdit, и при получении от собеседника очередной строки текста, добавляешь ее не в RichEdit, а сначала в этот StringList, а уж потом содержимое добавленной строки отрисовываешь в RichEdit. Обычной функцией Pos можно искать идентификаторы картинок, их у тебя будет не так много, я думаю, и выводить новую строку в RE по частям: то, что ДО id картинки - это простой текст, потом вместо ID вставляешь картинку через тот же InsertBitmap, а потом - проверяешь оставшуюся часть строки на наличие ID... Как результат - в RichEdit хранится собственно отображение переписки, а StringGrid содержит готовую историю...

Добавлять изображения в RE можно точно так же: добавлять в текущую позицию каретки ID картинки, и тут же рисовать строку InsertBitmap-ом... Опять же понадобится доп. переменная для хранения строки с ID...
Unconnected
Цитата
Насколько я понимаю, это для твоего ICQ-клиента, чтоб передавать и хранить в истории что-то типа : COOL : для отображения cool.bmp? Тогда можно сделать так: не преобразовывать изображение в текст, а наоборот. Смотри: заводишь переменную типа TStringList, которая будет хранить текст, отрисовываемый в RichEdit, и при получении от собеседника очередной строки текста, добавляешь ее не в RichEdit, а сначала в этот StringList, а уж потом содержимое добавленной строки отрисовываешь в RichEdit. Обычной функцией Pos можно искать идентификаторы картинок, их у тебя будет не так много, я думаю, и выводить новую строку в RE по частям: то, что ДО id картинки - это простой текст, потом вместо ID вставляешь картинку через тот же InsertBitmap, а потом - проверяешь оставшуюся часть строки на наличие ID... Как результат - в RichEdit хранится собственно отображение переписки, а StringGrid содержит готовую историю...

Добавлять изображения в RE можно точно так же: добавлять в текущую позицию каретки ID картинки, и тут же рисовать строку InsertBitmap-ом... Опять же понадобится доп. переменная для хранения строки с ID...


Ну, почти угадал...smile.gif Об реализации истории я ещё не думал, но там этот подход тоже пригодится. Для начала мне нужно научиться отправлять текст со смайлом. Я думал о том, что при отправке можно в РичЭдит выводить текст со смайлом, а в строковую переменную вводить сначала текст, а потом идентификатор смайла, и потом, при отправке через сокет, отправлять не содержимое РичЭдита, а содержимое строковой переменной. Но тут возникает небольшая проблема формирования строки. Вот допустим в РичЭдите строка "Hello, World" и улыбающийся смайл. Т.е. в строке, которая хранит текст с идентефикатором, находится "Hello, World SM1" (У меня все смайлы в ImageList'е, поэтому в качестве идентификатора будет выступать просто номер смайла). И тут вдруг пользователю приспичило после "Hello," поставить ещё один смайл. Возникает вопрос, на какое событие РичЭдита что нужно повесить, чтобы при добавлении смайла не в конец строки РичЭдита в нашей параллельной строке все это правильно отображалось(в плане идентификаторов смайлов)?
Unconnected
Цитата
Добавлять изображения в RE можно точно так же: добавлять в текущую позицию каретки ID картинки, и тут же рисовать строку InsertBitmap-ом... Опять же понадобится доп. переменная для хранения строки с ID...


Или ответ на мой вопрос кроется в этой фразе? Я просто не совсем понял её смысл, что это за InsertBitmap и как с помощью него можно Рисовать строку?
volvo
Цитата
что это за InsertBitmap
blink.gif Ты смотрел содержимое модуля, который присоединил в третьем посте? Там есть InsertBitmapToRE... Чуть позже попробую показать кодом, что я имел в виду...
Unconnected
Ну, я этой процедурой и добавляю, там нужно имя ричэдита в неё вписать и хэндл битмапа в качестве параметров. Только вот там нельзя определять, куда именно вставлять битмап. По крайней мере, я не знаю:)
volvo
Цитата
Только вот там нельзя определять, куда именно вставлять битмап
Битмап всегда вставляется в текущую позицию, туда, где находится курсор... Это сказано в DRKB, об этом же говорил Krid (автор модуля) там, где выкладывал этот модуль... То есть, все, что тебе надо - это установить курсор туда, куда нужно, а потом добавить изображение...
Unconnected
Ага, в принципе всё ясно... И ещё, как можно получить текущую позицию курсора в RichEdit?
volvo
"DRKB -> VCL -> TRichEdit -> Каретка -> Позиция курсора в TRichEdit" smile.gif
Unconnected
Спасибо, наконец иду дальше:)
Unconnected
Возникло одно непредвиденное затруднение...
Оформил я, значит, процедуру GetPosition в виде функции, возвращающей координаты курсора, и сделал формирование строки сообщения. Всё это дело висит на событии OnKeyPress РичЭдита. Выглядит вот так:

Function TForm1.GetPosition(Sender:TsRichEdit):TPoint;
var
iX,iY:Integer;
TheRichEdit:TsRichEdit;
begin
iX:=0;iY:=0;
TheRichEdit:=TsRichEdit(Sender);
iY:=SendMessage(TheRichEdit.Handle, EM_LINEFROMCHAR, TheRichEdit.SelStart,0);
iX:=TheRichEdit.SelStart - SendMessage(TheRichEdit.Handle, EM_LINEINDEX,iY, 0);
result.Y:=(iY+1);result.X:=(iX+1);
end;

procedure TForm1.sRichEdit1KeyPress(Sender: TObject; var Key: Char);
var pt:TPoint;
ss:string;
begin
ss:=key;
if key=#13 then begin
button4.click;
key:=#0;
exit;
end;
pt.X:=getposition(memo1).x;
pt.y:=getposition(memo1).y;
if pt.Y=1 then insert(ss,messag,pt.X)
else insert(ss,messag,(pt.Y*69)+pt.x);
end;


Вот так формируется строка. Если вставляется смайл, то в строку входит блок типа "#&номер_смайла#0". И это даже работает. Проблема в другом, допустим, пользователь набрал сообщение, со смайлом, вдруг увидел опечатку и стёр полмессаджа, в котором и был смайл. Как это можно отразить на формируемой строке? Я не могу придумать именно алгоритм действий. Можно, в принципе, обрабатывать нажатия BackSpace и Delete, но тогда придётся обработать ещё и ситуацию, когда пользователь выделил кусок текста и нажал Delete... Что посоветуете?..
volvo
Цитата
придётся обработать ещё и ситуацию, когда пользователь выделил кусок текста и нажал Delete
yes2.gif Придется... Если хочешь сделать работоспособную программу. Причем, ничего сложного-то в этом нет, тебе достаточно при получении VK_DELETE посмотреть, с какой позиции и сколько элементов удаляется (SetStart и SelLength), и удалить их из messag тоже...
Unconnected
Цитата
yes2.gif Придется... Если хочешь сделать работоспособную программу. Причем, ничего сложного-то в этом нет, тебе достаточно при получении VK_DELETE посмотреть, с какой позиции и сколько элементов удаляется (SetStart и SelLength), и удалить их из messag тоже...


Хм... ну допустим, а вот если в выделенном фрагменте будет смайл? Позицию, как я понял, он будет занимать одну, а вот в параллельной строке он занимает несколько символов... Тогда ещё надо узнать как то, есть ли в выделенном фрагменте смайлы...
volvo
Я окончательно запутался в том, что ты делаешь... Создавай тестовый проект, в котором будет только заполнение RichEdit-а так, как ты это делаешь, желательно, стандартными средствами (TRichEdit, а не какие-то посторонние компоненты, ICQClient-ы всяческие меня тоже не интересуют, я ничего постороннего ставить не буду, только то, что идет по умолчанию в Дельфи), архивируй его и присоединяй сюда. Откроется/запустится - попробую подсказать. Нет - значит нет, сразу предупреждаю.

Иначе получается "переливание из пустого в порожнее", я не телепат, чтобы знать, как именно ты все это организовал, что тебе надо "бабка за дедку, дедка за репку" и только потом что-то важное у тебя происходит. Надо видеть код, причем ТОЧНЫЙ код, а не "вот тут как-то так, а вот тут что-то типа этого".
Unconnected
Volvo, у тебя AlphaControls не установлен случаем? Просто создание панели смайлов и иже с нею идёт с помощью ImageList'а, который обычный SpeedButton не поддерживает.

Просто иначе я могу показать добавление только кодом, который компилироваться не будет...
Unconnected
Вот часть проекта с формированием строки, все компоненты там по умолчанию, за исключением TsSpeedButton'ов... Ну, уж если нет, так нет, буду по другому как-то делать smile.gif

Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.