|Delphi Clinic||C++Builder Gate||Training & Consultancy||Delphi Notes Weblog||Dr.Bob's Webshop|
The catch-up game
Remember how Borland claimed that the Delphi-envy was over with the release of Borland C++Builder version 1? Guess what happened when Delphi 3 came out...
Last January 13, Bob Swart and I visited a Press Conference in Amsterdam hosted by Martin Pamdeth. What we saw superficially looked exactly like Delphi 3 but actually was C++Builder 3. Again, the Delphi envy is over.
The project manager
C++Builder now sports a project manager that allows you to insert multiple projects into a project group. That's a difference from Delphi 3. However, compared to the project manager included in de Borland C++ IDE, it is a toy. It's useful, but it is a toy. The project manager for example does not know the concept of source pools and not all compiler options can be set from the interface. Besides that, you cannot set options on a per file basis. Packages
C++Builder now can handle packages. The mechanics are the same as in Delphi 3. However, you cannot use Delphi 3 packages directly in C++Builder, which makes it a bit less useable alas. In order to have the same package available in Delphi 3 as well as C++Builder, you have to rebuild the package with the C++Builder DCC32 compiler and then install the package. ActiveX
As for ActiveX, this is part of the catch-up game. C++Builder now has the same functionality as Delphi 3, including ActiveForms.
The basic difference here is that there are more options to set. As in Delphi 3, you can set version information. Different is the fact that C++Builder includes TASM, for which you can set options and a tab that lets you set advanced compiler options.
As in C++Builder version 1 and Borland C++ 5, we have an incremental linker. It sports the necessary options for linking packages. Some options previously supported in the linker are unsupported in C++Builder 3.
You now can debug an executable without having a project open, and you may start a debugging session from the command line using the -d switch. C++Builder also sports a module view that lets you look into various interesting details about the executable under scrutiny, for example the sources of which it consists, provided you have an executable with debugging information in it. Besides that, C++Builder also can show you an event log which shows you process control messages, breakpoint messages, OutputDebugString contents and Windows messages. It adds data watch breakpoints, lets you inspect local variables and you can set debugging options for all new projects.
One enhancement we sorely miss is a view of coprocessor registers in the debugging view. Component templates
Another productivity enhancement is the possibility to save a group of components and their relative positions as a template. If you want to reuse the layout, just place the template in your form and Presto, you're done.
C++ language extensions
The standard C++ library
The C++ standardisation process will be completed coming August if everything goes according to plan. Then a five-year cooling down period will commence. The standard includes a standard runtime library and a large set of data structures and algorithms formerly known as the standard template library. Borland licenses the Rogue Wave implementation of the standard C++ library version 2. Exactly to which draft working paper it adheres is uncertain, but I can say from the looks of it that it is a pretty recent draft.
C++Builder also sports some implementation-specific enhancements. The most important one is dynamic functions that are needed to mimic Delphi dynamic functions. Dynamic functions can only be used in classes that derive from TObject. If you do not adhere to that rule, the compiler will notify you with a syntax error. The 'dynamic' attribute is inherited, and dynamic functions cannot be overloaded. Pragma's
Also, the compiler understands a couple of new pragma's. The package pragma is used for initialising packages in the right order given their priority. Furthermore, the compiler understands how to push and pop option sets, which is quite useful.
C++Builder 1 used to instantiate all out-of-inline template methods. C++Builder 3 only does that for those methods actually used and the virtual methods of the instance of the template. This can significantly reduce you code size. If you explicitly instantiate a template, all methods are instantiated. You can use the template instantiation syntax for that. You also can revert to version 1 behaviour with the -Ja switch.
The compiler now understands a finally construct a la Delphi, however, you cannot combine a __finally construct with catch constructs. You have to use an extra try block to do that.
Basically, the VCL enhancements mean that C++Builder's VCL is up to date with Delphi 3's VCL.
There are a couple of enhancements to the database component. One of them is the DBE-independent datasets. If implemented correctly, you even can have some sort of long-term transactions by using the briefcase model. Instead of licensing it from a third party Borland includes its own implementation of the SQL Builder. Other than that, it's the catch-up game again, including even the Decision Cube.
Batch file projects
This is kind of a funny thing, but it allows you to code and run batch files. However, some commands cannot be used if you run it from C++Builder directly.
C++Builder now sports a console wizard that lets you specify a couple of options such as whether the console application is a console or GUI application, whether it is a DLL or executable and whether you want to include the VCL or not.
Importing resource scripts
You can use the resource import tool to import .RC files. There are some gotchas, and what you will need to do yourself is to replicate any functionality behind the dialogs and menus in the resource file. However, it is a good starting point for recreating OWL applications in C++Builder.
What's going to happen to Borland C++?
The message in the press presentation held in Amsterdam was that the Borland C++ line has ended. What then for those of us that wish to maintain our 16-bit stuff? Well, Borland C++ will be packaged with C++Builder so you still can use that as the tool for those kinds of applications.
Interoperability with Delphi
As I mentioned earlier, Delphi packages cannot be installed in C++Builder, which is a great loss for those people that have purchased Delphi packages in binary form. Borland, if you're listening, please please please make it possible to use binary Delphi packages in C++Builder, please. Really! Right now, your only option is to use DCC32 to recompile a package in source form for C++Builder and install the result.
Be careful if you want to use resource strings in Delphi units. C++Builder uses a macro to get at them, but the resulting macro can hide your own macros if they have the same name. You can use the -Sd switch to see the result of macro expansion to spot trouble if you have it.
Actually, C++Builder 3 has a little bit of influence on Delphi too. The Pascal compiler now supports default arguments to allow better interoperability with C++. Those default arguments can be used to translate two different constructors in Delphi into two C++ constructors with different argument lists in C++.
DELPHICLASS and DELPHIRETURN macros
If you used the above macros in C++Builder version 1, your code will work as expected. However, if you used __declspec instead, you must replace __declspec(delphiclass) with __declspec(delphiclass,package) and __declspec(delphireturn) with __declspec(delphireturn,package)
Upgrading from C++Builder 1
Changes in extensions
You must change the .mak extension of C++Builder 1 projects into the .bpr extension
If you are using OLE automation components, include OLE2.OBJ in your project. It is no longer included in VCL.LIB
The Win95 palette page is now the Win32 palette page, the OCX page is now ActiveX page and a number of controls that used to be in the System page are now in the Win3.1 page.
The typeinfo class is renamed into type_info, and you also should include <except.h>
The xmsg class
If you derive from the xmsg class, add throw() to the constructor of your class.
A number of functions are changed, for instance the arguments and return type of set_terminate.
TDataSet used to encapsulate the BDE. This is no longer the case, so if you want to use BDE, change TDataSet to TBDEDataSet. Some methods and properties are removes from the old TDataSet to yield the new one. Also, a number of objects have been moved from the DB unit to the DBTables unit.
OnExpanded, OnExpanding, OnCollapsed and OnCollapsing are now occurring in all parent nodes regardless of their expansion state.
TForm is split into a TCustomForm base class and its derivative TForm. The GetParentForm method now returns a TCustomForm, and GetChildren has an additional parameter to specify the form that must be searched.
C++Builder includes wrapper classes to create ActiveX controls from components. Old classes are for backward compatibility.
Quick Reports are converted, however the conversion has some limitations.
InitGraphics is no longer required and is removed from the unit.
EInvalidOperation and EOutOfResources are moved from controls.hpp to classes.hpp
The PropType field now is of type PPTypeInfo instead of PTypeInfo.
OLE2.hpp and OLEauto.hpp
These headers are for backward compatibility only. Do not use in new projects.
Some linker options have disappeared. Linking will proceed without warnings, however, the effect of the options is none. Also, -Oc and -OS have no effect in C++Builder 3 linking
Upgrading from Borland C++
No 16bit or DOS programs
C++Builder 3 cannot compile 16 bit executables or DOS executables. Objects and libraries compiled with Borland C++ 5.01 or earlier must be recompiled with a later Borland C++ compiler or with C++Builder 3 before they can be linked.
Converting .ide files
Project files that have the IDE extension created by Borland C++ 4.0 or later can be converted to BPR files with the idetobpr utility. If a source file exists with the same name as the ide-ifile, it will be embellished with the necessary information for the project manager to load the project. If you do not use the -v switch, references will be made to VCL enabled versions of libraries of OWL, BIDS, VCL, RTL and MFC. Otherwise, only MFC and VCL are updated to their latest names and _NO_VCL is added to the list of macros.
Any use of $ENV(BCROOT) in include and library paths are changed to $(BCB) Conclusion
This new version is definitely worth the upgrade from Borland C++ or C++Builder 1.0. One of the major improvements is a more recent C++ standard library. Besides that, there is a better interoperability between Delphi 3 and C++Builder 3, although not being able to use binary Delphi 3 packages is a big booboo. The compiler is still considerably slower than Delphi, but that is more a language issue than a compiler issue. However, the combination of Delphi 3 and C++Builder 3 allows you to combine the greater possibilities of C++ with the quick turnaround times of Delphi. All in all, my conclusion is that these two really belong together like Ebony and Ivory. So go to your local software vendor and get your upgrade. Presto!
I could not resist adding a wish list to this article. Borland, here I come. Please beef up the project manager to something similar in functionality to Borland C++. Next thing, add the coprocessor registers in de debugging view. Next, license a beefed up version of the standard C++ library that includes a streaming possibility like Borland C++ did. You might want to talk to RogueWave about it, or ObjectSpace for all I care. And last but not least, integrate Delphi and C++Builder in a proper way. As far as I am concerned, you might want to integrate the two products into one.