Получение объекта, используемого полями
Однако, в некоторых случаях этого недостаточно. Даже если этот метод вызывался из модуля данных, иногда фокус не переходит к управлению, которое редактируется (например, TDBGrid).
Вашему вниманию представлена подходящая функция для использования на формах обслуживания набора данных, для нахождения управления редактирования поля в наборе данных, связанном с DataSource.
// ----------------------------------------------------------------------------
// GetControlField - управление данных в окне (TForm, TPanel, и т.д.),
// источник данных (TDataSource) и имя поля, эта функция постарается найти и
// возвратить управление, которое используется для редактирования содержания поля,
// даже сетку.
//
// от Rubem Nascimento da Rocha (Manaus-AM/Brazil)
// ----------------------------------------------------------------------------
type
THackDBGrid = class(TCustomDBGrid);
function GetControlField(AOwner: TWinControl;
ADataSource: TDataSource; ADataField: String): TWinControl;
const
PropDataSource = 'DataSource';
PropDataField = 'DataField';
var
I: Integer;
Found: Boolean;
RefWinControl: TWinControl;
CurrControl: TControl;
PropInfo: PPropInfo;
PropValue: String;
Stack: TStringList; // recurse engine
AuxObject: TObject;
function GridHasField: Boolean;
var
_Field, _Qty: Integer;
_AName: String;
begin
Result := False;
with THackDBGrid(CurrControl) do
begin
_Qty := DataLink.FieldCount;
for _Field := 0 to _Qty - 1 do
begin
_AName := UpperCase(DataLink.Fields[_Field].FieldName);
Result := (_AName = UpperCase(ADataField));
if Result then Break;
end;
end;
end;
begin
Found := False;
RefWinControl := AOwner;
I := Pred(RefWinControl.ControlCount);
Result := NIL;
Stack := TStringList.Create;
try
while ((I >= 0) or (Stack.Count > 0)) and (not Found) do
begin
// Check if control will be only checked checado or if all your
// child controls, one-by-one, will do
CurrControl := RefWinControl.Controls[I];
if CurrControl is TWinControl then
if TWinControl(CurrControl).ControlCount > 0 then
begin
Stack.AddObject(IntToStr(I), RefWinControl);
RefWinControl := TWinControl(CurrControl);
I := Pred(RefWinControl.ControlCount);
Continue;
end;
PropInfo := GetPropInfo(CurrControl.ClassInfo, PropDataSource);
if Assigned(PropInfo) then
begin
AuxObject := TObject(GetOrdProp(CurrControl, PropInfo));
// check if control is a data-aware grid
if CurrControl is TCustomDBGrid then
Found := GridHasField
else
begin
PropInfo := GetPropInfo(PTypeInfo(CurrControl.ClassInfo),
PropDataField);
if Assigned(PropInfo) then
begin
// ... check if property has the search value
PropValue := GetStrProp(CurrControl, PropInfo);
Found := (TDataSource(AuxObject) = ADataSource) and
(UpperCase(PropValue) = UpperCase(ADataField));
end;
end;
end;
while (Pred(I) = -1) and (Stack.Count > 0) do
begin
I := StrToInt(Stack[Pred(Stack.Count)]);
RefWinControl := TWinControl(Stack.Objects[Pred(Stack.Count)]);
Stack.Delete(Pred(Stack.Count));
end;
Dec(I);
if Found then
result := TWinControl(CurrControl);
end;
finally
Stack.Free;
end;
end;
Комментарии