在DELPHI中使用API完成網(wǎng)格內(nèi)組件的嵌入
發(fā)表時(shí)間:2024-02-20 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]陳學(xué)軍 Delphi中向TDBGrid添加組件是一件十分麻煩的事情。筆者在這里向大家介紹一種利用WIN32 API函數(shù)在TDBGRID中嵌入CHECKBOX組件的方法。 TDBGrid部件是用于顯示和編輯數(shù)據(jù)庫(kù)表中記錄信息的重要部件,它是我們?cè)诔绦蛟O(shè)計(jì)過(guò)程中要經(jīng)常使用的一個(gè)強(qiáng)有力的工具。TD...
陳學(xué)軍
Delphi中向TDBGrid添加組件是一件十分麻煩的事情。筆者在這里向大家介紹一種利用WIN32 API函數(shù)在TDBGRID中嵌入CHECKBOX組件的方法。
TDBGrid部件是用于顯示和編輯數(shù)據(jù)庫(kù)表中記錄信息的重要部件,它是我們?cè)诔绦蛟O(shè)計(jì)過(guò)程中要經(jīng)常使用的一個(gè)強(qiáng)有力的工具。TDBGrid具有很多重要的屬性,我們可以在程序設(shè)計(jì)階段和程序運(yùn)行過(guò)程中進(jìn)行設(shè)置。TDBGrid部件中有很多重要的屬性,我們?cè)谶@里重點(diǎn)介紹Option屬性和DefaultDrawing屬性,其他屬性及其設(shè)置方法請(qǐng)參看聯(lián)機(jī)幫助文件。
Options屬性:它是TDBGrid部件的一個(gè)擴(kuò)展屬性,在程序設(shè)計(jì)階段設(shè)置Options屬性可以控制TDBGrid部件的顯示特性和對(duì)事件的響應(yīng)特性。
DefalultDrawing屬性:該屬性是布爾型屬性,它用于控制網(wǎng)格中各網(wǎng)格單元的繪制方式。在缺省情況下,該屬性的值為T(mén)rue,也就是說(shuō)Delphi使用網(wǎng)格本身缺省的方法繪制網(wǎng)格中各網(wǎng)格單元,并填充各網(wǎng)格單元中的內(nèi)容,各網(wǎng)格單元中的數(shù)據(jù)根據(jù)其對(duì)應(yīng)的字段部件的DisplayFormat屬性和EidtFormat屬性進(jìn)行顯示和繪制。如果DefaulDrawing屬性被設(shè)置為False,Delphi不會(huì)自動(dòng)地繪制網(wǎng)格中各網(wǎng)格單元和網(wǎng)格單元中的數(shù)據(jù),用戶必須自己為T(mén)DBGrid部件的OnDrawDataCell事件編寫(xiě)相應(yīng)的程序以用于繪制各網(wǎng)格單元和其中的數(shù)據(jù)。
需要注意的是,當(dāng)一個(gè)布爾字段得到焦點(diǎn)時(shí),TDBGrid.Options中的 gdEditing屬性不能被設(shè)置成為可編輯模式。另外,TDBGrid.DefaultDrawing屬性不要設(shè)置為FALSE,否則,就不能得到網(wǎng)格中畫(huà)布屬性的句柄。
程序設(shè)計(jì)開(kāi)始時(shí)就應(yīng)考慮:需要設(shè)定一變量來(lái)存儲(chǔ)原始的 TDBGrid.Options的所有屬性值。這樣,當(dāng)一boolean字段所在欄得到焦點(diǎn)時(shí)將要關(guān)閉TDBGrid.Options中g(shù)dEditing的可編輯模式。與此相對(duì)應(yīng),若該欄失去焦點(diǎn)時(shí),就要重新恢復(fù)原始的 TDBGrid.Options的所有屬性值。
在實(shí)例中可以通過(guò)鼠標(biāo)點(diǎn)擊或敲打空格鍵改變布爾值,這樣就需要觸發(fā)TDBGrid.OnCellClick事件和TDBGrid.OnKeyDown事件。因?yàn)檫@兩個(gè)事件都是改變單元格中邏輯字段的布爾值,所以為了減少代碼的重復(fù)最好創(chuàng)建一個(gè)私有過(guò)程(SaveBoolean;)來(lái)完成邏輯值的輸入,以后,在不同的事件中調(diào)用此過(guò)程即可。
對(duì) TDBGrid.OnDrawColumnCell事件的處理是整個(gè)程序的關(guān)鍵。處理嵌入組件的顯示的傳統(tǒng)方法是:在表單上實(shí)際添加組件對(duì)象,然后對(duì)組件的位置屬性與網(wǎng)格中單元格的位置屬性進(jìn)行調(diào)整,以達(dá)到嵌入的視覺(jué)效果。這種方法雖然可行但代碼量大,實(shí)際運(yùn)行時(shí)控制性很差。筆者采用的方法是充分利用WIN32 API函數(shù):DrawFrameControl(),由于此函數(shù)可以直接畫(huà)出Checkbox組件,所以就無(wú)須在表單中實(shí)際添加組件。如何使用API函數(shù):DrawFrameControl()是本程序技巧所在。
在TDBGrid.OnDrawColumnCell事件中,我想大家會(huì)注意到:設(shè)定一個(gè)整型數(shù)組常數(shù),而這個(gè)返回的整數(shù)值是與布爾值相一致的,如果字段是邏輯字段,則只將其布爾值放入數(shù)組中,提供給DrawFrameControl()函數(shù)中的狀態(tài)參數(shù)進(jìn)行調(diào)用,從而實(shí)現(xiàn)了Checkbox組件在網(wǎng)格中的嵌入效果。
源代碼如下:
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
// 這個(gè)整數(shù)值將按照布爾值返回,并送入數(shù)組
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
//確保該欄是邏輯字段和空格鍵在鍵盤(pán)中被敲擊
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;
以上源程序在PWIN+DELPHI5.0環(huán)境調(diào)試通過(guò),可以直接引用。