BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

SubClassing VirtualTreeView

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage)
View previous topic :: View next topic  
Author Message
masi
Guest





PostPosted: Mon Feb 27, 2006 3:03 pm    Post subject: SubClassing VirtualTreeView Reply with quote



A question about using Virtual TreeView with BCB6 or BCB2006:

If I try to subclass TVirtualStringTree I get the following error:

[Linker Error] Unresolved external '__fastcall
Virtualtrees::TBaseVirtualTree::DoGetHeaderCursor(void *&)' referenced from
MyVirtualStringTree.obj

No problem if I put a TVirtualStringTree object on a form, but what I'd like
is to have a component which is a subclass of TVirtualStringTree. What's
wrong?

thanks
masi urbano
Back to top
masi
Guest





PostPosted: Mon Feb 27, 2006 6:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote



Quote:

To get terms correct "subclassing" means you take control of a windowed
control's message handling function and process certain messages before
the
class can. What you are doing is descending a class from
TVirtualStringTree.


Yes, I wanted to mean that. Thanks.

Quote:
The problem you are encountering is a BCB compiler bug that does not
create the
correct mangled function name compared to what the Delphi compiler does.
I
thought Borland had fixed this for BDS but apparently they have not.

Add the following line to your C++ code (note, this is all one line).

#pragma alias "@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrpv" =
"@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrui"


Many thanks again

masi urbano
Back to top
Clayton Arends
Guest





PostPosted: Mon Feb 27, 2006 6:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote



"masi" <masiurb (AT) tin (DOT) it> wrote in message
news:440308b6$1 (AT) newsgroups (DOT) borland.com...

Quote:
If I try to subclass TVirtualStringTree I get the following error:

To get terms correct "subclassing" means you take control of a windowed
control's message handling function and process certain messages before the
class can. What you are doing is descending a class from
TVirtualStringTree.

The problem you are encountering is a BCB compiler bug that does not create
the
correct mangled function name compared to what the Delphi compiler does. I
thought Borland had fixed this for BDS but apparently they have not.

Add the following line to your C++ code (note, this is all one line).

#pragma alias "@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrpv" =
"@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrui"

HTH,
- Clayton
Back to top
masi
Guest





PostPosted: Mon Feb 27, 2006 11:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Quote:
Add the following line to your C++ code (note, this is all one line).

#pragma alias "@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrpv" =
"@Virtualtrees@TBaseVirtualTree@DoGetHeaderCursor$qqrrui"

Ok, it works fine on bcb6

But on BCB2006 I still got:

[Linker Error] Error: Unresolved external '__fastcall
Virtualtrees::TBaseVirtualTree::OriginalWMNCPaint(void *)' referenced from
......MYVIRTUALTREE.OBJ

any idea?
Back to top
Clayton Arends
Guest





PostPosted: Tue Feb 28, 2006 8:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Apparently I had "fixed" this problem before by simply removing the virtual
from the declaration since it was never used as a virtual anywhere.

The real fix is to use the same #prama line but replace DoGetHeaderCursor
with OriginalWMNCPaint. The mangling should be the same (I will check on
that later if it doesn't work for you).

- Clayton
Back to top
masi
Guest





PostPosted: Wed Mar 01, 2006 8:03 am    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Quote:
Apparently I had "fixed" this problem before by simply removing the
virtual from the declaration since it was never used as a virtual
anywhere.

Which declaration?

Quote:
The real fix is to use the same #prama line but replace DoGetHeaderCursor
with OriginalWMNCPaint. The mangling should be the same (I will check on
that later if it doesn't work for you).

No, it doesn't work with BCB2006: I got the same error

[Linker Error] Error: Unresolved external '__fastcall
Virtualtrees::TBaseVirtualTree::OriginalWMNCPaint(void *)' referenced from
......MYVIRTUALTREE.OBJ

many thanks for your help.

masi urbano
Back to top
Clayton Arends
Guest





PostPosted: Wed Mar 01, 2006 10:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

"masi" <masiurb (AT) tin (DOT) it> wrote in message
news:4405483a$1 (AT) newsgroups (DOT) borland.com...

Quote:
Which declaration?

In VirtualTrees.pas:

procedure OriginalWMNCPaint(DC: HDC); virtual;

All I had done long ago was to remove the virtual. This wasn't really the
best solution since it requires a source change. It's of no consequence
though since the correct solution is below.

Quote:
No, it doesn't work with BCB2006: I got the same error

Try this:

#pragma alias "@Virtualtrees@TBaseVirtualTree@OriginalWMNCPaint$qqrpv" =
"@Virtualtrees@TBaseVirtualTree@OriginalWMNCPaint$qqrui"

Again, this is all on one line.

- Clayton
Back to top
masi
Guest





PostPosted: Thu Mar 02, 2006 10:03 am    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Quote:
Try this:

#pragma alias "@Virtualtrees@TBaseVirtualTree@OriginalWMNCPaint$qqrpv" =
"@Virtualtrees@TBaseVirtualTree@OriginalWMNCPaint$qqrui"


it's magic for me, but it works fine!

thanks you very much

masi urbano
Back to top
Clayton Arends
Guest





PostPosted: Thu Mar 02, 2006 11:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

"masi" <masiurb (AT) tin (DOT) it> wrote in message
news:4406b803$1 (AT) newsgroups (DOT) borland.com...

Quote:
it's magic for me, but it works fine!

It does appear that way at first. Here is a breakdown (though probably not
entirely accurate since I don't know all of the inner workings of the
compiler/linker).

Compilers that support classes and same-name functions must create a name
mangled function name to tell two functions apart from one another. They do
this by taking the names of the parameters in the function and tacking them
in some obscure format to the end of the function name. In practice though
the compiler can make any name it wants as long as the same name is always
created for a particular reference.

Here is an example of how BCB and Delphi do things. TVirtualStringTree
exists in the "Virtualtrees" namespace. Here is the fully qualified name of
the method:

// C++
Virtualtrees::TVirtualStringTree::OriginalWMNCPaint(HDC)

// Object Pascal (Delphi)
Virtualtrees.TVirtualStringTree.OriginalWMNCPaint(HDC)

The problem stems from how the two compilers mangle names. Delphi treats
the HDC type (and all other Windows handles) as "unsigned integer" while BCB
treats the HDC type as "pointer to void". Following is the name mangled
version of the above method:

// C++
@Virtualtrees@TVirtualStringTree@OriginalWMNCPaint$qqrpv

// Delphi
@Virtualtrees@TVirtualStringTree@OriginalWMNCPaint$qqrui

Notice the difference "pv" (pointer to void) and "ui" (unsigned integer).

"#pragma alias" tells the compiler that any references to the name on the
left should really look like the name on the right. So, given the pragma
that I gave you before it converts all references to the C++ mangled name to
the real mangled name compiled by Delphi.

One way to know the mangled name would be to memorize it. However, I have
precious space left in my brain so I choose to determine the mangled name
using tools at my disposal. First I find the function that the C++ linker
cannot find in the PAS source. I then lookup that function name in the
corresponding BPL using Dependency Walker. If I can't find the BPL I create
a dummy PAS file and recreate the function. Then I make a C++ version of
the function and export it using the PACKAGE keyword in some test project.
I compile into an EXE and look up the mangled name using DW. Once I know
the two mangled names I can then make the #pragma.

It is very rare that I have to do this but it is a good trick to know when
the problem crops up.

- Clayton
Back to top
masi
Guest





PostPosted: Fri Mar 03, 2006 1:57 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Quote:
// C++
Virtualtrees::TVirtualStringTree::OriginalWMNCPaint(HDC)

// Object Pascal (Delphi)
Virtualtrees.TVirtualStringTree.OriginalWMNCPaint(HDC)

The problem stems from how the two compilers mangle names. Delphi treats
the HDC type (and all other Windows handles) as "unsigned integer" while
BCB treats the HDC type as "pointer to void". Following is the name
mangled version of the above method:

// C++
@Virtualtrees@TVirtualStringTree@OriginalWMNCPaint$qqrpv

// Delphi
@Virtualtrees@TVirtualStringTree@OriginalWMNCPaint$qqrui

Notice the difference "pv" (pointer to void) and "ui" (unsigned integer).

"#pragma alias" tells the compiler that any references to the name on the
left should really look like the name on the right.

It is very rare ...

But it happens sistematically everytime a virtual function has HDC, CURSOR,
etc. parameters, doesn't it?

Many thanks for your help and I appreciated much your explanation.

masi urbano
Back to top
Clayton Arends
Guest





PostPosted: Fri Mar 03, 2006 6:03 pm    Post subject: Re: SubClassing VirtualTreeView Reply with quote

Perhaps "very rare" isn't a correct assessment <g>. It happens more often
for component writing than it does for application development. But anyhow,
I'm glad the information was useful to you.

Good luck,

- Clayton
Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (VCL Components Usage) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.