home *** CD-ROM | disk | FTP | other *** search
- Unit E_Props;
- {-------------} Interface {--------------------}
- Uses
- Classes ,TypInfo;
- (*******************************************************************
- E_Props
- Get and set RTTI information routines.
- NOTE : I have encapsulated all RTTI manipulation routines in this
- unit due to the possibility that Borland may change the structure
- of RTTI with later releases. This way any changes required in an
- application can be made in only one place. The TEProperty class
- below provides an interface that can be used for displaying and
- editing a component's properties.
- Author : David Spies
- Contacts : Work - davidsp@eastsoft.com Home DSPIES@onecom.com *)
-
- Const
- PROP_NOTYPE = 0;
- PROP_STRTYPE = 1;
- PROP_INTTYPE = 2;
- PROP_REALTYPE = 3;
- PROP_BOOLTYPE = 4;
- PROP_CHARTYPE = 5;
- PROP_ENUMTYPE = 6;
- PROP_COLORTYPE = 7;
- PROP_CURSORTYPE = 8;
- PROP_SETTYPE = 9;
- PROP_CLASSTYPE = 10;
- PROP_MODALTYPE = 11;
- PROP_DBNAMETYPE = 12;
- PROP_DBIDXNAMETYPE = 13;
- PROP_DBTABNAMETYPE = 14;
- PROP_DBLOOKUPFIELD = 15;
-
- PROP_FONTSUB = 1;
- PROP_ICONSUB = 2;
- PROP_BMPSUB = 3;
- PROP_TSTRSUB = 4;
- PROP_DATASETSUB = 5;
- PROP_DATASOURCESUB = 6;
- Type
- TEProperty = Class
- EType : Word;
- SubType : Word;
- MaxChars : Word;
- MinVal : LongInt;
- MaxVal : LongInt;
- ClassAddr : LongInt;
- PValue : String;
- TypeInfo : PTypeInfo;
- end;
-
-
-
- Function E_IsPublishedProp( AComponent : TComponent;
- Const PropName : String) : Boolean;
-
-
- Function E_GetStrProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : String) : Boolean;
-
- Function E_GetIntProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Integer) : Boolean;
-
- Function E_GetBoolProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Boolean) : Boolean;
-
- Function E_GetRealProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Double) : Boolean;
-
- Function E_GetSetStrProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : String) : Boolean;
-
- Function E_SetStrProp( AComponent : TComponent;
- Const PropName : String;
- Const PropValue : String) : Boolean;
-
- Function E_SetIntProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Integer) : Boolean;
-
- Function E_SetRealProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Double) : Boolean;
-
- Function E_SetBoolProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Boolean) : Boolean;
-
- Function E_SetSetStrProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : String) : Boolean;
-
- Function E_EnumProperties( AComponent : TComponent;
- Var PropList : TStringList) : Integer;
-
- Function E_GetEnumList( CompProp : TEProperty;
- AList : TStrings) : Boolean;
-
-
- {-------------} Implementation {---------------}
- Uses
- Controls,Db,DbTables,Graphics,SysUtils;
- Type
- TIntegerSet = set of 0..SizeOf(Integer) * 8 - 1;
-
- (*******************************************************************
- E_GetPropInfo
- Internal helper routine to get a RTTI structure pointer.
- *******************************************************************)
- Function E_GetPropInfo( AComponent : TCOmponent;
- Const PropName : String;
- Var PropInfo : PPropInfo) : Boolean;
- begin
- PropInfo:=Nil;
- If AComponent<>Nil then
- Try
- PropInfo:=GetPropInfo(AComponent.ClassInfo,PropName);
- Except
- PropInfo:=Nil;
- end;
- Result:=PropInfo<>Nil;
- end;
- (*******************************************************************
- E_IsPublished
- Return true if PropName is a published property.
- *******************************************************************)
- Function E_IsPublishedProp( AComponent : TComponent;
- Const PropName : String) : Boolean;
- begin
- If Propname<>'' then
- Result:=GetPropInfo(AComponent.ClassInfo,PropName)<>Nil
- else
- Result:=False;
- end;
- (*******************************************************************
- E_Get????????
- The next several routines get the value of PropName from component.
- Returns False if property doesn't exist.
- *******************************************************************)
- Function E_GetStrProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : String) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- PropValue:=GetStrProp(TObJect(AComponent),PropInfo)
- else
- PropValue:='';
- end;
- Function E_GetIntProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Integer) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- PropValue:=GetOrdProp(TObJect(AComponent),PropInfo)
- else
- PropValue:=0;
- end;
- Function E_GetBoolProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Boolean) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- PropValue:=Boolean(GetOrdProp(TObJect(AComponent),PropInfo))
- else
- PropValue:=False;
- end;
- Function E_GetRealProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : Double) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- PropValue:=GetFloatProp(TObJect(AComponent),PropInfo)
- else
- PropValue:=0;
- end;
- Function E_GetSetStrProp( AComponent : TComponent;
- Const PropName : String;
- Var PropValue : String) : Boolean;
- Var
- PropInfo : PPropInfo;
- S : TIntegerSet;
- TypeInfo : PTypeInfo;
- I ,
- MinV ,
- MaxV : Integer;
- begin
- PropValue:='';
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- begin
- Integer(S):=GetOrdProp(TObJect(AComponent),PropInfo);
- TypeInfo:=GetTypeData(PropInfo^.PropType)^.CompType;
- MinV:=GetTypeData(TypeInfo).MinValue;
- MaxV:=GetTypeData(TypeInfo).MaxValue;
- PropValue := '[';
- for I := MinV to MaxV do
- if I in S then
- begin
- if Length(PropValue) <> 1 then
- PropValue := PropValue + ',';
- PropValue := PropValue + GetEnumName(TypeInfo,I);
- end;
- PropValue := PropValue + ']';
- end;
- end;
- (*******************************************************************
- E_Set????????
- The next several routines sets the value of PropName in component
- to PropVal. Returns False if property doesn't exist.
- *******************************************************************)
- Function E_SetStrProp( AComponent : TComponent;
- Const PropName : String;
- Const PropValue : String) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- SetStrProp(TObJect(AComponent),PropInfo,PropValue);
- end;
- Function E_SetIntProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Integer) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- SetOrdProp(TObJect(AComponent),PropInfo,PropValue);
- end;
- Function E_SetBoolProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Boolean) : Boolean;
- Var
- PropInfo : PPropInfo;
- PValue : Integer;
- begin
- PValue:=Ord(PropValue);
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- SetOrdProp(TObJect(AComponent),PropInfo,PValue);
-
- end;
- Function E_SetRealProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : Double) : Boolean;
- Var
- PropInfo : PPropInfo;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- SetFloatProp(TObJect(AComponent),PropInfo,PropValue);
- end;
- Function E_SetSetStrProp( AComponent : TComponent;
- Const PropName : String;
- PropValue : String) : Boolean;
- Var
- PropInfo : PPropInfo;
- S : TIntegerSet;
- TypeInfo : PTypeInfo;
- I : Integer;
- Tp : String;
- begin
- Result:=E_GetPropInfo(AComponent,PropName,PropInfo);
- If Result then
- begin
- While PropValue<>'' do
- begin
- I:=Pos('[',PropValue);
- If I=0 then
- I:=Pos(']',PropValue);
- If I=0 then
- Break;
- Delete(PropValue,I,1);
- end;
- S:=[];
- TypeInfo:=GetTypeData(PropInfo^.PropType)^.CompType;
- While PropValue<>'' do
- begin
- I:=Pos(',',PropValue);
- If I=0 then
- I:=Succ(Length(PropValue));
- Tp:=Copy(PropValue,1,Pred(I));
- Delete(PropValue,1,I);
- Include(S,GetEnumValue(TypeInfo,Tp));
- end;
- SetOrdProp(TObJect(AComponent),PropInfo,Integer(S));
- end;
- end;
- (*******************************************************************
- E_EnumProperties
- Enumerate the properties of a component and return them
- in stringlist Proplist where the string is the property name
- and a TEProperty class associated with the property describes
- how to manipulate the property. NOTE that it is expected that
- PropList has not been created.
- *******************************************************************)
- Function E_EnumProperties( AComponent : TComponent;
- Var PropList : TStringList) : Integer;
- Var
- PKinds : TTypeKinds;
- PList : PPropList;
- PtData : PTypeData;
- PropInfo : PPropInfo;
- CompProp : TEProperty;
- I,J : Integer;
- TReal : Double;
- TInt : Integer;
- S : TIntegerSet;
- Ts : String;
- PCount : Integer;
- begin
- PropList:=Nil;
- PKinds:=[tkInteger, tkChar, tkEnumeration, tkFloat,tkString, tkSet, tkClass, tkLString];
- Result:=GetPropList(AComponent.ClassInfo,PKinds,Nil);
- If Result>0 then
- begin
- GetMem(PList,Result * SizeOf(Pointer));
- Try
- Result:=GetPropList(AComponent.ClassInfo,PKinds,PList);
- If Result>0 then
- begin
- PropList:=TStringList.Create;
- for I := 0 to result - 1 do
- begin
- PropInfo := PList^[I];
- CompProp:=TEProperty.Create;
- With CompProp do
- begin
- TypeInfo:=PropInfo^.PropType;
- MinVal:=0;
- MaxVal:=0;
- ClassAddr:=0;
- MaxChars:=0;
- SubType:=0;
- end;
- With PropInfo^,PropType^ do
- begin
- If Kind<>tkClass then {Acts screwy for some reason}
- PtData:=GetTypeData(PropType);
- Case Kind Of
- tkFloat : begin
- TReal:=GetFloatProp(TObJect(AComponent),PropInfo);
- With CompProp do
- begin
- EType:=PROP_REALTYPE;
- Case PtData^.FloatType Of
- ftSingle : MaxChars:=8;
- ftDouble : MaxChars:=16;
- else
- MaxChars:=20;
- end;
- PValue:=FloatToStrF(TReal,ffGeneral,MaxChars,0);
- MaxChars:=22; {For -&. in edit}
- end;
- end;
- tkChar : begin
- TInt:=GetOrdProp(TObJect(AComponent),PropInfo);
- With CompProp do
- begin
- If (TInt<32) OR (TInt>127) then
- PValue:='#'+IntToStr(TInt)
- else
- PValue:=''+Chr(TInt);
- EType:=PROP_CHARTYPE;
- MaxChars:=4;
- end;
- end;
- tkString ,
- tkLString : With CompProp do
- begin
- EType:=PROP_STRTYPE;
- If Kind=tkString then
- MaxChars:=PtData^.MaxLength;
- If PropInfo^.Name='Name' then
- MaxChars:=63;
- PValue:=UpperCase(PropInfo.Name);
- If AComponent IS TTable then
- begin
- If Pvalue='DATABASENAME' then
- EType:=PROP_DBNAMETYPE
- else If PValue='INDEXNAME' then
- EType:=PROP_DBIDXNAMETYPE
- else If PValue='TABLENAME' then
- EType:=PROP_DBTABNAMETYPE;
- end
- else If (Pvalue='LOOKUPFIELD') OR (PValue='LOOKUPDISPLAY') then
- EType:=PROP_DBLOOKUPFIELD;
- PValue:=GetStrProp(TObJect(AComponent),PropInfo);
- end;
- tkEnumeration : begin
- TInt:=GetOrdProp(TObJect(AComponent),PropInfo);
- With CompProp do If UpperCase(Name)='BOOLEAN' then
- begin
- If TInt=0 then
- PValue:='False'
- else
- PValue:='True';
- EType:=PROP_BOOLTYPE;
- end
- else
- begin
- PValue:=GetEnumName(PropType,TInt);
- MinVal:=PtData^.MinValue;
- MaxVal:=PtData^.MaxValue;
- EType:=PROP_ENUMTYPE;
- end;
- end;
- tkInteger : With CompProp do
- begin
- TInt:=GetOrdProp(TObJect(AComponent),PropInfo);
- PValue:=UpperCase(PropInfo.Name);
- If Pos('COLOR',PValue)>0 then
- begin
- PValue:=ColorToString(TColor(TInt));
- EType:=PROP_COLORTYPE;
- end
- else If Pos('CURSOR',PValue)>0 then
- begin
- PValue:=CursorToString(TCursor(TInt));
- EType:=PROP_CURSORTYPE;
- end
- else
- begin
- PValue:=IntToStr(TInt);
- EType:=PROP_INTTYPE;
- If (PtData<>Nil) then
- begin
- MinVal:=PtData^.MinValue;
- MaxVal:=PtData^.MaxValue;
- end;
- Case PtData^.OrdType Of
- otSByte : MaxChars:=4;
- otUByte : MaxChars:=3;
- otSWord : MaxChars:=6;
- otUWord : MaxChars:=5;
- otSLong : MaxChars:=11;
- end;
- end;
- end;
- tkSet : With CompProp do
- begin
- EType:=PROP_SETTYPE;
- TypeInfo:=ptData^.CompType;
- PtData:=GetTypeData(TypeInfo);
- MinVal:=PtData^.MinValue;
- MaxVal:=PtData^.MaxValue;
- Integer(S):=GetOrdProp(TObJect(AComponent),PropInfo);
- CompProp.PValue := '[';
- for J := MinVal to MaxVal do
- if J IN S then
- begin
- if Length(PValue) <> 1 then
- PValue := PValue + ',';
- PValue := PValue + GetEnumName(TypeInfo,J);
- end;
- PValue := PValue + ']';
- end;
- tkClass : With CompProp do
- begin
- EType:=PROP_CLASSTYPE;
- Ts:=UpperCase(PropType^.Name);
- PValue:='('+PropType^.Name+')';
- ClassAddr:=GetOrdProp(AComponent,PropInfo);
- If Ts = 'TFONT' then
- begin
- SubType:=PROP_FONTSUB;
- If ClassAddr>0 then
- PValue:=TFont(ClassAddr).Name;
- end
- else If Ts = 'TICON' then
- SubType:=PROP_ICONSUB
- else If Ts = 'TBITMAP' then
- SubType:=PROP_BMPSUB
- else If Ts = 'TSTRINGS' then
- SubType:=PROP_TSTRSUB
- else If (Ts='TDATASET') OR (Ts='TTABLE') then
- begin
- If ClassAddr>0 then
- PValue:=TTable(ClassAddr).Name
- else
- PValue:='';
- SubType:=PROP_DATASETSUB;
- end
- else If (Ts='TDATASOURCE') then
- begin
- If ClassAddr>0 then
- PValue:=TDataSource(ClassAddr).Name
- else
- PValue:='';
- SubType:=PROP_DATASOURCESUB;
- end
- else
- begin
- PCount :=0; {Does It Have Some Properties?}
- If ClassAddr>0 then
- Try
- PCount:=GetPropList(TComponent(ClassAddr).ClassInfo,PKinds,Nil);
- Except
- PCount:=0;
- end;
- If PCount<1 then {Just Show It!}
- begin
- EType:=PROP_NOTYPE;
- PValue:='*'+PropType^.Name+'*';
- end;
- end;
- end;
- end;
- end;
- PropList.AddObject(PropInfo^.Name,CompProp);
- end;
- end;
- Finally
- If Result>0 then
- FreeMem(PList,Result*SizeOf(Pointer));
- end;
- end;
- end;
- (*******************************************************************
- E_GetEnumList
- Get a string list representing the values of a set type or
- an enumerated type property. NOTE that it is expected AList has
- already been created.
- *******************************************************************)
- Function E_GetEnumList( CompProp : TEProperty;
- AList : TStrings) : Boolean;
- Var
- I : Integer;
- begin
- AList.Clear;
- Result:=False;
- If CompProp=Nil then
- Exit;
- If CompProp.EType=PROP_BOOLTYPE then
- begin
- AList.Add('True');
- AList.Add('False');
- end
- else For I:=CompProp.MinVal to CompProp.MaxVal do
- AList.Add(GetEnumName(CompProp.TypeInfo,I));
- Result:=True;
- end;
- {-------------------------END OF FILE---------------------------------}
- end.
-
-
-