Delphi 利用API實現網格內組件的嵌入

 

在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;

 

發佈了72 篇原創文章 · 獲贊 13 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章