📄 66.htm
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>CTerm非常精华下载</title>
</head>
<body bgcolor="#FFFFFF">
<table border="0" width="100%" cellspacing="0" cellpadding="0" height="577">
<tr><td width="32%" rowspan="3" height="123"><img src="DDl_back.jpg" width="300" height="129" alt="DDl_back.jpg"></td><td width="30%" background="DDl_back2.jpg" height="35"><p align="center"><a href="http://bbs.tsinghua.edu.cn"><font face="黑体"><big><big>水木清华★</big></big></font></a></td></tr>
<tr>
<td width="68%" background="DDl_back2.jpg" height="44"><big><big><font face="黑体"><p align="center"> Delphi编程 (BM: strayli FlyingBoy) </font></big></big></td></tr>
<tr>
<td width="68%" height="44" bgcolor="#000000"><font face="黑体"><big><big><p align="center"></big></big><a href="http://cterm.163.net"><img src="banner.gif" width="400" height="60" alt="banner.gif"border="0"></a></font></td>
</tr>
<tr><td width="100%" colspan="2" height="454"> <p align="center">[<a href="index.htm">回到开始</a>][<a href="13.htm">上一层</a>][<a href="67.htm">下一篇</a>]
<hr><p align="left"><small>发信人: strayli (stray), 信区: Delphi <br>
标 题: How to write Delphi wizard(2) <br>
发信站: BBS 水木清华站 (Thu Nov 5 22:01:06 1998) WWW-POST <br>
<br>
After we click onthe OK-button to add the generic unit with our GenericExpert <br>
to the DCLUSR30 package, we need to confirm that Delphi needs to rebuild the <br>
package: <br>
<br>
<br>
<br>
<br>
After the package is rebuilt and installed into the Delphi 3 IDE again, we <br>
can inspect the Package Editor and see that the generic unit is now part of <br>
it. This simple example already illustrates that packages are not limited to <br>
components, but can contain Wizards as well. <br>
<br>
<br>
<br>
When Delphi is done with compiling and linking COMPLIB.DCL or DCLUSR30.DPL, <br>
you can find our first new Wizard in the Help menu: <br>
<br>
<br>
<br>
<br>
Just select the "Generic Wizard" and it will show the world that it's alive: <br>
<br>
<br>
<br>
<br>
As we can see, only the Execute method contains any significant code, and <br>
this will remain so for all Wizards to come. In order to avoid that we have <br>
to print a long listing in this paper for an Wizard where only one method is <br>
relevant, I'll propose the following technique: let's use a table to define <br>
the nine methods, and only specify the Execute method in detail. Our <br>
TGenericExpert would then become the following: <br>
<br>
<br>
TGenericExpert <br>
GetStyle: esStandard <br>
GetIDString: DrBob.TGenericExpert <br>
GetName: Generic Wizard <br>
GetAuthor (win32): Bob Swart (aka Dr.Bob) <br>
GetMenuText: &Generic Wizard... <br>
GetState: [esEnabled] <br>
GetGlyph: 0 <br>
GetPage (win32): <br>
GetComment: <br>
<br>
With only the Execute method outlined in detail (see previous listing). We <br>
will use this notation in the rest of this session. <br>
<br>
3. TSysInfoExpert <br>
Instead of just popping up a MessageDlg, we can show any form we'd like. In <br>
fact, this is just were the fun starts. Generally, we can consider our Wizard <br>
to consist of two parts: the Wizard engine and the form interface. We've just <br>
seen how to write the Wizard engine, and we all know how to write form <br>
interfaces, so let's put these two together and write our first <br>
something-more-than-trivial information Wizard. The information that I want <br>
the Wizard to present can be found in the SysUtils unit, and consists of the <br>
country specific informatin regarding currency and date/time formatting <br>
constants. In the on-line help we can find which constants are defined in <br>
SysUtils, but we can't see their value. This is unfortunate, since most of <br>
the time Delphi is of course up-and-running while we're developing, so <br>
SysUtils is active as well (remember: Delphi is written in Delphi!) and <br>
should know about these values. <br>
<br>
So, using the Dialog Expert, we can create a Multipage dialog, using a <br>
TabbedNotebook, and give the three pages the names "Currency", "Date" and <br>
ncy", "Date" and <br>
"Time". Next, we must drop a label on each of the pages, set autosize for <br>
each label to false, and make them about as big as the entire notebook (so <br>
multiple lines can be viewed). The source code for the form merely consists <br>
of putting the right values on the right places when the form is created (in <br>
the OnCreate handler), so nothing complex at all for the interface side of <br>
the SysInfo Wizard. The engine of TSysInfoExpert is as follows: <br>
<br>
<br>
TSysInfoExpert <br>
GetStyle: esStandard <br>
GetIDString: DrBob.TSysInfoExpert <br>
GetName: SysInfo Wizard <br>
GetAuthor (win32): Bob Swart (aka Dr.Bob) <br>
GetMenuText: &SysInfo Wizard... <br>
GetState: [esEnabled] <br>
GetGlyph: 0 <br>
GetPage (win32): <br>
GetComment: <br>
<br>
The Execute method of the SysInfo Wizard is almost as easy, since all we need <br>
to do is to create, show and free the form with the desired information. <br>
That's it. The source code for the Execute procedure is as follows: <br>
That's it. The source code for the Execute procedure is as follows: <br>
<br>
<br>
procedure TSysInfoExpert.Execute; <br>
begin <br>
with TSysInfoForm.Create(nil) do <br>
begin <br>
ShowModal; <br>
Free <br>
end <br>
end {Execute}; <br>
<br>
And presto! Our first "useful" Wizard, showing information at design time <br>
that isn't available any other way: <br>
<br>
<br>
This is only the first of many examples where we will see an Wizard engine <br>
that will show an interface form to show (or get) information to the user. <br>
One source of information to provide (or actions to apply) can be obtained <br>
from the so-called toolservices interface Delphi offers us in the <br>
TIToolServices class. <br>
<br>
4. ToolServices <br>
We've seen some generic but in fact pretty much useless Wizard so far. In <br>
order to write truly more useful Wizards, we need to do something special <br>
inside the Execute method, like show a (more) interesting form in which a lot <br>
of things can happen, a bit like we introduced with the TSysInfoExpert. <br>
Did you ever feel the need to load some project other than a .DPR file in the <br>
IDE? No? Never written any DLLs in Delphi? Well, I often have the need to <br>
open a .PAS or any file with an extension other than .DPR inside the IDE as <br>
my project. In fact, my need is so big, I want to write an Wizard to help me <br>
in browsing over my disk and directories in search for a certain file to open <br>
as a new project. <br>
But is this possible? To answer this question, we need to take a look at <br>
TOOLINTF.PAS from Delphi 1.0, the file that contains the definition of <br>
TIToolServices (the "I" stands for Interface again), which is as follows: <br>
<br>
<br>
unit ToolIntf; <br>
interface <br>
uses <br>
WinTypes, VirtIntf; <br>
<br>
Type <br>
TIToolServices = class(TInterface) <br>
ass(TInterface) <br>
public <br>
{ Action interfaces } <br>
function CloseProject: Boolean; virtual; export; abstract; <br>
function OpenProject(const ProjName: string): Boolean; virtual; export; <br>
abstract; <br>
function OpenProjectInfo(const ProjName: string): Boolean; virtual; <br>
export; abstract; <br>
function SaveProject: Boolean; virtual; export; abstract; <br>
function CloseFile(const FileName: string): Boolean; virtual; export; <br>
abstract; <br>
function SaveFile(const FileName: string): Boolean; virtual; export; <br>
abstract; <br>
function OpenFile(const FileName: string): Boolean; virtual; export; <br>
abstract; <br>
function ReloadFile(const FileName: string): Boolean; virtual; export; <br>
abstract; <br>
function ModalDialogBox(Instance: THandle; TemplateName: PChar; <br>
WndParent: HWnd; <br>
DialogFunc: TFarProc; InitParam: LongInt): Integer; virtual; export; <br>
abstract; <br>
function CreateModule(const ModuleName: string; Source, Form: TIStream; <br>
CreateFlags: TCreateModuleFlags): Boolean; virtual; export; abstract; <br>
xport; abstract; <br>
<br>
{ Project/UI information } <br>
function GetParentHandle: HWND; virtual; export; abstract; <br>
function GetProjectName: string; virtual; export; abstract; <br>
function GetUnitCount: Integer; virtual; export; abstract; <br>
function GetUnitName(Index: Integer): string; virtual; export; abstract; <br>
function GetFormCount: Integer; virtual; export; abstract; <br>
function GetFormName(Index: Integer): string; virtual; export; abstract; <br>
function GetCurrentFile: string; virtual; export; abstract; <br>
function IsFileOpen(const FileName: string): Boolean; virtual; export; <br>
abstract; <br>
function GetNewModuleName(var UnitIdent, FileName: string): Boolean; <br>
virtual; export; abstract; <br>
<br>
{ Component Library interface } <br>
function GetModuleCount: Integer; virtual; export; abstract; <br>
function GetModuleName(Index: Integer): string; virtual; export; <br>
abstract; <br>
function GetComponentCount(ModIndex: Integer): Integer; virtual; export; <br>
abstract; <br>
function GetComponentName(ModIndex,CompIndex: Integer): string; virtual; <br>
export; abstract; <br>
export; abstract; <br>
<br>
{function InstallModule(const ModuleName: string): Boolean; virtual; <br>
export; abstract; <br>
function CompileLibrary: Boolean; virtual; export; abstract; <br>
} <br>
<br>
{ Error handling } <br>
procedure RaiseException(const Message: string); virtual; export; <br>
abstract; <br>
end; <br>
<br>
implementation <br>
<br>
The Tool services object is created on the application (Delphi/C++Builder) <br>
side, and is passed to the VCS/Expert Manager DLL during initialization. Note <br>
that the application (Delphi/C++Builder) is responsible for creating and <br>
freeing the interface object, and the client should never free the interface. <br>
<br>
The following ToolServices functions are available to the client (for Delphi <br>
1.0 as well as 2.0x and 3): <br>
<br>
<br>
<br>
Actions <br>
CloseProject <br>
returns True if no project open, or if the currently open project can be <br>
closed. <br>
OpenProject <br>
returns True if the named project can be opened. You have to pass an empty <br>
string to create a new project and main form. <br>
OpenProjectInfo <br>
returns True if the named project file can be opened. This routine bypasses <br>
all the normal project load features (such as loading a desktop file, showing <br>
the source code, etc), and simply opens the .DPR and .OPT files. <br>
SaveProject <br>
returns True if the project is unmodified, if there is no project open, or if <br>
the open project can be saved. <br>
CloseFile <br>
returns True if the specified file is not currently open, or if it can be <br>
closed. <br>
OpenFile <br>
returns True if the specified file is already open or can be opened. <br>
ReloadFile <br>
returns True if the file is already open and was reloaded from disk. (NOTE: <br>
This will not perform any checking of the current editor state). <br>
RefreshBuffers <br>
causes the IDE to check the time/date stamp of each open file to determine if <br>
the file has changed on disk. If so, the file is re-read. <br>
ModalDialogBox <br>
used by non-VCL DLL's to present a dialog box which is modal. Note that DLLs <br>
written using VCL can simply call a form's ShowModal function. <br>
CreateModule <br>
Will create new module from memory images of the source and, optionally, the <br>
form file. <br>
The TCreateModuleFlags are: <br>
cmAddToProject: Add the new module to the currently open project. <br>
cmShowSource: Show the source file in the top-most editor window. <br>
cmShowForm: If a form is created, show it above the source. <br>
cmUnNamed: Will mark the module as unnamed which will cause the SaveAs dialog <br>
to show the first time the user attempts to save the file. <br>
cmNewUnit: Creates a new unit and adds it to the current project. NOTE: all <br>
other parameters are ignored. <br>
cmNewForm: Creates a new form and adds it to the current project. NOTE: all <br>
other parameters are ignored. <br>
cmMainForm: If the module includes a form, make it the main form of the <br>
currently open project. Only valid with the cmAddToProject option. <br>
cmMarkModified: Will insure that the new module is marked as modified. <br>
cmMarkModified: Will insure that the new module is marked as modified. <br>
Informational <br>
<br>
GetParentHandle <br>
returns a HWND which should be used as the parent for windows created by the <br>
client. <br>
GetProjectName <br>
returns a fully qualified path name of the currently open project file, or an <br>
empty string if no project is open. <br>
GetUnitCount <br>
returns the current number of units belonging to the project. <br>
GetUnitName <br>
returns a fully qualified name of the specified unit. <br>
GetFormCount <br>
returns the current number of forms belonging to the project. <br>
GetFormName <br>
returns a fully qualified name of the specified form file. <br>
GetCurrentFile <br>
returns a fully qualified name of the current file, which could either be a <br>
form or unit (.PAS). Returns a blank string if no file is currently selected. <br>
<br>
IsFileOpen <br>
<br>
<br>
-- <br>
※ 来源:·BBS 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 159.226.64.144] <br>
</small><hr>
<p align="center">[<a href="index.htm">回到开始</a>][<a href="13.htm">上一层</a>][<a href="67.htm">下一篇</a>]
<p align="center"><a href="http://cterm.163.net">欢迎访问Cterm主页</a></p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -