1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
| unit DBCustCB;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DBCtrls, Db, DBTables, StdCtrls, DBGrids;
type
TMSDBComboBox = class(TComboBox)
private
{ Private declarations }
FDataSource : TDataSource;
FDataField : TField;
FFieldName : String;
FDBGrid : TDBGrid;
FCellClicked : Boolean;
FBookmark : TBookmark;
FDBComboBoxOnEnter : Boolean;
procedure CreateGridNColumn;
procedure Click(var message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure DBGridEnter(Sender : TObject);
procedure DBGridExit(Sender : TObject);
procedure CellClick(Column : TColumn);
procedure AssignText;
procedure WMPaste(var Message : TMessage);message WM_Paste;
procedure WMCut(var Message: TMessage); message WM_CUT;
procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
protected
{ Protected declarations }
procedure Loaded; override;
procedure DoEnter; override;
procedure DoExit; override;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property DataField : String read FFieldName write FFieldName;
property DataSource : TDataSource read FDataSource write FDataSource;
end;
procedure Register;
implementation
constructor TMSDBComboBox.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csReplicatable];
CreateGridNColumn;
end;
procedure TMSDBComboBox.DoEnter;
begin
if not FDBComboBoxOnEnter then begin
inherited;
FDBComboBoxOnEnter := True;
end;
end;
procedure TMSDBComboBox.DoExit;
begin
inherited;
if not (Screen.ActiveControl = FDBGrid) then
FDBComboBoxOnEnter := False;
end;
procedure TMSDBComboBox.Click(var message: TWMLButtonDown);
var
SelfPoint : TPoint;
SelfExit : TNotifyEvent;
begin
try
SelfExit := Self.OnExit;
Self.OnExit := nil;
FCellClicked := False;
FBookmark := DataSource.DataSet.GetBookmark;
if not FDBComboBoxOnEnter then
Self.DoEnter;
FDataField := DataSource.DataSet.FieldByName(FFieldName);
FDBGrid.Parent := Screen.ActiveForm;
FDBGrid.Width := Self.Width;
FDBGrid.DataSource := DataSource;
FDBGrid.Columns.Items[0].Field := FDataField;
FDBGrid.Columns.Items[0].Width := Self.Width - 22;
FDBGrid.Enabled := True;
SelfPoint := Screen.ActiveForm.ScreenToClient(Self.Parent.ClientToScreen(Point(Self.Left,Self.Top)));
FDBGrid.Left := SelfPoint.X;
if ((Screen.ActiveForm.Height - SelfPoint.Y) >= FDBGrid.Height) then begin
FDBGrid.Top := SelfPoint.Y + Self.Height
end
else
begin
FDBGrid.Top := SelfPoint.Y - FDBGrid.Height;
end;
FDBGrid.DataSource := Self.DataSource;
FDBGrid.BringToFront;
FDBGrid.Visible := True;
FDBGrid.SetFocus;
finally
Self.OnExit := SelfExit;
end;
end;
procedure TMSDBComboBox.DBGridExit(Sender : TObject);
begin
inherited;
FDBGrid.Parent := Self;
FDBGrid.Visible := False;
if not FCellClicked then begin
try
DataSource.DataSet.GotoBookmark(FBookmark);
finally
DataSource.DataSet.FreeBookmark(FBookmark);
end;
end;
Self.SetFocus;
end;
procedure TMSDBComboBox.DBGridEnter(Sender : TObject);
begin
{ FCellClicked := False;
FBookmark := DataSource.DataSet.GetBookmark;
Self.OnEnter(Self);}
end;
procedure TMSDBComboBox.CellClick(Column : TColumn);
begin
FCellClicked := True;
AssignText;
FDBGrid.Visible := False;
Self.SetFocus;
if Assigned(Self.OnClick) then
Self.OnClick(Self);
end;
procedure TMSDBComboBox.AssignText;
begin
if (DataSource.DataSet.FindField(FFieldName) <> nil) then
Self.Text := DataSource.DataSet.FindField(FFieldName).AsString;
end;
procedure TMSDBComboBox.Loaded;
begin
inherited;
Self.ItemHeight := 0;
Self.Text := '';
end;
procedure TMSDBComboBox.CreateGridNColumn;
begin
FDBGrid := TDBGrid.Create(Self);
FDBGrid.Left := 1000;
FDBGrid.Top := 1000;
FDBGrid.Parent := Self;
FDBGrid.Options := FDBGrid.Options - [dgTitles,dgIndicator];
FDBGrid.Options := FDBGrid.Options + [dgRowSelect,dgTabs];
FDBGrid.Columns.Add;
FDBGrid.Visible := False;
FDBGrid.OnEnter := DBGridEnter;
FDBGrid.OnExit := DBGridExit;
FDBGrid.OnCellClick := CellClick;
FDBGrid.ReadOnly := True;
FDBGrid.TabStop := False;
end;
procedure TMSDBComboBox.WMPaste(var Message : TMessage);
begin
inherited;
end;
procedure TMSDBComboBox.WMCut(var Message: TMessage);
begin
inherited;
end;
procedure TMSDBComboBox.WMKeyDown(var Message: TWMKeyDown);
begin
inherited;
end;
destructor TMSDBComboBox.Destroy;
begin
if (FDBGrid.Parent <> nil) then begin
FDBGrid.Free;
FDBGrid := nil;
end;
inherited;
end;
procedure Register;
begin
RegisterComponents('Delphi 3.0 Components', [TMSDBComboBox]);
end;
end. |
Partager