Board index » cppbuilder » Why does "ItemIndex" not found in RTTI ??

Why does "ItemIndex" not found in RTTI ??


2003-10-06 09:52:06 PM
cppbuilder37
Hi, please forgive me for another question on this subject. On
the form i have one Combobox named "ComboBox1", which have 3
text lines - "aaa", "bbb", "ccc".
I need to use RTTI to read it's ItemIndex value and set it to
another value, but when i try to use GetPropInfo to get the
value of the "ItemIndex" i allways get NULL although ItemIndex
IS a propertie of a TComboBox (by the way why don't i see this
propertie in the Object Inspector when the ComboBox is in
focus?
Here is my very short code -
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include <TypInfo.hpp>
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TForm1::SpeedButton1Click( TObject *Sender )
{
TControl *c;
PTypeInfo pTypeInfo;
PPropInfo pPropInfo;
c = ComboBox1;
pTypeInfo = (PTypeInfo)c->ClassInfo();
pPropInfo = GetPropInfo( pTypeInfo, "ItemIndex" );
if( pPropInfo ) // Allways NULL!! why?
SetOrdProp( c, pPropInfo, 1 );
}
And a second question, when exactly do i have to use
GetVariantProp and SetVariantProp? what is it good for? for
example to read 'Top' or 'Left' of a component, should i use
GetVariantProp? or should i use GetPropInfo? what's the
different between them?
Thanks!
Ramm
 
 

Re:Why does "ItemIndex" not found in RTTI ??

Why not use ComboBox1->ItemIndex = 1; // or similar value?
The only properties you can set from the object inspector are those that are
published.
Other properties can only be set programatically - press F1 after selecting
a control and you should
get help on that component.
--
Rgds Pete
GenHelp: The Component Writers Help Authoring package
=================================
Web: www.frasersoft.net
"Ramm" < XXXX@XXXXX.COM >wrote in message
Hi, please forgive me for another question on this subject. On
the form i have one Combobox named "ComboBox1", which have 3
text lines - "aaa", "bbb", "ccc".
I need to use RTTI to read it's ItemIndex value and set it to
another value, but when i try to use GetPropInfo to get the
value of the "ItemIndex" i allways get NULL although ItemIndex
IS a propertie of a TComboBox (by the way why don't i see this
propertie in the Object Inspector when the ComboBox is in
focus?
<snip>
And a second question, when exactly do i have to use
GetVariantProp and SetVariantProp? what is it good for? for
example to read 'Top' or 'Left' of a component, should i use
GetVariantProp? or should i use GetPropInfo? what's the
different between them?
Thanks!
Ramm
 

Re:Why does "ItemIndex" not found in RTTI ??

"Ramm" < XXXX@XXXXX.COM >wrote in message
Quote
I need to use RTTI to read it's ItemIndex value and set it to
another value, but when i try to use GetPropInfo to get the
value of the "ItemIndex" i allways get NULL although ItemIndex
IS a propertie of a TComboBox (by the way why don't i see this
propertie in the Object Inspector when the ComboBox is in
focus?
The reason you don't see it in the Object Inspector is because the property
is not published. For the exact same reason GetPropInfo() will return NULL.
RTTI is only generated for published properties.
Quote
And a second question, when exactly do i have to use
GetVariantProp and SetVariantProp?
In case you are not sure with what kind of property your dealing with.
Quote
what is it good for? for
example to read 'Top' or 'Left' of a component, should i use
GetVariantProp?
For those properties you'd better use GetOrdProp instead.
Quote
or should i use GetPropInfo? what's the
different between them?
GetPropInfo() and GetVariantProp() are totally different. GetPropInfo()
returns RTTI about the property. GetVariantProp() returns the actual value
of the property.
Ralph
 

{smallsort}

Re:Why does "ItemIndex" not found in RTTI ??

Thanks! it's much more clear to me now. But why one propertie
is published and another one is not? why "Left" propertie for
example IS published but "ItemIndex" is no? what's the reason
behind it? why one IS and another one is NOT?
So you say that using RTTI i can Get/Set only this properties
that i can see in the Object Inspector?
The reason i wanted to set it using RTTI is that i read all the
info about my form and it's components from a special text file
which include component's info and several other things that
will determine how the application should behave. So if in this
text file i have info for several components that have a
"ItemIndex", i want only one line that will set this propertie
value, i don't want to write different code for each one, i
want to make the code as short as possible and to make sure
that if i write code that handle a propertie then it will
handle this propertie for any component.
Thanks for helping! :-)
Ramm
Ralph Kazemier" < XXXX@XXXXX.COM >wrote:
Quote

The reason you don't see it in the Object Inspector is because the property
is not published. For the exact same reason GetPropInfo() will return NULL.
RTTI is only generated for published properties.

>And a second question, when exactly do i have to use
>GetVariantProp and SetVariantProp?

In case you are not sure with what kind of property your dealing with.

>what is it good for? for
>example to read 'Top' or 'Left' of a component, should i use
>GetVariantProp?

For those properties you'd better use GetOrdProp instead.

>or should i use GetPropInfo? what's the
>different between them?

GetPropInfo() and GetVariantProp() are totally different. GetPropInfo()
returns RTTI about the property. GetVariantProp() returns the actual value
of the property.

Ralph
 

Re:Why does "ItemIndex" not found in RTTI ??

"Ramm" < XXXX@XXXXX.COM >wrote in message
Quote

But why one propertie
is published and another one is not? why "Left" propertie for
example IS published but "ItemIndex" is no? what's the reason
behind it? why one IS and another one is NOT?
The programmer of that particular component did not feel the need to publish
the property. I do not know the reason for it. Besides that, not every
property can be published. The property must either be a native data type
or a class derived from TObject. And even then, in some cases custom
property editors are necessary to edit the value for the property. Take
TStrings (TMemo::Lines, TComboBox::Items, etc) for example.
Quote
So you say that using RTTI i can Get/Set only this properties
that i can see in the Object Inspector?
That is not what I said exactly. I said that only published properties show
up in the Object Inspector. There is an extra rule though. The Object
Inspector only shows published properties which have a read _and_ a write
specifier.
class DELPHICLASS TMyComponent: public TComponent {
private:
int FInt;
__published:
__property int ReadWrite = { read = FInt, write = FInt };
__property int Read = { read = FInt };
__property int Write = { write = FInt };
};
While editing an instance of the above class, the Object Inspector will only
show the property ReadWrite. The properties Read and Write will not show
up. However, you can still use the function GetOrdProp() for the property
Read, and the function SetOrdProp() for the property Write.
Quote
So if in this
text file i have info for several components that have a
"ItemIndex", i want only one line that will set this propertie
value, i don't want to write different code for each one, i
want to make the code as short as possible and to make sure
that if i write code that handle a propertie then it will
handle this propertie for any component.
There is no way to set unpublished properties using RTTI, without extra
coding. What you could do is derive a custom component which does publish
the property and use that component in your application instead.
I don't see why you are not utilizing the VCL streaming system for this
functionality. All the pitfalls you might encounter are already dealt with
for you. There is no way you can get more out of RTTI than the VCL
streaming system already does.
Ralph
 

Re:Why does "ItemIndex" not found in RTTI ??

Hi, thank you very much for your help and time!
So as i understand from what you said i can use RTTI only to
Set/Get properties which are published, how can i know then if
"ItemIndex" property is published or not? i looked at the help
of the builder and i did not see anything about it.
I'm not sure that you understood what i meant about this text
file, what i'm trying to do is a text info file that will have
inside it all the information for building the application's
forms and the components and to determine the behave of the
application at runtime, by using this file the user will be
able to change/add very easely lot's of components and options
in this application by only changing this text file, without
having to use the builder for compiling again and to create
a new EXE file. this is what i'm trying to do.
So if my text file include the following 2 components for
example -
[Component]
Type = ListBox // ListBox
Name = MyListBox
Top = 10
Left = 10
TextLine = "First line"
TextLine = "Second line"
TextLine = "Third line"
ItemIndex = 2
[Component] // ComboBox
Type = ComboBox
Name = MyComboBox
Top = 80
Left = 80
TextLine = "First line"
TextLine = "Second line"
TextLine = "Third line"
ItemIndex = 1
Then i want one code that will handle the "ItemIndex" of the
ListBox and the "ItemIndex" of the ComboBox. First i'm using
the 'new' command to create the asked component ( TListBox or
TComboBox in this example ) then i want to call only one
function that will set this properties for any component, no
matter which component type, ComboBox, ListBox, or anything
else, so if this function include a short code then set the
ItemIndex for example then i want that this code will set this
property for any component type. Sorry for making it that long
but i hope that it's more clear now.
Sorry, but i did not really understood what you meant in the
following part of your answer -
"I don't see why you are not utilizing the VCL streaming
system for this functionality. All the pitfalls you might
encounter are already dealt with for you. There is no way you
can get more out of RTTI than the VCL streaming system already
does."
Thanks!
Ramm
 

Re:Why does "ItemIndex" not found in RTTI ??

Ramm wrote:
Quote
I need to use RTTI to read it's ItemIndex value and set it to
another value, but when i try to use GetPropInfo to get the
value of the "ItemIndex" i allways get NULL although ItemIndex
IS a propertie of a TComboBox (by the way why don't i see this
propertie in the Object Inspector when the ComboBox is in
focus?
Because ItemIndex is not a __published property, and RTTI is only
generated for published properties of classes that are descendants of
Delphi classes that were compiled in the {$M} state ($M is a Delphi
compiler directive).
So you're simply out of luck here.
--
Rudy Velthuis (TeamB)
"Vote early and vote often."
- Al Capone (1899-1947)
 

Re:Why does "ItemIndex" not found in RTTI ??

"Ramm" < XXXX@XXXXX.COM >wrote in message
Quote
So as i understand from what you said i can use RTTI only
to Set/Get properties which are published, how can i know
then if "ItemIndex" property is published or not?
Look in the actual header file for the component. If it is not declared
under the __published section for the component, then it is not published,
and thus RTTI will not see it.
Quote
i looked at the help of the builder and i did not see anything about it.
Pull up the help topic for TComboBox, and click on the "Properties" link. A
subwindow is displayed with all of the properties, including ItemIndex.
Notice that ItemIndex does not have a green box next to it. If you refer to
the "Legend" then you will see that a green box means "Published". Since
ItemIndex does not have a green box, then it is not published.
Quote
Then i want one code that will handle the "ItemIndex" of the
ListBox and the "ItemIndex" of the ComboBox.
What you're asking for is not doable with the native components since
ItemIndex is not available to RTTI. If you want RTTI to work for ItemIndex,
then you must do what Ralph already suggested - derive your own components,
publish the ItemIndex property, and then use those custom components instead
of the native ones. For example:
class TMyComboBox : public TComboBox
{
public:
__fastcall TMyComboBox(TComponent *Owner) : TComboBox(Owner) {}
__published:
__property ItemIndex; // <-- promote the existing property to
published
};
TMyComboBox *cb = new TMyComboBox(MyForm);
cb->Parent = MyForm;
//...
The component will work exactly the same as the original TComboBox in all
regards, but the ItemIndex will be available to RTTI now.
Gambit
 

Re:Why does "ItemIndex" not found in RTTI ??

"Ramm" < XXXX@XXXXX.COM >wrote in message
Quote
how can i know then if
"ItemIndex" property is published or not? i looked at the help
of the builder and i did not see anything about it.
You already found that GetPropInfo() returns NULL when there is no such
published property. You could also use the function IsPublishedProp().
Have a look at TypInfo.hpp, there are many functions which deal with RTTI.
Quote
I'm not sure that you understood what i meant about this text
file,
I do understand what you are trying to do. We have discussed this a couple
weeks ago. Back then I suggested to utilize the VCL streaming system.
Quote
what i'm trying to do is a text info file that will have
inside it all the information for building the application's
forms
And that is exactly what a .dfm resource is used for.
Quote
So if my text file include the following 2 components for
example -

[Component]
Type = ListBox // ListBox
Name = MyListBox
Top = 10
Left = 10
TextLine = "First line"
TextLine = "Second line"
TextLine = "Third line"
ItemIndex = 2
The following is the equivalent in .dfm:
object MyListBox: TListBox
Top = 10
Left = 10
Items.Strings = (
'First line'
'Second line'
'Third line'
)
end
TListBox does not have a property ItemIndex. You could derive a new class
from TListBox and publish the property. Then use that class in your
resource file. The same goes for a TComboBox and every other class where
you want access unpublished properties. Have you actually tried that?
Quote
First i'm using
the 'new' command to create the asked component ( TListBox or
TComboBox in this example )
When you make use of the VCL streaming system, you won't have to worry about
creating the components or assigning the actual properties values. You only
have to make sure that the classes used in .dfm resource are registered with
the VCL streaming system.
Quote
Sorry, but i did not really understood what you meant in the
following part of your answer -

"I don't see why you are not utilizing the VCL streaming
system for this functionality.
What you are trying to accomplish is in fact exactly what the VCL has
already implemented with the VCL streaming system.
Quote
All the pitfalls you might
encounter are already dealt with for you. There is no way you
can get more out of RTTI than the VCL streaming system already
does."
You might come across certain problems which are already solved.
First of all, creating the actual instances. You obviously need some sort
of class factory to create objects. This is tackled by the VCL by
RegisterClass().
Second, assign the property values. The VCL streaming system uses the RTTI
generated for the classes to assign properties their values which are
defined a .dfm resource. Sound familiar? ;)
Third, there any many features which are supported by the VCL streaming
system. Consider that you want to create a form on which different
components reside, which have to interact with each other. A typical
example, a TDBGrid, a TTable and a TDataSource. In a .dfm resource this
would like this;
object TForm
object TDBGrid
Align = alClient
DataSource = DataSource1
end
object Table1: TTable
DatabaseName = 'MyDatabase'
TableName = 'MyTable'
Active = True
end
object DataSource1: TDataSource
DataSet = Table1
end
end
How would you solve that in your script? But more importantly, do you want
to, knowing that the VCL can do it for you?
Another powerful feature which the streaming system supports is, inheriting
resources. Once a resource is read for a form, you can read additional
resources, which can refer to components already present at the form. This
way you could create default forms and override properties of existing
components and/or add new components in 'descendant' forms;
inherited TForm
inherited MainPanel: TPanel
object TSpeedButton
Left = 200
Top = 5
end
Yet another thing supported by the VCL streaming system, is referring to
published functions. Consider the following class;
class TMyForm: public TForm {
__published:
void __fastcall CloseFormClick(TObject* Sender);
...
};
And implementation;
void __fastcall TMyForm::CloseFormClick(TObject* Sender) {
Close();
}
You could stream the following .dfm resource;
object TMyForm
object TButton
Caption = 'Close'
OnClick = CloseFormClick
end
end
I am not saying that you should abandon your script, I just think that you
could encapsulate .dfm resources into it, which could save you a lot of
work.
Ralph
 

Re:Why does "ItemIndex" not found in RTTI ??

Thanks very much Remy, it's more clear now. I will check it but
not sure if i will use it in this project, it's a subject which
i need time to learn how to use, and i'm not having much time
for it now so i prefer using the simple methods which i know
how to use.
By the way i checked the code you gave me here, compilation
was OK only after i changed "MyForm" to "Form1", but when i
tried to run it i got Access Violation error which i don't have
much time to debug at this time, maybe later.
Thanks! :-)
Ramm
"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"Ramm" < XXXX@XXXXX.COM >wrote in message
news: XXXX@XXXXX.COM ...

>So as i understand from what you said i can use RTTI only
>to Set/Get properties which are published, how can i know
>then if "ItemIndex" property is published or not?

Look in the actual header file for the component. If it is not declared
under the __published section for the component, then it is not published,
and thus RTTI will not see it.

>i looked at the help of the builder and i did not see anything about it.

Pull up the help topic for TComboBox, and click on the "Properties" link. A
subwindow is displayed with all of the properties, including ItemIndex.
Notice that ItemIndex does not have a green box next to it. If you refer to
the "Legend" then you will see that a green box means "Published". Since
ItemIndex does not have a green box, then it is not published.

>Then i want one code that will handle the "ItemIndex" of the
>ListBox and the "ItemIndex" of the ComboBox.

What you're asking for is not doable with the native components since
ItemIndex is not available to RTTI. If you want RTTI to work for ItemIndex,
then you must do what Ralph already suggested - derive your own components,
publish the ItemIndex property, and then use those custom components instead
of the native ones. For example:

class TMyComboBox : public TComboBox
{
public:
__fastcall TMyComboBox(TComponent *Owner) : TComboBox(Owner) {}
__published:
__property ItemIndex; // <-- promote the existing property to
published
};

TMyComboBox *cb = new TMyComboBox(MyForm);
cb->Parent = MyForm;
//...

The component will work exactly the same as the original TComboBox in all
regards, but the ItemIndex will be available to RTTI now.


Gambit


 

Re:Why does "ItemIndex" not found in RTTI ??

Thanks :-)
I read your response, but as i explained to you last time, i'm
not sure that the approach you suggest me to use here is what i
need here, first of all becouse i don't have much time now to
learn all this subject and learn how to use the methodes you
talked about, i prefer using the simple methods which i already
know and know how to use, second - as i told you this text file
will contains many options which are not part of a normal .dfm
, in this file i'm going to write information that will
determine the behavior of the application durring runtime, it
will not be a normal .dfm file as you know it, so i'm not sure
that i can handle this file the way you suggested.
In any case, thanks very much for your help.
Ramm