zoukankan      html  css  js  c++  java
  • Delphi中的DBGrid控件

    在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下调试通过。 

  • 相关阅读:
    加州大学Santa Barbara量化课程
    专利分析与申请(2):SILK 专利的特点
    两种可分级语音编码器的量化器
    芬兰赫尔辛基工业大学DirAC工程:Directional audio coding
    SILK 的 Delay Decision 和 Dither
    Fraunhofer 研究院
    ICASSP 论文发表相关问题
    SILK 学习总结之位分配与低码率编码
    今天测试VOIP软件结果
    国内部分音频语音相关研究企业(实时更新)
  • 原文地址:https://www.cnblogs.com/jijm123/p/9048765.html
Copyright © 2011-2022 走看看