The IDE provides two-way development by integrating a graphical Form Designer and a text-oriented Source Code Editor, enabling you to develop applications from two angles. Using the ClassExplorer , Code Insight, and standard features of the Form Designer, C++Builder can even generate quite a bit of code!
You can use C++Builder to develop applications of many types, including those in the following list:
Windows or console applications
Client/server applications
Dynamic link libraries (DLLs)
Custom components and Packages
Component Object Model (COM) and ActiveX controls
All these applications are created using projects. A project is a collection of C++ source files, form files, and other file types that together define the application. C++Builder uses a special project file to store the structure of the project and to remember various project options that change the way the application is built.
C++Builder projects consist of many different types of files. C++Builder creates some files automatically; when a new project is started or when new items are added to an existing project, for instance. The developer creates other files, and there are still other files that are created when the application is compiled. Project files, no matter how they are created, can be categorized as follows :
Main project files
Form files
Package files
The desktop layout file
Backup files
When you create most projects, three main files are automatically created. They are shown in the following list:
C++Builder project file ProjectName .bpr
Main project source file ProjectName .cpp
Main project resource file ProjectName .res
The files are initially created internally for you to start using. The files will not be created on disk until you save the project.
By default your project is named Project1 . You can change the name of the project when you first save it by renaming the Project1.bpr file in the Save Project As dialog that appears. You should be careful naming the various files in your project. It's a good idea to name each form file the name of the form followed by Unit or Module (for instance, Form1Unit.cpp ).
The project file is a text file that contains the project options settings and the rules to build the project. This file has changed somewhat through the different versions of C++Builder. In C++Builder 1 through 4, the file was in a Makefile format. In C++Builder 1 the project file actually had the extension .mak to signify this. In C++Builder 5 the file changed to the Extensible Markup Language (XML) format.
This file contains the application entry (startup) code, and little else. C++Builder automatically maintains the file throughout development.
In a standard Windows application, the main project source file contains the WinMain() function as the application entry point. In other types of applications, this function might be named DllEntryPoint() or simply main() . Unlike most other auto-generated source files, this file has no corresponding header ( .h ) file. You'll seldom need to change the main project source file except to execute a function as the application starts, such as displaying a splash screen while the application is initializing.
NOTE
The IDE will regenerate this function when you add, remove, or reorder the forms in your project. Any code you change within the WinMain function will be removed, so be prepared to replace it.
In a VCL or non-VCL console application, this function is the standard main() function, and it will not be changed by C++Builder, so you can add your own code as needed.
This file contains the application's icon, the application version number, and other information. Not all application types have a project resource file.
Resource files in general store images, icons, and cursors for your project. To create these items, you typically use a tool such as the Image Editor provided by C++Builder. Resource files can also contain strings and other objects. For a more in-depth look at storing images in a resource file, see "Using Predefined Images in Custom Property and Component Editors" in Chapter 5, "Creating Property and Component Editors."
For each Form you create, C++Builder generates the following files:
The Form layout file UnitName .dfm
The Form source file UnitName .cpp
The Form header file UnitName .h
By default the unit name is Unit1 for the first Form created, Unit2 for the second, and so on. You can rename the Form files when saving the project. The extension .dfm stands for Delphi Form, a reminder that C++Builder is based partially on Borland's Delphi product. The .dfm file contains values that represent the graphical part of the Form, such as component locations, font styles, and so on.
In C++Builder versions 1 through 4, the .dfm file is saved in a binary format. It can be viewed as text in these versions by right-clicking the Form, and then selecting View As Text. In C++Builder 5, the .dfm file is saved in a text format by default, but it can be saved in binary format if required. For more information see the "FormsSave As Text" section in this chapter. You can edit the .dfm Form files if you want, but you rarely need to do so.
The .cpp file and its associated .h header file are created with the .dfm file each time you create a new Form. The .h file contains the C++ class definition for the Form. The .cpp file contains the event handler functions for the Form and for the components that you add to the Form. In simple applications, most of the code that you write will be placed in the Form's .cpp file.
To view the .cpp and .h files, do the following:
If your project is not open, select File, Open .
Select View, Units, and then choose the unit file of your Form and click OK or press Enter. The .cpp file for the Form will be displayed in the Code Editor.
To view the header file, right-click in the Form's .cpp file displayed in the Code Editor and choose Open Source/Header File, or click the tab for the .h file at the bottom of the editor window.
NOTE
Everything mentioned previously for Form files is also true for the DataModule forms that are used to contain nonvisual components. Those are discussed in Chapter 7, " Database Programming."
Packages are simply dynamic link libraries (DLLs) that can be shared among many C++Builder applications. They enable you to share classes, components, and data between applications. For example, the most frequently used C++Builder components reside in a Package called VCL. Most applications created in C++Builder share some common code from this package, provided in the Package file vcl60.bpl .
When you create your own components or libraries, you will need to create a package project.
The following are specific Package files:
The Package Project Options ( .bpk ) file.
Consider this file to be like a .bpr project file, but applicable only for packages. This file is created if you choose File New Package from the IDE menu.
The Borland Package Library ( .bpl ) file.
This is the runtime library generated by C++Builder for the package. It is like a DLL, except that it contains C++Builder-specific features. Its base name matches the Package source base name.
The Borland Package Import Library ( .bpi ) file.
Each time you compile the package source file, a .bpi file will be created. Again, its base name matches the package source base name.
The window layout for a project stores the arrangement of the various windows open in the IDE and the files open in the Source Code Editor. The next time the project is opened, these settings will be restored.
The Desktop options used to be stored in a file whose name had the format ProjectName .dsk and in the same folder as the project. As of C++Builder 6, these values are stored in the project file.
The IDE can be set to save the layout automatically when you close the project. From the menu, select Tools, Environment Options. This will take you to the Environment Options dialog. Select the Preferences tab and check AutoSave Options, Project Desktop.
C++Builder will create a backup file for each of your project's .bpr , .dfm , .cpp , and .h files each time you save your project, except for the first save. All backup file extensions are prefixed with the ~ symbol; thus, the .bpr file extension will become .~bp , .cpp will become .~cp , and so on.
The Project Manager displays the file structure of a project or project group . The Project Manager can be viewed by selecting View, Project Manager from the C++Builder menu. Figure 2.11 shows an example of the Project Manager window.
A project group is a collection of projects. Sometimes you need to create more than one project for an application. For example, an application could have a VCL project, a DLL project, and a console project. The information about the project group is stored in a project group file in the same folder as the project. It has the filename ProjectName .bpg .
The following are many of the things you can do in the project Manager:
Create a project group to hold one or more projects.
Add or remove projects in a project group.
Add or remove units from a project.
Reorder projects within a project group or units within a project using drag and drop.
Select a project for further operations.
Compile or build one or more of your projects.
Most of the operations (except for those using drag and drop) can be done using pop-up menus associated with the project group, project, or unit.
C++Builder offers a wide variety of options for you to use in controlling the build of your application. Those options generally apply to the project as a whole and are set at that level using the Project, Options menu entry, or Options from the project manager window pop-up for each project in a project group.
These options include a variety of important elements such as the interpretation of C++ language statements as pure ANSI or allowing VCL or MFC extensions; controlling the default data structure element alignment (default is quad word, but a particular program might require byte or word alignment); or what will happen to stack data when an exception is thrown.
You might want to have these settings be different in some compilation units. For instance, you might want some platform independent sections of the code to be compiled as pure ANSI, whereas a user interface should be able to use the VCL.
In many cases, you can and should deal with these option differences by creating and linking separate packages, each with their own options.
But in other cases, you might be able to restrict these option changes to a single or small number of compilation units, with the rest of the project using a standard set of options. This can be done fairly easily by clicking the compilation unit and picking Local Options from its pop-up menu. The resulting dialog offers a variety of options that are generally a subset of the options available for the project (for instance, linker options are not available for compilation units, but are available for the entire project).
Options for C++ units include language options, compiler options, directory search paths for include files, output paths for object files, and many others.
Not all units have local options. Delphi units, for example, do not enable you to override the Pascal options set for the project.
You might not only want to set specific project options for a compilation unit, but you might want a specific build tool as well (for instance, another compiler) for a specific compilation unit. C++ Builder allows this for some types of compilation units.
Tools, Build Tools enables you to create a new entry in the list of build tools and to associate that tool with one or more file extensions. Figure 2.12 shows the dialog to edit or add a tool.
Editing an existing tool such as the CCompiler or Preprocessor produces the dialog in Figure 2.13:
This dialog enables you to identify a variety of important elements that control the use of your build tool.
For instance, you can specify the file extensions this tool should automatically be applied to at build or make time (Default Extensions). You can specify the file extensions for which the tool will be available in the Program Manager pop-up menu. The final extension you can specify is the extension of the output from the tool. Although the documentation is silent on this, it is possible that a match of target extension to default extension is used to help order the sequence of executing the tools.
Command Line specifies the command line that will be executed when the time comes to use the tool in the build sequence. A variety of build macros can be supplied to the command line, which expands as follows:
$DEFINE any Project Options level #defines in effect.
$EXT The extension of the current file.
$INCLUDEPATH The directory path for #include files, drawn from the project or local options.
$NAME The name and extension of the current file.
$PATH The directory where the file exists.
$TARGETNAME The name of the target to be produced (usually the same as $NAME without the extension; can be used by the tool to help produce target files).
You can create your own command-line tool quite easily. For instance, the simple program (a VCL console application) in Listing 2.2 is the one shown running in Figure 2.14. It displays its command line (captured by the IDE and displayed in the message window), which includes expanded versions of the previous macros. Here is the command line from the Build Tool dialog:
F:\Mark\Development\CBuilder6\CommandLineTool\MacroLineTool $NAME $EXT $PATH $INCLUDEPATH $DEFINE $SAVE $TARGETNAME $LOCALCOMMAND
// - #include <vcl.h> #pragma hdrstop #include <iostream> // - #pragma argsused int main(int argc, char* argv[]) { for (int Index = 0; Index < argc; Index++) { std::cout << argv[Index] << "\n"; }; return 0; } // -
Obviously, you might get such a tool from a tool vendor, as well as writing one yourself. What kind of things could these tools do? Well, they could produce documentation, generate code, update program information databases, upload the latest build to the deployment machine, anything you can imagine. Build tools are not limited to processing source codethey can process .obj files, or .res files, or anything else you need.
The make process uses the interdependencies between compilation units to decide what to compile first, what to compile next and what to compile last. In the normal course of events, you don't really care how the make process decides to compile a project, as long as it makes sense. When you have a problem with a specific unit, you can simply compile it by itself.
But sometimes it makes sense to have infrequently changing modules compile following those that change frequently, which can shorten make times.
Top |