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

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

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

ASH - Automatic Syntax highlight (Attempt 2)

[Please note: I have my Delphi Editor colors set-to the [Ocean] colour speed settings for testing purposes. This setting works well on the default RichEdit white background, and most TokenTypes are in different colors from each other]

Okay now to do some real work. Most of the function have been written thereabouts. As a basis for writing this ASH I''''m going to use Project1.dpr which comes out of mpas2rtf.zip in the YourPasEdit zip file yrpasedit.zip. This is because it much smaller than YourPasEdit, and thus quicker to compile.

I suggest you put the contents of the mpas2rtf.zip into a separate directory. Also copy mwPas2Rtf.pas to testinput.pas using the Explorer shell - we''''ll be using this file as a sample pascal file for benchmarking.

Open Project1.dpr in Delphi, compile Project1, run it, and open the file testinput.pas by pressing [Button 1] and selecting it in the [OpenFile Dialog]. Do it a number of times, and record the time taken for each once the file is stabilised in the system cache. On my system it averages about 0.47 - 0.41 seconds once its in the cache (P133 - 16M - Win95b)

Preparing Project1''''s Unit1.pas

Now replace the contents of mpas2rtf.pas with that code in jhdpas2rtf.pas. Recompile. Now open up the testinput.pas sample file again by using [Button 1]. As you see - we get color - but it takes a "lot" longer: 1.20-1.25 seconds.

Try and speed it up if you like. You can start by commenting out the pascal-code that codes in the different Font and FontSizes in TPasConversion.SetRtf. Recompile and run again. This time it improves a bit to 1.10-1.15. Now try commenting out the code for different Colors. Wow - the speed decreases down to 0.49 - 0.44.

Hmm. This font and color stuff really packs a punch. We may need to look at this later in more detail if things end up too slow. For the moment we''''ll leave the code back in full working condition (so you''''ll need to go back and uncomment the code).

Now put the following base code into the [OnChange] event of the RichEdit1 in Unit1.pas of Project1. Most of this code is just based on what we have already covered elsewhere.
 
 

procedure TForm1.RichEdit1Change(Sender: TObject);

var

WasSelStart,WasRow,Row,BeginSelStart,EndSelStart: Integer;
MyRe: TRichEdit;
MyPBuff: array[0..255] of char;

begin

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

end;

Were going to use the GetToken() function to do all the hard work. We''''ll need some extra variables to pass to the GetToken function, so add to the var section:

MyTokenStr:string;
MyTokenState:TTokenState;
MyRun:PChar;
MySelStart: Integer;

These are similar to the variables we used in the ConvertReadStream - in fact we want to do "exactly" the same thing, just one single line at a time. Add this code before the last end;

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);

//
// ScanForRtf;
// SetRtf;
// WriteBuffer(Prefix + TokenStr + Postfix);
//

end;

end;

NB: As we will be using PasCon you''''ll have to move it from being a local variable of TForm1.Button1Click to be a global variable. This will  mean you''''ll have to move all the initialising:

PasCon:=TPasConversion.Create;
PasCon.UseDelphiHighlighting(3);

to a TForm1.Show, and the PasCon.Free to TForm1.Close procedure. It will still work if you only move the variable definition - but not for long... :-)

I''''ve left the code from the old ConvertReadStream in the example above to show what we "logically" still need to implement in the current context - that is manipulating the RichEdit Control directly. What we have now is the ability to cut up the current line in to different tokens, and know what type they are. We now have to add these tokens to current line with the right attributes (Fonts,Colors,Bold etc).

But wait. They are already on the line - well the text is anyway, but maybe not in the correct format (Color,Bold etc). So what actually could do is to select each token in its corresponding positon in the RichEdit control and just apply the appropriate attributes to them.

We did this back in the beginning remeber? When we set the >10 character lines to the color red. But how do we do this now? Lets look at what we have in the variables at hand when we hit "// SetRtf" the first time:
 


(these example uses Uni1.pas as the input file as its more interesting)
 



 

VARIABLES

01234567901234567890 Lines.Strings[R0] unit Unit1; MyPBuff unit Unit1; MyTokenState tsIdentifier MyTokenStr unit MyRun  Unit1;

So what we need to do is select the word ''''unit'''' in the RichEdit control, and set its attributes. We do this by setting SelStart to the position of ''''unit'''' in the RichEdit control, and SelLength to the length of the word ''''unit''''. And since ''''unit'''' is at the beginning of the current line - thats position is BeginSelStart (which I conveninently have stored in MySelStart - you''''ll see why). Lets replace the "pseudo" comment code with the following:

MyRe.SelStart       := MySelStart;
MyRe.SelLength    := Length(MyTokenStr);
MyRe.SelAttributes.Assign(PasCon.FParseFont[MyTokenState]);

end;

But remember we are in a loop - when we go around again we''''ll have the next token in the line, and the variables will look like this:
 

VARIABLES

01234567901234567890 Lines.Strings[R0] unit Unit1; MyPBuff unit Unit1; MyTokenState tsSpace MyTokenStr (space character) MyRun Unit1;

But (space character) isn''''t at BeginSelStart (#0) in the RichEdit control. Its further along (at position #4). Which just happens to be BeginSelStart + Length(''''unit''''). We need to update MySelStart after we process the preceeding token, but before we go around the loop again:

MySelStart := MySelStart + Length(MyTokenStr);

end;

Okay - this is where we are standing at the moment:
 
 

procedure TForm1.RichEdit1Change(Sender: TObject);

var

WasSelStart,WasRow,R

[1] [2] [3]  下一页


[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……
    咸宁网络警察报警平台