views:

808

answers:

3

We're trying to convert a piece of C++ code written in MFC which uses the CWnd.SubclassWindow method, into Borland C++ Builder code. Does anyone know how to do subclassing (subclass with a TForm object) - we're completely stuck. Any pointers will be much appreciated! TIA!

Specifics:

We have an existing base class written in Borland C++ which inherits from TForm, which is used to give all forms that inherits from it a certain look and feel (it processes WM_NCPAINT and WM_NCHITTESTheavily, for example).

Now we'd like to use this code to give forms written in other languages (MSVC++/MFC and C# to be exact) the same look and feel.

Instead of rewriting all the code we thought that using windows subclassing would be a great idea. Then we could stuff all the existing and tested code into a DLL and then just call it with a hWnd and that window would automagically get the new look and feel.

Exactly why this is so impossible is really not up to me to say - I don't code in Borland C++ myself. I wrote a stub in MFC in just a few minutes to show the Borland C++ developers what I wanted and they have spent days trying to mimic the MFC CWnd::SubclassWindow method without success.

From what I understand, the problem is that when you do a "new TForm()", then a new window is automatically created before you have any chance to stop it. So replacing then WindowProc works BUT an unwanted TForm window is floating around on the screen to no use!!!!

+1  A: 

I'll assume you mean VCL. You can set the WindowProc property of a TControl object to your own window procedure or another control's WindowProc.

EDIT: More answer, based on more specifics

To prevent new TForm from creating a window to float uselessly around the screen, you should just need to set its Visible property to false. Alternatively, you could override CreateParams to remove the WS_VISIBLE style from the window:

void __fastcall TBlahForm::CreateParams(TCreateParams &Params)
{
    TForm::CreateParams(Params);
    Params.Style&=~WS_VISIBLE;
}
//---------------------------------------------------------------------------

There'll still be an invisible window getting created, but as I understand the use case, this shouldn't be a big deal.

Overriding TCustomForm::CreateWnd is potentially another way of attacking the same problem.

My other suggestion would be to just port the code from BCB to VC++. If it's doing lots of mucking around with WM_NCPAINT and WM_NCHITTEST then it sounds an unlikely candidate to have lots of VCL-specific stuff in it - it's probably just banging straight on the Win32 API? If there's nothing VCL in there, compiling in VC++ should pretty much just magically work.

In any event: it's almost certainly possible. I have an app built with BCB5 (which predates WinXP) that through clever use of window hooks, subclassing and the like (most of which isn't my own) is still perfectly happy dealing with XP and even Aero (which isn't to say it isn't a pain to maintain). If that's possible, your application certainly should be. VCL follows a different paradigm to MFC, but it's nonetheless flexible.

Jon Bright
I couldn't stuff my answer into the 300 characters of a comment, so I edited the original question instead!
danbystrom
Thank you very much for your answer!!! However, I've looked at the code and recompiling to MSVC++ was the thing I really wanted to avoid. Among other things, it has nearly 100 small bitmap resources which I'm afraid I have to add manually one by one. *sigh*
danbystrom
+1  A: 

Have a look at the Codegear Online Docs, which describes the WindowProc mechanism for subclassing.

C++Builder uses the underlying Delphi VCL, so searching for "Delphi Window subclassing" will be more fruitful than trying to find something specifically C++. C++Builder programmers have to at least be capable of reading Delphi code, even if they don't have to write any!

Roddy
Looking for Delphi examples sound a great idea, thanks! :-)(The example you sent me is not applicable I'm afraid, since I want to subcalss a window that has already been created by another application, albeit in the same process).
danbystrom
A: 

I rewrote the whole thing into MFC code. Took a few days, but now it is working. sigh

danbystrom