RAD Studio |  |

Extending the IDE
Collapse All
Topics

Name | Description
Adding an Action to the Action List | The image index obtained in Adding an image to the image list is used to create an action, as shown below. The wizard uses the OnExecute and OnUpdate events. A common scenario is for a wizard to use the OnUpdate event to enable or disable the action. Be sure the OnUpdate event returns quickly, or the user will notice that the IDE becomes sluggish after loading your wizard. The action's OnExecute event is similar to the wizard's Execute method. If you are using a menu item to invoke a form or project wizard, you might even want to have OnExecute... more
Adding an Image to the Image List | Suppose you want to add a menu item to invoke your wizard. You also want to enable the user to add a toolbar button that invokes the wizard. The first step is to add an image to the IDE's image list. The index of your image can then be used for the action, which in turn is used by the menu item and toolbar button. Create a resource file that contains a 16 by 16 bitmap resource. Add the following code to your wizard's constructor:
Creating Forms and Projects | Delphi comes with a number of form and project wizards already installed, and you can write your own. The Object Repository lets you create static templates that can be used in a project, but a wizard offers much more power because it is dynamic. The wizard can prompt the user and create different kinds of files depending on the user's responses. A form or project wizard typically creates one or more new files. Instead of real files, however, it is best to create unnamed, unsaved modules. When the user saves them, the IDE prompts the user for a file name.... more
Debugging a Wizard | The Tools API provides you with a lot of flexibility in how your wizard interacts with the IDE. With the flexibility comes responsibility, however. It is easy to wind up with dangling pointers or other access violations. When writing wizards that use the native tools API, you can write code that causes the IDE to crash. It is also possible that you write a wizard that installs but does not act the way you want it to. One of the challenges of working with design-time code is debugging. It's an easy problem to solve, however. Because the wizard is installed... more
Deleting Toolbar Buttons | There is no convenient function for removing a button from a toolbar; you must send the CM_CONTROLCHANGE message, where the first parameter is the control to change, and the second parameter is zero to remove it or non-zero to add it to the toolbar. After removing the toolbar buttons, the destructor deletes the action and menu item. Deleting these items automatically removes them from the IDE's ActionList and MainMenu.
Extending the IDE | You can extend and customize the IDE with your own menu items, tool bar buttons, dynamic form-creation wizards, and more, using the Open Tools API (often shortened to just Tools API). The Tools API is a suite of over 100 interfaces that interact with and control the IDE, including the main menu, the tool bars, the main action list and image list, the source editor's internal buffers, keyboard macros and bindings, forms and their components in the form editor, the debugger and the process being debugged, code completion, the message view, and the To-Do list. Using the Tools API is... more
Implementing the Wizard Interfaces | Every wizard class must implement at least IOTAWizard, which requires implementing its ancestors, too: IOTANotifier and IInterface. Form and project wizards must implement all their ancestor interfaces, namely, IOTARepositoryWizard, IOTAWizard, IOTANotifier, and IInterface. For C++, to use NotifierObject as a base class you must use multiple inheritance. Your wizard class must inherit from NotifierObject and from the wizard interfaces that you need to implement, such as IOTAWizard. Because IOTAWizard inherits from IOTANotifier and IInterface, there is an ambiguity in the derived class: functions such as AddRef() are declared in every branch of the ancestral... more
Installing the Wizard Package | As with any other design-time package, a wizard package must have a Register function. (See Registering components for details about the Register function.) In the Register function, you can register any number of wizards by calling RegisterPackageWizard, and passing a wizard object as the sole argument, as shown below:
Interface Version Numbers | If you look closely at the declarations of some of the interfaces, such as IOTAMessageServices, you will see that they inherit from other interfaces with similar names, such as IOTAMessageServices50, which inherits from IOTAMessageServices40. This use of version numbers helps insulate your code from changes between releases of Delphi. The Tools API follows the basic principle of COM, namely, that an interface and its GUID never change. If a new release adds features to an interface, the Tools API declares a new interface that inherits from the old one. The GUID remains the same, attached to the... more
Notifying a Wizard of IDE Events | An important aspect of writing a well-behaved wizard is to have the wizard respond to IDE events. In particular, any wizard that keeps track of module interfaces must know when the user closes the module, so the wizard can release the interface. To do this, the wizard needs a notifier, which means you must write a notifier class. All notifier classes implement one or more notifier interfaces. The notifier interfaces define callback methods; the wizard registers a notifier object with the Tools API, and the IDE calls back to the notifier when something important happens. Every notifier interface inherits from... more
Obtaining Tools API Services | To do anything useful, a wizard needs access to the IDE: its editors, windows, menus, and so on. This is the role of the service interfaces. The Tools API includes many services, such as action services to perform file actions, editor services to access the source code editor, debugger services to access the debugger, and so on. The following table summarizes all the service interfaces. Tools API service interfaces
Overview of the Tools API | All of the Tools API declarations reside in a single unit, ToolsAPI. To use the Tools API, you typically use the designide package, which means you must build your Tools API add-in as a design-time package or as a DLL that uses runtime packages. For information about package and library issues, see Installing the wizard package. The main interface for writing a Tools API extension is IOTAWizard, so most IDE add-ins are called wizards. C++Builder and Delphi wizards are, for the most part, interoperable. You can write and compile a wizard in Delphi, then use it in C++Builder,... more
Using Editor Interfaces | Every module has at least one editor interface. Some modules have several editors, such as a source (.pas) file and form description (.dfm) file. All editors implement the IOTAEditor interface; cast the editor to a specific type to learn what kind of editor it is. For example, to obtain the form editor interface for a unit, you can do the following:
Using Module Interfaces | To obtain a module interface, start with the module services (IOTAModuleServices). You can query the module services for all open modules, look up a module from a file name or form name, or open a file to obtain its module interface. There are different kinds of modules for different kinds of files, such as projects, resources, and type libraries. Cast a module interface to a specific kind of module interface to learn whether the module is of that type. For example, one way to obtain the current project group interface is as follows:
Using Native IDE Objects | Wizards have full access to the main menu, tool bars, action list, and image list of the IDE. (Note that the IDE's many context menus are not accessible through the Tools API.) The starting point for working with native IDE objects is the INTAServices interface. Use this interface to add an image to the image list, an action to the action list, a menu item to the main menu, and a button to a tool bar. You can tie the action to the menu item and tool button. When the wizard is destroyed, it must clean up the objects it... more
Working with Files and Editors | It is important to understand how the Tools API works with files. The main interface is IOTAModule. A module represents a set of logically related open files. For example, a single module represents a single unit. The module, in turn, has one or more editors, where each editor represents one file, such as the unit source (.pas) or form (.dfm or .xfm) file. The editor interfaces reflect the internal state of the IDE's editors, so a wizard can see the modified code and forms that the user sees, even if the user has not saved any changes. The following... more
Writing a Wizard Class | There are four kinds of wizards, where the wizard kind depends on the interfaces that the wizard class implements. The following table describes the four kinds of wizards. The four kinds of wizards

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!