来源:远方网络 | 2005-12-31 9:37:12 | (有2001人读过)
1 此份文件的目的为何?
这份文件的目的是为了解答有关撰写 Delphi组件时常见或文件上找不到的问题。我曾经花了一段很长的时间来了解探索 TDataLink 类别,这让我觉得应该将撰写组件时常遇到的问题及经验心得写下来,分享给大家。不过我并不能保证写在这份文件里头的解答完全正确。如果你对其中的任何问题有更好的解决方法,或认为有什么信息适合放在这份文件里的话,请告知作者。有任何错误或缺漏也欢迎指正。
除了再加上更多的问题及解答外,我试着再补充两个部分:进阶程序设计师喜爱的工具:这也许跟组件设计没有直接的关系但至少它们跟 Delphi有关系。
2 在整合环境中如何找出组件所产生的问题?
唯一能找出问题的方法只有:
在 Delphi 整合环境的 Tools|Options 对话框的 Library 页中将『Compile with debug info』选项打勾。
选 Component|Rebuild Library 重新编译组件库。
从 Turbo Debugger 中执行 Delphi。
选File|Change Dir移至包含组件程序代码的目录下。
如果你的组件发生GPF时就可以检视堆栈然后得知到底是哪些发生问题了。
2 如何检视 Delphi 所产生的汇编语言码?
的回答:
开启登录编辑程序(REGEDIT.EXE),接着到『HKEY_CURRENT_USER\Software\Borland\Delphi\2.0\Debugging』下新增一个字符串机码『EnableCPU』,将它的字符串值设为『1』。此后Delphi整合环境的View选单下就会多一个『CPU』选项,它会开启一个窗口来检视目前程序指令的内存及汇编语言。你可以在侦错时利用单步追踪或其它方法来观察它。
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;
4 如何撰写一个无法放置到表格上的组件?
如果你不想让使用者将组件拉曳至表格上的话,使用 RegisterNoIcon 及 RegisterClass 程序来注册组件。
2.5 在程序代码编辑器中快速切换程序区段最简单的方法是什么?
在探索 VCL 原始程序代码时,强烈建议你最好熟悉程序代码编辑器里的书签功能。使用方法很简单:Ctrl-Shift-N,N 是从 0 至 9 的数字,用来设定一个书签。此后就可以使用 Ctrl-N 来跳跃至书签处。(译注:使用这项功能真的可以节省你许多来回卷动程序及找寻函式的时间,别迟疑了,快学吧!)
6 如何使我的组件在按下鼠标右键时出现快速功能选单?
你必须要建立一个组件编辑器。组件编辑器决定了组件在设计时期时对鼠标键的反应及动作,你可以为组件定义它自己的快速功能选单。
建立组件编辑器的步骤大致如下:
从 TComponentEditor 类别继承一个新的类别。
改写类别的 GetVerbCount、GetVerb及 ExecuteVerb方法。
在 Register 程序中使用 RegisterComponentEditor 程序来注册此组件编辑器。
有关组件编辑器这个主题在『Developing Delphi Components』这本书中有详尽的解说及信息。
7 为什么组件在设计时期会出现『I/O 103』的错误?
你可能在组件中使用了Writeln这个程序。
8 为什么组件编辑器不会将组件属性的变动储存起来?
我发现有时自制的组件编辑器不会将组件属性储存起来。设计时期一切正常,但是储存起来再重新读入后就有问题了。原因是你很可能忘了在组件编辑器中呼叫此方法:
Designer.Modified;
如此一来Delphi才会知道你的组件编辑器更改过属性值了。
9 如何在组件中加入滚动条组件并让它在设计时期能动作?
你的滚动条组件类别必须处理 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);
10 如何建立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;
|