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

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

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

blank.rtf - empty -so I could see the "plain" header line

{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\froman Times New Roman;}} 
{\colortbl\red0\green0\blue0;}\deflang1033\pard\plain\f2\fs20 \par }

plaintext.rtf - too see how having any text was handled

{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\froman Times New Roman;}}{\colortbl\red0\green0\blue0;} 
\deflang1033\pard\plain\f2\fs20 this is plain text
\par }

difffont.rtf - different font, same size, same text

{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\froman Times New Roman;}{\f3\fswiss\fprq2 Arial;}}{\colortbl\red0\green0\blue0;} 
\deflang1033\pard\plain\f3\fs20 plain text different font\plain\f2\fs20
\par }

diffsize.rtf - text set to 18 point in the default font

{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\froman Times New Roman;}}{\colortbl\red0\green0\blue0;} 
\deflang1033\pard\plain\f2\fs36 plain text different font\plain\f2\fs20
\par }

diffcolor.rtf - etc. my favourite of course - blue.

{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS Sans Serif;}{\f1\froman\fcharset2 Symbol;}{\f2\froman Times New Roman;}}{\colortbl\red0\green0\blue0;\red0\green0\blue255;
\deflang1033\pard\plain\f2\fs20\cf1 plain text different font\plain\f2\fs20 
\par }

Looking at the resultant codes you see how the RTF stream is formatted. It comprises a:

  1. INITIAL HEADER          (\rtf1\.....)
  2. FONTTABLE                  (\f0\fswiss...)
  3. COLORTABLE              (\colortbl)
  4. MISCELLANEOUS
  5. DEFAULT FORMAT      (\pard....)
  6. BODY OF THE FILE.

As a result of that I rewrote this code:

WriteToBuffer(''''{\rtf1\ansi\deff0\deftab720{\fonttbl{\f0\fswiss MS
SansSerif;}{\f1\froman\fcharset2 Symbol;}{\f2\fmodern Courier New;}}''''+#13+#10);
WriteToBuffer(''''{\colortbl\red0\green0\blue0;}''''+#13+#10);
WriteToBuffer(''''\deflang1033\pard\plain\f2\fs20 '''');

to become:

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

The procedures Write[Font,Color]Table basically creates a table of fonts/colors we can reference later on. Each Font and Color type is stored by index in a TList internally. It acts as a lookup tables - by matching the Font name or Color value we can find the [num] to code into the RTF stream at the required moment:

\f[num]      =      the index of which Font you want to use, as pre-set in the "on the fly" font table
\fs[num]    =     point size - (for example 20 = 10point)
\cf[num]    =     the index of which Color to use, as preset in "on the fly" color table
\cb[num]   =     which background color to use - (ignored in RichEdit version 2.0)

PROBLEM#2 Crashes in long comments or text (existing problem)
 

There is a bug in ScanForRtf. Can you see it?
 

procedure TPasConversion.AllocStrBuff;
begin

FStrBuffSize:= FStrBuffSize + 1024;
ReAllocMem(FStrBuff, FStrBuffSize);
FStrBuffEnd:= FStrBuff + 1023;

end; { AllocStrBuff }

procedure TPasConversion.ScanForRtf;
var
       i: Integer;
begin

     RunStr:= FStrBuff;
     FStrBuffEnd:= FStrBuff + 1023;

     for i:=1 to TokenLen do
     begin
          Case TokenStr[i] of
               ''''\'''', ''''{'''', ''''}'''':
               begin
                    RunStr^:= ''''\'''';
                    inc(RunStr);
               end
          end;

          if RunStr >= FStrBuffEnd then AllocStrBuff;
          RunStr^:= TokenStr[i];
          inc(RunStr);
     end;

     RunStr^:= #0;
     TokenStr:= FStrBuff;

end; { ScanForRtf }

EXAMPLE - code snippet from Pas2Rtf demonstrating the "long comment" bug

The problem: if FStrBuff is enlarged using AllocStrBuff() (to make it bigger to handle a very long comment) the Windows Memory manager probably has to re-allocate it by moving the entire string buffer somewhere else in memory. RunStr however is not adjusted for this change and stillpoints to the old memory area, now unallocated.

The fix: Reallocate RunStr in the AllocStrBuff routine so it points to the correct place in the new area of memory. Try and fix it yourself, or look at my garsely spaghetti code in jhdPasToRtf.pas.
 
 

Automatic Syntax Highlighting (my first implementation)
 

To understand how Automatic syntax highlighting works, you should have a close look at what happens in the Delphi 3.0 Editor. After all - if Borland was happy with it - who am I to argue :-)

Take note when the "syntax" changes and what is affected. In retrospect the difficult thing is to implement a highlighter that is:

  1. Fast
  2. Accurate
  3. Doesn''''t flicker
  4. Isn''''t obvious ("the someone is chasing me phenomenon".. you''''ll see)

1. When should we do the re-highlighting ?

In YourPasEdit the highlighting is done as the file is read in. Once this is done, the only way to make use of that technique would be to write out the file everytime it changes and read it back in again - obviously a very slow process. In my case, I basically wanted to just reformat the line(s) that have been changed, immediately after the change had been done i.e. after every new character, DELETE or BACKSPACE or even Paste or DragDrop had been processed. I needed something that was triggered everytime the control was effected in such a way.

What I needed then was an [Event].

2. Which event - there''''s so many to choose from ?

A RichEdit, like any control, has a number of [Events] triggered when you do various things to the control. What is not obvious, is that many events trigger other events in turn. So in choosing which Event(s) to hang your code off you have to ensure that (a) it catches all situations where you need to "fix" the highlighting and (b) it doesn''''t become re-entrant (i.e. what you do in the [Event], doesn''''t trigger itself again or any other [Event] that would call the "highlighting code"). From a quick look at the helpfile, I decided that [OnChange] seemed a likely candidate. According to the Delphi 3.0 Helpfile:
 

Write an OnChange event handler to take specific action whenever the text for the edit control may have changed. Use the Modified property to see if a change actually occurred. The Text property of the edit control will already be updated to reflect any changes. This event provides the first opportunity to respond to modifications that the user types into the edit control.

You may be thinking however: "Heh? What about those other things - like Methods and Properties. Can''''t they also change the text?" They sure can - but most end up triggering [OnChange] anyhow.

3. Is it what I want? - Rich text controls (from Delphi3 Helpfile)
 

The ri

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