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

2008-04-09 04:31:05来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

8. Basically it all seems to kind-of work.. can''''t we do some real programming now?

Okay, okay. But first we have a problem. Actually a rather big problem. The problem is PasCon. Why?

First: It returns RTF code.
Problem: We can''''t use RTF code.

Second: its designed to work an entire stream, and then give it back to us again as a whole.
Problem: We actually want greater control over it than this "all or nothing" approach.

OOP to the Rescue

When you have something that works in a situation, and needs to be applied in another situation were it has to do a similar, but subtly different job - you have two choices:

  1. copy the function, and re-write it for the new situation, or
  2. kludge around it (e.g use Pas2Rtf, and then write a RtfCodes2RtfControl procedure).

Modern languages however give you an option: OOP it. "Objectify" it. This is more than just deriving something from an existing object. It is in a sense programming in a "state of mind". Controls should be created so they can be used in a variety of situations - father than situation specific. In this case all PasCon can deal with is tokenising the input stream and returning code RTF text. What we really need to do is divide it into two entitites. We need to separate the [Parsing/Recognise the Token and TokenType] from the [Encode it in RTF codes].

So lets start with ConvertReadStream, editing it so it looks something like this:

function TPasConversion.ConvertReadStream: Integer;
begin

FOutBuffSize := size 3;
ReAllocMem(FOutBuff, FOutBuffSize);
FTokenState := tsUnknown;
FComment := csNo;
FBuffPos := 0;
FReadBuff := Memory;

{Write leading RTF}

WriteToBuffer(''''{\rtf1\ansi\deff0\deftab720'''');
WriteFontTable;
WriteColorTable;
WriteToBuffer(''''\deflang1033\pard\plain\f2\fs20 '''');

Result:= Read(FReadBuff^, Size);

if Result > 0 then
begin

FReadBuff[Result] := #0;
Run := FReadBuff;

while Run^ <> #0 do
begin

Run := GetToken(Run,FTokenState,TokenStr);
ScanForRTF;
SetRTF;
WriteToBuffer(PreFix TokenStr PostFix);

end;

{Write ending RTF}

WriteToBuffer(#13 #10 ''''\par }{'''' #13 #10);

end;

Clear;

SetPointer(FOutBuff, fBuffPos-1) ;

end; { ConvertReadStream }

The code for ConvertReadStream is now much smaller, and also easier to understand. We can then take all the code that used to be in ConvertReadStream that did the tokenizing and create a new subroutine - the GetToken function that just does the recognizing and labelling of the individual tokens. In the process we also loose a huge number of repeated lines of code, as well as a number of sub-routines such as HandleBorCom and HandleString.

//
// My Get Token routine
//

function TPasConversion.GetToken(Run: PChar; var aTokenState: TTokenState;
var aTokenStr: string):PChar;
begin

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:讲述如何开发一个控件,很有价值(三)

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