Image of Navigational Map linked to Home / Contents / Search How to write Delphi Wizards

ToolServices
Image of Line Break

We've seen some generic but in fact pretty much useless Wizard so far. In order to write truly more useful Wizards, we need to do something special inside the Execute method, like show a (more) interesting form in which a lot of things can happen, a bit like we introduced with the TSysInfoExpert.
Did you ever feel the need to load some project other than a .DPR file in the IDE? No? Never written any DLLs in Delphi? Well, I often have the need to open a .PAS or any file with an extension other than .DPR inside the IDE as my project. In fact, my need is so big, I want to write an Wizard to help me in browsing over my disk and directories in search for a certain file to open as a new project.
But is this possible? To answer this question, we need to take a look at TOOLINTF.PAS from Delphi 1.0, the file that contains the definition of TIToolServices (the "I" stands for Interface again), which is as follows:

unit ToolIntf;
interface
uses
  WinTypes, VirtIntf;

Type
  TIToolServices = class(TInterface)
  public
    { Action interfaces }
    function CloseProject: Boolean; virtual; export; abstract;
    function OpenProject(const ProjName: string): Boolean; virtual; export; abstract;
    function OpenProjectInfo(const ProjName: string): Boolean; virtual; export; abstract;
    function SaveProject: Boolean; virtual; export; abstract;
    function CloseFile(const FileName: string): Boolean; virtual; export; abstract;
    function SaveFile(const FileName: string): Boolean; virtual; export; abstract;
    function OpenFile(const FileName: string): Boolean; virtual; export; abstract;
    function ReloadFile(const FileName: string): Boolean; virtual; export; abstract;
    function ModalDialogBox(Instance: THandle; TemplateName: PChar;  WndParent: HWnd;
      DialogFunc: TFarProc; InitParam: LongInt): Integer; virtual; export; abstract;
    function CreateModule(const ModuleName: string; Source, Form: TIStream;
      CreateFlags: TCreateModuleFlags): Boolean; virtual; export; abstract;

    { Project/UI information }
    function GetParentHandle: HWND; virtual; export; abstract;
    function GetProjectName: string; virtual; export; abstract;
    function GetUnitCount: Integer; virtual; export; abstract;
    function GetUnitName(Index: Integer): string; virtual; export; abstract;
    function GetFormCount: Integer; virtual; export; abstract;
    function GetFormName(Index: Integer): string; virtual; export; abstract;
    function GetCurrentFile: string; virtual; export; abstract;
    function IsFileOpen(const FileName: string): Boolean; virtual; export; abstract;
    function GetNewModuleName(var UnitIdent, FileName: string): Boolean; virtual; export; abstract;

    { Component Library interface }
    function GetModuleCount: Integer; virtual; export; abstract;
    function GetModuleName(Index: Integer): string; virtual; export; abstract;
    function GetComponentCount(ModIndex: Integer): Integer; virtual; export; abstract;
    function GetComponentName(ModIndex, CompIndex: Integer): string; virtual; export; abstract;

   {function InstallModule(const ModuleName: string): Boolean; virtual; export; abstract;
    function CompileLibrary: Boolean; virtual; export; abstract;
   }

    { Error handling }
    procedure RaiseException(const Message: string); virtual; export; abstract;
  end;

implementation

The Tool services object is created on the application (Delphi/C++Builder) side, and is passed to the VCS/Expert Manager DLL during initialization. Note that the application (Delphi/C++Builder) is responsible for creating and freeing the interface object, and the client should never free the interface.

The following ToolServices functions are available to the client (for Delphi 1.0 as well as 2.0x and 3):

Actions
  • CloseProject
    returns True if no project open, or if the currently open project can be closed.
  • OpenProject
    returns True if the named project can be opened. You have to pass an empty string to create a new project and main form.
  • OpenProjectInfo
    returns True if the named project file can be opened. This routine bypasses all the normal project load features (such as loading a desktop file, showing the source code, etc), and simply opens the .DPR and .OPT files.
  • SaveProject
    returns True if the project is unmodified, if there is no project open, or if the open project can be saved.
  • CloseFile
    returns True if the specified file is not currently open, or if it can be closed.
  • OpenFile
    returns True if the specified file is already open or can be opened.
  • ReloadFile
    returns True if the file is already open and was reloaded from disk. (NOTE: This will not perform any checking of the current editor state).
  • RefreshBuffers
    causes the IDE to check the time/date stamp of each open file to determine if the file has changed on disk. If so, the file is re-read.
  • ModalDialogBox
    used by non-VCL DLL's to present a dialog box which is modal. Note that DLLs written using VCL can simply call a form's ShowModal function.
  • CreateModule
    Will create new module from memory images of the source and, optionally, the form file.

    Informational

  • GetParentHandle
    returns a HWND which should be used as the parent for windows created by the client.
  • GetProjectName
    returns a fully qualified path name of the currently open project file, or an empty string if no project is open.
  • GetUnitCount
    returns the current number of units belonging to the project.
  • GetUnitName
    returns a fully qualified name of the specified unit.
  • GetFormCount
    returns the current number of forms belonging to the project.
  • GetFormName
    returns a fully qualified name of the specified form file.
  • GetCurrentFile
    returns a fully qualified name of the current file, which could either be a form or unit (.PAS). Returns a blank string if no file is currently selected.
  • IsFileOpen
    returns True if the named file is currently open.
  • GetNewModuleName
    Automatically generates a valid Filename and Unit identifier. Uses the same mechanism as used by the IDE.

    Component library interface

  • GetModuleCount
    Returns the number of currently installed modules in the component library.
  • GetModuleName
    Returns then name of the module given its index.
  • GetComponentCount
    Returns the number of components installed in a particular module.
  • GetComponentName
    Returns the name of the component given its module index and index in that module.

    Error handling

  • RaiseException
    This will cause an Exception to be raised with the IDE with the string passed to this function. NOTE: This will cause the stack to unwind and control will NOT return to this point. It is the resposibility of the Library to be sure it has correctly handled the error condition before calling this procedure.
  • TIToolInterface for Delphi 2.0x and 3

    Delphi 2.0x and 3 have an expanded Open Tools API (compared to Delphi 1.x), which is not only reflected in a few new methods for TIExpert, but especially for TIToolServices. The following additional methods are new and for the 32-bits versions of Delphi only (methods that are shared with Delphi 1.0 have been left out for now):

    TIToolServices = class(TInterface)
    public
      { Action interfaces }
      function CreateModuleEx(const ModuleName, FormName, AncestorClass,
        FileSystem: string; Source, Form: TIStream;
        CreateFlags: TCreateModuleFlags): TIModuleInterface; virtual;
          stdcall; abstract;
    
      { Project/UI information }
      function EnumProjectUnits(EnumProc: TProjectEnumProc; Param: Pointer): Boolean;
        virtual; stdcall; abstract;
    
      { Virtual File system interfaces }
      function RegisterFileSystem(AVirtualFileSystem: TIVirtualFileSystem): Boolean;
        virtual; stdcall; abstract;
      function UnRegisterFileSystem(const Ident: string): Boolean; virtual;
        stdcall; abstract;
      function GetFileSystem(const Ident: string): TIVirtualFileSystem; virtual;
        stdcall; abstract;
    
      { Editor Interfaces }
      function GetModuleInterface(const FileName: string): TIModuleInterface;
        virtual; stdcall; abstract;
      function GetFormModuleInterface(const FormName: string): TIModuleInterface;
        virtual; stdcall; abstract;
    
      { Menu Interfaces }
      function GetMainMenu: TIMainMenuIntf; virtual; stdcall; abstract;
    
      { Notification registration }
      function AddNotifier(AddInNotifier: TIAddInNotifier): Boolean;
        virtual; stdcall; abstract;
      function RemoveNotifier(AddInNotifier: TIAddInNotifier): Boolean;
        virtual; stdcall; abstract;
    
      { Pascal string handling functions }
      function NewPascalString(Str: PChar): Pointer; virtual; stdcall; abstract;
      procedure FreePascalString(var Str: Pointer); virtual; stdcall; abstract;
      procedure ReferencePascalString(var Str: Pointer); virtual; stdcall; abstract;
      procedure AssignPascalString(var Dest, Src: Pointer); virtual;
        stdcall; abstract;
    
      { Configuration Access }
      function GetBaseRegistryKey: string; virtual; stdcall; abstract;
    end;
    

    The following ToolServices functions are available to the client for 32-bits versions of Delphi only:

    Actions
  • CreateModuleEx
    New extended form of CreateModule. This will return a TIModuleInterface. All CreateModes from CreateModule are supported with only the following differences:

    Informational

  • EnumProjectUnits
    Calls EnumProc once for each unit in the project.

    Editor

  • GetModuleInterface
    Return an module interface associated with the given file. This function returns the same interface instance for a given module, only the reference count is adjusted. The user of this interface owns it and must call release when finished.
  • GetFormModuleInterface
    returns an module interface associated with the given form.

    Menu

  • GetMainMenu
    Returns an interface to the IDE's main menu. See TIMainMenuIntf for details.

    Notification

  • AddNotifier
    Registers an instance of a descendant to TIAddIn- Notifier.
  • RemoveNotifier
    Removes a registered instance of a TIAddInNotifier.

    Configuration Access

  • GetBaseRegistryKey
    returns a string representing the full path to Delphi's base registry key. This key is relative to HKEY_CURRENT_USER.

    Virtual File System

  • The RegisterFileSystem and UnRegisterFileSystem methods seem to be present to prepare for future porting and operating/filesystem specific issues. Nice to know Borland is working on that as well!

    Pascal String Handling

  • The Pascal string handling functions are provided for IDE add-in writers to use a language other than Pascal. (C or C++, for example). Add-in writers using Delphi will never need to use these functions, but we'll focus on them for the sake of completeness:

  • Image of Arrow linked to Next Article Image of Arrow linked to Next Article
    Image of Line Break
    [HOME] [TABLE OF CONTENTS] [SEARCH]