转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
讲述如何开发一个控件,很有价值(七)         ★★★★

讲述如何开发一个控件,很有价值(七)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1431 更新时间:2009/4/23 18:44:04

SUCCESS - (Nearly...)
 

I think you''''ll agree we are pretty close. There is just a little bit of flicker. This flicker is the SelStart jumping the Cursor position around the text. We need to hide this. This "Cursor" is also known as a Caret. Looking throught Win32.Hlp again we find the lovely, and appropriately named, HideCaret() function.

Lets try this then: everytime we change the value of MyRe.SelStart lets call HideCaret(MyRe.Handle) immediately before.

I''''ll be kind - that doesn''''t work. I tried 2 x HideCaret(MyRe.Handle), and it still didn''''t work. Neither did three,four or 25x. So close - but yet - so far. I think its time for another Delphi Rule:

DELPHI RULE #5 - If you bother to get your way through the atrocious index of the Win32.HLP file to find what you are looking for - make sure you really read what you found properly!

The key was the last paragraph in the description of not HideCaret but ShowCaret (which I had also read as I thought we were going to need it, especially to reverse my 25x HideCaret()). You also need another Delphi Rule to understand it:
 

The caret is a shared resource; there is only one caret in the system. A window should show a caret only when the window has the keyboard focus or is active. 

DELPHI RULE #6 - Everything (basically) is a Window

You see the RichEdit is a windows control and is also.. in a weird sense.. a window. It has a Handle, which is why HideCaret would accept it. So re-reading the last line again we get:
 

The caret is a shared resource; there is only one caret in the system. A [RichEdit] should show a caret only when the [RichEdit] has the keyboard focus or is active. 

So - in the end - we''''re back to were we started - we have to disable the RichEdit to stop the final bit of flickering. This also (co-incidentially) means that EM_HIDESELECTION is not needed anymore (if HideSelection is set properly during Design time). So in the end everyone gets 10/10 for marks!

ASH Version 0.9b
 
 

procedure TForm1.RichEdit1Change(Sender: TObject);

var

SaveOnChangeIn: TNotifyEvent; 
WasSelStart,WasRow,Row,BeginSelStart,EndSelStart: Integer;
MyRe : TRichEdit;
MyPBuff: array[0..255] of char;
MyTokenStr:string;
MyTokenState:TTokenState;
MyRun:PChar;
MySelStart: Integer; 

begin

MyRe := TRichEdit(Sender);

SaveOnChangeIn := MyRe.OnChange;
MyRe.OnChange  := nil;

MyRe.Enabled   := False;

WasSelStart      := MyRE.SelStart;
WasRow            := MyRE.Perform(EM_LINEFROMCHAR, MyRE.SelStart, 0);
Row                    := WasRow;
BeginSelStart    := MyRe.Perform(EM_LINEINDEX, Row, 0);
EndSelStart       := BeginSelStart + Length(MyRE.Lines.Strings[Row]);

StrPCopy(MyPBuff,MyRE.Lines.Strings[Row]);
MYPBuff[Length(MyRE.Lines.Strings[Row])] := #0; 
MySelStart   := BeginSelStart;
MyRun         := MyPBuff;

while(MyRun^ <> #0) do
begin

MyRun := PasCon.GetToken(MyRun,MyTokenState,MyTokenStr);

MyRE.SelStart := MySelStart;
MyRE.SelLength := Length(MyTokenStr);

If MyRE.SelAttributes.Name <> PasCon.FParseFont[MyTokenState].Name then MyRE.SelAttributes.Name := PasCon.FParseFont[MyTokenState].Name;

If MyRE.SelAttributes.Color <> PasCon.FParseFont[MyTokenState].Color then MyRE.SelAttributes.Color := PasCon.FParseFont[MyTokenState].Color;

if MyRE.SelAttributes.Style <> PasCon.FParseFont[MyTokenState].Style then MyRE.SelAttributes.Style := PasCon.FParseFont[MyTokenState].Style;

MySelStart := MySelStart + Length(MyTokenStr);

end;

MyRE.SelStart          := WasSelStart;
MyRE.SelLength      := 0;
MyRe.OnChange     := SaveOnChangeIn;
MyRe.Enabled         := True;

MyRe.SetFocus;

end;

Towards - ASH Version 1.0b

Couple of problems with the last version if you try it out for size:

  1. 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)

  2.  
  3. 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.

  4.  
  5. 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).)

  6.  


     
     

    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.

    [1] [2]  下一页


    [Delphi程序]讲述如何开发一个控件,很有价值(六)  [Delphi程序]讲述如何开发一个控件,很有价值(五)
    [Delphi程序]讲述如何开发一个控件,很有价值(四)  [Delphi程序]讲述如何开发一个控件,很有价值(三)
    [Delphi程序]讲述如何开发一个控件,很有价值(二)  [Delphi程序]讲述如何开发一个控件,很有价值
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台