怎样编写DELPHI向导(三)
发信人: strayli (stray), 信区: Delphi
标 题: How to write Delphi wizard(3)
发信站: BBS 水木清华站 (Thu Nov 5 22:02:23 1998) WWW-POST
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:
cmExisting: Will create an existing module from the given file system.
AncestorClass: This must specify an existing base class in the project. (use
the cmAddToProject flag to add a module to the project first).
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:
NewPascalString: Allocates and returns a pascal long string from the provided
PChar (char*, in C). Passing an empty string or nil for the PChar will return
nil for the string (Pascal's equivalent of an empty string).
FreePascalString: Attempts to free the given Pascal string by decrementing
the internal reference count and releasing the memory if the count returns to
zero.
ReferencePascalString: Increments the reference count of the given Pascal
string. This allows the calling function to manually extend the lifetime of
the string. A corresponding call to FreePascalString must be made in order to
actually release the string's memory.
AssignPascalString: Assigns one Pascal string to another. Never directly
assign Pascal strings to each other. Doing so will orphan memory and cause a
memory leak. The destination may be referencing another string, so the
reference count of that string must be decremented. Likewise, the reference
count of the source string must be incremented.
5. TFileOpenDialogExpert
Well, with the TIToolServices class we sure have a lot of information and
power at our disposal, don't we!? Let's try to do something easy that doesn't
get us into trouble right away. The API that I'm looking for that will allow
me to open any file as a new project seems to be OpenProject, which takes a
fully qualified filename as only argument.
The engine for the first version of the TFileOpenExpert is as follows:
TFileOpenExpert
GetStyle: esStandard
GetIDString: DrBob.TFileOpenExpert.standard
GetName: FileOpen Wizard
GetAuthor (win32): Bob Swart (aka Dr.Bob)
GetMenuText: &FileOpen Wizard...
GetState: [esEnabled]
GetGlyph: 0
GetPage (win32):
GetComment:
So, all we need to do in the Execute procedure, is somehow get the fully
qualified filename, and call ToolServices.OpenProject with it. The easiest
way seems to be using a TOpenDialog, which we can create and execute on the
fly, so the code of Execute looks as follows now:
procedure TFileOpenExpert.Execute;
begin
with TOpenDialog.Create(nil) do
begin
if Execute then
ToolServices.OpenProject(FileName);
Free
end
end {Execute};
Well, it's almost what we want. We forgot to initialise the filter of the
TOpenDialog, so we need to do that as well. Other than that, we can indeed
open up new projects, but we don't close the files of any previous projects
that were loaded. So, we need to call SaveProject and CloseProject prior to
calling our OpenProject.
procedure TFileOpenExpert.Execute;
begin
with TOpenDialog.Create(nil) do
begin
Title := GetName; { name of Wizard as OpenDialog caption }
Filter := 'All Files (*.*)|*.*';
Options := Options + [ofShowHelp, ofPathMustExist, ofFileMustExist];
HelpContext := 0;
if Execute then
begin
ToolServices.SaveProject;
ToolServices.CloseProject;
ToolServices.OpenProject(FileName)
end;
Free
end
end {Execute};