From: Tom Serface on
No problem. At least you had the same answer so I don't have to worry that
I was too sleepy to get it right :o)

Tom

"Giovanni Dicanio" <giovanni.dicanio(a)invalid.it> wrote in message
news:ec39CyDNIHA.4584(a)TK2MSFTNGP03.phx.gbl...
> Ops, Tom: sorry if I answered again...
> (Your post did not appear on my Outlook when I sent mine)
>
> G
>
>
> "Tom Serface" <tom.nospam(a)camaswood.com> ha scritto nel messaggio
> news:1522916F-602D-4ED7-96A2-5EBF78CF9D4A(a)microsoft.com...
>> I'm guessing that you're getting this error since the listbox is
>> returning a void * which is not related to a QLin *. I would try
>> reinterpret_cast or just saying
>>
>> QLin* pLin = (QLin*)pItem;
>>
>> Tom
>>
>> "Vaclav" <vjedlicka(a)atlas.cz> wrote in message
>> news:uB1TA6ANIHA.4880(a)TK2MSFTNGP03.phx.gbl...
>>> Hello,
>>>
>>> I am trying to get a pointer stored in a CListBox item.
>>>
>>>
>>> int li_index = m_lineTypesListBox.GetCurSel();
>>> if (LB_ERR == li_index)
>>> {
>>> return 0;
>>> }
>>>
>>> void* pItem = m_lineTypesListBox.GetItemDataPtr(li_index);
>>> QLin* pLin = dynamic_cast<QLin*>(pItem);
>>>
>>>
>>> Getting
>>> error C2681: 'void *' : invalid expression type for dynamic_cast
>>>
>>>
>>> Thanks
>>> Vaclav
>>>
>>
>
>

From: Giovanni Dicanio on

"Joseph M. Newcomer" <newcomer(a)flounder.com> ha scritto nel messaggio
news:9k64l3dgmr5dtfl3cc65t3s67lh2rjp48d(a)4ax.com...

> It probably would have been better if these methods had been virtual, but
> in the interest
> of "efficiency" they are not.
>
> I see no reason to have stored it in a void *.

Hi Joe,

I may be missing something, but I think that using 'virtual' in this context
would not be of important help.

The problem here is the type of the return value. If you have a method
declared as virtual, this does not help much.

The help that virtual gives is when you want to use polymorphism and
pointers, e.g.

class Base
{
...
public:
virtual void * GetSomething();
};

class Derived : public Base
{
...
public:
virtual void * GetSomething();
};

And so if you have:

Base * p = new Derived();
p->GetSomething();

then Derived::GetSomething() is called (and not Base::GetSomething).

I think that using templates would have helped better (because the return
type can be made a template type), but I see several problems when I try to
mix templates and MFC... for example, for message maps.

What do you think about this (templates and MFC) ?

Thanks,
Giovanni


From: Tom Serface on
Hi G,

I think what Joe is saying is that you can override the function to return
the right kind of pointer then you don't have to fool with it. That works,
of course, if you intend to use the list box only for one kind of pointer.
When I do this sort of thing I tend to make another structure that has a:

type
pointer to data

That way if I want to have more than one type of data (depending on the item
in the list box or list control or tree control) I can check the type before
casting. You could do this in the overridden functions and just have one
for each type you intend to return.

Tom

"Giovanni Dicanio" <giovanni.dicanio(a)invalid.it> wrote in message
news:uFpddJNNIHA.280(a)TK2MSFTNGP03.phx.gbl...
>
> "Joseph M. Newcomer" <newcomer(a)flounder.com> ha scritto nel messaggio
> news:9k64l3dgmr5dtfl3cc65t3s67lh2rjp48d(a)4ax.com...
>
>> It probably would have been better if these methods had been virtual, but
>> in the interest
>> of "efficiency" they are not.
>>
>> I see no reason to have stored it in a void *.
>
> Hi Joe,
>
> I may be missing something, but I think that using 'virtual' in this
> context would not be of important help.
>
> The problem here is the type of the return value. If you have a method
> declared as virtual, this does not help much.
>
> The help that virtual gives is when you want to use polymorphism and
> pointers, e.g.
>
> class Base
> {
> ...
> public:
> virtual void * GetSomething();
> };
>
> class Derived : public Base
> {
> ...
> public:
> virtual void * GetSomething();
> };
>
> And so if you have:
>
> Base * p = new Derived();
> p->GetSomething();
>
> then Derived::GetSomething() is called (and not Base::GetSomething).
>
> I think that using templates would have helped better (because the return
> type can be made a template type), but I see several problems when I try
> to mix templates and MFC... for example, for message maps.
>
> What do you think about this (templates and MFC) ?
>
> Thanks,
> Giovanni
>
>

From: Joseph M. Newcomer on
Yes, because typically when I use GetItemDataPtr, there is one unique type used for the
ItemData. If I need "many different types", then I will typically declare a superclass of
the types and derive the various subtypes from the superclass, and provide virtual methods
in the superclass to handle actions.

My comment about not having virtual methods, however, deals with the fact that under C++,
calling a function by the name of a superclass function only hides the superclass name, so
if you call via the superclass you get the superclass method, not the subclass method. It
would have been a lot nicer if they had been virtual methods.
joe

On Sun, 2 Dec 2007 14:54:28 -0800, "Tom Serface" <tom.nospam(a)camaswood.com> wrote:

>Hi G,
>
>I think what Joe is saying is that you can override the function to return
>the right kind of pointer then you don't have to fool with it. That works,
>of course, if you intend to use the list box only for one kind of pointer.
>When I do this sort of thing I tend to make another structure that has a:
>
>type
>pointer to data
>
>That way if I want to have more than one type of data (depending on the item
>in the list box or list control or tree control) I can check the type before
>casting. You could do this in the overridden functions and just have one
>for each type you intend to return.
>
>Tom
>
>"Giovanni Dicanio" <giovanni.dicanio(a)invalid.it> wrote in message
>news:uFpddJNNIHA.280(a)TK2MSFTNGP03.phx.gbl...
>>
>> "Joseph M. Newcomer" <newcomer(a)flounder.com> ha scritto nel messaggio
>> news:9k64l3dgmr5dtfl3cc65t3s67lh2rjp48d(a)4ax.com...
>>
>>> It probably would have been better if these methods had been virtual, but
>>> in the interest
>>> of "efficiency" they are not.
>>>
>>> I see no reason to have stored it in a void *.
>>
>> Hi Joe,
>>
>> I may be missing something, but I think that using 'virtual' in this
>> context would not be of important help.
>>
>> The problem here is the type of the return value. If you have a method
>> declared as virtual, this does not help much.
>>
>> The help that virtual gives is when you want to use polymorphism and
>> pointers, e.g.
>>
>> class Base
>> {
>> ...
>> public:
>> virtual void * GetSomething();
>> };
>>
>> class Derived : public Base
>> {
>> ...
>> public:
>> virtual void * GetSomething();
>> };
>>
>> And so if you have:
>>
>> Base * p = new Derived();
>> p->GetSomething();
>>
>> then Derived::GetSomething() is called (and not Base::GetSomething).
>>
>> I think that using templates would have helped better (because the return
>> type can be made a template type), but I see several problems when I try
>> to mix templates and MFC... for example, for message maps.
>>
>> What do you think about this (templates and MFC) ?
>>
>> Thanks,
>> Giovanni
>>
>>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Giovanni Dicanio on

"Tom Serface" <tom.nospam(a)camaswood.com> ha scritto nel messaggio
news:1FC8172A-016E-4F9E-959A-076933477866(a)microsoft.com...

> When I do this sort of thing I tend to make another structure that has a:
>
> type
> pointer to data
>
> That way if I want to have more than one type of data (depending on the
> item in the list box or list control or tree control) I can check the type
> before casting.

Hi Tom,

Thanks.

So you implement what seems to be like a "variant" (i.e. you put in a custom
structure the type ID and the [pointer to] data).

Yes, I used this design pattern sometimes.

However, I think that with templates, we could gain better type safety, and
less switch-based code ( switch( type ) { case Type_Int:...; case
Type_Double...} ).
e.g.:

template <typename T> // T = contained type
class ListBox< T >
{
...

T * GetItemDataPtr();
};

G