 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Martin Moeller Guest
|
Posted: Thu Sep 18, 2003 3:17 pm Post subject: Deriving from TCustomListView |
|
|
Hi,
Its my first attempt to derive a component, and it's using the wizard to
customerize a TListView in vsReport mode, aiming at an IDE capable design
with specific link to virtula data and their editing.
While it's pretty straight forward to derive directly from TListView, I
thought to do it from TCustomListView in order to also tune the properties,
getting rid of the unnecessary and setting the default values differently.
And here are the problems of the first attempts:
- deriving from TCustom as it is, there are almost no properties, while
adding from the help the declarations one by one into the publish part lets
them appear, but the end product does not handle the Colums correctly. As a
matter of fact, I had to comment the Column property ( __property
TListColumn* Column[int Index] = {read=GetColumnFromIndex}; ) as it always
created an out of range error when installed.
- taking the entire published property list from the header file
comctrls.hpp seems to work, but I couldn't change any of the default values,
nor the ViewStyle, nor the simple GridLines.
Who can help?
Tks & Rgds, Martin
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 5:18 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Martin Moeller" <martin.moeller (AT) moema (DOT) it> wrote
| Quote: | - deriving from TCustom as it is, there are almost no properties
|
Correct. That is the whole purpose of the TCustom... classes. They allow
you to pick&choose what you want to expose.
| Quote: | while adding from the help the declarations one by one into the
publish part lets them appear, but the end product does not handle
the Colums correctly.
|
Without seeing your actual code, I would guess that you are somehow misusing
it. Please always show your actual code.
| Quote: | As a matter of fact, I had to comment the Column property
( __property TListColumn* Column[int Index] = {read=GetColumnFromIndex}; )
as it always created an out of range error when installed.
|
When exposing protected properties from base classes, you do not need to
redeclare the entire property declaration in full. You only need to specify
just the property's name. In other words:
__published:
__property Columns;
__property HideSelection;
// etc...
No more, no less.
Gambit
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 5:48 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Martin Moeller" <martin.moeller (AT) moema (DOT) it> wrote
| Quote: |
- deriving from TCustom as it is, there are almost no properties, while
adding from the help the declarations one by one into the publish part lets
them appear, but the end product does not handle the Colums correctly. As a
matter of fact, I had to comment the Column property ( __property
TListColumn* Column[int Index] = {read=GetColumnFromIndex}; ) as it always
created an out of range error when installed.
|
You can not publish the property Column like that. Declare it in the public
section instead.
| Quote: | - taking the entire published property list from the header file
comctrls.hpp seems to work, but I couldn't change any of the default values,
nor the ViewStyle, nor the simple GridLines.
|
The default specifier of a property only _informs_ the VCL streaming system what
the default value for a property is. Properties which have their default values
will not to be streamed to a .dfm resource. You as a programmer are responsible
for the fact that property really is initialized to its default value. For
example;
class TmyComponent: public TComponent {
typedef TComponent inherited;
protected:
int FSomeIntProp;
public:
__fastcall TmyComponent::TmyComponent(TComponent* Owner):
TComponent(Owner),
FSomeIntProp(50) // initialize FSomeIntProp to 50
{
}
__published:
__property int
SomeIntProp={read=FSomeIntProp,write=FSomeIntProp,default=50};
};
So, if you want to have other default values for properties while deriving from
TCustomListView, you must assign the properties that new default value. Best
place to do that is in the constructor;
class TmyListView: public TCustomListView {
typedef TCustomListView inherited;
public:
__fastcall TmyListView(TComponent* Owner);
inherited(Owner)
{
FViewStyle = vsReport;
}
__published:
__property TViewStyle ViewStyle = {
read = FViewStyle,
write = SetViewStyle,
default = vsReport
};
};
But, now you have run into an annoyance of the VCL library. Most of the
published members of VCL components are declared private. So you do not have
access to them directly. The example above will not compile, since
TCustomListView::FViewStyle is declared private. You should introduce a getter
and setter for the property;
class TmyListView: public TCustomListView {
typedef TCustomListView inherited;
protected:
TViewStyle __fastcall GetViewStyle() {
return inherited::ViewStyle;
}
void __fastcall SetViewStyle(TViewStyle Value) {
inherited::ViewStyle = Value;
}
public:
__fastcall TmyListView(TComponent* Owner);
inherited(Owner)
{
FViewStyle = vsReport;
}
__published:
__property TViewStyle ViewStyle = {
read = GetViewStyle,
write = SetViewStyle,
default = vsReport
};
};
Use the same approach for other properties like GridLines.
Ralph
|
|
| Back to top |
|
 |
Martin Moeller Guest
|
Posted: Thu Sep 18, 2003 6:00 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Remy Lebeau (TeamB)" <gambit47 (AT) yahoo (DOT) com> wrote:
| Quote: |
- deriving from TCustom as it is, there are almost no properties
Correct. That is the whole purpose of the TCustom... classes. They allow
you to pick&choose what you want to expose.
|
Which means the Custom version is (almost) fully working except the publish
list. Is that generally the case with the vcl class strategy?
| Quote: | while adding from the help the declarations one by one into the
publish part lets them appear, but the end product does not handle
the Colums correctly.
Without seeing your actual code, I would guess that you are somehow
misusing
it. Please always show your actual code.
|
Full page of property list, with declaration from the wizard and properties
from the help.
Here a portion with colums:
class PACKAGE MLsvVrep1 : public TCustomListView // TListView
{
private:
protected:
public:
__fastcall MLsvVrep1(TComponent* Owner);
__published:
__property Forms::TBorderStyle BorderStyle = {read=FBorderStyle,
write=SetBorderStyle, default=1};
__property Graphics::TCanvas* Canvas = {read=FCanvas};
__property bool CheckBoxes = {read=FCheckboxes, write=SetCheckboxes,
default=1};
__property bool ColumnClick = {read=FColumnClick, write=SetColumnClick,
default=1};
__property TListColumns* Columns = {read=FListColumns,
write=SetListColumns};
__property TListColumn* Column[int Index] = {read=GetColumnFromIndex};
//enum TViewStyle { vsIcon, vsSmallIcon, vsList, vsReport };
__property TViewStyle ViewStyle = {read=FViewStyle, write=FViewStyle,
default=3};
__property bool ReadOnly = {read=FReadOnly, write=SetReadOnly,
default=true};
__property bool ShowColumnHeaders = {read=FShowColumnHeaders,
write=SetColumnHeaders, default=1};
__property TListItem* DropTarget = {read=GetDropTarget,
write=SetDropTarget};
......
Other questions:
On the hpp they also include the inherited statement, not created by wizard.
Is it necessary to shorthand declarations?
typedef TCustomListView inherited;
Further I have can not change the propertie's value. What I want is the IDE
Objetc inspector to for instance set the ViewStyle to vsReport and not
vsIcon.
How do you do that?
And the default value ( like __property GridLines = {default=true} , is
said that you still have to set it in the constructor and it is not
influencing the IDE.
What it is good for then? Only to limit the resource saved values?
Finally, how can I assign an icon for use in the components palette AFTER
the component has been created? Can not associate the *.dcr of an older
version of TListView derivate (now deleted) to my actual one.
Tks & Rgds, Martin
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 6:02 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote
| Quote: | FViewStyle = vsReport;
snip
__property TViewStyle ViewStyle = {
read = FViewStyle,
write = SetViewStyle,
default = vsReport
};
|
Since TListView already has a working ViewStyle property, you should be
utilizing that, not making your own manually:
class TMyListView : public TCustomListView
{
public:
__fastcall TMyListView(TComponent *Owner);
__published:
__property ViewStyle = {default = vsReport};
};
__fastcall TMyListView::TMyListView(TComponent *Owner)
: TCustomListView(Owner)
{
ViewStyle = vsReport;
}
| Quote: | You should introduce a getter and setter for the property
|
There is no need for that. Simply promote the existing property from
protected to published. See above. It is possible to redeclare the default
value for an existing property without re-writing the entire property
functionality yourself.
Gambit
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 6:17 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Martin Moeller" <martin.moeller (AT) moema (DOT) it> wrote
| Quote: | Which means the Custom version is (almost) fully working
except the publish list.
|
Correct. If you were to look at ComCtrls.hpp, for example, you would see
that TListView does nothing more than promote TCustomListView's protected
properties. TListView does not add any extra functionality to
TCustomListView.
| Quote: | Is that generally the case with the vcl class strategy?
|
Yes. Borland introduced the TCustom... classes specifically for the purpose
of extending the VCL with new classes while leveraging existing
functionality and to allow the component writers to utilize just the
particular pieces they are actually interested in using.
| Quote: | Here a portion with colums:
|
As I suspected, you are misusing the properties. To promote an existing
property from protected to public/published, you do not need to include the
full declarations, just the property names only. In other words:
class PACKAGE MLsvVrep1 : public TCustomListView
{
public:
__fastcall MLsvVrep1(TComponent* Owner);
__published:
__property BorderStyle;
__property CheckBoxes = {default=true};
__property ColumnClick = {default=true};
__property Columns};
__property ViewStyle = {default=vsReport};
__property ReadOnly = {default=true};
__property ShowColumnHeaders;
};
__fastcall MLsvVrep1::MLsvVrep1(TComponent* Owner)
: TCustomListView(Owner)
{
CheckBoxes = true;
ColumnClick = true;
ViewStyle = vsReport;
ReadOnly = true;
}
| Quote: | On the hpp they also include the inherited statement, not
created by wizard. Is it necessary to shorthand declarations?
typedef TCustomListView inherited;
|
It is not necessary, but it is common, particularly if your own code will
ever be invoking base class behaviors. It just makes the code easier to
read and understand what it is actually doing. It is also a carry-over from
Delphi (which the VCL is written in), as Delphi has an 'inherited' keyword
in the Pascal language which the C++ language does not. So the typedef is a
workaround for allowing C++ code to be similar to Delphi code.
| Quote: | Further I have can not change the propertie's value. What I want
is the IDE Objetc inspector to for instance set the ViewStyle to
vsReport and not vsIcon. How do you do that?
|
See above.
| Quote: | And the default value ( like __property GridLines = {default=true} ,
is said that you still have to set it in the constructor and it is not
influencing the IDE.
|
Correct.
| Quote: | What it is good for then? Only to limit the resource saved values?
|
Yes, it is only used by the DFM streaming system to cut down on the overhead
of storing and retrieving unnecessary values. As far as the physical data
is concerned, default values always need to be set up in the actual code for
the class. That is always the case even for non-VCL classes. Class members
should always be initialized in a constructor. That is why constructors
exist in the first place.
| Quote: | Finally, how can I assign an icon for use in the components palette AFTER
the component has been created? Can not associate the *.dcr of an older
version of TListView derivate (now deleted) to my actual one.
|
Use the Image Editor that comes with BCB to set up a .RES file containing
the desired bitmap, make sure the bitmap itself inside the .RES file is
named the same as the component class name, in all caps, ie MLSVVREP1. And
then simply add the .RES file to your component's package.
Gambit
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 6:17 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Remy Lebeau (TeamB)" <gambit47 (AT) yahoo (DOT) com> wrote
| Quote: | Since TListView already has a working ViewStyle property, you should be
utilizing that, not making your own manually:
class TMyListView : public TCustomListView
{
public:
__fastcall TMyListView(TComponent *Owner);
__published:
__property ViewStyle = {default = vsReport};
};
__fastcall TMyListView::TMyListView(TComponent *Owner)
: TCustomListView(Owner)
{
ViewStyle = vsReport;
}
|
What version of Borland are you using? This code does not compile under BCB5.
I think that leaving out the read and write specifiers results in a copy of the
'inherited' read and write specifiers. And as I stated in my previous post,
these are declared private in TCustomListView, thus you do not have access to
them.
Ralph
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 6:20 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Remy Lebeau (TeamB)" <gambit47 (AT) yahoo (DOT) com> wrote
| Quote: | Since TListView already has a working ViewStyle property, you should be
utilizing that, not making your own manually:
|
I am not deriving from TListView, but TCustomListView.
Ralph
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 6:25 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote
| Quote: | What version of Borland are you using?
|
3, 4, 5 and 6 :-)
| Quote: | This code does not compile under BCB5.
|
It compiles, installs, and runs just fine for me when I copy/paste it as-is
from my previous message into a new package under BCB5.
| Quote: | I think that leaving out the read and write specifiers results in a copy
of the 'inherited' read and write specifiers. And as I stated in my
previous post, these are declared private in TCustomListView, thus
you do not have access to them.
|
If that were really the case, then TListView itself would fail to compile,
as would half of the entire VCL library. What I have shown is the preferred
way to promote base class properties. It does not matter that the
read/write specifiers themselves are private. The original property was
declared as protected, and thus can be promoted.
TCustomListView::SetViewStyle() is private, but you don't see TListView
complaining about it, do you? Neither will TMyListView.
I assure you, what I posted works fine. I have been writing custom VCL
components for several years, and I am in the VCL's own source code almost
daily. I know how the VCL works.
Gambit
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 6:26 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote
| Quote: | I am not deriving from TListView, but TCustomListView.
|
ViewStyle is declared and implemneted in TCustomListView, not TListView.
TListView merely promotes it to published for use, just as your own code is
trying to do.
Gambit
|
|
| Back to top |
|
 |
Martin Moeller Guest
|
Posted: Thu Sep 18, 2003 6:44 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote:
| Quote: | And as I stated in my previous post,
these are declared private in TCustomListView,
|
Just checked in comctrls: they are declared protected.
Rgds and thanks, Martin
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 6:53 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Remy Lebeau (TeamB)" <gambit47 (AT) yahoo (DOT) com> wrote
| Quote: |
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote in message
news:3f69f57e (AT) newsgroups (DOT) borland.com...
What version of Borland are you using?
3, 4, 5 and 6
|
I think I have a copy of version 1 laying around here somewhere. Interested?
<g>
| Quote: | It compiles, installs, and runs just fine for me when I copy/paste it as-is
from my previous message into a new package under BCB5.
|
I missed the fact that you left out the type. I thought I had it as-is, sorry
;)
__property ViewStyle = { default = 3 };
or;
__property TViewStyle ViewStyle = { default = 3 };
Ralph
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 6:55 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Martin Moeller" <martin.moeller (AT) moema (DOT) it> wrote
| Quote: | Just checked in comctrls: they are declared protected.
|
The property is declared protected, the member is declared private.
Ralph
|
|
| Back to top |
|
 |
Ralph Kazemier Guest
|
Posted: Thu Sep 18, 2003 6:58 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Remy Lebeau (TeamB)" <gambit47 (AT) yahoo (DOT) com> wrote
| Quote: | ViewStyle is declared and implemneted in TCustomListView, not TListView.
|
I was using that implementation. Incorrectly or at least unhandy, but still ;)
Ralph
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Thu Sep 18, 2003 7:02 pm Post subject: Re: Deriving from TCustomListView |
|
|
"Ralph Kazemier" <ralph.kazemier (AT) jess (DOT) nl> wrote
| Quote: | __property TViewStyle ViewStyle = { default = 3 };
|
Do not specify the data type when promoting an existing property. Only the
name. The only time you specify a data type and read.write specifiers is
when you are actually creating a new property that you are going to actually
implement in your own code.
Gambit
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|