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

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

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

To start with I used the Edit1 Control to display the results of all these variables. I then tried manipulating text in the RichEdit to see what values I got. You should do the same. Type slowly in:

1234567890<CR>1234567890<CR>1234567890

and see how the results are reflected in the Edit control as you do so. Then experiment - try adding stuff to the ends of lines, and in the beginning of the line, and middle of lines. You may have to refer back to the Code to work out which number represents which variable.

Okay, now using the variables we have, lets try selecting the text of the current line, and display it in a new Edit Control (Edit2).

Add the following code to see what happens (don’t forget to add the second edit control and make it as wide as possible):

  MyRe.SelStart    := BeginSelStart;
  MyRe.SelLength   := EndSelStart - BeginSelStart;
  Edit2.Text       := MyRe.SelText;
end;

Run the program and try it out.

OOPS - That doesn''''t work - the text remains selected and the original cursor position is lost.
We need to reset SelStart and SelLength before we finish in the [OnChange] event. So let’s add at the end:

  MyRe.SelStart    := WasSelStart;      //back to were we started
  MyRe.SelLength   := 0;                  // nothing selected
end;

While playing with text in the edit control I discovered something weird.

If you typed [1] then <CR> then [2] the Edit1 displayed [4-1-3-4].

But there were only two characters in the display.

I made a mistake. It appears that RichEdit.Text can tell you where the beginning and end of line is. Why? Because you can access the <CR><LF> characters in the Text string. So we could have manipulated the Text property of the control to work out the beginning and end of lines by reading back and forward from SelStart to find <CR><LF> characters. We may not have known which line we were on, but we would know where it began and ended. Nevertheless we should keep this in mind, it might come in handy later.

But it doesn''''t matter - the EM_###### messages are a neat way of doing things. And they work. For the moment at least we''''ll stick with them.

7. Okay implement: Part 2 - Change the format

After the line Edit2.Text := MyRe.SelText, but before the "resetting" part, lets put some logic in to turn lines RED when they are longer than a certain length:

if (MyRe.SelLength > 10) then MyRe.SelAttributes.Color := clRed;

You''''ll notice two things if you test this out. First - it does work. Second however, is that if you type a line > 10 characters, press return and type one character - its in Red. This is because it inherits the Attributes of the preceding text. Just like if you have bold on in a Word processor, it doesn''''t reset if you press return. So lets change the line to include an else situation:

else MyRe.SelAttributes.Color := clBlack;

That seems to work - except when you press return in the middle of a > 10 character line you have already typed (which is already Red) to leave a stump < 10 characters on the line above - it remains red. This is because the code leaves you on the next line, and SelStart refers to this new line, not the previous one. In our eventual code, we''''ll have to take care to ensure this doesn''''t happen - we have to catch this situation and deal with it. It wont be the only situation I''''m sure....

PS: There will be a number of situation we''''re we''''ll have to be careful. Can you think of any now? Try putting a lot of text in the Control (or manipulate a loaded file) and selecting some and using the inherit Drag and Drop (move your Mouse over some selected text, press and hold down the Left MouseButton and then drag away) to move some text. This only Triggers one OnChange Event. We may also be moving multiple lines along the way. In the future we''''ll have to put in some code to detect this happening, and ensure the [OnChange] event can deal with the need to reformat in two different locations. That means thinking in the back of the head about how in the future we may have to deal with this kind of situation, and ensure our code to deal with the simple situation can be adapted - i.e. be "versatile".

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;

  &

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