Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "KOL";
Текущий архив: 2007.04.01;
Скачать: [xml.tar.bz2];

Вниз

Рисование в RichEdit   Найти похожие ветки 

 
Andr-04   (2006-07-08 19:48) [0]

Никак не могу корректно обновлять нарисованное в RichEdit через Canvas! При обрабатывании OnPaint (не важно как - и через OnMessage, и через своё событие) нарисованный фрагмент при прокручивании размножается, а если отлавливать прокрутку, то перерисовка происходит не всегда, да и на границе остаются следы рисунка. Если у кого есть опыт в данной области, какие именно события нужно отлавливать, какие сообщения нужно отправлять при их обработке и т.д. поделитесь, пожалуйста!


 
KilkennyCat ©   (2006-07-09 02:40) [1]

Посмотрите пример у RxLib, там вроде бы, было.


 
KilkennyCat ©   (2006-07-09 02:41) [2]

прошу прощения, не заметил, что - KOL...


 
Andr-04   (2006-07-10 15:02) [3]

Поскольку больше никто ничего не советует, решил посмотреть RxLib, но что-то связанное с рисованием мне там найти не удалось. Подскажите, пожалуйста, как воспользоваться RxRichEdit для рисования на нём. Вообще, мне нужно всего-навсего нарисовать рамку, внутри которой необходимо будет изменять текст, а уже правее неё должен следовать неизменяемый текст (ну, предотвратить изменение изменяемого проще простого). Пробовал использовать таблицу из 1 строки и 1 столбца, но правее неё разместить ничего не удалось, а при создании таблицы из 1 строки и 2 столбцов не удалось скрыть границы второй ячейки. Жду предложений.


 
Unknown Mystic ©   (2006-07-10 18:12) [4]

А как советовать, если ничего не понятно?.. Привел бы минимальный код что ли...

А ты его вообще отчищаешь перед тем как поновой рисовать то?


 
Andr-04   (2006-07-11 18:04) [5]

А зачем очищать-то? Пусть на нарисованном рисуется! Боюсь, конечно, выглядеть идиотом, но всё-таки рискну привести свой код (это не конечный, а предварительный. На нём вместо прямоугольника рисуется простой отрезок. Но суть от этого не меняется)! :-)
function TForm1.RichEdit1Message(var Msg: tagMSG;
 var Rslt: Integer): Boolean;
var
 x, y: Integer;
begin
 if msg.message=wm_paint then
   begin
     x:=GetScrollPos(RichEdit1.Handle, SB_HORZ);
     y:=GetScrollPos(RichEdit1.Handle, SB_VERT);
     RichEdit1.Canvas.Rectangle(33-x, 20-y, 88-x, 50-y);
   end;
 result:=false;
end;

Причём я ещё не затрагиваю проблему белого фона внутри прямоугольника - думаю, в карайнем случае отрезками нарисую, т.к. BrushStyle тоже не помогает.
Для испытания моего кода необходимо предварительно в RichEdit "забить" мусор.


 
Andr-04   (2006-07-11 18:08) [6]


> На нём вместо прямоугольника рисуется простой отрезок. Но
> суть от этого не меняется

Уже подправил перед отправлением поста, но убрать в сообщении эту реплику забыл.


 
Andr-04   (2006-07-12 16:38) [7]

Ура, понял почему так происходит! Дело в том, что при перемещении ползунка полосы прокрутки кнопкой мыши до её отпускания GetScrollPos выдаёт начальное положение полос прокрутки, с которого она началась. GetScrollInfo тоже ничего корректного не выводит (возможно, не правильно выставляю параметр fMask (я устанавливаю его в SIF_POS)). Если я иду не в том направлении - поправьте, если в том - подскажите что нужно изменить. Все примеры рисования, которые я находил в интернете, не расчитыны на перемещение нарисованного при прокрутке RichEdit. Поэтому решение этого вопроса будет полезно и не только при KOL-программировании.


 
Unknown Mystic ©   (2006-07-12 21:21) [8]

В общем так, с графикой я не работал, так что мало что могу подсказать...

Но помоему мое предположение верно - "размножение" происходит из-за того, что ты не удаляешь то, что до этого рисовал. И вообще что-то страшное ты замутил с высчитыванием того, не ясно чего :)

Замени обработчик wm_paint на вот это и посмотри что будет...
    RichEdit1.Canvas.FillRect(RichEdit1.Canvas.ClipRect());
    RichEdit1.Canvas.Rectangle(33, 20, 88, 50);

Конечно не особо, но во всяком случае прямоугольник не плодится ;)


 
Andr-04   (2006-07-12 21:36) [9]

Не, мне нужно чтобы это нарисованное изображение не сидело фоном, а тоже, вместе с текстом, ПЕРЕМЕЩАЛОСЬ!


 
Unknown Mystic ©   (2006-07-13 03:15) [10]

Ааа... Теперь понял :)

Ну тогда что-то вроде:
function TForm1.RichEdit1Message(var Msg: tagMSG;
 var Rslt: Integer): Boolean;
var
 SI: TScrollInfo;
 x, y: Integer;
begin
 if msg.message = WM_PAINT then
 begin
   x := 0;
   y := 0;

   FillChar(SI, SizeOf(SI), 0);
   SI.cbSize := SizeOf(SI);
   SI.fMask := SIF_RANGE or SIF_POS or SIF_TRACKPOS or SIF_PAGE;
   GetScrollInfo(RichEdit1.Handle, SB_VERT, SI);

   EditBox2.Text := Int2Str(SI.nPos);
   EditBox3.Text := Int2Str(SI.nTrackPos);
   if SI.nTrackPos = 0 then y := SI.nPos
   else y := SI.nTrackPos;
   RichEdit1.Canvas.Rectangle(50 - x, 50 - y, 150 - x, 150 - y);
 end;
 Result := FALSE;
end;


Правда в маске может что-то лишнее - не разбирался. Это первое, что я в KOL.PAS нашел - лениво самому SI заполнять было :))


 
Andr-04   (2006-07-13 10:34) [11]

Да, получилось, но всё равно очень часто случаются случаи и размножения, и съезжания рисунка (например, после опускания из самого верхнего положения кнопкой "вниз" полосы и поднятия ползунком). Я даже пытался перехватывать wm_vscroll и, в зависимости от метода прокрутки (ползунком, стрелочкой или пространством между ползунком и стрелочкой) выставлял текущее значение y - ничего не помогло. Вот примерно то, что у меня сейчас:
var
 y: Integer;
 SI: TScrollInfo;
begin
 if (msg.message=wm_paint) or (msg.message=wm_vscroll) then
   begin
     GetScrollInfo( RichEdit1.Handle, SB_VERT, SI );
     if msg.message=wm_vscroll then
       if LoWord(Msg.wParam)=SB_THUMBTRACK then
         y:=si.nTrackPos
       else
         y:=si.nPos
     else
       if SI.nTrackPos = 0 then
         y := SI.nPos
       else
         y := SI.nTrackPos;
     RichEdit1.Canvas.MoveTo(33, 20-y);
     RichEdit1.Canvas.LineTo(88, 20-y);
     RichEdit1.Canvas.LineTo(88, 50-y);
     RichEdit1.Canvas.LineTo(33, 50-y);
     RichEdit1.Canvas.LineTo(33, 20-y);
   end;
 result:=false;
end;

Да, ещё замечу, что даже если обрабатывать исключительно все события, а не только wm_paint, то всё равно прорисовка прямоугольника иногда не срабатывает! Возможно можно попробовать в сам RichEdit помещать компоненты (это возможно), но, помню, когда-то экспериментировал - и всё равно прорисовка страдала! Вот так загадка!..


 
Unknown Mystic ©   (2006-07-14 00:40) [12]

Так... Посмотрел еще малость.

Двоение в приведенном тобой примере - думается результат не совсем корректной проверки:
if SI.nTrackPos = 0 then y := SI.nPos
  else y := SI.nTrackPos;


Надо по нормальному вытаскивать прокручивается ли окно за ползунок или нет.

Ну и второе - это при вводе строк, которые пересекают рисунок...


 
Andr-04   (2006-07-14 11:33) [13]

Да, я уже ещё малость переделал - заметил ещё, что при опускании на самый низ nTrackPos возвращает величину на 1 больше максимальной. Это тоже исправил. И перерисовку сделал на любое событие OnMessage кроме wm_vscroll, но всё равно замечаются случаи недорисованности (ненарисованности) (например, если отвести ползунок вниз, а затем, не отпуская кнопку мыши, увести курсор очень далеко от полосы прокрутки, чтобы полоса вернулась на прежнее состояние). Если же wm_vscroll тоже обрабатывать, то прямоугольник будет размножаться, хотя случай, описанный в скобках выше, в таком случае определяется, но прямоугольник рисуется до прокрутки, из-за чего его всё равно не видно. Вот что у меня сейчас:
var
 cscr: Integer = 0;
function TForm1.RichEdit1Message(var Msg: tagMSG;
 var Rslt: Integer): Boolean;
var
 y: Integer;
 SI: TScrollInfo;
begin
 if msg.message=wm_vscroll then
   cscr:=LoWord(Msg.wParam)
 else
   begin
     SI.cbSize := Sizeof( SI );
     SI.fMask := SIF_POS or SIF_RANGE or SIF_TRACKPOS or SIF_PAGE;
     GetScrollInfo( RichEdit1.Handle, SB_VERT, SI );
     if cscr=SB_THUMBTRACK then
       y := SI.nTrackPos
     else
       y := SI.nPos;
     if y>si.nMax-si.nPage then
       y:=si.nMax-si.nPage;
     RichEdit1.Canvas.Pen.Color:=clBlack;
     RichEdit1.Canvas.MoveTo(33, 20-y);
     RichEdit1.Canvas.LineTo(88, 20-y);
     RichEdit1.Canvas.LineTo(88, 50-y);
     RichEdit1.Canvas.LineTo(33, 50-y);
     RichEdit1.Canvas.LineTo(33, 20-y);
     RichEdit1.Canvas.Pen.Color:=RichEdit1.Color;
     RichEdit1.Canvas.MoveTo(0, 0);
     RichEdit1.Canvas.LineTo(RichEdit1.ClientWidth, 0); //это чтобы на самой верхней линии RichEdit не оставались следы от нарисованного прямоугольника
   end;
 result:=false;
end;


 
Unknown Mystic ©   (2006-07-15 23:48) [14]

Не знаю из-за чего оно не отрисовывается, но при этом сообщение WM_PAINT посылается и отлавливается...


 
Andr-04   (2006-07-20 22:04) [15]

Прошу прощения, что не писал - уезжал из дома. Да, WM_PAINT тоже отлавливается, но НЕ при уводе курсора во время перемещения ползунка прокрутки на большое расстояние от самой полосы. В такой момент WM_PAINT не отлавливается, и не знаю почему. А как быть на счёт добавления runtime компонентов непосредственно в RichEdit? Может там возможно как-то сделать корректную отрисовку? Я уже давно этот эксперимент проводил, поэтому у меня ничего не сохранилось. Я тогда CheckBox помещал... Помню только что он корректно перемещался, но тоже рзмножался... Может кому-нибудь удастся добиться каких-нибудь результатов? Если конкретно - нужно будет в различных условиях помещать либо EditBox, либо CheckBox, либо RadioBox (с определением ситуации когда помещать каждый проблем нет - просто необходимо проверить перечисленные 3 случая). Тут ещё на ум приходит плагин Миранды (альтернативный ICQ клиент), вроде Scriver.dll называется... В нём в качестве истории сеанса переписки используется RichEdit, где каждое сообщение можно разделять горизонтальной полосой, которая перерисовывается корректно. Думал, что это специфическая RTF-команда, но когда при помощи WinHex посмотрел содержимое памяти приложения, ничего специфического не обнаружил. Следовательно, это либо runtime-компоненты, либо обработка прорисовки.


 
homm ©   (2006-07-20 23:59) [16]

> [15] Andr-04   (20.07.06 22:04)

в qip во время запроса авторизации у пользователя, у которого спрашивают авторизации, появляются 2 кнопки: соответственно принять и отказатся. (уж не знаю как эта информация поможет, но...  :) )


 
Andr-04   (2006-07-21 19:28) [17]


> в qip во время запроса авторизации у пользователя, у которого
> спрашивают авторизации, появляются 2 кнопки: соответственно
> принять и отказатся. (уж не знаю как эта информация поможет,
>  но...  :) )

Да уж... Действитльно кроме ":)" ничего не скажешь... Но тут у нас, извините, не каламбур! И по этому прошу отвечать строго по теме! Плагин Scriver от Mirand"ы имеет к этому отношение - его делали люди на основе RichEdit, и им удалось сделать корректную прорисовку. Вопрос: каким образом? А две кнопочки и в Mirand"е появляются... Это не удивительно, а логично!


 
AndreyRus   (2006-07-22 00:03) [18]

Да уж... Действитльно кроме ":)" ничего не скажешь...
Аааа! :)
Homm не проснулся!


 
Andr-04   (2006-07-22 10:01) [19]

Ну пусть тогда просыпается и подключается к решению задачи! Подключайтесь все! :-) И давайте без флуда! Без этого уже не мало написано, хотя бывает и намного больше...


 
Andr-04   (2006-07-22 10:04) [20]

И пишу в основном я... :-)


 
homm ©   (2006-07-22 13:57) [21]


> Homm не проснулся!

В qip тоже RichEdit используется :P


 
homm ©   (2006-07-22 13:59) [22]

а еще он написан на дельфи. А еще автор рускоязычный. Может к нему на мыло обрариться?

ЗЫ Чесное слово, мне бы тоже было интересно решение, но у меня нет времени, так что сори :)


 
Andr-04   (2006-07-22 20:15) [23]


> В qip тоже RichEdit используется :P

Не могли бы подсказать в каком именно месте? Специально только что скачал новую с офф. сайта - там везде TRichView - и в истории, и в окне переписки... А RichView и RichEdit - далеко не одно и тоже!
P.S. Но если бы не этот случай, ещё не знаю когда бы этот QIP увидел в глаза...
Так что плагин Scriver.dll от Mirand"ы остаётся в силе!


 
AndreyRus   (2006-07-24 05:14) [24]


>RichView и RichEdit - далеко не одно и тоже!

А что такое - RichView?


 
Unknown Mystic ©   (2006-07-24 12:37) [25]


> Да, WM_PAINT тоже отлавливается, но НЕ при уводе курсора
> во время перемещения ползунка прокрутки на большое расстояние
> от самой полосы.

Ты уверен? Я так понял имеется ввиду момент, когда при отводе курсора на большое расстояние, ползунок из некоторого положения перескакивает в начало.
Так вот, если не ошибаюсь, в этом случае WM_PAINT проходит... Попробуй в его обработчик этого события поставить инкремент значения какого-нибудь эдита...


 
Andr-04   (2006-07-24 15:11) [26]


> Ты уверен? Я так понял имеется ввиду момент, когда при отводе
> курсора на большое расстояние, ползунок из некоторого положения
> перескакивает в начало.
> Так вот, если не ошибаюсь, в этом случае WM_PAINT проходит.
> .. Попробуй в его обработчик этого события поставить инкремент
> значения какого-нибудь эдита...

Вот именно, что WM_PAINT не происходит в этом случае! Уверен на 99% (1% - резерв ;-) )! Проверьте собственноручно мой код в 13-м посте и убедитесь в этом сами!


> А что такое - RichView?

А RichView - это набор компонент для работы с RTF, только с дополнительными (даже по сравнению с RxRichEdit) наворотами. Но он платный, и существует только для VCL, т.е. для собравшейся здесь публики он ни коем образом не пригоден. К тому же, у меня есть подозрение, что он полностью написан с нуля, поэтому и переделывать его на KOL нет никакого смысла. Яркий пример его использования, как я уже говорил - это QIP. Но лично мне он не понравился! :-)

Также я успел 22.07.2006г. написать письмо разработчикам Scriver.dll с просьбой помочь мне, но ответ они писать пока упорно не хотят! :-(


 
Unknown Mystic ©   (2006-07-25 02:19) [27]

Могу только повторить то, что уже сказал перед этим. Только уже без "если не ошибаюсь" - только что еще раз проверил...


 
Andr-04   (2006-07-25 11:30) [28]

Да как это прорисовывается!? Только что ещё раз специально проверил - прямоугольник рисуется только ПОСЛЕ отпускания кнопки мыши! Это нужно исключить! Нужно чтобы прямоугольник рисовался сразу после возврата к началу, а не после того как ещё мышку отпустишь! Приведите, пожалуйста Ваш код, а проверьте мой из поста №13.


 
Unknown Mystic ©   (2006-07-25 13:07) [29]

Я не говорил что прорисовывается! Я сказал, что WM_PAINT проходит. (см. 14, а также 25 и 27)


 
Andr-04   (2006-07-25 21:00) [30]

И какой тогда толк от WM_PAINT? Мне кажется, здесь нужен немного другой подход, который мне найти так и не удалось! Пожалуйста, кто может, подскажите!



Страницы: 1 вся ветка

Форум: "KOL";
Текущий архив: 2007.04.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.064 c
3-1168937991
pavel_guzhanov
2007-01-16 11:59
2007.04.01
Как проверить содержимое поле типа DateTime на null


2-1173258178
sergeyst
2007-03-07 12:02
2007.04.01
Как убрать слэш из пути


3-1168467333
r2d2
2007-01-11 01:15
2007.04.01
экспорт из access


15-1173156404
eXPell
2007-03-06 07:46
2007.04.01
Эх, раз...


15-1173225780
Ksander
2007-03-07 03:03
2007.04.01
JSP&mysql





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский