C++Builder 5 Developers Guide
We've focused solely on creating packages for representing IDE extensions such as wizards, but a standard DLL can also be used to host IDE extensions. The DLL that you create must export a function initialization function called INITWIZARD0001 . An example implementation for this function is shown here.
extern "C" bool __stdcall __declspec(dllexport) INITWIZARD0001( const _di_IBorlandIDEServices services, TWizardRegisterProc RegisterProc, TWizardTerminateProc&) { LocalIDEServices = services; RegisterProc(new MemStatusWizard()); return true; }
The IDE looks for this function when it loads the DLL. So we can differentiate between a package and a DLL, the following code, shown in Listing 23.20, has been added to the wizard_memstatus.cpp source file.
Listing 23.20 Handling Builds Between Packages and DLLs
#ifndef DLL // it's a package namespace Wizard_memstatus { void __fastcall PACKAGE Register() { RegisterPackageWizard(new MemStatusWizard()); } } #endif #ifdef DLL // it's a dll extern "C" bool __stdcall __declspec(dllexport) INITWIZARD0001( const _di_IBorlandIDEServices services, TWizardRegisterProc RegisterProc, TWizardTerminateProc&) { LocalIDEServices = services; // found in ToolsAPIEx RegisterProc(new MemStatusWizard()); return true; } #endif
If we build a standard DLL, we no longer need the PACKAGE Register() function. To identify the type of build to be performed, the ToolsAPIEx.h file contains the following definition.
//#define DLL // enable this if building a DLL #ifdef DLL // we'll need this for building a DLL #define BorlandIDEServices LocalIDEServices extern _di_IBorlandIDEServices LocalIDEServices; #endif
Notice the #define DLL line commented out. If we remove the comment qualifier, and recompile and link our program, a DLL with a .bpl file extension will be produced for our wizard.
Next , the key is for the DLL to be identified in the Windows Registry with the IDE for the IDE extension to take affect. This is accomplished by adding an entry to the registry under the following key:
HKEY_CURRENT_USER\Software\Borland\C++Builder.0\Experts
Always use a unique name for the entry such as the ID string that was set using our wizard's GetIDString() method. Also, include the full path to the DLL for the value field. Figure 23.9 illustrates the entry made in the registry.
Figure 23.9. The Registry Editor.
The next time C++Builder launches, it will load the library files it encounters in the registry.
WHICH ONE ”PACKAGE OR DLL?
Most developers find that it's simpler to incorporate an IDE extension inside a package rather than a DLL. Furthermore, it is easier to reload design-time packages rather than DLLS when you're developing your extension because you can see your results immediately (no need to close and reopen the IDE). However, the one drawback with packages is that unit name and form name clashes are more susceptible than a DLL implementation. Therefore, one recommendation is to port your code into a DLL for final delivery when you're happy with your IDE extension. Keep in mind that the DLL should always be built with the VCL runtime package if it uses any of the Native Tool API interfaces. |
|
Top |