说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

用Delphi开发分隔线组件

HTML文档下载 WORD文档下载 PDF文档下载
用Delphi开发分隔线组件

【摘要】本文以分隔线为例,采用面向对象方法,介绍了如何用Delphi开发Windows

的可视化控件。可视化控件具有较强的实用价值,用Delphi语言开发控件简便、方

便、

效率高。

关键词:Delphi 控件 面向对象

一、引言

Delphi除了能采用可视化方法进行编程和系统开发外,还有非常重要的一个功能,

就是能用其语言本身开发Delphi的可视化控件(Component)。Delphi是完全面向对

象的语言,其各个控件都是从最基本的类TClass逐步继承而来,因此,编程者也可

通过继承Delphi标准的控件类,开发出自己的控件,以满足某些特殊需要或使界面

更为友好、美观。

在Windows 95的某些窗口中,用到了很多分隔线(如在资源管理器窗口中)。分隔

线将一个窗口分成两个或多个部分。这些部分可能是面板(Panel)、图形、列表框

或编辑区。当鼠标移到分隔线上时,光标会变成左右箭头或上下箭头,将鼠标按住

并按指示的方向左右或上下拖动,就会使其中某部分放大,而另一部分缩小,从而

提高了窗口各部分的可视范围,增加了窗口的信息量。

二、基本原理

分隔线界于窗口中两个控件之间。首先要在当前窗口中找到分隔线控件,并记录它

的状态;然后要在窗口中找到与它相邻的控件,并记录它们的当前状态,然后再通

过分隔线的鼠标事件控制各个控件的移动及尺寸变化,从而达到用分隔线分隔窗口

的动态效果。

三、分隔线控件(TSplit)对象

分隔线控件对象由现有的控件对象继承而来,在此基础上,还必须有它本身的私有

变量(方法)和公有变量(方法)。具体为:

1、 首先定义分隔线控件类:TSplit。由于Delphi的面板控件Tpanel具有可改变其

凸凹、形状大小等属性,所支持的事件方法也较多,因此采用Tpanel作为TSplit的

父类。

2、 定义TSplit的私有变量和方法:与分隔线有关的一些控件,如其所在的窗口、

分隔线本身、分隔线的坐标、分隔线在移动时使其大小改变的控件(主要指分隔线

的左侧或上侧的控件,以下称目标)等,这些定义为私有变量;对分隔线和其周围

控件的检测、画阴影线以及求其状态等过程(子程序),定义为私有方法。其中关

键的变量有FSplitControl,FSizeTarget,它们为分隔线变量和所移动的目标控件

变量,通过调用私有方法GetComponent可将它们赋值,得到分隔线和目标的实例,

从而便于对他们操作。在分隔线移动时,DrawSizegLine方法画出它的阴影线。

3、定义公共方法:公共方法定义了TSplit的构造函数、开始移动分隔线、改变分隔

线 的 位 置、分隔线停止移动时调整目标(被分隔线改变形状的控件)尺寸等过

程,以及分隔线的鼠标事件:按下、移动和弹起。另外,还定义了分隔线是否可移

动的属性(property),以判断分隔线的当前状态。

鼠标事件是分隔线移动和目标改变大小的触发点,对鼠标事件进行重载,使得移动

和变化得以实现。在MouseDown事件中,加入了公共方法BeginSizing,对分隔线对

象初始化;MouseMove事件中加入ChangeSizing方法,改变分隔线位置和画阴影;

MouseUp事件中加入EndSizing,停止分隔线的移动,改变目标大小。

4、分隔线控件实现过程 (见附录:split.pas程序及其说明。)

四、控件的安装方法

在Delphi 1.0的系统菜单Options下(2.0为Components),选择Install Component子

菜单,弹出对话框,按Add按纽,在输入栏键入程序名及其路径,再按OK键,等待编

译完毕,在Delphi的控件列表中的Sample栏中就会出现我们所开发的新控件:

Split。

五、使用方法

1、 建立一个新的项目文件(Project),在新窗口上放置一个面板(或列表框、树

型结构列表、图形框、记忆框等),将其Align属性设为Left;

2、 从控件列表中的Sample栏中选取Split控件放于窗口,将其形状改为垂直的长条

窄棒,并将Align属性设为Left,Cursor属性设为crHSplit;

3、 再在窗口中放一个面板(或其他控件),将其Align属性设为Client;

4、 运行该项目文件,当鼠标移动到分隔线上,且光标变为左右箭头时,即能将其

两边的部分放大或缩小。

若想做成上下分隔线,将以上1和2中的Align属性设为Top,2中的Cursor属性设为

crVSplit,其余不变即可。

另外用户还可在3中的面板上再按1、2、3的步骤进行操作,将整个窗口用两个分隔

线分为3个部分。以此类推,可将窗口分为任意多个部分。

本程序在Delphi 1.0和2.0下调试通过。

附录:源程序split.pas

unit Split;

interface

uses

SysUtils

WinTypes

WinProcs

Messages

Classes

Graphics

Controls

Forms

Dialogs

ExtCtrls;

type {定义分隔线控件类}

TSpliter = class(TPanel) {TSpliter类从Tpanel类继承}

private {定义私有变量和方法}

FForm: TForm; {分隔线所在的窗口变量}

FSplitControl

FSizeTarget: Tcontrol; {分隔线及要改变的目标控件变量}

FVertical: Boolean; {分隔线方向变量}

FSplit: TPoint; {分隔线坐标变量}

FAOwner: TComponent; {分隔线的拥有者变量}

procedure GetComponents; {获得分隔线和目标实例}

function GetSizing: Boolean; {判断分隔线状态}

procedure DrawSizingLine; {画分隔线阴影}

public {定义公共方法}

constructor Create(AOwner: TComponent);override; {构造函数}

procedure BeginSizing; {移动前初始化}

procedure ChangeSizing(X

Y: Integer); {改变分隔线位置}

procedure EndSizing; {终止移动}

property Sizing: Boolean read GetSizing; {分隔线是否可移动属性}

procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X

Y:Integer); Override; {按下鼠标事件}

procedure MouseMove(Shift: TShiftState; X

Y: Integer);override; {移动鼠

标事件}

procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X

Y: Integer);override; {弹起鼠标事件}

end;

procedure Register; {控件注册}

implementation

constructor TSpliter.Create(AOwner: TComponent);

begin

inherited Create(AOwner);

FAOwner := AOwner;

FForm:= TForm(FAOwner); {定义分隔线所在的窗口类}

end;

function CToC(C1

C2: TControl; P: TPoint): TPoint; {转换分隔线坐标函数}

begin

Result := C1.ScreenToClient(C2.ClientToScreen(P)); {将分隔线坐标转化为窗

口坐标}

end;

function TSpliter.GetSizing: Boolean;

begin

Result := FSplitControl <> nil; {是否获得了分隔线变量}

end;

procedure TSpliter.DrawSizingLine;

var P: TPoint;

begin

P := CToC(FForm

FSplitControl

FSplit);

with FForm.Canvas do begin

MoveTo(P.X

P.Y);

if FVertical then {若为上下移动的分隔线,画横向阴影线}

LineTo(CToC(FForm

FSplitControl

Point(FSplitControl.Width

0)).X

P.Y)

else {否则}

LineTo(P.X

CToC(FForm

FSplitControl

Point(0

FSplitControl.Height)

).Y) {画竖直的阴影线}

end;

end;

procedure TSpliter.BeginSizing;

begin

GetComponents;

SetCaptureControl(FSplitControl); {使分隔线可接受鼠标事件}

if FVertical then {获得分隔线的坐标}

FSplit := Point(0

FSplitControl.Top) else

FSplit := Point(FSplitControl.Left

0);

FForm.Canvas.Handle := GetDCEx(FForm.Handle

0

DCX_CACHE or

DCX_CLIPSIBLINGS

or DCX_LOCKWINDOWUPDATE); {取窗口句柄}

with FForm.Canvas do begin {设置画笔状态模式}

Pen.Color := clWhite;

if FVertical then

Pen.Width := FSplitControl.Height else

Pen.Width := FSplitControl.Width;

Pen.Mode := pmXOR;

end;

DrawSizingLine;

end;

procedure TSpliter.ChangeSizing(X

Y: Integer);

begin

DrawSizingLine;

if FVertical then FSplit.Y := Y else FSplit.X := X; {移动分隔线位置}

DrawSizingLine;

end;

procedure TSpliter.EndSizing;

var

DC: HDC;

P: TPoint;

begin

DrawSizingLine;

P := CToC(FSizeTarget

FSplitControl

FSplit); {将分隔线坐标转化为目标控

件坐标}

SetCaptureControl(nil); {将可接收鼠标事件的控件置空}

FSplitControl := nil; {分隔线对象指向空}

with FForm do begin

DC := Canvas.Handle;

Canvas.Handle := 0;

ReleaseDC(Handle

DC); {释放窗口句柄}

end;

if FVertical then begin {若为上下移动的分隔线}

if P.Y >= FSizeTarget.Parent.Height then Exit {若分隔线超过窗口高度退出}

else FSizeTarget.Height := P.Y; {否则改变目标高度}

end

else begin

if P.X >= FSizeTarget.Parent.Width then Exit {若分隔线超过窗口宽度退出}

else FSizeTarget.Width:= P.X; {否则改变目标宽度}

end;

end;

procedure TSpliter.MouseDown(Button: TMouseButton; Shift: TShiftState;

X

Y: Integer);

begin

inherited MouseDown(Button

Shift

X

Y); {继承原方法}

if (Button = mbLeft) and (Shift = [ssLeft]) then BeginSizing; {判断鼠标按

键,开始移动}

end;

procedure TSpliter.MouseMove(Shift: TShiftState; X

Y: Integer);

begin

inherited MouseMove(Shift

X

Y);

if Sizing then ChangeSizing(X

Y);

end;

procedure TSpliter.MouseUp(Button: TMouseButton; Shift: TShiftState;X

Y: Integer);

begin

inherited MouseUp(Button

Shift

X

Y);

if Sizing then EndSizing; {若获得分隔线对象,结束移动}

end;

procedure TSpliter.GetComponents;

var I: Integer;

begin

FSplitControl:= GetCaptureControl; {获得窗口中的分隔线对象}

FVertical := FSplitControl.Width > FSplitControl.Height;

if not FVertical then begin {若为横向分隔线}

for I:= 0 to FSplitControl.Parent.ControlCount-1 do {在分隔线所在的控件上

搜寻与它相邻的控件}

begin

if (FSplitControl <> FSplitControl.Parent.Controls[I]) and

(FSplitControl.Left - FSplitControl.Parent.Controls[I].Width >= 0) and

(FSplitControl.Left - FSplitControl.Parent.Controls[I].Width < 8) then

begin

FSizeTarget:= TControl(FSplitControl.Parent.Controls[I]); {获得目标控件}

Break; {跳出循环}

end

end;

end

else begin {若为纵向分隔线}

for I:= 0 to FSplitControl.Parent.ControlCount-1 do begin

if (FSplitControl <> FSplitControl.Parent.Controls[I]) and

(FSplitControl.Top - FSplitControl.Parent.Controls[I].Height >= 0) and

(FSplitControl.Top - FSplitControl.Parent.Controls[I].Height < 8) then

begin

FSizeTarget:= TControl(FSplitControl.Parent.Controls[I]);

Break;

end;

end;

end;

end;

procedure Register;

begin

RegisterComponents('Samples'

[TSpliter]); {将分隔线控件注册到Sample控件

列表中}

end;

end.

MOTODEV初体验,高效Android开发工具 Simple让BASIC语言编写Android程序 MOTODev试用报告- Android开发效率之源 安装MOTODEV Studio for Android版方法 Android开发工具-motoDEV studio介绍 Android过后Chrome OS又是如何开发? Android安全模型导致开发时功能受限 Android导出一个JAR库 APK汉化原理及方法 APK文件格式分析,Android反编译入门(一) ApiDemos中的Android Widget例子解析 APK签名导出向导 - Use the Export Wizard 剖析Android自带Widget - Music播放器 剖析Android自带Widget - Clock指针钟表 C#取得Excel工作簿工作表名称 C#中用Automation自动化方式对Excel的操作 VB如何打开或保存为有密码保护的Excel sheets工作表 VB在Excel表格文件中搜索指定内容 VB复制Excel表到另外一个Excel中 Java实现生成网站快照缩略图片 php实现生成网站快照缩略图片 C#实现生成网站快照缩略图片 VB比较两个Excel表格的内容 VB实现Excel按列或行排序 VB删除EXCEL表格指定行 用vb.net写的验证码识别代码 VB删除EXCEL表格指定列 Oracle数据库Windows 2003环境自动备份批处理 VB通过ADODB连接EXCEL表格文件读取数据 使用VBScript卸载软件 Discuz X2用户注册过程SQL java中如何象windows那样拦截其他窗口的消息? 告别CSDN,第一个全部进入全部给分 同一个submit可否和如何递交给不同的服务器端的不同的action处理? 一个关于tomcat中servlet的棘手问题。。。。。 谁有jbuilder6的license keys或serial number? 請教:vb里dim oRs as ADODB.Recordset與dim oRs as new ADODB.Recordset的區別在哪里? 请大家指点下在深圳哪里可以办个边防证?谢谢 在程序中如何得到一网页中的按钮焦点? 用vc生成曲面要用到那些类? 有關微軟的MCSE認証 请问如何用DELPHI实现拨号连接服务器? 有关界面的问题 如何实现Windows 2000 Server 远程拨号登录?请奉上你的经验和智慧!!! 莱鸟级的问题,你敢来挑战吗? TADODataSet 读磁盘文件是怎么用的? 我的毕业设计,一百分的送分题啊!!!!!!!!!!!!!!!!!1 请教这个函数的作用 //创建列的问题,谁帮我看一看缺什么,谢了 如何在本地访问远程数据库,用什么样的方法在速度、安全上都好一些 请大家指点下在深圳哪里可以办个边防证?谢谢 各位大侠,谁能介绍一下utf8,还有怎么把它转到gb2132编码呢? 我的毕业设计,一百分的送分题啊!!!!!!!!!!!!!!!!!1 窗体问题。。。 现有一个小项目: 怎样动态增加表格? 有人解决了jive的中文问题吗?? 报表就是查询结果吗?用VB很难做吗?为什么这么多人讨论,请问设计报表难点是什么? 请问我的VC地ClassView无法打开,有什么快速的方法可以打开 一个关于tomcat中servlet的棘手问题..... 谁可以帮我提供一个PHP的站内目录管理程序! 请问c++中,函数重载和虚函数有什么区别,在实现多态性方面有差别吗? 现有一个小项目: 如何对多个按钮的BN_ClICK进行映射 SQLserver备份与恢复 Delphi中怎样声明一个类?怎样实现多态?如果要在类库的一个类中添加一个方法又怎么做? 然后怎样封装它?是不是封装以后维护就非常简单? 可 计算机网络--〉清华大学出版社,作者:Andrew S Tanenbaum哪里有电子版下载 把播放F4的时间上《我们程序员都是活雷锋》 随便问问:VC能不能调用Access中的Form,Report 用ADO在线程中打不开数据库,请帮忙 如何在VB中动态的加载Dll,并使用其加载的函数??? 高手们看过来 Oracle初学,兄弟们多帮忙了! 怎么打开一个.txt文件,然后一行一行读取? 请问大家知道一个局域网里的IP在因特网上如何表示的呢。 请问各位,如何在我的程序中用代码生成Access数据库? 神啊,救救我吧,我想要含笑半步喋=== 请教NT4。0下的IE2。0怎样升级到IE6。0或IE5。0? 我要在程序中重载CBitmap类的一个函数,请问如何做 为什么我在bcb的new中找不到multitier(就是多层)选项页 请问如何知道数据库中有哪些表存在?在线等待 向各位大侠求救中 稀 硫酸氢钠溶液 与 碳酸钠溶液 的化学方程式 化学分辨稀硫酸,氯化钠溶液,氢氧化钠溶液.只用酚酞指示剂和适当的仪器设计一个简单的实验,将三种溶液区别出来,写出相关实验现象和结论.除此之外,你还能想出哪些鉴别方法. 氧气和烧碱溶液会反应吗?氯化钠和水会反应吗? 碳酸钠和硫酸氢钠可以反应么如上...讲一下关于酸式盐和盐的反应问题........ 我国根本政治制度和我国基本政治制度是什么 中国的基本政治制度、根本政治制度是什么?详细说明他们的含义、意义等~ 亚硫酸氢钠、硫酸氢钠、碳酸钠、碳酸氢钠、硫酸钠的电离和水解的化学反应方程式? 中国的政治制度 我国基本政治制度是什么?我国基本制度是什么? .下列物质中碳元素质量分数最小的( ) A.碳酸钙 B.干冰 C.金刚石 D甲烷 不懂是什么 意思啊 3号线 可以直接到上海的虹口足球场吗或者 从火车站出去后 什么可以直接坐到虹口足球场 紧急的 已知某固体粉末是由NaCL,Ba(N03)2,CuSO4,Na2SO4,Na2CO3中的一种或几种组成,取这种粉末加足量的水,振荡后呈浑浊,再加稀盐酸,沉淀不溶解,过滤后得无色溶液,取滤液并滴加AgNO3溶液,产生白色沉淀色沉 就一种碳元素能组合成多少种物质,像碳,钻石 篮球的一号位,二号位,三号位…等是啥意思 中华人民共和国基本的政治制度是什么? 只含有碳元素的物质 A.一定是金刚石 B.一定是石墨 C.一定是纯净物只含有碳元素的物质 A.一定是金刚石B.一定是石墨C.一定是纯净物D.可能是混合物 cf里面的 一号位 二号位 三号位 不是 是在沙漠灰中 一号位是主道机枪 其他的不知道了. 已知某固体粉末是由NAC1、BA(NO3)2、CUSO4、NA2SO4、NA2CO3中已知某固体粉末是由NaC1、Ba( N03)2、CuSO4、Na2SO4、Na2C03中的一种或几种组成,取这种粉末加足量的水,振荡后变浑浊,再加稀盐酸,沉淀不溶解, 将金刚石和石墨混在 一起,是纯净物还是混合物[ 他们都是C原子构成] 1、2、3号是什么意思GAY 里1、2、3、号是什么意思? 我国基本政治制度有哪些? 金刚石和石墨放一起是单质还是混合物 怎样分离金刚石与石墨或碳混合物?得到纯净金刚石!金刚石的熔点是3550℃,石墨的熔点是3652℃~3697℃(升华)。石墨熔点高于金刚石。加热是没有办法得到金刚石的,我说的是人造金刚石,能 氢氧化钠溶液易变质的原因是什么? 将钻石与石墨混合在一起,得到的是混合物么? 美国政治制度为何会如此持久 这对我们中国有什么启示? 新中国政治制度的突出特点概括地说 中世纪欧洲的基本政治状况是 ( ) ①封建割据严重 ②封建王权衰弱③天主教会居于至高无上的地位 ④世俗王权与教会神权处于绝对对立状态A.①②③④ B.①②③ C.②③④ D.①③④怎么选择 列出15个食物中的可数名词 美国与日本政治制度异同,中国与美日政治制度的不同及根本原因能不能简明扼要, 现有一包白色粉末可能由NaCl Na2SO4 Na2CO3 CuSO4 中的一种或几种组成如题、现做如下实验:1.取少量粉末,加水溶解得无色溶液.2.另取少量粉末,滴加稀盐酸,无明显现象.请回答(1)根据上述实验 不经过思考,脱口而出的词语是什么, 什么是人类的1号病、2号病、3号病啊? 一包白色粉末可能是CuSO4,CaCl2,Na2CO3,NaCl四种物质中的一种或几种组成,为确定白色粉末成分,一包白色粉末可能是CuSO4,CaCl2,Na2CO3,NaCl四种物质中的一种或几种组成,为确定白色粉末成分,进行了如 李阳所说的脱口而出是什么意思?如何检验自己能否脱口而出? 为什么说中国的政治制度要比美国的政治制度先进? 想请教下,以聚乙二醇为基础油和以丙二醇为基础油产出的切削油有何区别呢?分别可以用在哪些领域呢?谢谢乙二醇可以用作切削油的基础油吗?如果可以的话又是用来切什么的啊?谢谢哦! 自得其乐是什么意思?脱口而出什么意思? 太空3号治什么病? 中世纪欧州最强大的是哪国?是不是神圣罗马国? 中国早期政治制度的特点是什么? 什么是疾病险?疾病险的定义是什么?如何定义疾病险?疾病险的具体含义是什么? 中世纪的欧洲国家如果我想去有保存多一点的中世纪的建筑物,文化的国家,有什么国家? 中国早期政治制度的特点 美国、中国两国的政治制度 中世纪时期欧洲有哪些国家?越详细越好...好的有追分... 有一包白色粉末,其中可能含有NaCl、CuCl2、Ba(NO3)2、NaCO3、NaSO4、K2CO3.先按下列步骤进行试验:1.将该粉末溶于水得到无色溶液和白色沉淀2.再滤出的沉淀中加入稀硝酸后,有部分沉淀溶解,同时产 吾病甚中“甚”是什么意思? 不小心把水银弄到了水壶里喝了有什么伤害吗? “重口”是什么思今天看了新一期的洛奇花园,其中:“原来搞阴郁音乐的.都这么重口?”中的“重口”是什么意思?我不要网上抄的!我想要好理解的!(我很纯jie) 往往不病则已、是什么意思? 沾过了水银的水壶还能不能用?今天用温度计的时候,温度计破裂,水银掉到了烧水壶里.那么这个水壶以后还能不能用?能用的话该怎么消毒?不能用又该怎么处理? 好重口!这是啥片儿啊? 烷烃的同分异构体的种数与碳原子个数有没有规律(有什么规律)? 水银不小心掉在了正在烧开水的热水壶里,把水倒掉再烧一壶,还可以喝吗?水银会不会在盖子上凝固呢? 重口什么意思 在氧气、铝、二氧化锰、硫酸、过氧化氢、氢氧化钠、氢氧化钡、氯化钠、硫酸铜中,选出恰当的物质,……在氧气、铝、二氧化锰、硫酸、过氧化氢、氢氧化钠、氢氧化钡、氯化钠、硫酸铜 碳酸钠和硫酸氢钠反应的化学方程式二楼和三楼都是我的朋友,而且都答得不错!我该选谁?(看到这个多少给我回一个) 我国的政治制度是什么?根本政治制度. 什么与氢氧化钠反应生成氯化钠和难容物,难容物与氧气和水反应生成另一种难容物
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘