Re: ? Extending and (Forcibly?) Overriding a Class
On Sat, 29 Nov 2008 19:16:12 -0500, "Alec S." <nospam@127.0.0.1> wrote:
Hi,
I am trying to extend a CListCtrl so that I can add features to it. What I need
is a way to make it so that InsertColumn requires an extra parameter. I do not
want to allow the existing one to be used externally since it would allow the
insertion of a column without providing the new information that my version
needs.
The only way to "withdraw" a public function is to make the object a
private member variable or if non-virtual, use private derivation. Then the
containing class can expose whatever functionality it wants. Neither method
will work when extending CListCtrl, which requires that you use public
derivation.
For example, I want to add a parameter that specifies the width /type/ of the
column. That is, it would be set to one of several values to determine if the
width is a plain integer width, not resizable, or dynamically calculated based
on one of a few different factors. Thus, when inserting a column, I need to be
able to require that extra information.
That would be the ideal, but you might find it easier to set it to a
default and require the use of another function to set a non-default value.
What's the best way to do this? I thought of overloading the standard
InsertColumn and having that either return an error (-1 in this case) or
ASSERTing.
You mean "overriding", but that's impossible as InsertColumn is not
virtual.
That way, I could provide another function that has the extra
argument (preferably with a default value), that in turn calls
CListCtrl::InsertColumn. However there are more than one InsertColumn and worse,
I guess I would have to extend the LVCOLUMN structure as well right?
Is there a better way?
No doubt InsertColumn is just a thin wrapper around the SendMessaging of a
Windows message, in this case LVM_INSERTCOLUMN, so if you want your derived
class to handle InsertColumn calls, you need to handle this message. Do not
"extend" LVCOLUMN, because that would require versioning it somehow so that
your LVM_INSERTCOLUMN handler can distinguish the "extended" struct from
the usual one, and there's no way to do that without making a bogus
assumption or two somewhere in the process. This suggests that the best
approach is to handle LVM_INSERTCOLUMN, set your extra information to some
default value in your message handler, and provide another function to set
a non-default value. You /could/ write a MyInsertColumn function that
includes the extra parameter, but it doesn't solve the problem that
InsertColumn and LVM_INSERTCOLUMN remain available.
As for "hiding" the non-virtual CListCtrl::InsertColumn with a function of
the same name that behaves very differently, don't. This is considered evil
under public derivation because the base class function remains available.
Moreover, it does nothing to help someone who directly sends
LVM_INSERTCOLUMN.
--
Doug Harrison
Visual C++ MVP