天天看点

TDBGRID一些小技巧 .

摘  要:本文给TDBGrid增加了dgThumbTracking、及dgMouseWheel两个选项,用来支持滚动条的跟踪和鼠标滚轮。以及有关DBGrid行列颜色的一个技巧。

关键词:C++Builder  TDBGrid  ThumbTracking  MouseWheel  控件

  TDBGrid是数据库应用程序不能不使用的一个控件,它功能出奇的强大,基本上可以完成所有数据报表的显示,甚至还可以显示ADT和数组字段;TDBGrid的操作也很简单,比如固定字段的转换,实用又方便,它的属性、方法、事件等也都很直观;但就像能耐大的人都有点脾气一样,TDBGrid也有一些让我们不好理解的行为,其中大家谈论最多就是它怪异的键盘操作方式。

  我在实际应用中感到很奇怪的是TDBGrid经TCustomDBGrid从TCustomGrid派生而来,却为什么不再支持TCustomGrid的goThumbTracking选项,滚动条的实时跟踪是很实用的,无法想象浏览一个记录集时,非要放开鼠标键才能知道滚动到记录集的什么位置。另外,TDBGrid对鼠标滚轮的支持有问题,当使用滚轮时,只是滚动了输入框,而没有滚动记录集,出现了焦点与当前记录不一致的错误。

  技巧一、二,提供滚动条的实时跟踪及鼠标滚轮的支持。

  直接从TDBGrid继承,创建一个TJDBGrid控件,增加了dgThumbTracking、及dgMouseWheel两个选项,源码如下:

  //JDBGrid.h文件内容

//-------------------------------------------------------------------------  #ifndef JDBGridH

  #define JDBGridH

//-------------------------------------------------------------------------  #include <SysUtils.hpp>

  #include <Classes.hpp>

  #include <Controls.hpp>

  #include <DBGrids.hpp>

  #include <Grids.hpp>

//-------------------------------------------------------------------------  class PACKAGE TJDBGrid : public TDBGrid

  {

  enum TDBGridOption{ dgEditing, dgAlwaysShowEditor,

                       dgTitles, dgIndicator, dgColumnResize,

                       dgColLines, dgRowLines, dgTabs,

                       dgRowSelect, dgAlwaysShowSelection,

                       dgConfirmDelete, dgCancelOnExit,

                       dgMultiSelect ,dgThumbTracking,dgMouseWheel};

  typedef Set<TDBGridOption,dgEditing,goThumbTracking>  TDBGridOptions;

  private:

          TDBGridOptions FOptions;

  protected:

          TWndMethod DBGridProc;

          TWndMethod DBInplaceEditProc;

          virtual void __fastcall JDBInplaceEditProc(Messages::TMessage &Message);

          virtual void __fastcall JDBGridProc(Messages::TMessage& Message);

          virtual Grids::TInplaceEdit* __fastcall CreateEditor(void);

          void __fastcall SetOptions(TDBGridOptions Value);

  public:

  __fastcall TJDBGrid(TComponent* Owner);

  __published:

__property TDBGridOptions Options = {read=FOptions, write=SetOptions,default=27901};

  };

  //-------------------------------------------------------------------------

  #endif

//JDBGrid.cpp文件内容

//-------------------------------------------------------------------------  #include <vcl.h>

  #pragma hdrstop

  #include "JDBGrid.h"

  #pragma package(smart_init)

 //-------------------------------------------------------------------------         static inline void ValidCtrCheck(TJDBGrid *)

  {

          new TJDBGrid(NULL);

  }

//-------------------------------------------------------------------------fastcall TJDBGrid::TJDBGrid(TComponent* Owner):TDBGrid(Owner)

  {

     short *shortTmp;

     Dbgrids::TDBGridOptions optionsTmp;

     (void*)shortTmp=(void*)&FOptions;

     *shortTmp=27901;

     (void*)shortTmp=(void*)&optionsTmp;

     *shortTmp=3325;

     TDBGrid::Options=optionsTmp;

     DBGridProc=WindowProc;

     WindowProc=JDBGridProc;

  }

//-------------------------------------------------------------------------  void __fastcall TJDBGrid::SetOptions(TDBGridOptions Value)

  {

     short *pValue,*pOp,*pFOp,saveValue;

     Dbgrids::TDBGridOptions DBGridOptions;

     (void*)pValue=(void*)&Value;

     (void*)pOp=(void*)&DBGridOptions;

     (void*)pFOp=(void*)&FOptions;

     *pOp=*pValue & 0x1fff;

     TDBGrid::Options=DBGridOptions;

     DBGridOptions=TDBGrid::Options;

     *pFOp=*pOp | (*pValue & 0x6000);

  }

  //-------------------------------------------------------------------------  void __fastcall TJDBGrid::JDBInplaceEditProc(Messages::TMessage &Message)

  {

     switch (Message.Msg)

     {

        case WM_MOUSEWHEEL:

           if(Options.Contains(dgMouseWheel))

           {

              if (DataLink->Active)

              {

               if (Message.WParam<0)

                 {

                if (DataLink->DataSet->RecNo<DataLink->DataSet->RecordCount)

                DataLink->DataSet->RecNo++;

                 }

                 else

                 {

                    if (DataLink->DataSet->RecNo>1)

                       DataLink->DataSet->RecNo--;

                 }

              }

              if (!Options.Contains(dgAlwaysShowEditor))

                 EditorMode=false;

              return;

           }

        break;

     }

     DBInplaceEditProc(Message);

  }

//-------------------------------------------------------------------------  Grids::TInplaceEdit* __fastcall TJDBGrid::CreateEditor(void)

  {

     TInplaceEdit *tmp;

     tmp=TDBGrid::CreateEditor();

     DBInplaceEditProc=tmp->WindowProc;

     tmp->WindowProc=JDBInplaceEditProc;

     return tmp;

  }

 //-------------------------------------------------------------------------  void __fastcall TJDBGrid::JDBGridProc(Messages::TMessage& Message)

  {

     switch (Message.Msg)

     {

        case WM_VSCROLL:

        case WM_HSCROLL:

           if (Options.Contains(dgThumbTracking))

              if (Message.WParamLo==5)

              {

                 DBGridProc(Message);

                 Message.WParamLo=4;

                 DBGridProc(Message);

                 Message.WParam=8;

              }

        break;

        case WM_MOUSEWHEEL:

           if(Options.Contains(dgMouseWheel))

           {

              DBGridProc(Message);

              if (DataLink->Active)

              {

                 if (Message.WParam<0)

                 {

              if (DataLink->DataSet->RecNo<DataLink->DataSet->RecordCount)

              DataLink->DataSet->RecNo++;

                 }

                 else

                 {

              if (DataLink->DataSet->RecNo>1)

              DataLink->DataSet->RecNo--;

                 }

              }

              if (!Options.Contains(dgAlwaysShowEditor))

              EditorMode=false;

              return;

           }

        break;

     }

     DBGridProc(Message);

  }

  //-------------------------------------------------------------------------

  namespace Jdbgrid

  {

          void __fastcall PACKAGE Register()

          {

                   TComponentClass classes[1] = {__classid(TJDBGrid)};

                   RegisterComponents("Samples", classes, 0);

          }

  }

  //-------------------------------------------------------------------------

  技巧三,行列不同颜色时,交叉部位颜色的设置。

  如图:在交叉部位使用行列颜色的alpha混合。

响应TDBGrid的OnDrawColumnCell事件如下:

    void __fastcall TForm1::JDBGrid1DrawColumnCell(TObject *Sender,

          const TRect &Rect, int DataCol, TColumn *Column,

          TGridDrawState State)

    {

       int recordNo,tmpInt;

       if (JDBGrid1->DataSource->DataSet->Active)

       {

          recordNo=DataCol=JDBGrid1->DataSource->DataSet->RecNo % 10;

          if (recordNo ==0 || recordNo>5 )

             JDBGrid1->Canvas->Brush->Color=0xb0b0ff;

          else

             JDBGrid1->Canvas->Brush->Color=0xffe0e0;

          tmpInt=Column->Color;

          if (tmpInt!=clWindow)

          {

              int R1,G1,B1,R2,G2,B2,rgbTmp;

              int alpha=60;

              rgbTmp=JDBGrid1->Canvas->Brush->Color;

              R1=tmpInt & 0xff;

              G1=(tmpInt & 0xff00)>>8;

              B1=(tmpInt & 0xff0000)>>16;

              R2=rgbTmp & 0xff;

              G2=(rgbTmp & 0xff00)>>8;

              B2=(rgbTmp & 0xff0000)>>16;

              R1=(R1*alpha+R2*(256-alpha))>>8;

              G1=(G1*alpha+G2*(256-alpha))>>8;

              B1=(B1*alpha+B2*(256-alpha))>>8;

              JDBGrid1->Canvas->Brush->Color=(TColor)(R1+(G1<<8)+(B1<<16));

          }

          JDBGrid1->Canvas->FillRect(Rect);

       }

       JDBGrid1->DefaultDrawColumnCell(Rect,DataCol,Column,State);

    }

  以上代码在C++Builder 6.0 Windows XP下调试通过。