Examples Delphi

Title: How to set all data ware control
Question: How to set all data ware control's datasource property?
Answer:
Last time, I have written a powerful function that can set all controls' Enabled property that laid on a WinControl. This is benefit of Object-Oriented, for Enabled is a property of TControl, and all visible control are inherited from TControl.
When I develop database program, someone asked me how to set datasource property of data ware controls just like my EnableControls function. The answer is no. Why? Because Datasource property is only belong to data ware control, so data ware control doesn't have a parent that contains Datasource property. For example, TEdit is inherited from TCustomMaskEdit, TDBMemo is inherited from TCustomMemo, and their parents have no Datasource property.
Is another way can do this? Yes. Thanks to Delphi's RTTI, with its powerful function we can do many things. A pitfall of Delphi is that RTTI is undocumented.
First you should use TypInfo unit if you want to use RTTI. If you want to set ordinary property you should use
procedure SetOrdProp(Instance: TObject; PropInfo: PPropInfo; Value: Longint);
Instance is the Component whose property will be set, Value is what we want to set. PropInfo is get from another function
function GetPropInfo(TypeInfo: PTypeInfo; const PropName: string): PPropInfo;
PropName is the property name of the component, which want to be set value. To get TypeInfo just call class procedure ClassInfo.
With these two procedures I can write a procedure named SetOrdPropertyValueX. To make this procedure powerful, I made this procedure support callback function. This will make it difficult to use, so I write another procedure SetOrdPropertyValue to use it easily.
If you want to set datasource property of all data ware controls which on the Form1 to DataSource1, then try to use this statement:
SetOrdPropertyValue(Form1, 'DataSource', Integer(DataSource1));
These procedure can only set ordinary property, you can also write procedure to set string property, float property, variant property and so on.
I have written these procedures in Delphi 4. I think it will work in Delphi 3, it also works in Delphi 5. But using RTTI in Delphi 5 is much easier than Delphi 4. I have read an article of Delphi Informant which say about this, for copy write reason, I cannot say this. You can go to TypInfo unit to watch many overload function have been added.
Thanks to read my article, good luck.
The source code of my two procedures:
type
TOrdPropertyCallBack = procedure(AComponent: TComponent; APropertyName:
string; AOldValue: LongInt; var ANewValue: LongInt) of object;
/////////////////////////////////////////////////////////////////
// MethodName: SetOrdPropertyValueX
// Function : Set all components of :AParent which has
//property :APropertyName
//
//to :APropertyValue. If assigned :AComponentClass, then when set
//value, it need judge its inherited from. Note: the Value is
// LongInt
// Author : Chen Jiangyong
// Date : 1999/08/30
/////////////////////////////////////////////////////////////////
procedure SetOrdPropertyValueX(AParent: TWinControl; const
APropertyName: string; const APropertyValue: LongInt;
ACallBack: TOrdPropertyCallBack; const AComponentClass:
TComponentClass);
var
i: Integer;
PropInfo: PPropInfo;
HasProperty: Boolean;
OldValue, TmpValue: LongInt;
AComponent: TComponent;
begin
for i := 0 to AParent.ComponentCount - 1 do begin
AComponent := AParent.Components[i];
PropInfo := GetPropInfo(AComponent.ClassInfo, APropertyName);
HasProperty := PropInfo nil;
if HasProperty then begin
if Assigned(AComponentClass) then begin
if not ((PropInfo^.PropType^.Kind = tkClass) and
(GetTypeData( PropInfo^.PropType^).ClassType.InheritsFrom(AComponentClass)))
then
Continue;
end;
TmpValue := APropertyValue;
if Assigned(ACallBack) then begin
OldValue := GetOrdProp(AComponent, PropInfo);
ACallBack(AComponent, APropertyName, OldValue, TmpValue);
end;
SetOrdProp(AComponent, PropInfo, TmpValue);
if AComponent is TWinControl then
SetOrdPropertyValueX(TWinControl(AComponent),
APropertyName,
APropertyValue, ACallBack, AComponentClass);
end
end
end;
/////////////////////////////////////////////////////////////////
// MethodName: SetOrdPropertyValue
// Function : Set all components of :AParent which has
//property :APropertyName
//
// to :APropertyValue. Note: the Value is LongInt
// Author : Chen Jiangyong
// Date : 1999/09/22
/////////////////////////////////////////////////////////////////
procedure SetOrdPropertyValue(AParent: TWinControl; const
APropertyName: string; const APropertyValue: LongInt); overload;
begin
SetOrdPropertyValueX(AParent, APropertyName, APropertyValue,
nil, nil);
end;