请看实例:超链接文字标签控件 for Delphi 之完全开发手册
众所周知,从网上下载的共享软件或是免费软件中,其版权信息中多数都有一个超链接标签,或指向作者的主页地址,或指向作者的Email地址。当我们在编制自己的软件时,也常常在软件的About对话框中,用文本标签实现这个功能。但每次都这样设置文本标签的一些属性,添加一些事件处理程序,未免有些麻烦。(当然,将设计好的对话框存成模板,也可以避免这种重复劳动,但限制了使用的灵活性!)利用Delphi自定义控件的强大功能,我们可以自己创建一个超链接标签控件,从而彻底地解决这个问题。下面笔者就此问题,介绍如何编制一个简单的超链接控件,如有不妥之处,敬请指教。
在编制控件之前,我们应当了解开发一个标准Delphi控件的一般过程。一个标准的Delphi控件或者是从某个已存在的类通过继承而来,或者是直接创建一个新类,但一般多是继承一个已有的类,再添加一些属性方法(事件),或对已有的属性方法(事件)进行修改,达到自己的特定要求。因而,我们在开发控件之前,选择一个合适的、已经存在的类作为控件的祖先,对我们后续的工作有百利而无一害。第二步就是创建一个控件的源代码框架。这一步我们可以手工创建,也可以通过Delphi自动创建。第三步是最关键的一步----写源代码并调试。(废话!)最后,我们需要将编制好的控件向Delphi注册,添加到Delphi的Component Palette中,以便将来可以反复使用。
现在我们就按照上面的步骤来具体介绍TNetLabel(今天要介绍的“主角”啦!)的开发过程。
1、分析我们的要求如下:TNetLabel应该有超链接的外观,即字体的颜色为蓝色,有下划线,鼠标光标移动到其上时,应变成手形。并且当用户单击超链接标签时,应调用相应的应用程序,如浏览器、Email软件等。其实这些功能都可以在Delphi中的TLabel控件的基础上来完成,因而我们就选取TLabel作为TNetLabel的祖先。
2、利用Delphi自动建立新控件TNetLabel的源代码框架。启动Delphi,选取主菜单中的File/New...,则弹出如图1所示的对话框,选择Component并单击OK按钮。此时出现如图2所示的对话框,在其中的Ancestor Type(祖先类型)下拉列表框中选取TLabel,表示新控件TNetLabel以TLabel为祖先。在Class Name(类名)中填入TNetLabel,在Palette Page(控件面板页面)列表框中选择Samples,表示将TNetLabel控件注册后,放到Samples页中。或者,我们可以输入一个新的页面名称,如Dotsoft,注册之后,会在控件面板中出现一个名为Dotsoft的新页面。完成这几步之后,点击OK按钮,Delphi就会自动为你生成一个名为NetLabel的单元,将它存储为NetLabel.pas源程序文件。这个文件就是控件TNetLabel的源代码框架。
3、编写TNetLabel源代码。(这一步是关键吆!)在这一步中,我们就是要实现TNetLabel的一些特殊属性和方法。
首先我们增加两个新属性HyperLink和HyperLinkKind。其中HyperLink声明为string类型,用来设置超链接的锚点,如:www.microsoft.com,abcd@hotmail.com等。之所以添加该属性,而不直接使用祖先TLabel的Caption属性,是为了使Caption属性可以使用与锚点不同文字,达到外观是“微软公司网站”,而超链接是指向“www.mircosoft.com”的效果。HyperLinkKind属性用来指明超链接的类型,如“http://”、“mailto:”、“Telnet:”等等,这样就扩大了本控件的适用范围,而不仅仅局限于访问WWW网站和发送电子邮件。为此, 我们先定义一个枚举类型:
type
THyperLink = (hlHTTP, hlMail, hlTelnet, hlGopher, hlNews, hlFTP);
并将HyperLinkKind声明为THyperLink类型。添加私有变量FHyperLinkKind和FHyperLink到TNetLabel类声明的private段中,作为属性HyperLinkKind和HyperLink的数据域,代码如下:
FHyperLinkKind: THyperLink;
FHyperLink: string;
声明可读写属性HyperLinkKind和HyperLink,添加以下代码到TNetLabel的类声明的published段中:
property HyperLinkKind: THyperLink read FHyperLinkKind write FHyperLinkKind default hlMail;
property HyperLink: string read FHyperLink write FHyperLink;
这样我们就在TNetLabel中定义了两个新属性,实现了超链接锚点的设置和存储功能。
然后, 我们需要再添加两个新属性HLinkColor和VLinkColor,均声明为TColor类型,用来实现超链接文字标签的外观颜色。其中属性HLinkColor用来设置当鼠标指针移动到超链接上时文字标签的颜色,VLinkColor用来设置超链接被访问之后文字标签的颜色。原来的祖先TLabel.Font的Color属性仍然可以使用,可以用它来设置超链接未被访问时的文字颜色。新属性HLinkColor和VLinkColor的数据域分别定义如下:
FHLinkColor: TColor;
FVLinkColor: TColor;
属性声明如下:
property HLinkColor: TColor read FHLinkColor write FHLinkColor default clBlue;
property VLinkColor: TColor read FVLinkColor write FVLinkColor default clNavy;
至此,TNetLabel又多了两个用于超链接颜色设置的新属性。但仅仅只有这两个属性还不行,我们还需要用代码进行进一步的处理。众所周知,在浏览器中,当鼠标指针移动到超链接上时,往往超链接的文字下面会出现下划线的CSS特效。为了实现这个CSS特效功能,我们就必须为TNetLabel控件添加对鼠标指针进入和移出事件的事件处理程序。事实上,这个功能可以通过对Windows消息CM_MOUSEENTER和CM_MOUSELEAVE的响应来实现。添加如下过程声明到TNetLabel类声明的private段中,作为对以上两个鼠标消息的消息处理函数:
procedure CMMouseEnter(var AMsg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var AMsg: TMessage); message CM_MOUSELEAVE;
并在单元文件的implementation节实现这两个消息处理函数,请参见后面给出的源代码和注释。
最后,我们需要重载祖先类TLabel的Create构造方法和Click方法。在新的Create方法中,我们要设置一些属性的缺省值,如cursor属性设置为手形指针(crHandPoint)。在新的Click方法中,我们则要针对不同的超链接类型,调用不同的外部应用程序,响应用户的点击操作,详细代码参见所附的完整源代码。
4、保存编辑好的源代码,选取主菜单中的Component/Install Component...,弹出如图3所示的对话框,点击Browse...按钮,在文件打开对话框中选择刚刚保存的NetLabel.pas文件(缺省时保存在Delphi系统目录下的Lib子目录中),一路OK之后,TNetLabel控件就会出现在新增的Dotsoft页面中。唯一的一点点遗憾就是它的小图标和TLabel的完全一样。别着急,只要用Delphi自带的Image Editor创建一个名为NetLabel.dcr的资源文件,并新建一个24*24点阵的位图图标,命名为TNetLabel,存到NetLabel.pas所在目录,Delphi就会自动识别并安装它。注册安装好之后的TNetLabel标签控件如图4所示。(怎么样?哈!哈!哈!......)
以下是TNetLabel源代码:
unit NetLabel;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ShellAPI;
// 由于程序后面要用到Windows API函数调用,此处应加入对ShellAPI单元的引用
type
THyperLink = (hlHTTP, hlMail, hlTelnet, hlGopher, hlNews, hlFTP);
// 定义一个新的类型:THyperLink 为枚举类型
type
TNetLabel = class(TLabel)
private
FHyperLinkKind: THyperLink;
FHyperLink: string;
FHLinkColor: TColor;
FVLinkColor: TColor;
// 定义私有类型的变量,分别作为属性HyperLinkKind、HyperLink、HLinkColor和VLinkColor的数据域
FColor: TColor; //私有变量FColor用作存放颜色值的临时变量
procedure CMMouseEnter(var AMsg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var AMsg: TMessage); message CM_MOUSELEAVE;
// 定义Windows消息处理函数,分别处理鼠标消息CM_MOUSEENTER和CM_MOUSELEAVE
{ Private declarations }
protected
{ Protected declarations }
public
constructor Create(AOwner: TComponent); Override;
// 重载TLabel的构造方法,在新声明Create方法中对TNetLabel控件的属性进行初始化
procedure Click; override;
// 重载TLabel祖先TCustomLabel中的Click方法,在新声明的Click方法中实现超链接调用
{ Public declarations }
published
property HyperLinkKind: THyperLink read FHyperLinkKind write FHyperLinkKind default hlMail;
// 声明属性HyperLinkKind,采用直接读写私有数据域FHyperLinkKind的值,并用关键词default定义缺省值为hlMail
property HyperLink: string read FHyperLink write FHyperLink;
// 声明属性HyperLink,采用直接读写私有数据域FHyperLink的值
property HLinkColor: TColor read FHLinkColor write FHLinkColor default clBlue;
// 声明属性HLinkColor,采用直接读写私有数据域FHLinkColor的值,并定义缺省值为clBlue
property VLinkColor: TColor read FVLinkColor write FVLinkColor default clNavy;
// 声明属性VLinkColor,采用直接读写私有数据域FVLinkColor的值,并定义缺省值为clNavy
{ Published declarations }
end;
procedure Register; // 此过程由Delphi生成源代码框架时自动生成
implementation
procedure TNetLabel.CMMouseEnter(var AMsg: TMessage);
begin
FColor := Font.Color; // 存储初始颜色值到临时变量FColor中
Font.color := FHLinkColor; // 设置文字标签颜色为属性HLinkColor中的颜色
Font.style := Font.style + [fsUnderLine]; // 添加文字标签的字体修饰属性为有下划线
end;
procedure TNetLabel.CMMouseLeave(var AMsg: TMessage);
begin
Font.color := FColor; // 恢复初始文字标签的颜色
Font.style := Font.style - [fsUnderLine]; // 恢复初始文字标签的字体属性
end;
constructor TNetLabel.Create(AOwner: TComponent);
begin
inherited Create(AOwner); // 继承调用TLabel的Create方法
FHyperLinkKind := hlMail; // 初始化私有变量
FHyperLink := 'zhangzhen@263.net';
FHLinkColor := clBlue;
FVLinkColor := clNavy;
with self do
begin
cursor := crHandPoint; // 初始化TNetLabel的鼠标指针为手形
caption := FHyperLink;
// 默认时TNetLabel的Caption属性与HyperLink属性内容相同,但在使用该控件时可以设置为不同的字符串。比如:Caption置为“给我写信”,而在HyperLink属性中将超链接设置为邮箱地址,如zhangzhen@263.net
Font.Color := clMaroon; // 初始化TNetLabel的字体颜色为clMaroon
FColor := Font.color; // 存储初始颜色值到临时变量FColor中
end;
end;
procedure TNetLabel.Click;
begin
inherited Click; // 继承调用TLabel的Click方法
if FHyperLink <> '' then
begin
case FHyperLinkKind of
hlHTTP : ShellExecute(parent.handle,nil,pchar('http://' + FHyperLink),nil,nil,sw_shownormal);
hlMail : ShellExecute(parent.handle,nil,pchar('mailto:' + FHyperLink),nil,nil,sw_shownormal);
hlFTP : ShellExecute(parent.handle,nil,pchar('ftp://' + FHyperLink),nil,nil,sw_shownormal);
hlNews : ShellExecute(parent.handle,nil,pchar('news:' + FHyperLink),nil,nil,sw_shownormal);
hlGopher : ShellExecute(parent.handle,nil,pchar('gopher://' + FHyperLink),nil,nil,sw_shownormal);
hlTelnet : ShellExecute(parent.handle,nil,pchar('telnet:' + FHyperLink),nil,nil,sw_shownormal);
// 调用Windows API函数 ShellExecute,实现超链接调用
end;
FColor := FVLinkColor;
// 将VLinkColor属性中访问后超链接文字标签的颜色保存在变量FColor中,以便在CMMouseLeave消息处理程序中重新设置文字标签的颜色
end;
end;
procedure Register;
begin
RegisterComponents('Dotsoft', [TNetLabel]);
// 由Delphi自动生成,RegisterComponents的第一个参数指出控件所在页面,第二个参数指出控件的名称
end;
end.
至此,一个简单的TNetLabel控件就开发完成了,但如果要成为一个真正意义上的完整控件,还需要增加错误处理机制、联机帮助等等功能,有兴趣的读者可以自己再加以完善。好了,新建一个工程,添加一个TNetLabel控件试试吧!
此控件的源代码在Delphi 4.0中编译安装成功,如有问题,欢迎来信与我交流!
Email:zhangzhen@263.net