unit Unit1;
{
Article:
Adding components to a DBGrid
http://delphi.about.com/library/weekly/aa081903a.htm
How to place just about any Delphi control
(visual component) into a cell of a DGBrid.
Find out how to put a CheckBox, a ComboBox
(drop down list box) and even an Image inside
a DBGrid.
..............................................
Zarko Gajic, BSCS
About Guide to Delphi Programming
http://delphi.about.com
how to advertise: http://delphi.about.com/library/bladvertise.htm
free newsletter: http://delphi.about.com/library/blnewsletter.htm
forum: http://forums.about.com/ab-delphi/start/
..............................................
}
interface
uses
Buttons, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGrids, DB, ADODB, StdCtrls, DBCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
ADOTable1: TADOTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
ADOTable1AuthorEmail: TWideStringField;
ADOTable1Title: TWideStringField;
ADOTable1Description: TWideStringField;
ADOTable1Subject: TWideStringField;
ADOTable1Winner: TBooleanField;
ADOTable1Image: TBlobField;
ADOTable1Round: TIntegerField;
DBCheckBox1: TDBCheckBox;
DataSource2: TDataSource;
ADOQuery1: TADOQuery;
DBLookupComboBox1: TDBLookupComboBox;
procedure FormCreate(Sender: TObject);
procedure DBGrid1ColExit(Sender: TObject);
procedure DBGrid1KeyPress(Sender: TObject; var Key: Char);
procedure DBCheckBox1Click(Sender: TObject);
procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
procedure DBGrid1CellClick(Column: TColumn);
private
procedure SetupGridPickList(const FieldName : string; const sql : string);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);
const IsChecked : array[Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
DrawState: Integer;
DrawRect: TRect;
begin
if (gdFocused in State) then
begin
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
DBCheckBox1.Top := Rect.Top + DBGrid1.top + 2;
DBCheckBox1.Width := Rect.Right - Rect.Left;
DBCheckBox1.Height := Rect.Bottom - Rect.Top;
DBCheckBox1.Visible := True;
end;
if (Column.Field.FieldName = DBLookupComboBox1.DataField) then
with DBLookupComboBox1 do begin
Left := Rect.Left + DBGrid1.Left + 2;
Top := Rect.Top + DBGrid1.Top + 2;
Width := Rect.Right - Rect.Left;
Width := Rect.Right - Rect.Left;
Height := Rect.Bottom - Rect.Top;
Visible := True;
end
end
else {in this else area draw any "stay behind" bitmaps}
begin
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DrawRect:=Rect;
InflateRect(DrawRect,-1,-1);
DrawState := ISChecked[Column.Field.AsBoolean];
DBGrid1.Canvas.FillRect(Rect);
DrawFrameControl(DBGrid1.Canvas.Handle, DrawRect, DFC_BUTTON, DrawState);
end;
end; //if focused
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DBGrid1.Align:=alClient;
//setup check box
DBCheckBox1.DataSource := DataSource1;
DBCheckBox1.DataField := 'Winner';
DBCheckBox1.Visible := False;
DBCheckBox1.Color := DBGrid1.Color;
DBCheckBox1.Caption := '';
//setup DBLookupComboBox
DataSource2.DataSet := AdoQuery1;
with AdoQuery1 do
begin
Connection := AdoConnection1;
SQL.Text := 'SELECT Name, Email FROM Authors';
Open;
FieldByName('Email').DisplayWidth:=15;
FieldByName('Name').DisplayWidth:=15;
end;
with DBLookupComboBox1 do
begin
DataSource := DataSource1; // -> Table1 -> DBGrid1
ListSource := DataSource2;
DataField := 'AuthorEmail'; // from Table1 - displayed in the DBGrid
KeyField := 'Email';
ListField := 'Name; Email';
Color := clCream;
Visible := False;
DropDownWidth := 200;
end;
//setup PickList for the 'Subject' field
SetupGridPickList('Subject', 'SELECT Name FROM Subjects');
end;
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
if DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField then DBCheckBox1.Visible := False;
if DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField then DBLookupComboBox1.Visible := False
end;
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if (key = Chr(9)) then Exit;
if (DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField)
then
begin
DBCheckBox1.SetFocus;
SendMessage(DBCheckBox1.Handle, WM_Char, word(Key), 0);
end;
if (DBGrid1.SelectedField.FieldName = DBLookupComboBox1.DataField) then
begin
DBLookupComboBox1.SetFocus;
SendMessage(DBLookupComboBox1.Handle, WM_Char, word(Key), 0);
end
end;
procedure TForm1.DBCheckBox1Click(Sender: TObject);
begin
if DBCheckBox1.Checked then
DBCheckBox1.Caption := DBCheckBox1.ValueChecked
else
DBCheckBox1.Caption := DBCheckBox1.ValueUnChecked;
end;
procedure TForm1.SetupGridPickList(const FieldName, sql: string);
var slPickList:TStringList;
Query : TADOQuery;
i:integer;
begin
slPickList:=TStringList.Create;
Query := TADOQuery.Create(self);
try
Query.Connection := ADOConnection1;
Query.SQL.Text := sql;
Query.Open;
while not Query.EOF do
begin
slPickList.Add(Query.Fields[0].AsString);
Query.Next;
end; //while
//place the list it the correct column
for i:=0 to DBGrid1.Columns.Count-1 do begin
if DBGrid1.Columns[i].FieldName = FieldName then
begin
DBGrid1.Columns[i].PickList:=slPickList;
Break;
end;
end;
finally
slPickList.Free;
Query.Free;
end; //try
end; (*SetupGridPickList*)
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
//Making the drop-down pick list appear faster by
//mimicking a hit to the F2 key followed by Alt + DownArrow
if Column.PickList.Count > 0 then
begin
keybd_event(VK_F2,0,0,0);
keybd_event(VK_F2,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU,0,0,0);
keybd_event(VK_DOWN,0,0,0);
keybd_event(VK_DOWN,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_MENU,0,KEYEVENTF_KEYUP,0);
end;
end;
end.