关于向导制作的讨论(300分)

  • 主题发起人 主题发起人 Pan Ying
  • 开始时间 开始时间
P

Pan Ying

Unregistered / Unconfirmed
GUEST, unregistred user!
因为CNPack的关系,搜集有关向导制作的资料。
不知道各位有没有制作过向导,原来的向导(3.0中)使用exptintf.pas中的TIExpert这
个模拟接口(http://www.delphibbs.com/delphibbs/dispq.asp?lid=922469),但5.0中
使用了toolsapi.pas中的IOTAWizard接口及其他接口,不知道是不是编向导的人太少了,
相关的资料很少,在Delphi社区中只有很少的资料(或许我搜索的方式不对),有一个
KeyBinding的例子外好像就没有了。
如果你对向导有了解,不妨讲讲你的心得;如果你有过研究,不妨讲讲向导的具体知识;
如果你曾写过关于此方面的文章,不妨贴出来给大家看看;如果你写过代码,为何不让我们
分享一下,上传到Delphi网站,如http://delphi.mychangshu.com/。
所有有用的贴子都有分,如果是关于新的接口的话更好,总共预计分发1000分吧。
无论你是低手还是高手,只要你对向导制作有了解,都欢迎发贴!
那些排名在我前面的高手不要因为我的分数少而不参与哦。:)

本贴预计开放到5月。
因为我不常上网,请看过此贴的大富翁能将此贴提前,谢谢![:)]
 
我觉得编向导就是编一个界面,再加上一系列的操作!
 
可以很有条理的完成一件事!!
 
现在的向导可是与Delphi系统紧密结合的,其实你现在在Delphi中用的不少工具就是向导。
 
编向导是我强项, 各种向导都编过,不过暂时没时间编成资料,有时间就写一点吧
 
我对向导的研究不太深,仅限于TNootBook加上一些操作。下面是大名鼎鼎的郝新庚的作品,
贴上来供你参考。

{**********************************************************}
{ }
{ TWizardCtrl Component Version 1.01 }
{ }
{ Written by DayDream Studio, 1999/6/10 }
{ Last Modified by DayDream Studio, 1999/12/29 }
{ }
{ This is a freeware. If you make cool changes to it, }
{ please send them to me. }
{ }
{ Email: haoem@126.com }
{ URL: http://haoxg.yeah.net }
{ }
{**********************************************************}

unit WizardCtrl;

interface

uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;

type
TBackNextClickEvent = procedure(Sender: TObject; var AllowChange: Boolean) of object;

TWizardCtrl = class(TCustomControl)
private
{ Private declarations }
FNoteBook: TNoteBook;
FHelpButton: TButton;
FBackButton: TButton;
FNextButton: TButton;
FCancelButton: TButton;
FHelpCaption: string;
FBackCaption: string;
FNextCaption: string;
FCancelCaption: string;
FFinishCaption: string;
FHelpVisible: Boolean;
FHelpLeftAlign: Boolean;
FFinished: Boolean;
FPageName: string;
FOnHelpClick: TNotifyEvent;
FOnBackClick: TBackNextClickEvent;
FOnNextClick: TBackNextClickEvent;
FOnCancelClick: TNotifyEvent;
FOnFinishClick: TNotifyEvent;
FOnPageChange: TNotifyEvent;

procedure SetNoteBook(Value: TNoteBook);
procedure SetHelpCaption(Value: string);
procedure SetBackCaption(Value: string);
procedure SetNextCaption(Value: string);
procedure SetCancelCaption(Value: string);
procedure SetFinishCaption(Value: string);
procedure SetHelpVisible(Value: Boolean);
procedure SetHelpLeftAlign(Value: Boolean);
procedure SetPageIndex(Index: Integer);

function GetPageIndex: Integer;

procedure HelpButtonClick(Sender: TObject);
procedure BackButtonClick(Sender: TObject);
procedure NextButtonClick(Sender: TObject);
procedure CancelButtonClick (Sender: TObject);

procedure AdjustButtons(PageIdx: Integer);
protected
{ Protected declarations }
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure Paint; override;
procedure Resize; override;

public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property PageName: string read FPageName;
property PageIndex: Integer read GetPageIndex write SetPageIndex;
property Finished: Boolean read FFinished;
property HelpButton: TButton read FHelpButton;
property BackButton: TButton read FBackButton;
property NextButton: TButton read FNextButton;
property CancelButton: TButton read FCancelButton;

procedure FirstPage;
procedure LastPage;
procedure NextPage;
procedure PrevPage;
published
{ Published declarations }
property NoteBook: TNoteBook read FNoteBook write SetNoteBook;
property CaptionOfHelp: string read FHelpCaption write SetHelpCaption;
property CaptionOfBack: string read FBackCaption write SetBackCaption;
property CaptionOfNext: string read FNextCaption write SetNextCaption;
property CaptionOfCancel: string read FCancelCaption write SetCancelCaption;
property CaptionOfFinish: string read FFinishCaption write SetFinishCaption;
property HelpVisible: Boolean read FHelpVisible write SetHelpVisible;
property HelpLeftAlign: Boolean read FHelpLeftAlign write SetHelpLeftAlign;
property BorderWidth;

property OnHelpClick: TNotifyEvent read FOnHelpClick write FOnHelpClick;
property OnBackClick: TBackNextClickEvent read FOnBackClick write FOnBackClick;
property OnNextClick: TBackNextClickEvent read FOnNextClick write FOnNextClick;
property OnCancelClick: TNotifyEvent read FOnCancelClick write FOnCancelClick;
property OnFinishClick: TNotifyEvent read FOnFinishClick write FOnFinishClick;
property OnPageChange: TNotifyEvent read FOnPageChange write FOnPageChange;

end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('DayDream', [TWizardCtrl]);
end;

constructor TWizardCtrl.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Align := alBottom;
Height := 48;
FHelpVisible := True;
FHelpLeftAlign := False;
FFinished := False;
FPageName := '';
BorderWidth := 7;

FHelpButton := TButton.Create(Self);
FHelpButton.Parent := Self;
FHelpButton.OnClick := HelpButtonClick;
FHelpButton.Width:=75;
FHelpButton.Height:=23;
FHelpButton.TabOrder := 2;
CaptionOfHelp := '帮助';

FBackButton := TButton.Create(Self);
FBackButton.Parent := Self;
FBackButton.OnClick := BackButtonClick;
FBackButton.Width:=75;
FBackButton.Height:=23;
FBackButton.TabOrder := 3;
CaptionOfBack := '< 上一步';

FNextButton := TButton.Create(Self);
FNextButton.Parent := Self;
FNextButton.OnClick := NextButtonClick;
FNextButton.Width:=75;
FNextButton.Height:=23;
FNextButton.TabOrder := 0;
FNextButton.Default := True;
CaptionOfNext := '下一步 >';
CaptionOfFinish := '完成';

FCancelButton := TButton.Create(Self);
FCancelButton.Parent := Self;
FCancelButton.OnClick := CancelButtonClick;
FCancelButton.Width:=75;
FCancelButton.Height:=23;
FCancelButton.TabOrder := 1;
CaptionOfCancel := '取消';
end;

destructor TWizardCtrl.Destroy;
begin
FHelpButton.Free;
FBackButton.Free;
FNextButton.Free;
FCancelButton.Free;
inherited Destroy;
end;

procedure TWizardCtrl.SetNoteBook(Value: TNoteBook);
begin
FNoteBook := Value;
if FNoteBook = nil then exit;

FPageName := FNoteBook.ActivePage;
AdjustButtons(FNoteBook.PageIndex);
end;

procedure TWizardCtrl.SetHelpCaption(Value: string);
begin
FHelpCaption := Value;
FHelpButton.Caption := Value;
Invalidate;
end;

procedure TWizardCtrl.SetBackCaption(Value: string);
begin
FBackCaption := Value;
FBackButton.Caption := Value;
Invalidate;
end;

procedure TWizardCtrl.SetNextCaption(Value: string);
begin
FNextCaption := Value;
if not FFinished then FNextButton.Caption := Value;
Invalidate;
end;

procedure TWizardCtrl.SetCancelCaption(Value: string);
begin
FCancelCaption := Value;
FCancelButton.Caption := Value;
Invalidate;
end;

procedure TWizardCtrl.SetFinishCaption(Value: string);
begin
FFinishCaption := Value;
if FFinished then FNextButton.Caption := Value;
Invalidate;
end;

procedure TWizardCtrl.SetHelpVisible(Value: Boolean);
begin
FHelpVisible := Value;
FHelpButton.Visible := Value;
end;

procedure TWizardCtrl.SetHelpLeftAlign(Value: Boolean);
begin
FHelpLeftAlign := Value;
Paint;
end;

procedure TWizardCtrl.SetPageIndex(Index: Integer);
begin
if not Assigned(FNoteBook) then exit;
if (Index < 0) or (Index >= FNoteBook.Pages.Count) then exit;
if FNoteBook.PageIndex = Index then exit;

FNoteBook.PageIndex := Index;
AdjustButtons(Index);
FPageName := FNoteBook.ActivePage;
if Assigned(FOnPageChange) then FOnPageChange(Self);
end;

function TWizardCtrl.GetPageIndex: Integer;
begin
if not Assigned(FNoteBook) then
begin
Result := -1;
end else
begin
Result := FNoteBook.PageIndex;
end;
end;

procedure TWizardCtrl.HelpButtonClick(Sender: TObject);
begin
if Assigned(FOnHelpClick) then
FOnHelpClick(Self);
end;

procedure TWizardCtrl.BackButtonClick(Sender: TObject);
var
i: Integer;
AllowChange: Boolean;
begin
if Assigned(FNoteBook) then
begin
i := FNoteBook.PageIndex;
if i > 0 then
begin
AllowChange := True;
if Assigned(FOnBackClick) then
FOnBackClick(Self, AllowChange);
if AllowChange then
begin
Dec(i);
FNoteBook.PageIndex := i;
FNextButton.Enabled := True;
AdjustButtons(i);
FNextButton.Caption := FNextCaption;
FPageName := FNoteBook.ActivePage;
if Assigned(FOnPageChange) then FOnPageChange(Self);
end;
end;
end;
end;

procedure TWizardCtrl.NextButtonClick(Sender: TObject);
var
i: Integer;
AllowChange: Boolean;
begin
if Assigned(FNoteBook) then
begin
i := FNoteBook.PageIndex;
if i < FNoteBook.Pages.Count - 1 then
begin
AllowChange := True;
if Assigned(FOnNextClick) then
FOnNextClick(Self, AllowChange);
if AllowChange then
begin
Inc(i);
FNoteBook.PageIndex := i;
FBackButton.Enabled := True;
AdjustButtons(i);
FPageName := FNoteBook.ActivePage;
if Assigned(FOnPageChange) then FOnPageChange(Self);
exit;
end;
end;
end;
if FFinished then
begin
if Assigned(FOnFinishClick) then
FOnFinishClick(Self);
end;
end;

procedure TWizardCtrl.CancelButtonClick (Sender: TObject);
begin
if Assigned(FOnCancelClick) then
FOnCancelClick(Self);
end;

procedure TWizardCtrl.AdjustButtons(PageIdx: Integer);
begin
if FNoteBook.Pages.Count = 1 then
begin
FBackButton.Enabled := False;
FNextButton.Enabled := True;
FNextButton.Caption := FFinishCaption;
FFinished := True;
end
else if PageIdx = FNoteBook.Pages.Count - 1 then
begin
FBackButton.Enabled := True;
FNextButton.Enabled := True;
FNextButton.Caption := FFinishCaption;
FFinished := True;
end
else if PageIdx = 0 then
begin
FBackButton.Enabled := False;
FNextButton.Enabled := True;
FNextButton.Caption := FNextCaption;
FFinished := False;
end else
begin
FBackButton.Enabled := True;
FNextButton.Enabled := True;
FNextButton.Caption := FNextCaption;
FFinished := False;
end;
end;

procedure TWizardCtrl.FirstPage;
begin
if not Assigned(FNoteBook) then exit;
SetPageIndex(0);
end;

procedure TWizardCtrl.LastPage;
begin
if not Assigned(FNoteBook) then exit;
SetPageIndex(FNoteBook.Pages.Count - 1);
end;

procedure TWizardCtrl.NextPage;
begin
if not Assigned(FNoteBook) then exit;
SetPageIndex(FNoteBook.PageIndex + 1);
end;

procedure TWizardCtrl.PrevPage;
begin
if not Assigned(FNoteBook) then exit;
SetPageIndex(FNoteBook.PageIndex - 1);
end;

procedure TWizardCtrl.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FNoteBook) then
FNoteBook := nil;
end;

procedure TWizardCtrl.Paint;
begin
inherited Paint;
with Canvas do
begin
Pen.Color := clBtnShadow;
MoveTo(0, 0);
LineTo(Self.ClientWidth, 0);
Pen.Color := clBtnhighlight;
MoveTo(0, 1);
LineTo(Self.ClientWidth, 1);
End;

FHelpButton.Top := Self.ClientHeight - FHelpButton.Height;
FBackButton.Top := Self.ClientHeight - FBackButton.Height;
FNextButton.Top := Self.ClientHeight - FNextButton.Height;
FCancelButton.Top := Self.ClientHeight - FCancelButton.Height;

FCancelButton.Left := Self.ClientWidth - FCancelButton.Width;
FNextButton.Left := FCancelButton.Left - FNextButton.Width - 10;
FBackButton.Left := FNextButton.Left - FBackButton.Width;

if FHelpLeftAlign then
FHelpButton.Left := 0
else
FHelpButton.Left := FBackButton.Left - FHelpButton.Width - 10;

if FHelpVisible then
FHelpButton.Visible := True
else
FHelpButton.Visible := False;

if not Assigned(FNoteBook) then
begin
FBackButton.Enabled := False;
FNextButton.Enabled := False;
FNextButton.Caption := FFinishCaption;
end;
end;

procedure TWizardCtrl.Resize;
begin
inherited Resize;
end;

end.
 
向导制作不完全手册 一
作者:李清一

向导的定义
所谓DELPHI 向导就是,就是指在设计期中可以调用一些专用的窗口去
编辑控件的某些属性。去弥补 object inspector 的局限。

向导的分类
向导主要分五种:
1 Expert: IDE扩展,例如 palette properties,new items 这种窗口
2 Version Control
3 Component Editor 创建和控件相连的对话框,例如Tquery 在双击控件时出现
的窗口。
4 property editor 创建和属性相连的对话框,例如Tstrings这种,双击属性栏
(或点右边那个按钮)时出现的窗口。
5 Editors InterFaces Delphi编辑器的接口,允许第三方程序使用它
在编写控件中我们常用的是第3和第4种,所以下面也只讨论这二种

相关的概念
在delphi5中,和向导相关的类主要定义在 DsgnIntf.pas 文件中。
在学习设置向导之前,有三点是先要了解的:
第一是向导和控件一样,一定要向IDE注册后才能用
第二是向导最终目的的作用是把数据保存在DFM文件中,所以这是学习的关键
第三属性的字符串值,和属性值是不同的,字符值是用来显示于object inspector中的
属性值是指属性真正的值。例如 Tstrings的属性值是Tstrings类型的,字符值是 <ITEMS>

下面我们先初步了解二个重要的基类。
TPropertyEditor类
第一 TPropertyEditor //属性编辑的基类,所有属性编辑器都要从它继承
方法:
Activate
当你在object inspector中选择对应的属性,并且GetAttributes设置为 paSubProperties + paMultiSelect时,IDE就会调用这个方法
AllEqual
当你选择一个以上的控件,并 GetAttributes 设置为 paMultiSelect.IDE就会调用这个
方法,如果这些控件的该属性都相同就返回TRUE,并调用 GetValue 显示值,否则在
Object Inspector 中显示空白。
AutoFill
假如GetAttributes设置为 paValueList.本属性设置为 TRUE时,你在下拉选择属性值
的时候,当前选中的值会自动被填到Object Inspector中的对应属性栏中。
Edit
这个方法是在制作属性向导时必须重载(override)的 .
当你在对应的属性栏双击时,IDE就会调用这个方法,所以
在这个方法和我们就要完成数据读取,窗口初始化,显示等操作
GetAttributes
这个方河也是要重载(override)的 .用于设中属性的属性,如下:
TPropertyAttributes:
paValueList: 设置后,当你按属性栏右边的控钮时会弹出一个下拉框(如Tcolor的设置)
下控框的值由 GetValues 方法的 proc 参数设置。

paSortList: Object Inspector会把 GetValues 方法返回的值列表进后排序。

paSubProperties: 设置后,属性的左边会出现一个+号,单击加号,会展开其所有子属性
也就是该属性的所有 property 。(如字体的设置)

paDialog: 设置后,属性的右边会出现 '...' 按钮,单击后出现对话框。

paMultiSelect: 设置后,当你选择一个以上的控件时,这个属性仍允许显示在
Object Inspector中,(如 name属性等)

paAutoUpdate: 设置后,当你在设置属性值的过程中,每一次操作都会导致马上调用
SetValue 方法去改变属性值,而不是在你确认后(如回车后)再改变,
如 Caption 属性,
paReadOnly: 只读属性

paRevertable: 允许在按Esc键时恢复原来的值,崭套型的属性(如字体)
不能设置这个属性。
GetComponent
返回指定索引值的控件,主要用于在GetAttributes 设置为 paMultiSelect时,在
所选择的控件中找到某一个控件。
GetEditLimit
返回在 object inspector 中编辑属性时,所允许的最大长度,默认为 255.
GetName
所回属性名,如果你希望编辑属性时,在 Object Inspector 中显示属性名就重载它。
GetProperties
在属性有子属性(或崭套有属性时),可以重载这个方法,并通过设置 PropertyProc
参数为子属性分配 TPropertyEdtior 。例如集合属性向导就调用这个方法为每为子属性
分配一个向导,用于设置其为 TRUE 或 False来设置这个项是否在集合中。

GetPropType
返回正在编辑的属性的类信息指针
GetValue
所回属性的字符串值,默认是'(unknown)'.
GetValues
在 GetAttributes 设置为 paValueList 时使用 Proc 参数用于设置属性所能接受的
值列表。
Initialize
在 property editor 创造之后,使用之前会呼叫该方法。
SetValue(Value)
在设置属性的字符串值时会呼叫该方法. property editor应该可以传送这个字符串
并呼叫一个 SetXxxValue 方,如果字符串的格式或值范围不对,property editor应该可以
触发一个异常.
ListMeasureWidth(Value, Canvas, AWidth)
在计算属性下拉框的宽度时触发,以你可以改变下拉框的宽度。
ListMeasureHeight(Value, Canvas, AHeight)
在计算属性下拉框的高度时触发,以你可以改变下拉框的高度。
ListDrawValue(Value, Canvas, Rect, Selected)
在画下拉框的值单元时触发,这个和 TListBox 的 OnDrawItem 相似,
可以让你在下拉框上画图,(如光标设置的下拉框)
PropDrawName(Canvas, Rect, Selected)
在画属性列的名字单元时触发,这个和 TListBox 的 OnDrawItem 相似,
PropDrawValue(Canvas, Rect, Selected)
在画属性列的值单元时触发,这个和 TListBox 的 OnDrawItem 相似,
Name property
GetName 返回的值。
PrivateDirectory property
属性返回:
"HKEY_CURRENT_USER/Software/Borland/Delphi/*/Globals/PrivateDir"
中注册的EXE文件或一个目录。
如果你的 property editor 需要一些额外的文件 (模板,范例等),应该保存在该目录中
Value property
GetValue 返回的值。
Modified
通知IDE控件属性已被修改,在执行SetXxxValue 为方法时,会自动执行Modified。
GetXxxValue
获取属性值(多选时为第一个控件的值)你可以根据属性的值类型使用不同的 SetXxxxValue
SetXxxValue
设置属性值(多选时为所有控件同样设置),你可以根据属性的值类型使用不同的 SetXxxxValue
方法。
GetVisualValue
返回一个可显示的值,如果只有一个控件被选择,或多个被选择的控件的值都一样时
就返回属性的值,否则返回空字符串


TComponentEditor
ComponentEditor分配于控件,在你双击控件时弹出 。

Create(AComponent, ADesigner)
创造一个 component editor. AComponent 是激活它的控件. ADesigner 是IDE提供
的一个接口,提供一些设计期的信息。

Edit
在双击控件时IDE会调用这个方法. 如果GetVerbCount大于0, edit 将会调用 ExecuteVerb(0)。

ExecuteVerb(Index),GetVerb,GetVerbCount,PrepareItem
当你在某些控件(如Tdataset)上单击右键时,你发现菜单中会出现一些控件特有菜单项。
上面这四个方法就是用于控制,这些菜单项的。
GetVerbCount 用菜单项的数量。
GetVerb用于设置 Index 参数 指定的菜单项的Caption
Executeverb用于设置 Index 参数指定的菜单项要执行的操作
PrepareItem 在IDE准备创造菜单项时触发,让你可以定制菜单项的设置(如加上图片等)

IsInInlined
当控件在Frame实例上面时本函数返回TRUE.

以上这二个类和常规类的使用方法有点不同,它由用户按需要定义,由IDE进行调用,它们的函数
其实就等于IDE向我们要一个值,一个执行动作。

向导的注册
我们使用控件要先注册控件,同样要使用 向导同样要先注册,不然IDE怎么知道有什么向导。
和注册控件一样,注册向导同样执行于 procedure Register; 这个特殊方法中。
有二个相关的方法。
方法一:
procedure RegisterPropertyEditor(PropertyType: PTypeInfo; ComponentClass: TClass;
const PropertyName: string; EditorClass: TPropertyEditorClass);
用于注册一个属性编辑向导名。
其中
PropertyType
属性类的类信息,这个类信息可以用内部函数TypeInfo来获得 例如:TypeInfo(TMyRange) TypeInfo(TShapes)
ComponentClass
限制那一些控件可以使用这个属性编辑器。如果设置为 nil,则不管是那一种控件,只要其属性的
属性类是PropertyType所指定的类即会使用向导进行设置(除非控件有单独的设置).这个设置是范围
越小权限越高,范围相同的即用户定义的权限较高。

PropertyName
指定什么名字的属性可以使用这个属性编辑器,如果设置为''则可以使用该属性编辑器的属性由 PropertyType 和 ComponentClass 来确定。

以上三个参数用联合指定那一些属性可以使用本属性编辑器。也就是 ComponentClass中的、类为 PropertyType的、名字为PropertyName的属性使用本属性编辑器。

EditorClass
属性编辑器类。
方法二:
procedure RegisterComponentEditor(ComponentClass: TComponentClass;
ComponentEditor: TComponentEditorClass);
用于注册一个控件编辑器:

ComponentClass
使用该控件编辑器的控件

ComponentEditor
控件编辑器类。


 
谢谢各位!
to HD_Copy:
你好像贴的是一个向导窗体的控件,与我说的向导略有不同。:)
to lqy:
谢谢你的贴子,不过我在这里说的只是指你文章中说的第一种,即Expert,现在Delphi
中也称为Wizard。主要有以下几种形式,一是出现在New...对话框中,用于新建一个窗体
或者程序;出现在Help菜单或其他菜单里,启动后可以与Delphi环境相作用,如Code View
一样。

仍感谢各位!!
 
Pan Ying兄,好久没联系了,还在研究向导哩!
呵呵,CnPack向导组中兴有望了:)
对了,开发组内部发的邮件你收到没?为何不见你加入共创软件联盟啊?
 
向高手学习~
 
Pan Ying兄,你近来很忙吗?
 
pagecontroler
new几个page出来
除了第一个之外,其他的visible属性设置为false
每一页都作按钮,按下之后本页的visible变为false,下一页的变为true
你要的是这个吗?
 
to yygw
工作还没找到

to esimon
不好意思,不是这个意思。 :D
 
Pan Ying兄,我相信以你的能力,一定会有满意的收获的,记得开发组还有很多朋友在
关心你啊!
 
一个简单的例子:
unit DumbWiz;

interface

uses
ShareMem, SysUtils, Windows, ToolsAPI;

type
TDumbWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard)
// IOTAWizard methods
function GetIDString: string;
function GetName: string;
function GetState: TWizardState;
procedure Execute;
// IOTAMenuWizard method
function GetMenuText: string;
end;

procedure Register;

implementation

uses Dialogs;

function TDumbWizard.GetName: string;
begin
Result := 'Dumb Wizard';
end;

function TDumbWizard.GetState: TWizardState;
begin
Result := [wsEnabled];
end;

function TDumbWizard.GetIDString: String;
begin
Result := 'DDG.DumbWizard';
end;

procedure TDumbWizard.Execute;
begin
MessageDlg('This is a dumb wizard.', mtInformation, [mbOk], 0);
end;

function TDumbWizard.GetMenuText: string;
begin
Result := 'Dumb Wizard';
end;

procedure Register;
begin
RegisterPackageWizard(TDumbWizard.Create);
end;

end.
 
忙于自己的事,一直没有来看,:(
谢谢各位朋友的关心。
在5月份关闭本贴,如果我有新的发现,会在这里贴出来的。
 
后退
顶部