亚索打卡牌出装:dbgrideh

来源:百度文库 编辑:偶看新闻 时间:2024/04/26 06:15:44
由DBGrid与DBGridEh的冲突,引发关于uses单元们的作用顺序的思考2008-09-26 16:23相信许多Delphi编程者都用过或体验过TDBGridEh这个第三方控件。我前几天编程时,也试着去用DBGridEh,却小小地吃了一个苦头。在此无意诋毁TDBGridEh(EhLib)或DBGrid,它们都是很好用的数据感知表格控件,只不过它们之间有冲突而已。
  事情经过是:
  我在编一个铁路物流货场管理程序时,用到了表格控件,最初,我用了DBGrid,但DBGrid无法直接设置表格的行高,于是我删掉DBGrid,改用DBGridEh。至此一切正常。后来我发现其实行高不必控制,于是我又把DBGridEh删掉,换做DBGrid。至此仍然一切正常。
  然后,问题来了。由于表格显示的数据记录需要区分来货和走货,也就是说根据操作数量的正负,用不同的颜色显示每一条记录。于是我在DBGrid的OnDrawColumnCell事件里写代码设置颜色,并用DefaultDrawColumnCell方法重绘表格。代码写好后,运行......奇怪!在DefaultDrawColumnCell那一行怎么提示“Incompatible types”错误?
  我脑袋开始晕了。应该不会是我设置和代码的问题啊!这个程序很大,从头至尾编来,我几乎没有犯过任何错误的。无奈,旁观者清,我求助于网友伴水清清。伴水说,是不是有哪个单元没有引用啊?
  伴水一言提醒了我。乖乖,倒不是哪个单元没有引用,而是多引用了DBGridEh的两个单元!(向窗体上拖放DBGridEh时自动添加的,而删掉控件时添加的单元并不自动删除)于是我把uses部分的GridsEh, DBGridEh这两个单元引用删掉,OK。

  由此我想,虽然DBGridEh和DBGrid的DefaultDrawColumnCell方法参数数量是相同的。但DBGridEh的DefaultDrawColumnCell方法的某个参数与DBGrid的该方法的某个参数的类型有细微不同。然后,编译器对于同名方法实际是overload或override的(具体是哪个操作,我没看,不敢乱说)。也就是说,假设在uses部分先后有A、B两个单元,都有一个Proc方法,如果在程序中不指明使用的是哪个单元的Proc方法,编译器会默认使用后者单元。

  我懒得去查看DBGridEh是如何定义DefaultDrawColumnCell方法的,朋友们可以去看一下,如果我说得不对,麻烦您联系我指正。

  为了让大家体会这个冲突,请使用下面的演示程序:

unit Unit1;

interface

uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    Dialogs, Grids, DBGrids, GridsEh, DBGridEh, DB, DBTables;

type
    TForm1 = class(TForm)
      DBGrid1: TDBGrid;
      DBGridEh1: TDBGridEh;
      DataSource1: TDataSource;
      Table1: TTable;
      procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
        DataCol: Integer; Column: TColumn; State: TGridDrawState);
      procedure DBGridEh1DrawColumnCell(Sender: TObject; const Rect: TRect;
        DataCol: Integer; Column: TColumnEh; State: TGridDrawState);
      procedure FormCreate(Sender: TObject);
    private
      { Private declarations }
    public
      { Public declarations }
    end;

var
    Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
    DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
{    //先把下面的代码注掉,程序是可以正常编译运行的
     with TDBGrid(Sender) do begin
      if DataSource.DataSet.RecNo mod 2 = 0 then
        Canvas.Font.Color := clBlue
      else
        Canvas.Font.Color := clRed;
      DefaultDrawColumnCell(Rect, DataCol, Column, State);
    end;
}
end;

procedure TForm1.DBGridEh1DrawColumnCell(Sender: TObject;
    const Rect: TRect; DataCol: Integer; Column: TColumnEh;
    State: TGridDrawState);
begin
     with TDBGridEh(Sender) do begin
      if DataSource.DataSet.RecNo mod 2 = 0 then
        Canvas.Font.Color := clBlue
      else
        Canvas.Font.Color := clRed;
      DefaultDrawColumnCell(Rect, DataCol, Column, State);
    end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    Self.Table1.Close;
    Self.Table1.DatabaseName := 'DBDEMOS';
    Self.Table1.TableName := 'animals.dbf';
    Self.DataSource1.DataSet := Table1;
    Self.DBGrid1.DataSource := DataSource1;
    Self.DBGridEh1.DataSource := DataSource1;
    Self.Table1.Open;
end;

end.

  编译运行上面的程序,会成功通过。
  然后,如果把uses部分“GridsEh, DBGridEh,”这两个单元引用往前移两个位置,移到“Grids, DBGrids,”前面去,就会出错。
  如果把程序中注释掉的部分去掉注释,那么,随着“GridsEh, DBGridEh,”和“Grids, DBGrids,”两个的谁在前谁在后,程序出错的位置也分别变换出现在两个DefaultDrawColumnCell方法上