{
 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
 相关贴子:
 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1080798
 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
}
1.VCL组件开发的几个主要基类TComponent、TControl、TWinControl、TGraphicControl、TCustomControl的主要功能及各类的用途?
2.ComponentState属性的用途
3.如果有一个属性为指向另一个类的实例(如TDataSource的Dataset属性), 要注意的事项
4.property宣告的具体心得及注意事项、Keyword Default及Stored的意义
5.TControl与TWinControl的差异
6.TWinControl中如何封装Windows窗体(或者说, Windows的消息通知(message call), 经过了什么过程, 成为Delphi的Method Call) ? Windows的消息处理机制?
或者另一个问法, 在一个Control中, 要处理消息(message), 除了定义消息函数 (procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;) 外, 尚有那些方式?
7.设计覆合式控件的注意事项
8.对Windows基本窗体(Eidt, Button, ListBox....)的了解及说明?
9.组件源码的分析
10.组件作品的交流

解决方案 »

  1.   

    1.VCL组件开发的几个主要基类TComponent、TControl、TWinControl、TGraphicControl、TCustomControl的主要功能及各类用途?
    TComponent:因封装了设计期的一些信息而使得可以在设计时使用,当然要在设计时使用还必须注册到Delphi的IDE控件面板,所以TComponent是所有可以放在控件面板上的类的基类。
    实现了IInterface, IInterfaceComponentReference接口。
    TControl:顾名思义,这才是真正的Delphi的"控件"。我们常说的Delphi控件应该就是从它来继承,它是所有可视类的基类,可以在运行时看见。它封装了几封了所有的鼠标消息和部份界面的消息、外壳消息。
    另外最重要的是它填充装了所有的消息分发。
    TWinControl:当然它就是窗口控件,对应着VC里的窗口类(我不太懂VC),也是在Windows中的具有唯一标识Handle的类,所有容器类和可获得焦点的类都是从它上面继承。
    作为窗口控件,它当然封装了所有的窗口消息,比如键盘消息。
    TGraphicControl:从TControl上继承下来,没有窗口句柄,但是增加了画布Canvas,通过Canvas封装了主要的图形绘制API函数。
    TCustomControl:类似于TGraphicControl,不过它是从TWinControl继承下来的,有了窗口句柄.
    它和TGraphicControl一样,只处理了WM_PAINT消息。
    2.ComponentState属性的用途
    用于判断TComponent继承下来的类的状态,比如是否是设计期或者装载期等等。
    3.如果有一个属性为指向另一个类的实例(如TDataSource的Dataset属性), 要注意的事项
    我想最重要应该是在写接品方法中调用另一个类实例的FreeNotification方法,经以便在另一个类实例析构的时候清空本类实例的相关属性(将相关成员字段设为nil)。
    4.property宣告的具体心得及注意事项、Keyword Default及Stored的意义
    这方面的东东其实主要看个人喜好,我的感觉在宣告一个属性时应尽可能避免这个属性可以不能过写接口而改写,那样可能为这个属性改变量所作的努力将不起作用,
    比如动态数组类型的属性:最好不要声时动态数组类型的属性,因为在Delphi中动态数组类型的数组其实和指针差不多,它可以直接操作这个属性而不会调用写接口,除非你用赋值符号为动态数组赋值(这在Delphi中应尽量避免使用),
    如果确实有动态数组类型的属性,可以通过定义属性下标来将其转换成简单类型或复合类型的属性
    而一些类属性,一般在写接口中需要使用Assign方法来赋值,比如大多数可视控件的Font属性,或部份控件的TPicture类型属性,而且这样的属性因为本身有Assign方法,可能不会使用赋值运算为其赋值(在Delphi中应尽量避免使用赋值运算对类实例赋值,
    除非真的是要两个实例变量指向同一个实例),所有一般不仅需要处理写接品,还需要给这个属性所对应的成员字段定义OnChange事件。
    至于Default指示,不用看楼上也具定说得很多,关键是要注意,它并不对属性对应的私有成员初始化,如果需要初始化,则需要在构造函数中进行。
    它仅仅用来指示属性是否需要被流化以保存在dfm文件中,编译以资源的形式进入EXE,可以有效的减小EXE文件的容量,并提示程序加载速度。
    Stored指示的作用与Default指示字相仿,不过Default只是指定一个值,如果属性值在设计期间与这个值相同,就不流化,而且Default只支持有限的几种简单定长类型数据。
    而Stored而可以通过一个Boolean函数来检查设计期间的属性值是否需要流化,这个函数可以非常复杂。5.TControl与TWinControl的差异
    TControl的和TWinControl其实在上面已经比较清楚了,主要就是一一个是父类,一个是子类,TWinControl比TControl增加了Handle和相关的方法和属性,以用相应的消息处理函数,
    最主要的是,除是多了句柄之外,因为可以获得焦点,所以多了键盘相关的消息和方法。6.TWinControl中如何封装Windows窗体(或者说, Windows的消息通知(message call), 经过了什么过程, 成为Delphi的Method Call) ? Windows的消息处理机制?
    或者另一个问法, 在一个Control中, 要处理消息(message), 除了定义消息函数 (procedure WMSetFocus(var Message: TWMSetFocus); message WM_SETFOCUS;) 外, 尚有那些方式?
    这个可复杂了点,首先,TControl有于个属性WindowProc,其实它是一个事件,只不过Delphi中的所有类都没有把它放到published域,所以我们从没有在设计期间看到这个属性,
    但是它的确存在,而且作用非常大,在TControl中的构造函数中,在重用了父类的构造代码后的第一行就是给这个事件赋了值,这个值是成员方法WndProc,这是一个动态方法,
    可以重载,它完成了几乎所有鼠标消息和界面消息的分发.我们如果需要自己来处理这些分发,一种方法可以重载这个方法,另一种是自己定WindowProc事件句柄。
    不过我便能愿意重载一些。其实到这里就可以明白,除了重载消息处理函数外,我们也可以载重WndProc方法来处理消息和重写WindowProc事件来处理消息。共至少有三种方法。其他程序向Delphi编译的程序的窗口发的消息Delphi是如何能接收到的?请看CreateWnd方法中有一句WindowClass.lpfnWndProc := @InitWndProc;就是句告诉Windows这个窗口的消息由InitWndProc这个回调函数来处理,
    而在InitWndProc这个函数中的一段汇编把它和TWinControl.FObjectInstance联系起来,再转到TWinControl.Create(AOwner: TComponent)中,第二行的FObjectInstance := Classes.MakeObjectInstance(MainWndProc);
    才真正引出主角MainWndProc,它个函数很简单,就是触发WindowProc事件,把接收到的消息传给这个事件,再由个这事件来分发。好了说了一大通,但是太乱,可能不会有太多人能明白。
    好在我们一般情况下不需要关心这些,只需要知道处理消息的三种方法就行了。7.设计覆合式控件的注意事项
    说得简单点,就是注意谁是容器,谁是子对象就行了,在构告的时候把子对象的Parent属性和Owner设为容器,设计时就不会出现两个或者多个可操作纵的对象(而是只有一个唯一的对象可供用户操作)。
      

  2.   

    7.设计覆合式控件的注意事项
    此中有一个小诀窍。如果希望你容器中创建的子控件仍然能够被选中和编辑。则应该使得子控件的Owner为Form。
      

  3.   

    我有一本书,叫DELPHI部件开发指南,那真叫好!西南交大出版社出的。
      

  4.   

    第一部分 简介
    1.1 此份文档的目的为何?第二部份 整合环境2.1 在整合环境中如何找出构件所产生的问题?
    2.2 如何检视Delphi所产生的汇编码?
    2.3 我可以在运行时刻动态建立构件,但在设计时刻就会发生错误。为什麽?
    2.4 如何撰写一个无法放置到表格上的构件?
    2.5 在程序码编辑器中快速切换程序区段最简单的方法是什麽?
    2.6 如何使我的构件在按下鼠标右键时出现快速功能选单?
    2.7 为什麽构件在设计时刻会出现『I/O 103』的错误?
    2.8 为什麽构件编辑器不会将构件属性的变动储存起来?第三部分 在构件中使用其它构件3.1 如何在构件中加入卷轴构件并让它在设计时刻能动作?
    3.2 如何建立Windows95式样的卷轴?第四部分 Bound Controls4.1 哪里可以找得到有关TDataLink类的说明文档?
    4.2 如何得知一个dataset中有几笔记录?第五部分 VCL5.1 使用整合环境调试时如何追踪检视VCL构件的程序码?
    5.2 我的构件叁考到其它构件,如何得到叁考构件被消灭的讯息?
    5.3 什麽是构件讯息?
    5.4 我的构件得到输入焦点後仍不能接受键盘讯息,为什麽?第六部分 其它信息6.1 有哪些书介绍或讲解如何撰写构件?
    6.2 有哪些Web站台可以取得撰写构件的信息?第七部分 构件的储存与载入7.1 如何将包含其它对象的对象一起存入DFM档?
    7.2 如何得知构件是否正从数据流中读出?
    7.3 如何确定构件的属性是否被正确地储存?第八部分 工具程序8.1 有没有Delphi版本的 YACC 及 LEX?
    8.2 如何秀出JPEG格式图形档?第九部分 基本编程技巧9.1 如何建立不定数目的对象数组?
    9.2 Delphi 2.0的 WinCrt 单元到哪去了?
    9.3 自制构件时该从哪个类继承?第十部分 进阶编程技巧10.1 Delphi有与 C++ 一样的 I/O Stream 类吗?
    10.2 如何取得列举型态变量的文字表示?第十一部分 构件虚拟方法11.1 如何得知构件的 window handle 是何时建立的?
    11.2 如何得知是否表格上所有构件都已载入完成?
    11.3 在哪里绘制构件最适合?
    11.4 如何改变构件的窗口式样?第十二部分 Windows API12.1 构件卷动时闪动的很厉害,如何克服这种情况?
    12.2 如何重新启动Windows?
    12.3 如何快速大量地更改构件数据?第十三部分 控制项边框13.1 为什麽我的构件的 Ctl3D 属性设为 True 之後,它依然没有 3D 的边框呢?
    13.2 如何实作 BorderStyle 属性?第十四部分 控制项式样14.1 当构件重绘时如何防止闪动的情况?第十五部分 窗口消息15.1 为什麽我的构件得不到方向键的讯息?
    15.2 有没有与 Visual Basic『DoEvents』同样功能的函式?
    --------------------------------------------------------------------------------第一部分 简介1.1 此份文档的目的为何?这份文档的目的是为了解答有关撰写 Delphi构件时常见或文档上找不到的问题。我曾经花了一段很长的时间来了解探索 TDataLink 类,这让我觉得应该将撰写构件时常遇到的问题及经验心得写下来,分享给大家。不过我并不能保证写在这份文档里头的解答完全正确。如果你对其中的任何问题有更好的解决方法,或认为有什麽信息适合放在这份文档里的话,请告知作者。有任何错误或缺漏也欢迎指正。
    除了再加上更多的问题及解答外,我试着再补充两个部分:
    进阶编程师喜爱的工具:这也许跟构件设计没有直接的关系但至少它们跟 Delphi有关系。
    值得叁考的文档刊物:由於空间的关系,这份文档不能放置太多的范例程序,因此叁考其它文档是十分需要的。这不是一份教材式的文档,我不会做太多条理式的说明,但会试着将最具有叁考价值的文献列出。
    --------------------------------------------------------------------------------第二部份 整合环境2.1 在整合环境中如何找出构件所产生的问题?
    我发现唯一能找出问题的方法只有:
    在 Delphi 整合环境的 Tools|Options 对话框的 Library 页中将『Compile with debug info』选项打勾。
    选 Component|Rebuild Library 重新编译构件库。
    从 Turbo Debugger 中执行 Delphi。
    选File|Change Dir移至包含构件程序码的目录下。
    如果你的构件发生GPF时就可以检视堆栈然後得知到底是哪些发生问题了。
    2.2 如何检视 Delphi 所产生的汇编码?
    Glen Boyd 的回答:
    开启登录编辑程序(REGEDIT.EXE),接着到『HKEY_CURRENT_USER2.0』下新增一个字符串机码『EnableCPU』,将它的字符串值设为『1』。此後Delphi整合环境的View选单下就会多一个『CPU』选项,它会开启一个窗口来检视目前程序指令的内存及汇编。你可以在侦错时利用单步追踪或其它方法来观察它。
    2.3 我可以在运行时刻动态建立构件,但在设计时刻就会发生错误。为什麽?
    你的构件必须继承自TComponent类或其衍生类。
    你的构件建构函式及灭构函式宣告必须看起来像这样:
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override ;
    所有在published区段宣告的字段型态必须是ordinal、single、double、extended 、comp、currency、string、small set(译注:指元素编号不超过0..31这个范围的集合;平常的集合可容许的范围为0..255)、method pointer或class其中一种。如果你宣告了其它型态的字段,Delphi编译器并不会检查出错误。然而当你使用这个构件时依然会得到一个GPF。如果你想让TMyComponent构件可以在设计时刻操作,注意下面的宣告会引发十分严重的问题:
    type TComplex = record
    RealPart: Double;
    ComplexPart: Double;
    end;
    class TMyComponent = Class(TComponent)
    private
    F1: TComplex;
    published
    property P1: TComplex read F1 write F1;
    end;2.4 如何撰写一个无法放置到表格上的构件?
    Ray Lischner 的回答:
    如果你不想让使用者将构件拉曳至表格上的话,使用 RegisterNoIcon 及 RegisterClass 过程来注册构件。
    2.5 在程序码编辑器中快速切换程序区段最简单的方法是什麽?
    Ray Konopka 的回答:
    在探索 VCL 源码时,强烈建议你最好熟悉程序码编辑器里的书签功能。使用方法很简单:Ctrl-Shift-N,N 是从 0 至 9 的数字,用来配置一个书签。此後就可以使用 Ctrl-N 来跳跃至书签处。(译注:使用这项功能真的可以节省你许多来回卷动程序及找寻函式的时间,别迟疑了,快学吧!)
    2.6 如何使我的构件在按下鼠标右键时出现快速功能选单?
    你必须要建立一个构件编辑器。构件编辑器决定了构件在设计时刻时对鼠标键的反应及动作,你可以为构件定义它自己的快速功能选单。
    建立构件编辑器的步骤大致如下:
    从 TComponentEditor 类继承一个新的类。
    改写类的 GetVerbCount、GetVerb及 ExecuteVerb方法。
    在 Register 过程中使用 RegisterComponentEditor 过程来注册此构件编辑器。
    有关构件编辑器这个主题在『Developing Delphi Components』这本书中有详尽的解说及信息。
    2.7 为什麽构件在设计时刻会出现『I/O 103』的错误?
    你可能在构件中使用了Writeln这个过程。
    2.8 为什麽构件编辑器不会将构件属性的变动储存起来?
    我发现有时自制的构件编辑器不会将构件属性储存起来。设计时刻一切正常,但是储存起来再重新读入後就有问题了。
    原因是你很可能忘了在构件编辑器中调用此方法:
    Designer.Modified;
    如此一来Delphi才会知道你的构件编辑器更改过属性值了。
    --------------------------------------------------------------------------------第三部分在构件中使用其它构件3.1 如何在构件中加入卷轴构件并让它在设计时刻能动作?
    你的卷轴构件类必须处理 CM_DESIGNHITTEST 构件讯息才行。
    TMyScrollBar = class (TScrollBar)
    procedure CMDesignHitTest
    (var Message: TCMDesignHitTest); message CM_DESIGNHITTEST;
    end;procedure TMyScrollBar.CMDesignHitTest( var Message: TCMDesignHitTest);
    begin
    Message.Result := 1;
    end;
    你的构件必须以以下方法建立卷轴:
    TMyScrollBar.Create(nil);
    而不是
    TMyScrollBar.Create(Self);3.2 如何建立Windows95式样的卷轴?
    你必须配置卷轴的页面大小。你可以用以下的程序码来做:
    procedure SetPageSize(ScrollBar: TScrollBar; PageSize: Integer);
    var
    ScrollInfo: TScrollInfo;
    begin
    ScrollInfo.cbSize := Sizeof (ScrollInfo);
    ScrollInfo.fMask := SIF_PAGE;
    ScrollInfo.nPage := PageSize;
    SetScrollInfo (ScrollBar.Handle, SB_CTL, ScrollInfo, True);
    end;
    要取得目前页面大小可用如下方法:
    function GetpageSize (ScrollBar: TScrollBar): Integer;
    var
    ScrollInfo: TScrollInfo;
    begin
    if HandleAllocated then
    begin
    ScrollInfo.cbSize := SizeOf (ScrollInfo);
    ScrollInfo.fMask := SIF_PAGE;
    GetScrollInfo (ScrollBar.Handle, SB_CTL, ScrollInfo);
    Result := ScrollInfo.nPage;
    end;
    end;
    --------------------------------------------------------------------------------第四部分 Bound Controls4.1 哪里可以找得到有关 TDataLink 类的说明文档?
    我可以大胆地说全世界有关 TDataLink 的说明文档只有一份,就在这儿:
    属性 (Property) 介绍
    property Active: Boolean(唯读)
    当此 DataLink 连结至一个已开启的 DataSource 时会传回 True。当 Active 状态改变时会
      

  5.   

    触发ActiveChanged方法。
    property ActiveRecord: Integer(可读写)
    用来配置或取得 DataLink 缓冲区中目前所指向的记录代码,代码的范围是 0 .. BufferCount - 1。使用它来配置记录代码时必须小心不要超过这个范围,否则可能导致不可预期的错误。
    property BufferCount: Integer(可读写)
    DataLink 拥有一个数据缓冲区。而 BufferCount 属性即用来配置或取得缓冲区大小,缓冲区大小决定了一个dataset同时可以显视的数据记录笔数。对大部分的数据感知元件来说,BufferCount 的值是 1;但对 TDataGrid 来说,BufferCount 代表它的可视列数目。
    property DataSet: TDataSet(唯读)
    传回此 DataLink 所连结的 DataSet。其实就是 DataSource.DataSet。
    property DataSource: TDataSource(可读写)
    传回此DataLink所连结的DataSource。
    property DataSourceFixed: Boolean(可读写)
    这个属性可用来防止 DataSource 属性被更改。如果此属性设为 True,当我们试着改变 DataSource 属性时会引发一个例外。
    property Editing: Boolean(唯读)
    如果 DataLink 正处於编辑状态则传回 True。
    property ReadOnly: Boolean(可读写)
    配置 DataLink 是否为唯读状态。这个属性并不会影响所连结的 DataSet。在唯读状态下这个 DataLink 无法进入编辑状态。
    property RecordCount: Integer(唯读)
    传回DataSet的数据记录数目。
    方法 (Method) 介绍
    function Edit: Boolean;
    让所连结的DataSet进入编辑状态。传回值: 成功传回 True ,失败传回 False
    procedure UpdateRecord;
    我们不直接调用这个方法,它是提供其它程序来调用的。这个方法只有配置一个旗帜然後调用UpdateData 方法。
    虚拟方法 ( Virtual Method )
    要让 TDataLink 对象与构件沟通必须改写下列这些方法:
    procedure ActiveChanged
    当连结的 DataSource 开启状态改变时会调用此方法。使用 Active 属性可以得知目前是否为开启状态。
    procedure CheckBrowseMode
    数据库有任何改变之後都会先调用这个方法。
    procedure DataSetChanged;
    当下列任一事件发生时都会调用此方法:
    移至DataSet的开头
    移至DataSet的结尾
    在DataSet中插入或新增数据
    删除DataSet的数据
    取消DataSet的编辑
    更新记录
    如果不想改写这个方法只要在其中调用:
    RecordChanged(nil);
    procedure DataSetScrolled(Distance: Integer)
    每当目前记录变更时会调用此方法。Distance 叁数代表缓冲区欲卷动的行数。(其值范围皆在 -1 .. 1 之间)。使用 ActiveRecord 属性可以取得缓冲区中目前所指向的记录。我们无法强制让 DataLink 的缓冲区卷动。
    procedure FocusControl(Field: TFieldRef)
    与TField.FocusControl方法相同。
    procedure EditingChanged
    当 DataLink 的编辑状态改变时会调用此方法。使用 Editing 属性可以得知DataLink 是否 正处於编辑状态。
    procedure LayoutChanged
    当 DataSet 的 Layout 改变时会调用此方法(例如新增一个column)。
    procedure RecordChanged(Field: TField)
    当下列任一事件发生时都会调用此方法:
    目前记录进入编辑状态
    目前记录内容更动
    procedure UpdateData
    在一笔记录被更新以前会调用此方法。你可以调用 Abort 过程来防止数据库更新。
    4.2 如何得知一个 dataset 中有几笔记录?
    TDateSet 的 RecNo 属性可以传回数据记录的数目,但很不幸地它只适用於 dBase 及 Paradox 的数据表格。若想得知目前数据记录的编号,可以从 TDataLink 类衍生一个新的类,然後进行下 列步骤:
    改写 DataSetScrolled 方法以取得目前记录是否被卷动。
    改写 DataSetChanged 方法来确认目前记录是否跳至最前面或最後面了。
    接着你可以将这个新类的对象连结到TDataSource对象上然後就可以随时得知目前的记录编号了。
    --------------------------------------------------------------------------------
      

  6.   


    第五部分 VCL5.1 使用整合环境调试时如何追踪检视 VCL构件的程序码?
    将你想要追踪的 VCL 原始程序单元拷贝至存放专案的目录中并重新编译构件库,此後你就可以在那些 VCL单元中追踪检视程序码了。
    5.2 我的构件叁考到其它构件,如何得到叁考构件被消灭的讯息?
    Max Nilson 的回答:
    TComponent 类提供了 Notification 方法。当一个构件被移除时我们可以利用这个方法得到消息以进行适当的反应。你可以叁考『Component Writer's Guide』内有关 Notification 及FreeNotification 这两个方法的说明。
    当你的构件叁考到另一个构件,例如,你的构件中有一个 TDataSource 型态的属性。那 你必须改写此构件的 Notification 方法,在其中检查被移除的构件是否就是本身所叁考的构件。预设情况下,当构件被移除时,所有其它在同一个表格上的构件才会收到消息,如果叁考构件位於另一个表格上时,你的构件无法得知这件事情。Delphi 2.0 推出了TDataModule,叁考构件位於另一个表格上的机会大幅增加,所以你应该利用 FreeNotification 方法来确定当叁考构件移除时,你一定可以得到消息。如果你不改写 Notification 方法来处理叁考构件被移除的讯息,这会让 Delphi整合环境陷入十分不稳定的状态。它可能不会立刻当掉,但你也不能再正常地继续其它工作了。
    下面是一个范例,当你的构件叁考其它构件时,千万记得要做以下的处理:
    TMyComponent = class (TComponent)
    private
    FDataSource: TDataSource;
    procedure SetDataSource(Value: TDataSource);
    protected
    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    published
    property DataSource: TDataSource read FDataSource write SetDataSource;
    end;procedure TMyComponent.SetDataSource(Value: TDataSource);
    begin
    if Value <> FDataSource then
    begin
    FDataSource := Value;
    // 告诉叁考构件说,当它被移除时记得通知我一声。
    if FDataSource <> nil then FDataSource.FreeNotification(Self)
    end;
    end;procedure TMyComponent.Notification(AComponent: TComponent; Operation:TOperation);
    begin
    inherited Notification(AComponent, Operation);
    // 如果被移除的正是叁考构件,把FDataSource字段清除。
    if (Operation = opRemove) and (AComponent = FDataSource) then
    FDataSource := nil
    end;5.3 什麽是构件讯息?
    构件讯息是什麽?它十分类似Windows的窗口消息,只有一点不同:构件讯息只适用於 VCL 构件;而窗口消息可以用在系统内所有具有 window handle 的控制项或窗口。如果你有一个具有 Font 属性的构件(例如TLabel构件),当我们更改它的 Font 属性时并没有送出窗口消息(译注:TLabel 构件不是窗口控制项,根本也没有窗口 Handle可以让我们传送窗口消息),但是控制项仍然知道字体改变了所以要重画自己,为什麽?因为我们有构件讯息。
    构件讯息不可以由虚拟方法来处理,这可能是设计 VCL 时的考量,大概是因为不想让虚 拟方法表格(Virtual Method Table)过於庞大的原因。
    『Secrets of Delphi 2.0』这本书对於所有的构件讯息有十分详尽的解说。
    接下来我们列出一些比较常见的构件讯息及它们的作用。标示着『Notification Only』 的讯息表示送出这个讯息只是为了通知构件某件消息而己,并不传入任何叁数而且也不需要传回值。
    CM_ACTIVATE (Notification Only)
    当表格成为焦点窗口时会传给本身这个讯息。
    CM_CTL3DCHANGED (Notification Only)
    当控制项的Ctl3D属性更改时会传给本身这个讯息。
    CM_DESIGNHITTEST 叁数:TCMDesignHitTest 传回值:0或1
    在设计时刻当鼠标移到构件上头时,整合环境会送给此构件这个讯息。此讯息的目的用来决定构件在设计时刻是否要处理鼠标讯息。如果传回值是 1,整合环境就让构件自行处理鼠标讯息;若传回值是 0,则整合环境会帮你处理鼠标讯息。如果传回值永远是 1,那麽构件的快速功能选单则永远不会出现;如果构件不处理这个讯息或永远传回 0,那此构件在设计时刻将无法对鼠标讯息做任何反应。
    CM_FONTCHANGED (Notification Only)
    控制项的字体改变後送给本身此讯息。
    CM_FONTCHANGE (Notification Only)
    当控制项收到WM_FONTCHANGE窗口消息时会送给本身这个讯息。
    CM_PARENTCTL3DCHANGED (Notification Only)
    当构件父控制项的Ctl3D属性改变或配置新的父控制项时会收到此讯息。
    CM_PARENTCOLORCHANGED (Notification Only)
    当构件父控制项的 Color 属性改变或配置新的父控制项时会收到此讯息。
    CM_PARENTFONTCHANGED (Notification Only)
    当构件父控制项的Font属性改变或配置新的父控制项时会收到此讯息。
    CM_PARENTSHOWHINTCHANGED (Notification Only)
    当构件父控制项的ShowHint属性改变或配置新的父控制项时会收到此讯息。
    CM_WININICHANGE 叁数:TWMWinIniChange 传回值:无
    当控制项收到WM_WININICHANGE窗口消息时会送给本身这个讯息。5.4 我的构件得到输入焦点後仍不能接受键盘讯息,为什麽?
    如果你的构件有 DragMode 属性而且将它设成 dmAutomatic 时,很有可能让你的构件以为它正被拖放但实际上并没有的情况。在 Controls 单元中有一个区域变量 DragControl 指 向目前正被拖放的构件。你遇到的情况很可能就是明明没有拖放的动作但是DragControl 变量却指向你的构件。在 TWinControl 的 WndProc 方法中,当 DragControl 变量指向构件本身时,会忽略所有键盘讯息,这就是原因了!
    --------------------------------------------------------------------------------第六部分 其它信息6.1 有哪些书介绍或讲解如何撰写构件?
    有关撰写构件的『标准』叁考书籍:
    『Developing Delphi Components』 作者:Ray Konopka 出版:Coriolis Group下面这本书并不专注於构件写作,但里面提到许多构件撰写者不可不知的信息:『Secrets of Delphi 2』 作者:Ray Lischner 出版:Waite Group
    另外一本构件撰写的好书,它有许多在『Developing Delphi Components』里找不到的信息:『Programming Delphi Custom Components』 作者:Fred Bulback 出版:M&T Books6.2 有哪些Web站台可以取得撰写构件的信息?
    全世界最大的 Delphi Web 站台『Delphi SuperPage』
    (译注:亚洲地区使用者可以就近到位於日本的 Mirror Site )我在下面这些站台中找到许多构件的源码:
    Temple of Delphi
    Delphi Free Stuff
    (译注:『Your Delphi Programming Resource』整理构件也十分用心! )(译注:台湾地区目前维持最好的 Delphi 站台是『32 Bit Delphi 深度历险』及其 Mirror Site)
    你也可以使用一些搜寻引擎来寻找有关 Delphi 的站台:
    Yahoo
    Alta Vista
    (译注:Excite 搜寻引擎也别错过罗!)
    --------------------------------------------------------------------------------第七部分 构件的储存与载入7.1 如何将包含其它对象的对象一起存入 DFM 档?
    我试过许多方法,包括改写构件的 DefineProperties及 WriteComponents方法,但都还是失败了。所以我只能说要解决这个问题的话只有使用 Delphi 原本的方法一途。将包含其它对象的对象一起储存起来的步骤大致如下:
    确定你要储存的所有对象都是从 TComponent 类衍生下来的。
    将所有需要储存的变量宣告在 published 区段。
    在构件的 Register 过程中调用 RegisterComponents过程来注册所有你要储存起来的类。
    每个拥有子控制项的类必须改写 GetChildren 方法以储存每个子控制项。(在 Delphi 1.0 中你必须改写 WriteComponents 方法并且为每个子控制项调用 WriteComponent方法)。将对象载入的方法用了点小技巧。你必须改写构件的 GetChildOwner 及 GetChildParent 方法,否则 Delphi会将所有对象的拥有者都配置为构件所在的表格。(在Delphi 1.0 中你必须改写ReadState方法)。7.2 如何得知构件是否正从数据流中读出?
    当构件正从数据流中读出时,它的 ComponentState 属性会包含csLoading 旗帜。constructor TMyClass.Create(AOwner: TComponent);
    begin
    if csLoading in AOwner.ComponentState then
    begin ... end
    else
    begin ... end;
    end;7.3 如何确定构件的属性是否被正确地储存?
    有许多很简单的方法可以验证属性是否被正确地储存在文件里:
    在整合环境中用鼠标右键点选表格然後选择『View as Text』。然而万一 DFM 档 有任何错误的话,你将什麽也看不到。
    开个 DOS 窗口,利用 Delphi 所附的『Convert』程序将 DFM 档转成文字格式。
    Stefan Hoffmeister 指出复制或剪下构件後,到任何一个文书编辑器(如记事本)中贴上,你就可以看到此构件的文字表示。你甚至可以编辑这些文字表示後再将它贴回 Delphi整合环境的表格上。--------------------------------------------------------------------------------