在Delphi中,DBGrid控件是一个开发数据库软件不能不使用的控件,其功能非常强大,可以配合SQL语句实现几乎所有数据报表的显示,操作也非常简单,属性、过程、事件等都非常直观,但是使用中,有时侯还是需要一些其他功能,例如打印、斑马纹显示、将DBGrid中的数据转存到Excel97中等等。这就需要我们定制DBGrid,以更好的适应我们的实际需要。本人根据使用Delphi的体会,定制了DBGrid,实现了以上列举的功能,对于打印功能则是在DBGrid的基础上联合QuickReport的功能,直接进行DBGrid的打印及预览,用户感觉不到QuickReport的存在,只需调用方法WpaperPreview即可;对于转存数据到Excel也是一样,不过这里使用的是自动化变量Excel而已。由于程序太长,不能详细列举,这里介绍一个完整的实现斑马纹显示的DBGrid,名字是NewDBGrid。根据这个小程序,读者可以添加其他更好、更多、更实用的功能。

   NewDBGrid的实现原理就是继承DBGrid的所有功能,同时添加新的属性:Wzebra,WfirstColor ,WsecondColor。当Wzebra的值为True时,显示斑马纹效果,其显示的效果是单数行颜色为WfirstColor,双数行颜色为WsecondColor。具体的见下面程序清单:

unit NewDBGrid;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
DB, Grids, DBGrids,Excel97;
type
TDrawFieldCellEvent = procedure(Sender: TObject; Field: TField;
var Color: TCOlor;Var Font: TFont;Row:Longint) of object;
//新的数据控件由 TDBGrid 继承而来
TNewDBGrid = class(TDBGrid)
private
//私有变量
FWZebra: Boolean; //是否显示斑马颜色
FWFirstColor : TColor; //单数行颜色
FWSecondColor : TCOlor; //双数行颜色
FDrawFieldCellEvent : TDrawFieldCellEvent;
procedure AutoInitialize; //自动初使化过程
procedure AutoDestroy;
function GetWFirstColor : TColor; 
//FirstColor 的读写函数及过程
procedure SetWFirstColor(Value : TColor);
function GetWSecondColor : TCOlor;
procedure SetWSecondColor(Value : TColor);
function GetWZebra : Boolean;
procedure SetWZebra(Value : Boolean);
protected
procedure Scroll(Distance: Integer); override;
//本控件的重点过程
procedure DrawCell(Acol,ARow: Longint;ARect:
TRect;AState: TGridDrawState); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property WZebra: Boolean read GetWZebra write SetWZebra;
property OnDblClick;
property OnDragDrop;
property OnKeyUp;
property OnKeyDown;
property OnKeyPress;
property OnEnter;
property OnExit;
property OnDrawDataCell;
property WFirstColor : TColor
read GetWFirstColor write SetWFirstColor ;
property WSecondColor : TColor
read GetWSecondColor write SetWSecondColor ;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents(?Data Controls?, [TNewDBGrid]);
end;
procedure TNewDBGrid.AutoInitialize;
begin
FWFirstColor := RGB(239,254,247);
FWSecondColor := RGB(249,244,245);
{可以在次添加需要的其它控件及初使化参数}
end;
procedure TNewDBGrid.AutoDestroy;
begin
{在这里释放自己添加参数等占用的系统资源}
end;

procedure TNewDBGrid.SetWZebra(Value : Boolean);
begin
FWZebra := Value;
Refresh;
end;

function TNewDBGrid.GetWZebra: Boolean;
begin
Result :=FWZebra;
end;

function TNewDBGrid.GetWFirstColor : TColor;
begin
Result := FWFirstColor;
end;
procedure TNewDBGrid.SetWFirstColor(Value : TColor);
begin
FWFirstColor := Value;
Refresh;
end;

function TNewDBGrid.GetWSecondColor : TColor;
begin
Result := FWSecondColor;
end;
procedure TNewDBGrid.SetWSecondColor(Value : TColor);
begin
FWSecondColor := Value;
Refresh;
end;

constructor TNewDBGrid.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
AutoInitialize;
end;

destructor TNewDBGrid.Destroy;
begin
AutoDestroy;
inherited Destroy;
end;

//实现斑马效果
procedure TNewDBGrid.DrawCell(ACol,ARow:
Longint;ARect: TRect;AState: TGridDrawState);
var
OldActive: Integer;
Highlight: Boolean;
Value: string;
DrawColumn: Tcolumn;
cl: TColor;
fn: TFont;
begin
{如果处于控件装载状态,则直接填充颜色后退出}
if csLoading in ComponentState then
begin
Canvas.Brush.Color := Color;
Canvas.FillRect(ARect);
Exit;
end;
if (gdFixed in AState) and (ACol - IndicatorOffset 〈 0 ) then
begin
inherited DrawCell(ACol,ARow,ARect,AState);
Exit;
end;
{对于列标题,不用任何修饰}
if (dgTitles in Options) and (ARow = 0) then
begin
inherited DrawCell(ACol,ARow,ARect,AState);
Exit;
end;
if (dgTitles in Options) then Dec(ARow);
Dec(ACol,IndicatorOffset);
if (gdFixed in AState) and ([dgRowLines,dgColLines] * Options =
[dgRowLines,dgColLines]) then
begin
{缩减ARect,以便填写数据}
InflateRect(ARect,-1,-1);
end
else
with Canvas do
begin
DrawColumn := Columns[ACol];
Font := DrawColumn.Font;
Brush.Color := DrawColumn.Color;
Font.Color := DrawColumn.Font.Color;
if FWZebra then //如果属性WZebra为True则显示斑马纹
if Odd(ARow) then
Brush.Color := FWSecondColor
else
Brush.Color := FWFirstColor;
if (DataLink = nil) or not DataLink.Active then
FillRect(ARect)
else
begin
Value := ??;
OldActive := DataLink.ActiveRecord;
try
DataLink.ActiveRecord := ARow;
if Assigned(DrawColumn.Field) then
begin
Value := DrawColumn.Field.DisplayText;
if Assigned(FDrawFieldCellEvent) then
begin
cl := Brush.Color;
fn := Font;
FDrawFieldCellEvent(self,DrawColumn.Field,cl,fn,ARow);
Brush.Color := cl;
Font := fn;
end;
end;
Highlight := HighlightCell(ACol,ARow,Value,AState);
if Highlight and (not FWZebra) then
begin
Brush.Color := clHighlight;
Font.Color := clHighlightText;
end;
if DefaultDrawing then
DefaultDrawColumnCell(ARect,ACol,DrawColumn,AState);
if Columns.State = csDefault then
DrawDataCell(ARect,DrawColumn.Field,AState);
DrawColumnCell(ARect,ACol,DrawColumn,AState);
finally
DataLink.Activerecord := OldActive;
end;
if DefaultDrawing and (gdSelected in AState) and
((dgAlwaysShowSelection in Options) or Focused)
and not (csDesigning in Componentstate)
and not (dgRowSelect in Options)
and (ValidParentForm(self).ActiveControl = self) then
begin
//显示当前光标处为蓝底黄字,同时加粗显示
Windows.DrawFocusRect(Handle,ARect);
Canvas.Brush.COlor := clBlue;
Canvas.FillRect(ARect);
Canvas.Font.Color := clYellow;
Canvas.Font.Style := [fsBold];
DefaultDrawColumnCell(ARect,ACol,DrawColumn,AState);
end;
end;
end;
if (gdFixed in AState) and ([dgRowLines,dgColLines] * Options =
[dgRowLines,dgColLines]) then
begin
InflateRect(ARect,-2,-2);
DrawEdge(Canvas.Handle,ARect,BDR_RAISEDINNER,BF_BOTTOMRIGHT);
DrawEdge(Canvas.Handle,ARect,BDR_SUNKENINNER,BF_TOPLEFT);
end;
end;
//如果移动光标等,则需要刷新显示DBGrid
procedure TNewDBGrid.Scroll(Distance: Integer);
begin
inherited Scroll(Distance);
refresh;
end;
end.

   以上程序在Win98 + Delphi 5下调试通过。

Delphi中的DBGrid控件的更多相关文章

  1. Delphi中使用TXMLDocument控件应注意的问题 转

    Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...

  2. Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转

    关于用Delphi中的Indy控件实现收发邮件的几点学习记录             这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...

  3. Delphi中代替WebBrowser控件的第三方控件

    这几天,接触到在delphi中内嵌网页,用delphi7自带的TWebBrowser控件,显示的内容与本机IE8显示的不一样,但是跟装IE8之前的IE6显示一个效果.现在赶脚是下面两个原因中的一个: ...

  4. delphi中通过http控件上载文件的问题(紧急) 整理的CSDN 帖子

    http控件能不能实现post文件?要求效果就像普通的html中通过表单(form中<INPUT TYPE="FILE" NAME="FILE1" SIZ ...

  5. Delphi中使用TXMLDocument控件应注意的问题

    今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却遇到了非常奇怪的问题,下面分享一下 procedure TMainForm.Button1Click(Send ...

  6. 在DELPHI中动态创建控件以及控件的事件

    在DELPHI中我们经常要动态的创建控件以及控件的事件.例如,我们可能想根据程序需要动态的创建一些Tshape组件来创建某个图形,并使得在鼠标移动上去之后可以完成某些操作.这一般需要需要三步: 生成一 ...

  7. delphi中的Label控件背景透明

    Label1.Transparent:=true;你在它的属性窗口把它的Transparent属性改成TRUE就行了 来自为知笔记(Wiz)

  8. delphi中使用mediaplayer控件播放音乐

    新建一个名字为media的文件夹,把要播放的音乐文件放在这个文件夹里. ExtractFilePath是用来获得产生的可执行程式所在的路径,因为我们把要播放的音乐文件放在了可执行程式的那个根目录下. ...

  9. delphi如何按照控件的左右顺序来遍历窗体中的每个控件 [问题点数:20 http://bbs.csdn.net/topics/380216822

    delphi如何按照控件的左右顺序来遍历窗体中的每个控件delphi默认是按照控件添加进窗体的顺序来遍历的,有没有哪个属性能控制这个/?? 更多0分享到:   对我有用[0] 丢个板砖[0] 引用 | ...

随机推荐

  1. 20155319 2017-2018-1《信息安全系统设计》第四周课堂测试、Makefile、myod

    20155319 2017-2018-1<信息安全系统设计>第四周课堂测试.Makefile.myod 测试2-gcc测试 1.用gcc 进行预处理,编译,汇编,链接vi输入的代码 2.生 ...

  2. cogs696 longest prefix

    cogs696 longest prefix 原题链接 IOI1996原题? 其实这题我不会. map+string+手动氧气大法好 //就是这么皮(滑稽 Code // It is made by ...

  3. C# VS,连接到oracle 报要升级到8.多少版本的错

    1:确定服务器的oracle版本 2:本地的客户端版本要和服务器一致 3:操作系统位数要一致

  4. 解析build.gradle文件

    Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言DSL来声明项目设置,摒弃了传统XML(如Ant和Maven)的各种繁琐配置 项目结构如上图: 1.最外层目录下的b ...

  5. Unity Lighting - Light Types 灯光类型(八)

      Light Types 灯光类型 We have now covered some of the project settings which need to be considered befo ...

  6. python-python爬取妹子图片

    # -*- conding=utf-8 -*- import requests from bs4 import BeautifulSoup import io url = "https:// ...

  7. 译 - 高可用的mesos计算框架设计

    原文地址 http://mesos.apache.org/documentation/latest/high-availability-framework-guide/ 阅读建议:有写过或者看过Mes ...

  8. 苹果没放弃手写笔 这样的iPad你想要吗?

    12 月 31 日,美国专利与商标局(The U.S. Patent and Trademark Office)当地时间周四批准了一项来自苹果的专利申请,该专利主要描述的是一种可以通过陀螺仪.无线通讯 ...

  9. 所见即所得:七大无需编程的DIY开发工具

    现如今,各种DIY开发工具不断的出现,使得企业和个人在短短几分钟内就能完成应用的创建和发布,大大节省了在时间和资金上的投入.此外,DIY工具的出现,也帮助广大不具备专业知识和技术的“移动开发粉”创建自 ...

  10. JS - Promise使用详解--摘抄笔记

    第一部分: JS - Promise使用详解1(基本概念.使用优点) 一.promises相关概念 promises 的概念是由 CommonJS 小组的成员在 Promises/A 规范中提出来的. ...