Recent

Author Topic: [solved] RichMemo and CHARFORMAT2 - highlight text  (Read 4410 times)

Nicole

  • Hero Member
  • *****
  • Posts: 970
[solved] RichMemo and CHARFORMAT2 - highlight text
« on: August 02, 2022, 10:30:57 am »
I received an answer, which I very appreciated:
https://forum.lazarus.freepascal.org/index.php/topic,60019.msg448099.html#msg448099

However it does not work for me, because
CHARFORMAT2
is not found.
In which unit may it be?

I use Richmemo, NOT lzRichEdit.
One link says, it would be struct.inc, but this did not work neither.

This is my new unit:

Code: Pascal  [Select][+][-]
  1. unit unit_RichMemo;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, graphics,
  9.   Windows, RichMemo, RichMemoUtils;
  10.  
  11.   type
  12.     TmyRichMemo = class(TObject)
  13.       procedure RichMemoHighlightRange(R: TRichMemo; ASelStart, ASelLength: integer; AColor: TColor);
  14.       procedure RichMemoHighlightReset(R: TRichMemo);
  15.       procedure RichMemoHighlightWord(R: TRichMemo; AWord: string; AColor: TColor);
  16.       end;
  17.  
  18. Var myRichMemo: TRichMemo;
  19.  
  20. implementation
  21. //uses struct.inc;
  22.  
  23. procedure TmyRichMemo.RichMemoHighlightRange(R: TRichMemo; ASelStart, ASelLength: integer; AColor: TColor);
  24. var
  25.   Format: CHARFORMAT2;  // ist in struct.inc
  26.   OldSelStart, OldSelLength: integer;
  27. begin
  28.   R.Lines.BeginUpdate;
  29.   try
  30.  
  31.     OldSelStart := R.SelStart;
  32.     OldSelLength := R.SelLength;
  33.  
  34.     R.SelStart := ASelStart;
  35.     R.SelLength := ASelLength;
  36.  
  37.     FillChar(Format, SizeOf(Format), 0);
  38.     Format.cbSize := SizeOf(Format);
  39.     SendMessage(R.Handle, EM_GETCHARFORMAT, WPARAM(True), LPARAM(@Format));
  40.     Format.dwMask := CFM_BACKCOLOR;
  41.     if AColor = 0 then
  42.     begin
  43.       Format.dwEffects := CFE_AUTOBACKCOLOR;
  44.     end
  45.     else
  46.     begin
  47.       Format.dwEffects := 0;
  48.       Format.crBackColor := ColorToRGB(AColor);
  49.     end;
  50.     SendMessage(R.Handle, EM_SETCHARFORMAT, SCF_SELECTION, LPARAM(@Format));
  51.  
  52.   finally
  53.     R.SelStart := OldSelStart;
  54.     R.SelLength := OldSelLength;
  55.     R.Lines.EndUpdate;
  56.   end;
  57.  
  58. end;
  59.  
  60. procedure TmyRichMemo.RichMemoHighlightReset(R: TRichMemo);
  61. begin
  62.   RichMemoHighlightRange(R, 0, R.GetTextLen, 0);
  63. end;
  64.  
  65. procedure TmyRichMemo.RichMemoHighlightWord(R: TRichMemo; AWord: string; AColor: TColor);
  66. var
  67.   Start, Found: integer;
  68. begin
  69.   Start := 0;
  70.   Found := R.Search(AWord, Start, R.GetTextLen, []);
  71.  
  72.   while (Found <> -1) do
  73.   begin
  74.     RichMemoHighLightRange(R, Found, Length(AWord), AColor);
  75.     Start := Found + 1;
  76.     Found := R.Search(AWord, Start, R.GetTextLen, []);
  77.   end;
  78.  
  79. end;
  80. //
  81. //procedure TForm1.FormCreate(Sender: TObject);
  82. //begin
  83. //  LoadRtfFile(RichMemo1, 'c:\temp\test.rtf');
  84. //end;
  85. //
  86. //procedure TForm1.Button1Click(Sender: TObject);
  87. //begin
  88. //  RichMemoHighlightReset(RichMemo1);
  89. //end;
  90. //
  91. //procedure TForm1.Button2Click(Sender: TObject);
  92. //begin
  93. //  RichMemoHighlightWord(RichMemo1, 'Lorem', clYellow);
  94. //  RichMemoHighlightWord(RichMemo1, 'Ipsum', clMoneyGreen);
  95. //end;
  96.  
  97. end.
  98.  
« Last Edit: August 03, 2022, 06:52:52 pm by Nicole »

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #1 on: August 02, 2022, 11:34:59 pm »
Didn't I put the uses in my answer ???
Yes I did  ;)

Code: Pascal  [Select][+][-]
  1. uses Windows, RichEdit, RichMemoUtils;

(One of those has the CHARFORMAT2 in it, I think the RichEdit.)

You could have asked the question in that topic  :D

skalogryz

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2770
    • havefunsoft.com
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #2 on: August 03, 2022, 02:08:06 am »
O_o
CFE_AUTOBACKCOLOR and CFE_AUTOCOLOR is something i was looking for!

SetRangeParams however should work as well, with tmm_BackColor used.

Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #3 on: August 03, 2022, 09:46:50 am »
Thank you for the answers.
Yes, this SHOULD be part of RichEdit, never the less, the compiler does not accept CHARFORMAT2

about
RiCFE_AUTOBACKCOLOR and CFE_AUTOCOLOR
tmm_BackColor

Can you please give me an example how to use?
I post a syntax, which is accepted for Color.
RichMemo1.SetRangeColor(RichMemo1.SelStart,RichMemo1.SelLength, clRed);

How would a line look alike for the mentioned parameters?
The above is only for color and I found Range parameter for underline etc.

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #4 on: August 03, 2022, 10:41:23 am »
Yes, this SHOULD be part of RichEdit, never the less, the compiler does not accept CHARFORMAT2
I just checked. It is in RichEdit. And my code is still compilable for me.

Code: Pascal  [Select][+][-]
  1.      CHARFORMAT2 = CHARFORMAT2A;

So I'm not sure what you mean by "the compiler does not accept CHARFORMAT2".
In that case you have done something wrong.

Show the exact error message (you can right-click it and choose copy) and code.

PS. My code worked perfectly (I also showed you a screen shot).
New Project, drop two buttons on the form and a TRichMemo.
Double click the buttons and a piece of empty form to create the Button1Click, Button2Click and FormCreate.
After that copy and paste my code from the other topic over the created functions and also include the uses line.
Create a c:\temp\test.rtf and run the project.
It should work without errors.

Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #5 on: August 03, 2022, 11:58:36 am »
I tried both CHARFORMAT2 and CHARFORMAT2A.
My Lazarus is 2.2.2 and the RichMemo I got over the online tool for Lazarus.

You wrote "RichEdit" instead of RichMemo. This was just a typo? Or do you have lzRichMemo as well?
This may be the difference.

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #6 on: August 03, 2022, 12:02:40 pm »
You wrote "RichEdit" instead of RichMemo. This was just a typo?
NO NO. I really meant RichEdit. That's unit in base FPC.

I really copied and pasted my code so when I copy and paste something I really can't make any typos  ;)

So just add RichEdit to the uses (like I tried to say already) and you can use CHARFORMAT2 just fine  :D

BTW. RichMemo also uses RichEdit internally (in the source) for these structures from the base RichEdit.
« Last Edit: August 03, 2022, 12:04:21 pm by rvk »

Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #7 on: August 03, 2022, 01:13:15 pm »
Thank you for the clearification.

As I came from Delphi I used RichEdit quite often. So I searched a while for it. I only found lzRichEdit, of which was said, it would give some troubles. And RichMemo.

I just rechecked the Online Packet Manager and there is no RichEdit.
Where do you have RichEdit from?

And: Are there other advantages but bringing this highlight Var to work?
Because it would rather need a lot of work to change my new RichMemos to a new RichEdit again.

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #8 on: August 03, 2022, 01:21:04 pm »
I just rechecked the Online Packet Manager and there is no RichEdit.
Where do you have RichEdit from?
As I stated multiple times... the RichEdit.pp is part of the standard installation.
You don't need to install anything for it.
Just add RichEdit to your uses and your done.

NO NO. I really meant RichEdit. That's unit in base FPC.

And: Are there other advantages but bringing this highlight Var to work?
Because it would rather need a lot of work to change my new RichMemos to a new RichEdit again.
As said... the RichEdit.pp is just a helper unit. It does NOT contain any components and there is no install needed.
You just keep on using RichMemo.

RichMemo also uses RichEdit.pp internally. Again, it's just a helper unit you can add to your uses to make use of CHARFORMAT2.


Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #9 on: August 03, 2022, 06:06:03 pm »
Please one more times for stupid.
I cannot find it.
I attach a screenshot, how I searched.

rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #10 on: August 03, 2022, 06:09:29 pm »
It's not a component or package.
It's just a UNIT. RichEdit.pp.
You don't have to search for it.

Just ADD RichEdit to your uses !!! (You do know how to add it in your code?)
Just do it.
Do not post again until you have added it there.
And then it should just compile.
If you get an error after you added it, you can post again  ;)

« Last Edit: August 03, 2022, 06:11:29 pm by rvk »

Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #11 on: August 03, 2022, 06:52:34 pm »
Thank you so very much for your patience!
It woooorks  ;D :D ;D :D ;D

I am very new to Lazarus and could not imagine such a construction.
The ending "pp" said nothing to me.

But am I correct, that I cannot re-use my old TRichEdits from Delphi directly?
I tried to change "TRichMemo" into "TRichEdit", but failed.

At the moment I do only my first steps to learn before I migrate the real huge project, so many TEdits there.
I am not very optimistic, the tool of Lazarus will help me to migrate, because I used 3 bought components in Delphi.
So questions about TEdits are important to me.


rvk

  • Hero Member
  • *****
  • Posts: 6162
Re: RichMemo and CHARFORMAT2 - highlight text
« Reply #12 on: August 03, 2022, 07:04:25 pm »
It woooorks  ;D :D ;D :D ;D
Yep, it was that simple  :D

.pp files are just the same as .pas files.
.pp is the extention for free pascal source files (just like .pas is for Turbo Pascal/Delphi).
And FPC/Lazarus can handle both .pas and it's own .pp extensions.

But am I correct, that I cannot re-use my old TRichEdits from Delphi directly?
I tried to change "TRichMemo" into "TRichEdit", but failed.
Yes, RichEdit.pp is just a helper unit where certain structures for communicating with the riched20.dll are. (Everything on Windows RichMemo is eventually dependent on that .dll, same as in Delphi)
But you can't reuse the TRichEdit one on one.
(Although TRichMemo isn't much different from TRichEdit there are some subtle differences).

You'll just have to change the TRichEdit in the sources to TRichMemo (or let the converter do that if it can) and see what needs changing.

O, also look and see if you need replacement for any used TDBRichEdit (the one where the RTF is directly stored in a database).

Nicole

  • Hero Member
  • *****
  • Posts: 970
Re: [solved] RichMemo and CHARFORMAT2 - highlight text
« Reply #13 on: August 03, 2022, 07:30:59 pm »
I learned more in our thread as I would have learned if I had understood at sudden.

TBEdit I did not use.
My nightmare is more complex: TBStringGrid used together with the query-calc-event nested into FireDac and then TChartPro on top.
Perhaps the nightmare must be lived to simplify these old structures.
I hope for a butterfly effect and to leave much behind me and climb out light and free.

rick2691

  • Sr. Member
  • ****
  • Posts: 444
Re: [solved] RichMemo and CHARFORMAT2 - highlight text
« Reply #14 on: August 19, 2022, 08:26:25 pm »
Great code. It is something that I was looking for. I have also seen a need for improvement.

In the RichMemoHighlightWord procedure:
replace RichMemoHighLightRange(R, Found, Length(AWord), AColor)
with RichMemoHighLightRange(R, Found, utf8length(AWord), AColor)

the utf8length(AWord) will make it work with unicode.

Rick
Windows 11, LAZ 2.0.10, FPC 3.2.0, SVN 63526, i386-win32-win32/win64, using windows unit

 

TinyPortal © 2005-2018