วันจันทร์ที่ 30 มกราคม พ.ศ. 2555

Adding components to a DBGrid

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.

ไม่มีความคิดเห็น:

แสดงความคิดเห็น