| View previous topic :: View next topic |
| Author |
Message |
masi Guest
|
Posted: Mon Feb 27, 2006 3:03 pm Post subject: SubClassing VirtualTreeView |
|
|
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
|
Posted: Mon Feb 27, 2006 6:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
| 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
|
Posted: Mon Feb 27, 2006 6:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
"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
|
Posted: Mon Feb 27, 2006 11:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
| 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
|
Posted: Tue Feb 28, 2006 8:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
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
|
Posted: Wed Mar 01, 2006 8:03 am Post subject: Re: SubClassing VirtualTreeView |
|
|
| 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
|
Posted: Wed Mar 01, 2006 10:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
"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
|
Posted: Thu Mar 02, 2006 10:03 am Post subject: Re: SubClassing VirtualTreeView |
|
|
| 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
|
Posted: Thu Mar 02, 2006 11:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
"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
|
Posted: Fri Mar 03, 2006 1:57 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
| 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
|
Posted: Fri Mar 03, 2006 6:03 pm Post subject: Re: SubClassing VirtualTreeView |
|
|
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 |
|
 |
|