讲述如何开发一个控件,很有价值(七)[2]
[入库:2005年8月18日] [更新:2007年3月24日]
towards - ash version 1.0b
couple of problems with the last version if you try it out for size:
- its slightly inefficient in that everytime selattributes is changed it forces a repaint of the same token in the control. we should instead use some variable (e.g var doformat:boolean) to decided if we need to reformat, and then check the value of doformat at the end of this checking, and do it all then by a simple selattribute.assign(fparsefont[mytokenstate]). this means we can also change the seperate "if" statements to a single if ... then .. else .. if ... then .. else which should code faster - especially if you put the various test situations in the order of likeliness to occur (e.g font changes less frequently than the color, so should be further down the if..else..if)
- for some reason if you type a {style comment} on a line, after about 4-7 characters it reverts to different colours. i can't seem to work out yet why this happens - but i understand why its not being picked up. selattributes returns the value of the "initial" styling of the entire selected block. so if you select text which starts off black and then becomes blue, selattributes.color will equal clblack. we must also examine selattributes.consistentattributes to ensure that the entire selection is consistent in the way it is highlighted. if it isn't - then we want to force it to be rehighlighted - its obviously not in the correct format.
- multi-line comments are a big pain e.g { words <cr> word <cr> words }. i don't have them in my 4gl so i didn't need to fix this sort of problem. however i do have muti-line strings - so i need to be able to string strings across many lines. the trouble is we have to code to program over a number of lines - but have a look at what happens in delphi when you place a "{" anywhere in the code. the highlighting can force a repaint of the entire 2,000,000 lines of text in the control. we could catch that situation - ie if the last token on the line is a tscomment and it doesn't end in '}' we could increase sellength until it did or we reach the end of the richedit.lines. (that basically what the tokeniser does anyway with all that inc(run).)
that easy. but what happens if you then delete the "{"? you need to go forward 2,000,000 lines and put the highlighting back again? we could decide to keep going until the if...then..else..list didn't set doformat := true. but what happens if we're in a colour mode were comment highlighting style = keyword highlighting style. we would stop prematurely. so this "logic" wont help in all situations.
- you can still get the "someone is chasing you effect" - except now its "someone is fleeing from you" effect. it happens when you have (* this is a comment *) and delete the first *-character. the control takes an appreciable time to rehighlight the text.
- while looking for a fix for the last problem, i remembered the richedit.lines.beginupdate function. but that didn't help either. what we need is a richedit.beginupdate. what would that do? it would increase an internal counter by one everytime it was called. richedit.endupdate would do the opposite. then we would create our own wm_paint message handler. this is received everytime windows wants the control to repaint a portion of itself. if we catch this message then we can stop processing of these message until the internal counter = 0 again. then, and only then, will the control repaint itself - ditching we would hope most of the intervening steps.
- fixing the mult-line comments:
my current idea is to use the richedit.lines.object to store the tokentype of the first token on each line. this way we could easily know how far we need to go when re-hightlighting multi-line comments. initially this would be set to nil. i think this will work.
[editor update: this didn't actually work - as the richedit.lines.object isn't implemented in trichedit control. it is
always nil regardless of what you assigned to it]
- upgrading to richedit98:
本文关键:控件开发