TCSCode
asked on
How do I make a install app act like installshield
How do I make a install program act like installshield, i would like to make a install program but i don't know how to make the forms go back and forth like installshield does. i want to have three buttons "Back, Next, and Cancel". When the next butoon is pressed, I want the next form to show and the current form to hide. When i press the back button i want it to goto the previous form. How can i do this? examples code please. TCSCode.
Here's an example of how to use it - I have snipped out a bunch of code that really serves to confuse the issue - it pretty simple, the form has a page control with a number of pages on it as well as Next, Prev, Cancel and Finish buttons...
Give me a yell if you have any questions...
unit CrashPayment;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, AdvGrid, ComCtrls, RippleComps, ExtCtrls,
Mortgages,
RippleForms;
type
TCrashPaymentWizardForm = class(TRippleForm)
// Big snip for brevity
btnHelp: TButton;
btnPrevious: TButton;
btnFinish: TButton;
bntNext: TButton
// Another big snip
procedure btnPreviousClick(Sender: TObject);
procedure bntNextClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnHelpClick(Sender: TObject);
procedure MemoEnter(Sender: TObject);
procedure btnFinishClick(Sender: TObject);
procedure PageControl1Change(Sender: TObject);
procedure PageControl1Changing(Sende r: TObject;
var AllowChange: Boolean);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SetButtonEnablement;
end;
var
CrashPaymentWizardForm: TCrashPaymentWizardForm;
implementation
uses
WizardUtils,
ImageModule,
MortCalcDecls;
{$R *.DFM}
procedure TCrashPaymentWizardForm.bt nPreviousC lick(Sende r: TObject);
begin
WizardChangePageControlTab (PageContr ol1,
WizardFindTheNextPage(Page Control1, false),
Image1, SetButtonEnablement);
end;
procedure TCrashPaymentWizardForm.bn tNextClick (Sender: TObject);
begin
WizardChangePageControlTab (PageContr ol1,
WizardFindTheNextPage(Page Control1, true),
Image1, SetButtonEnablement);
end;
procedure TCrashPaymentWizardForm.Fo rmCreate(S ender: TObject);
begin
PageControl1.ActivePage := PageControl1.Pages[0];
SetButtonEnablement;
end;
procedure TCrashPaymentWizardForm.Se tButtonEna blement;
begin
btnPrevious.Enabled := PageControl1.Pages[0] <> PageControl1.ActivePage;
bntNext.visible := WizardFindTheNextPage(Page Control1, true) <> Nil;
btnFinish.visible := not bntNext.visible;
end;
procedure TCrashPaymentWizardForm.bt nFinishCli ck(Sender: TObject);
var
AllowChange : Boolean;
begin
AllowChange := True;
PageControl1Changing(PageC ontrol1.Ac tivePage, AllowChange);
if not AllowChange then
exit;
ModalResult := mrOK;
end;
procedure TCrashPaymentWizardForm.Pa geControl1 Change(Sen der: TObject);
var
// I : integer;
FreeIncome : Double;
begin
If PageControl1.ActivePage = NameTab then
begin
ActiveControl := ScenarioNameEdit;
ScenarioNameEdit.Text := TheScenario.Name;
ScenarioDescriptionEdit.te xt := TheScenario.Description;
end;
// Etc...
end;
procedure TCrashPaymentWizardForm.Pa geControl1 Changing(S ender: TObject;
var AllowChange: Boolean);
//var
// I : Integer;
begin
AllowChange := False;
If PageControl1.ActivePage = NameTab then
begin
if not (ScenarioNameEdit.CheckVal id) then
exit;
if ScenarioDescriptionEdit.te xt = '' then
begin
ShowMessage('Please supply a description');
exit;
end;
TheScenario.Name := ScenarioNameEdit.Text;
TheScenario.Description := ScenarioDescriptionEdit.te xt;
end;
//Etc...
AllowChange := True;
end;
procedure TCrashPaymentWizardForm.Bu tton2Click (Sender: TObject);
begin
if MessageDlg('Do you want to cancel setting up this crash repayment scenario?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
TheScenario.Free;
ModalResult := mrCancel;
end;
end;
end.
Give me a yell if you have any questions...
unit CrashPayment;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids, AdvGrid, ComCtrls, RippleComps, ExtCtrls,
Mortgages,
RippleForms;
type
TCrashPaymentWizardForm = class(TRippleForm)
// Big snip for brevity
btnHelp: TButton;
btnPrevious: TButton;
btnFinish: TButton;
bntNext: TButton
// Another big snip
procedure btnPreviousClick(Sender: TObject);
procedure bntNextClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnHelpClick(Sender: TObject);
procedure MemoEnter(Sender: TObject);
procedure btnFinishClick(Sender: TObject);
procedure PageControl1Change(Sender:
procedure PageControl1Changing(Sende
var AllowChange: Boolean);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
procedure SetButtonEnablement;
end;
var
CrashPaymentWizardForm: TCrashPaymentWizardForm;
implementation
uses
WizardUtils,
ImageModule,
MortCalcDecls;
{$R *.DFM}
procedure TCrashPaymentWizardForm.bt
begin
WizardChangePageControlTab
WizardFindTheNextPage(Page
Image1, SetButtonEnablement);
end;
procedure TCrashPaymentWizardForm.bn
begin
WizardChangePageControlTab
WizardFindTheNextPage(Page
Image1, SetButtonEnablement);
end;
procedure TCrashPaymentWizardForm.Fo
begin
PageControl1.ActivePage := PageControl1.Pages[0];
SetButtonEnablement;
end;
procedure TCrashPaymentWizardForm.Se
begin
btnPrevious.Enabled := PageControl1.Pages[0] <> PageControl1.ActivePage;
bntNext.visible := WizardFindTheNextPage(Page
btnFinish.visible := not bntNext.visible;
end;
procedure TCrashPaymentWizardForm.bt
var
AllowChange : Boolean;
begin
AllowChange := True;
PageControl1Changing(PageC
if not AllowChange then
exit;
ModalResult := mrOK;
end;
procedure TCrashPaymentWizardForm.Pa
var
// I : integer;
FreeIncome : Double;
begin
If PageControl1.ActivePage = NameTab then
begin
ActiveControl := ScenarioNameEdit;
ScenarioNameEdit.Text := TheScenario.Name;
ScenarioDescriptionEdit.te
end;
// Etc...
end;
procedure TCrashPaymentWizardForm.Pa
var AllowChange: Boolean);
//var
// I : Integer;
begin
AllowChange := False;
If PageControl1.ActivePage = NameTab then
begin
if not (ScenarioNameEdit.CheckVal
exit;
if ScenarioDescriptionEdit.te
begin
ShowMessage('Please supply a description');
exit;
end;
TheScenario.Name := ScenarioNameEdit.Text;
TheScenario.Description := ScenarioDescriptionEdit.te
end;
//Etc...
AllowChange := True;
end;
procedure TCrashPaymentWizardForm.Bu
begin
if MessageDlg('Do you want to cancel setting up this crash repayment scenario?',
mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
TheScenario.Free;
ModalResult := mrCancel;
end;
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls;
const
NUM_PANELS = 3;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
Edit1: TEdit;
Panel2: TPanel;
Edit2: TEdit;
Panel3: TPanel;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
pn: Integer;
procedure SelectPanel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
pn := 1;
SelectPanel;
end;
procedure TForm1.Button2Click(Sender : TObject);
begin
if pn > 1 then
begin
dec(pn);
SelectPanel;
end;
end;
procedure TForm1.Button3Click(Sender : TObject);
begin
if pn < NUM_PANELS then
begin
Inc(pn);
SelectPanel;
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
close;
end;
procedure TForm1.SelectPanel;
var i: Integer;
begin
for i := 1 to NUM_PANELS do
TPanel(FindComponent('Pane l' + IntToStr(i))).Visible := (i = pn);
end;
end.
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls;
const
NUM_PANELS = 3;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
Edit1: TEdit;
Panel2: TPanel;
Edit2: TEdit;
Panel3: TPanel;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
pn: Integer;
procedure SelectPanel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
pn := 1;
SelectPanel;
end;
procedure TForm1.Button2Click(Sender
begin
if pn > 1 then
begin
dec(pn);
SelectPanel;
end;
end;
procedure TForm1.Button3Click(Sender
begin
if pn < NUM_PANELS then
begin
Inc(pn);
SelectPanel;
end;
end;
procedure TForm1.Button1Click(Sender
begin
close;
end;
procedure TForm1.SelectPanel;
var i: Integer;
begin
for i := 1 to NUM_PANELS do
TPanel(FindComponent('Pane
end;
end.
TCS,
I'd have to say Eps has got it right mate. Use a single form with several panels of the same size and just hold a variable for each panel i.e.
procedure nextbuttonclick
begin
Case (panelnumber) of
1:begin
end;
2:begin
end;
and so on.... then have an identical event handler for the backbuttonclick
Gabe
I'd have to say Eps has got it right mate. Use a single form with several panels of the same size and just hold a variable for each panel i.e.
procedure nextbuttonclick
begin
Case (panelnumber) of
1:begin
end;
2:begin
end;
and so on.... then have an identical event handler for the backbuttonclick
Gabe
Gabe: Why do you say that?
TCSCode: I should mention that you set the pages in the page control to hide their tab (ShowTab = False in object inspector).
Cheers,
Raymond.
TCSCode: I should mention that you set the pages in the page control to hide their tab (ShowTab = False in object inspector).
Cheers,
Raymond.
Sorry Ray but the main massive application I have worked on with Delphi I started out using a pagecontrol and although it was easier to deal with in the IDE (slightly) in the long run the code is significantly more extensive for the pc (look at the difference between your example and eps) not to mention that PC's are flashy and dont switch smoothly through each other as a set of panels does which is why in my app I used panels and have found it alot easier to use. This is of course just my opinion and I am not as advanced as you Ray, as is evidenced by our Expert points lol :P but from my own personal experience, panels is the way to go.
Gabe
Gabe
Gabe: The code I posted perhaps does a little more than TSCCode requires as it supports removing pages from the 'wizard' without actually removing them from the page control itself.
I wrote the 'wizard' code as I have a number of wizards in my Mortgage Planner application - it made the amount of code required to manage each individual wizard quite small...
I have written several apps which use PCs extensively (even nested ones) with no flicker problems (though you have said in another thread you were using lots of images etc).
Well, TCSCode - its your call.
Cheers,
Raymond.
I wrote the 'wizard' code as I have a number of wizards in my Mortgage Planner application - it made the amount of code required to manage each individual wizard quite small...
I have written several apps which use PCs extensively (even nested ones) with no flicker problems (though you have said in another thread you were using lots of images etc).
Well, TCSCode - its your call.
Cheers,
Raymond.
Raymond, Showtab := false means that the content of that tab will be invisible to I guess.....
Oops - There's no ShowTab property, I meant the TabVisible property.
(And no Epsylon, it doesn't mean the content of the tab is invisible :-)
Cheers,
Raymond.
(And no Epsylon, it doesn't mean the content of the tab is invisible :-)
Cheers,
Raymond.
Raymond, what about the SelectNext method:
procedure TForm1.NextButtonClick(Sen der: TObject);
begin
PageControl1.SelectNextPag e(true);
end;
procedure TForm1.BackButtonClick(Sen der: TObject);
begin
PageControl1.SelectNextPag e(false);
end;
procedure TForm1.NextButtonClick(Sen
begin
PageControl1.SelectNextPag
end;
procedure TForm1.BackButtonClick(Sen
begin
PageControl1.SelectNextPag
end;
ASKER
Sorry rwilson, But I have to award Epsylon with the points. Epsylon's code is easier and smaller.
ASKER
Epsylon answer this message for your points. Thank's for the help.
Thanks a lot TCSCode.
The answer is:
Use a few panels and stack them on top of each other. Make sure the panel's name are: Panel1, Panel2, ... Paneln.
Here is the code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls;
const
NUM_PANELS = 3;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
Edit1: TEdit;
Panel2: TPanel;
Edit2: TEdit;
Panel3: TPanel;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
pn: Integer;
procedure SelectPanel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
pn := 1;
SelectPanel;
end;
procedure TForm1.Button2Click(Sender : TObject);
begin
if pn > 1 then
begin
dec(pn);
SelectPanel;
end;
end;
procedure TForm1.Button3Click(Sender : TObject);
begin
if pn < NUM_PANELS then
begin
Inc(pn);
SelectPanel;
end;
end;
procedure TForm1.Button1Click(Sender : TObject);
begin
close;
end;
procedure TForm1.SelectPanel;
var i: Integer;
begin
for i := 1 to NUM_PANELS do
TPanel(FindComponent('Pane l' + IntToStr(i))).Visible := (i = pn);
end;
end.
Epsylon :o)
The answer is:
Use a few panels and stack them on top of each other. Make sure the panel's name are: Panel1, Panel2, ... Paneln.
Here is the code:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ExtCtrls;
const
NUM_PANELS = 3;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Panel1: TPanel;
Edit1: TEdit;
Panel2: TPanel;
Edit2: TEdit;
Panel3: TPanel;
Edit3: TEdit;
procedure FormCreate(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
pn: Integer;
procedure SelectPanel;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
pn := 1;
SelectPanel;
end;
procedure TForm1.Button2Click(Sender
begin
if pn > 1 then
begin
dec(pn);
SelectPanel;
end;
end;
procedure TForm1.Button3Click(Sender
begin
if pn < NUM_PANELS then
begin
Inc(pn);
SelectPanel;
end;
end;
procedure TForm1.Button1Click(Sender
begin
close;
end;
procedure TForm1.SelectPanel;
var i: Integer;
begin
for i := 1 to NUM_PANELS do
TPanel(FindComponent('Pane
end;
end.
Epsylon :o)
epsylon: SelectNextPage is fine as long as you don't want the OnChange and OnChanging methods called. Of course this sucks badly when you're building a wizard as you need to validate the pages.
TCSCode: Well, as I say, it's your choice. Personally I think you are actually making work for yourself using panels, but that's just my opinion. Good luck.
Cheers,
Raymond.
TCSCode: Well, as I say, it's your choice. Personally I think you are actually making work for yourself using panels, but that's just my opinion. Good luck.
Cheers,
Raymond.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh yeah, epsylon, your answer won't like reordering pages :-) (just another case where PC's are actually rather useful.
Cheers,
Raymond.
Cheers,
Raymond.
Raymond, to be honest, when I saw this question yesterday I wanted to answer this question with a PageControl solution as well the solution I just submitted as an answer. But when I saw that you answered it already I omitted the PageControl version. When I just came here I was supprised to see that I was asked to submit it.
Let TCSCode decide....
Epsylon.
Let TCSCode decide....
Epsylon.
ASKER
Hi Epsylon,
Heres yours points, Thank's again.
Heres yours points, Thank's again.
ASKER
Hi rwilson,
Yes your code might save me work, if you can email me a copy of your code working to hyperon@eudoramail.com, then i will also reward you with points aswel.
TCSCode.
Yes your code might save me work, if you can email me a copy of your code working to hyperon@eudoramail.com, then i will also reward you with points aswel.
TCSCode.
TSCCode: I am emailing 'wizard.zip' to you, its a full project showing a simple three page PC - it also includes an image - note that the image is moved between pages 'cos I tend to use the same one for all pages in a particular wizard...
Cheers,
Raymond.
Cheers,
Raymond.
ASKER
Great Thank's.
unit WizardUtils;
interface
uses
ComCtrls,
extctrls;
type
TSetButtonEnablement = procedure of Object;
function WizardFindTheNextPage(Page
GoForward: Boolean): TTabSheet;
procedure WizardChangePageControlTab
Tab : TTabSheet;
Image : TImage;
SetButtonEnablement : TSetButtonEnablement);
implementation
function WizardFindTheNextPage(Page
GoForward: Boolean): TTabSheet;
var
increment : Integer;
begin
Result := PageControl.ActivePage;
if GoForward then
Increment := 1
else
Increment := -1;
if (Result.PageIndex + Increment >= 0) and
(Result.PageIndex + Increment <= PageControl.Pagecount - 1) then
repeat
Result := PageControl.Pages[Result.P
until (Result.Enabled or
(Result.PageIndex = 0) or
(Result.PageIndex = PageControl.PageCount - 1))
else
Result := Nil;
if assigned(Result) and not Result.Enabled then
Result := Nil;
end;
procedure WizardChangePageControlTab
Tab : TTabSheet;
Image : TImage;
SetButtonEnablement : TSetButtonEnablement);
var
AllowChange : Boolean;
begin
if not assigned(Tab) then
exit;
AllowChange := True;
if Assigned(PageControl.OnCha
PageControl.OnChanging(Tab
if AllowChange then
begin
if assigned(Image) then
Image.Parent := Tab;
PageControl.ActivePage := Tab;
SetButtonEnablement;
if Assigned(PageControl.OnCha
PageControl.OnChange(Tab);
end;
end;
end.
Cheers,
Raymond.