在DELPHI中利用API实现网格内组件的嵌入


======================================================
注:本文源代码点此下载
======================================================

delphi中向tdbgrid添加组件是一件十分麻烦的事情。笔者在这里向大家介绍一种利用win32 api函数在tdbgrid中嵌入checkbox组件的方法。

tdbgrid部件是用于显示和编辑数据库表中记录信息的重要部件,它是我们在程序设计过程中要经常使用的一个强有力的工具。tdbgrid具有很多重要的属性,我们可以在程序设计阶段和程序运行过程中进行设置。tdbgrid部件中有很多重要的属性,我们在这里重点介绍option属性和defaultdrawing属性,其他属性及其设置方法请参看联机帮助文件。

options属性:它是tdbgrid部件的一个扩展属性,在程序设计阶段设置options属性可以控制tdbgrid部件的显示特性和对事件的响应特性。

defalultdrawing属性:该属性是布尔型属性,它用于控制网格中各网格单元的绘制方式。在缺省情况下,该属性的值为true,也就是说delphi使用网格本身缺省的方法绘制网格中各网格单元,并填充各网格单元中的内容,各网格单元中的数据根据其对应的字段部件的displayformat属性和eidtformat属性进行显示和绘制。如果defauldrawing属性被设置为false,delphi不会自动地绘制网格中各网格单元和网格单元中的数据,用户必须自己为tdbgrid部件的ondrawdatacell事件编写相应的程序以用于绘制各网格单元和其中的数据。

需要注意的是,当一个布尔字段得到焦点时,tdbgrid.options中的 gdediting属性不能被设置成为可编辑模式。另外,tdbgrid.defaultdrawing属性不要设置为false,否则,就不能得到网格中画布属性的句柄。

程序设计开始时就应考虑:需要设定一变量来存储原始的 tdbgrid.options的所有属性值。这样,当一boolean字段所在栏得到焦点时将要关闭tdbgrid.options中gdediting的可编辑模式。与此相对应,若该栏失去焦点时,就要重新恢复原始的 tdbgrid.options的所有属性值。

在实例中可以通过鼠标点击或敲打空格键改变布尔值,这样就需要触发tdbgrid.oncellclick事件和tdbgrid.onkeydown事件。因为这两个事件都是改变单元格中逻辑字段的布尔值,所以为了减少代码的重复最好创建一个私有过程(saveboolean;)来完成逻辑值的输入,以后,在不同的事件中调用此过程即可。

对 tdbgrid.ondrawcolumncell事件的处理是整个程序的关键。处理嵌入组件的显示的传统方法是:在表单上实际添加组件对象,然后对组件的位置属性与网格中单元格的位置属性进行调整,以达到嵌入的视觉效果。这种方法虽然可行但代码量大,实际运行时控制性很差。笔者采用的方法是充分利用win32 api函数:drawframecontrol(),由于此函数可以直接画出checkbox组件,所以就无须在表单中实际添加组件。如何使用api函数:drawframecontrol()是本程序技巧所在。

在tdbgrid.ondrawcolumncell事件中,我想大家会注意到:设定一个整型数组常数,而这个返回的整数值是与布尔值相一致的,如果字段是逻辑字段,则只将其布尔值放入数组中,提供给drawframecontrol()函数中的状态参数进行调用,从而实现了checkbox组件在网格中的嵌入效果。

源代码如下:

type

tform1 = class(tform)

datasource1: tdatasource;

table1: ttable;

dbgrid1: tdbgrid;

procedure dbgrid1drawcolumncell(sender: tobject;

const rect: trect; datacol: integer;

column: tcolumn; state: tgriddrawstate);

procedure dbgrid1colenter(sender: tobject);

procedure dbgrid1colexit(sender: tobject);

procedure dbgrid1cellclick(column: tcolumn);

procedure dbgrid1keydown(sender: tobject; var key: word;

shift: tshiftstate);

private

{ private declarations }

originaloptions : tdbgridoptions;

procedure saveboolean;

public

{ public declarations }

end;

{...}

procedure tform1.dbgrid1drawcolumncell(sender: tobject;

const rect: trect; datacol: integer;

column: tcolumn; state: tgriddrawstate);

const

// 这个整数值将按照布尔值返回,并送入数组

ctrlstate : array[boolean] of integer = (dfcs_buttoncheck,

dfcs_buttoncheck or dfcs_checked);

begin

//确保只有在逻辑字段才能插入组件

if column.field.datatype = ftboolean then

begin

dbgrid1.canvas.fillrect(rect);

drawframecontrol(dbgrid1.canvas.handle,

rect,

dfc_button,

ctrlstate[column.field.asboolean]);

end;

end;

procedure tform1.dbgrid1colenter(sender: tobject);

begin

// 确保该栏是逻辑字段

if dbgrid1.selectedfield.datatype = ftboolean then

begin

originaloptions := dbgrid1.options;

dbgrid1.options := dbgrid1.options - [dgediting];

end;

end;

procedure tform1.dbgrid1colexit(sender: tobject);

begin

//确保该栏是逻辑字段

if dbgrid1.selectedfield.datatype = ftboolean then

dbgrid1.options := originaloptions;

end;

procedure tform1.dbgrid1cellclick(column: tcolumn);

begin

//确保该栏是逻辑字段

if dbgrid1.selectedfield.datatype = ftboolean then

saveboolean();

end;

procedure tform1.dbgrid1keydown(sender: tobject;

var key: word; shift: tshiftstate);

begin

//确保该栏是逻辑字段和空格键在键盘中被敲击

if ( key = vk_space ) and

( dbgrid1.selectedfield.datatype = ftboolean ) then

saveboolean();

end;

procedure tform1.saveboolean;

begin

dbgrid1.selectedfield.dataset.edit;

dbgrid1.selectedfield.asboolean :=

not dbgrid1.selectedfield.asboolean;

dbgrid1.selectedfield.dataset.post;

end;

以上源程序在pwin+delphi5.0环境调试通过,可以直接引用。


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值