IonicWind Software

IWBasic => Tutorials => Topic started by: Andy on March 29, 2020, 03:52:49 AM

Title: Rich edit control colouring
Post by: Andy on March 29, 2020, 03:52:49 AM
This year so far, I have been working with rich edit controls - something I haven't really touched on much before, so a little learning was required.

IWBasic has built in functions to help you do things like get text, colour text etc, so that's where I naturally started.

I've been working on loading a test file with 4,085 lines of code and started to test the time taken to colour these lines of text.

My initial attempts started at around 5 seconds to do it.

Well 5 seconds is quite fast when you think of how many words it colours, but 5 seconds is a wait that can start to irritate you, so I needed to go faster than that.

First I noticed that if I disabled showing the rich edit vertical scroll bar it completed quicker - I forget how much now, but it was enough to leave it hidden and create my own scroll bar as a replacement.

So that is step 1, hide the vertical scroll bar and use a custom one.

Now, what else can be done?

With a lot of reading I came across something interesting....

Turning off messages for my rich edit control (rHandle) before colouring speeds things up apparently?, so I tried it like this...

  SendMessage(rHandle,EM_SETEVENTMASK,0,0)
  SendMessage(rHandle,WM_SETREDRAW,false,0)

And indeed it did! - it saved at least 2.7 seconds, getting it down to 2.2 seconds.

So Step 2 - turn of messages for your rich edit control before colouring it.

When finished colouring, turn the messages back on again...

  SendMessage(rHandle,WM_SETREDRAW,true,0)
  InvalidateRect(rHandle,0,true)
  SendMessage(rHandle,EM_SETEVENTMASK,TRUE,ENM_CHANGE | ENM_SCROLL)

Here "rHandle" is just a handle to my rich edit control.

What next?

Use Win32 API calls instead of IWBasic's built in commands...

Instead of say @RTSETSELSELECTION use this:

SendMessage(rHandle,EM_SETSEL,(#i[GetLine].StartPos[c1]+Offset),(#i[GetLine].EndPos[c1]+Offset))

(#i[GetLine].StartPos[c1]+Offset) and (#i[GetLine].EndPos[c1]+Offset)) are just my calculated start and end positions to select for highlighting.

Now for colouring,

  cf.dwMask = CFM_COLOR
  cf.crTextColor = #h[GetLine].Colour[c1]
  cf.cbSize = sizeof(cf)
  SendMessage(rHandle,EM_SETCHARFORMAT,SCF_SELECTION,&cf)

To do this, you will this structure defined:

type CHARFORMAT
    UINT        cbSize
    DWORD      dwMask
    DWORD      dwEffects
    LONG        yHeight
    LONG        yOffset
    COLORREF    crTextColor
    BYTE        bCharSet
    BYTE        bPitchAndFamily
    char        szFaceName[LF_FACESIZE]
endtype

CHARFORMAT cf

Steps 3 and 4, use Win32 API calls instead of the built in commands and add $INCLUDE "Richedit,inc" to your program.

Step 5, use pointers instead of arrays.

Following these steps I have got the colouring of 4,085 lines of code down from 4.9 seconds to 1.5 seconds.

Hope you find this interesting (if you haven't already fallen asleep!).

Andy.
:)
Title: Re: Rich edit control colouring
Post by: h3kt0r on March 29, 2020, 05:41:05 AM
Well done Andy. Keep up the good work !
;)
Title: Re: Rich edit control colouring
Post by: LarryMc on March 29, 2020, 10:57:46 AM
I have a question ...just for kicks
You can't possibly SEE 4000-10000 lines on the screen at one time on the screen.
So why spend the time to color 4000-10000 lines.
Why not just spend the time to only color the lines that can be seen like 40 or 60?

You're wanting speed....

LarryMc
Title: Re: Rich edit control colouring
Post by: Andy on March 30, 2020, 03:24:40 AM
Hecktor,

Thanks very much for the support! and you have helped me with this - so thanks again.

Larry,

Well the obvious thing to do is to only colour the lines you can see not the whole file.

However I ran into difficulties, I was trying to colour say 35 lines at a time when I scrolled, but the colouring was slow and it was delaying the thumb scroll.

So I decided to see just how fast I could actually colour the whole file...

I'm glad I did because I've learnt some invaluable things along the way (as posted above).

Now based on what I have learned trying to colour the whole file as fast as possible I have now gone back to the original idea of only colouring a nominal 100 lines on load, and colouring the rest as you scroll.

So all the speed up tricks posted above have now been implemented when scrolling, and I'm very pleased to say it works very well now.

All keywords are coloured correctly as are quotations, I just now need to colour commented lines to finish off this section then I can move on to other things in my editor.

This whole speeding up process has delayed me by probably 3 weeks or so.

Like an old joke about British Rail - I get there in the end!  :D

Andy.
 :)
 
Title: Re: Rich edit control colouring
Post by: aurelCB on March 30, 2020, 05:41:37 AM
Andy 
there is another but hard option
if you find similar code in NASM assembler then you may try it inject into code ?
Title: Re: Rich edit control colouring
Post by: Andy on March 31, 2020, 05:01:01 AM
Good suggestion Aurel,

But I think that's above me!

Andy.
Title: Re: Rich edit control colouring - colour as you go
Post by: Andy on April 02, 2020, 05:54:29 AM
Thought I would post this.

My editor is a very long way away from being finished, but it's colouring sufficiently fast enough now when you scroll vertically so I thought I would share what I have got so far...

Subroutines / code that may be of interest to you:

ColourLineZ (in the include file)

This subroutine takes a line of text and detects words, delimiters, quotations and single comment characters. Depending on what it finds, it will colour appropriately.

ColourText sub (in the xeditor4.iwb file)

It gets the first visible line on screen.
This turns off messages from the rich edit prior to colouring.
Invokes a subroutine called "GetTheScrollPos" (in the xeditor4.iwb file)
Then turns rich edit messages back on.

GetTheScrollPos sub (in the xeditor4.iwb file)

This gets each line of text, and the "Offset" (start position of the first character on the line).
Then in a FOR / NEXT loop calls "ColourLineZ" (as mentioned above).

In the xeditor4.iwb file

Line 343 is where I make the program invoke colouring as and when someone scrolls.


How to

Compile as single file (F8) with the include file in the same location.

Questions 1 and 2

Do you think it colours the text fast enough, looks okay to me - but that's just me!
Do the lines look coloured correctly to you?

Observation

When scrolling downwards, I do see the cursor flashing / the wait symbol briefly - is there a way to stop this / turn it off until you have finished scrolling?

Anyway, attached are the files + a test file which is loaded.

There is a lot of junk in the files, so please just ignore them - will tidy it up later.

Please let me know what you think.

Thanks,
Andy.
Title: Re: Rich edit control colouring
Post by: Brian on April 02, 2020, 06:14:44 AM
Andy,

Can't compile - it is asking for xeditor.iwb, which is missing, I think

Brian

Edit: Sorry, Andy. Just rename xeditor4.iwb to xeditor.iwb. Works then