RichViewEdit input string under the original horizontal line problem

General TRichView support forum. Please post your questions here
Post Reply
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

RichViewEdit input string under the original horizontal line problem

I don't know much English.
The first time I used RichViewEdit, I asked you how to input multiple lines of string in RichViewEdit, and there was a line under the word (like a letter paper effect).

For example, the long string
str:=' Delphi是全新的可视化编程环境,为我们提供了一种方便、快捷的Windows应用程序开发工具。它使用了Microsoft, Windows图形用户界面的许多先进特性和设计思想,采用了弹性可重复利用的完整的面向对象程序语言(Object-Oriented Language)、当今世界上最快的编辑器、最为领先的数据库技术。'+#13#10+' 真正的程序员用C,聪明的程序员用Delphi。——网上传闻。'
The code I need to implement.
See connection for the final effect :(thanks again for your reply) Why don't you let the texture

' Delphi是全新的可视化编程环境,为我们提供了一种方便、快捷的Windows应用程序工具。它使用了Microsoft, Windows___
图形用户界面的许多先进特性和设计思想,采用了弹性可重复利用的完整的面向对象程序语言(Object-Oriented Language)、当
世界上最快的编辑器、最为领先的数据库技术。_________________________________________________________________
真正的程序员用C,聪明的程序员用Delphi。——网上传闻。________________________________________________________

See the attachment for the specific effect
Attachments
通天塔7.jpg
通天塔7.jpg (58.66 KiB) Viewed 36310 times
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: RichViewEdit input string under the original horizontal line problem

Post by Sergey Tkachenko »

1) The first idea: you can use paragraph borders. You can hide all sides of paragraph borders except for the bottom side, and the result will look like notebook lines... But not completely. Lines will be drawn below paragraphs, not below each line. And some paragraphs may contain several lines.

2) The second idea: you can use a background texture (assign BackgroundBitmap property). But this solution is good only if you know the exact line size

3) If you know line size, you can use OnPaint event instead of a background picture.
The code below draws lines every 30 pixels:

Code: Select all

procedure TForm3.RichViewEdit1Paint(Sender: TCustomRichView; ACanvas: TCanvas;
  Prepaint: Boolean);
var
  i, DY: Integer;
const
  LineHeight = 30;
begin
  if Prepaint then
    exit;
  ACanvas.Pen.Color := $EE9900;
  ACanvas.Pen.Style := psSolid;
  ACanvas.Pen.Width := 1;
  DY := -(Sender.VScrollPos*Sender.VSmallStep) mod LineHeight;
  for i := 0 to Sender.ClientHeight div LineHeight + 1 do
  begin
    ACanvas.MoveTo(0, DY + i * LineHeight);
    ACanvas.LineTo(Sender.ClientWidth, DY + i * LineHeight);
  end;
end;
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: RichViewEdit input string under the original horizontal line problem

Post by Sergey Tkachenko »

Finally, I found the best solution:

4) You can use OnPaint to draw lines below each text line:

Code: Select all

procedure TForm3.RichViewEdit1Paint(Sender: TCustomRichView; ACanvas: TCanvas;
  Prepaint: Boolean);
var
  i, Y: Integer;
  FirstDrawItemNo, LastDrawItemNo: Integer;
begin
  if Prepaint then
    exit;
  ACanvas.Pen.Color := $EE9900;
  ACanvas.Pen.Style := psSolid;
  ACanvas.Pen.Width := 1;

  Sender.RVData.Item2FirstDrawItem(Sender.FirstItemVisible, FirstDrawItemNo);
  Sender.RVData.Item2LastDrawItem(Sender.LastItemVisible, LastDrawItemNo);

  for i := FirstDrawItemNo to LastDrawItemNo do
    if Sender.RVData.DrawItems[i].FromNewLine then
    begin
      Y := Sender.RVData.DrawItems[i].Top + Sender.RVData.DrawItems[i].Height -
        (Sender.VScrollPos*Sender.VSmallStep);
      ACanvas.MoveTo(0, Y);
      ACanvas.LineTo(Sender.ClientWidth, Y);
  end;
end;
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

Re: RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

Thank you very much!!
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

Re: RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

TO Sergey Tkachenko

procedure TForm3.RichViewEdit1Paint(Sender: TCustomRichView; ACanvas: TCanvas;
Prepaint: Boolean);
var
i, Y: Integer;
FirstDrawItemNo, LastDrawItemNo: Integer;
begin
if Prepaint then
exit;
ACanvas.Pen.Color := $EE9900;
ACanvas.Pen.Style := psSolid;
ACanvas.Pen.Width := 1;

Sender.RVData.Item2FirstDrawItem(Sender.FirstItemVisible, FirstDrawItemNo);
Sender.RVData.Item2LastDrawItem(Sender.LastItemVisible, LastDrawItemNo);

for i := FirstDrawItemNo to LastDrawItemNo do
if Sender.RVData.DrawItems.FromNewLine then
begin
Y := Sender.RVData.DrawItems.Top + Sender.RVData.DrawItems.Height -
(Sender.VScrollPos*Sender.VSmallStep);
ACanvas.MoveTo(0, Y);
ACanvas.LineTo(Sender.ClientWidth, Y);
end;
end;
//////////
I found :
This method will draw when the mouse click in the edit area, it flickers. How to fix it?
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: RichViewEdit input string under the original horizontal line problem

Post by Sergey Tkachenko »

Yes, you are right, drawing in OnPaint event may flicker, because it draws directly in the editor's canvas, without double buffering.

We could use TRVStyle.OnDrawParaBack event instead, but, unfortunately, it does not have enough parameters to perform this kind of drawing. Two additional parameters defining how the drawing area is shifted are required. I'll add them in the next update of TRichView. Meanwhile, OnPaint is the only way to implement this feature.
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

Re: RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

Let me use the,
Form.DoubleBuffered:=true;
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

Re: RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

Code: Select all

procedure TForm3.RichViewEdit1Paint(Sender: TCustomRichView; ACanvas: TCanvas;
  Prepaint: Boolean);
var
  i, Y: Integer;
  FirstDrawItemNo, LastDrawItemNo: Integer;
begin
  if Prepaint then
    exit;
  ACanvas.Pen.Color := $EE9900;
  ACanvas.Pen.Style := psSolid;
  ACanvas.Pen.Width := 1;

  Sender.RVData.Item2FirstDrawItem(Sender.FirstItemVisible, FirstDrawItemNo);
  Sender.RVData.Item2LastDrawItem(Sender.LastItemVisible, LastDrawItemNo);

  for i := FirstDrawItemNo to LastDrawItemNo do
    if Sender.RVData.DrawItems[i].FromNewLine then
    begin
      Y := Sender.RVData.DrawItems[i].Top + Sender.RVData.DrawItems[i].Height -
        (Sender.VScrollPos*Sender.VSmallStep);
      ACanvas.MoveTo(0, Y);
      ACanvas.LineTo(Sender.ClientWidth, Y);
  end; 
end;
@Sergey Tkachenko I remember you saying that the next version would allow using "TRVStyle.OnDrawParaBack" instead of "RichViewEdit1Paint". I wonder how to implement the function of drawing horizontal lines using "TRVStyle.OnDrawParaBack".
I'm attaching the original code, and I would appreciate it if you could help me figure out how to implement this function in TRVStyle.OnDrawParaBack. Thank you very much!
Wish you a pleasant work!
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: RichViewEdit input string under the original horizontal line problem

Post by Sergey Tkachenko »

I am sorry, but additional parameters defining the shift of coordinates were still not added :(
Probably, one more custom painting item would be a better solution than modifying OnParaBack.
I'll add it in the next update. I can send a beta version to you if you need it sooner; please remind me after a week.
wsy211
Posts: 15
Joined: Tue Sep 25, 2018 9:10 am

Re: RichViewEdit input string under the original horizontal line problem

Post by wsy211 »

@Sergey Tkachenko
I came to remind you, thank you for your help! Wish you a happy work!
Post Reply