Задался вопросом создания "мастера" для чего нибудь.
Наш мастер должен иметь страницу приветствия, финиша и разные прочие страницы.
Итак, что мы делаем. На форму кидаем TopPanel (TPanel), pcWizard (TPageControl), Bevel1 (TBevel) и ActionList. Для начала разберемся с верхней панелью. Я поместил там lblCaption и lblHint (TLabel), а также картинку.
В pcWizard создаем 3 закладки: tsWelcome, tsFinish, tsPage1. Первые две будут очень похожие, даже одинаковые, только текст будет разный. На них помещает текст приветствия и какую-нибудь подходящую картинку. Картинка желательно большего размера по высоте.
В ActionList создаем 3 события (Action): acNext, acBack, acCancelDone.
В TBevel размещаем 3 кнопки: "Назад", "Далее", "Отмена". И присваиваем им соответствующие события из ActionList.
На странице tsPage1 для демонстрации разместим один CheckBox. Переход далее будет осуществляться только если он отмечен.
Ну вот и все с дизайном. Переходим к коду.
При старте нашей формы нам нужно убрать шапки с закладок. В FormCreate напишем.
type
TDialogWizard = class(TForm)
.....
public
procedure CheckWhenPageActive;
...
end;
procedure TDialogWizard.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 0 to pcWizard.PageCount - 1 do
pcWizard.Pages[i].TabVisible := False;
pcWizard.ActivePage := tsWelcome;
CheckWhenPageActive;
end;
Здесь мы скрыли все заголовки со страниц, установили стартовую и запустили процедуру CheckWhenPageActive. Она отвечает за отображение верхней панели, текста на ней и отображение кнопок навигации. Вот ее код:
var
DialogWizard: TDialogWizard;
PNextPage, PPrevPage: ^TTabSheet;
.....
procedure TDialogWizard.CheckWhenPageActive;
var
PPage : ^TTabSheet;
begin
PPage := @(pcWizard.ActivePage);
if PPage^ = tsWelcome then
begin
TopPanel.Visible := false;
PNextPage := @tsPage1;
PPrevPage := nil;
end;
if PPage^ = tsFinish then
begin
TopPanel.Visible := false;
PNextPage := nil;
PPrevPage := nil;
acCancelDone.Caption := 'Готово';
end;
if PPage^ = tsPage1 then
begin
TopPanel.Visible := true;
PNextPage := @tsFinish;
PPrevPage := nil;
lblCaption.Caption := '';
lblHint.Caption := '';
end;
acNext.Visible := PNextPage <> nil;
acBack.Visible := PPrevPage <> nil;
end;
В процедуре проверяем какая страница активна. Для каждой страницы нам необходимо указать предыдущую страницу и следующую (указатели PNextPage, PPrevPage: ^TTabSheet). Можно было бы и просто менять с помощью SelectNextPage, но тогда их надо в дизайнере отсортировать по очередности. А если надо пропустить? Я решил указывать это для каждой страницы. Если какая-либо ссылка не указана, то и соответствующая кнопка не будет видна. Например: tsWelcome - видна кнопка далее, следующая страница tsPage1. А у tsPage1, появилась возможность отображать заголовок и комментарий к странице. TopPanel.Visible := true - говорит, о том, что верхняя панель будет показана.
Итак мы знаем какая страница будет следующей. Начинаем обрабатывать переход.
procedure TDialogWizard.acNextExecute(Sender: TObject);
begin
if AllowChangePage then
begin
pcWizard.ActivePage := PNextPage^;
CheckWhenPageActive;
end;
end;
Функция AllowChangePage проверяет, можно ли переходить к следующей странице. Если она принимает значение TRUE, то переходим к следующей странице. Вот ее код:
type
TDialogWizard = class(TForm)
.....
private
function AllowChangePage: boolean;
.....
end;
function TDialogWizard.AllowChangePage: boolean;
var
PPage : ^TTabSheet;
begin
result := true;
PPage := @(pcWizard.ActivePage);
if PPage^ = tsPage1 then
begin
result := CheckBox1.Checked;
end;
end;
Помните на tsPage1 мы кидали CheckBox. Так вот эта функция проверяет отмечен он или нет, и либо разрешает, либо запрещает переход.
С переходом назад проще. Просто переходим назад.
procedure TDialogWizard.acBackExecute(Sender: TObject);
begin
pcWizard.ActivePage := PPrevPage^;
CheckWhenPageActive;
end;
Осталась кнопка "Отмена/Готово". Тут тоже все просто.
procedure TDialogWizard.acCancelDoneExecute(Sender: TObject);
begin
if pcWizard.ActivePage <> tsFinish then
close
else
begin
// Тут что-то делаем.
close;
end;
end;
Если страница не последняя (tsFinish), то закрываем мастер, а нет можем выполнить отмену произведенных операций к примеру и закрыть.
Ну вот и все. Подведет итог.
Мы имеем 2 процедуры в которых отрабатывается страница:
CheckWhenPageActive - Определяем что показывать, а что нет. + Навигация.
AllowChangePage - Делаем проверку на странице.
Что-то делать в мастере можно по ходу выполнения в процедуре AllowChangePage, либо создать еще страницу, ну скажем tsProgress и делать все на ней. Но опять же в процедуре AllowChangePage. Можно организовать отмену каких-либо операций в процедуре acCancelDoneExecute.
Ну что же, удачи.
Исходник проекта DialogWizard
Наш мастер должен иметь страницу приветствия, финиша и разные прочие страницы.
Страница приветствия
Рабочая страница
Итак, что мы делаем. На форму кидаем TopPanel (TPanel), pcWizard (TPageControl), Bevel1 (TBevel) и ActionList. Для начала разберемся с верхней панелью. Я поместил там lblCaption и lblHint (TLabel), а также картинку.
В pcWizard создаем 3 закладки: tsWelcome, tsFinish, tsPage1. Первые две будут очень похожие, даже одинаковые, только текст будет разный. На них помещает текст приветствия и какую-нибудь подходящую картинку. Картинка желательно большего размера по высоте.
В ActionList создаем 3 события (Action): acNext, acBack, acCancelDone.
В TBevel размещаем 3 кнопки: "Назад", "Далее", "Отмена". И присваиваем им соответствующие события из ActionList.
На странице tsPage1 для демонстрации разместим один CheckBox. Переход далее будет осуществляться только если он отмечен.
Ну вот и все с дизайном. Переходим к коду.
При старте нашей формы нам нужно убрать шапки с закладок. В FormCreate напишем.
type
TDialogWizard = class(TForm)
.....
public
procedure CheckWhenPageActive;
...
end;
procedure TDialogWizard.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i := 0 to pcWizard.PageCount - 1 do
pcWizard.Pages[i].TabVisible := False;
pcWizard.ActivePage := tsWelcome;
CheckWhenPageActive;
end;
Здесь мы скрыли все заголовки со страниц, установили стартовую и запустили процедуру CheckWhenPageActive. Она отвечает за отображение верхней панели, текста на ней и отображение кнопок навигации. Вот ее код:
var
DialogWizard: TDialogWizard;
PNextPage, PPrevPage: ^TTabSheet;
.....
procedure TDialogWizard.CheckWhenPageActive;
var
PPage : ^TTabSheet;
begin
PPage := @(pcWizard.ActivePage);
if PPage^ = tsWelcome then
begin
TopPanel.Visible := false;
PNextPage := @tsPage1;
PPrevPage := nil;
end;
if PPage^ = tsFinish then
begin
TopPanel.Visible := false;
PNextPage := nil;
PPrevPage := nil;
acCancelDone.Caption := 'Готово';
end;
if PPage^ = tsPage1 then
begin
TopPanel.Visible := true;
PNextPage := @tsFinish;
PPrevPage := nil;
lblCaption.Caption := '';
lblHint.Caption := '';
end;
acNext.Visible := PNextPage <> nil;
acBack.Visible := PPrevPage <> nil;
end;
В процедуре проверяем какая страница активна. Для каждой страницы нам необходимо указать предыдущую страницу и следующую (указатели PNextPage, PPrevPage: ^TTabSheet). Можно было бы и просто менять с помощью SelectNextPage, но тогда их надо в дизайнере отсортировать по очередности. А если надо пропустить? Я решил указывать это для каждой страницы. Если какая-либо ссылка не указана, то и соответствующая кнопка не будет видна. Например: tsWelcome - видна кнопка далее, следующая страница tsPage1. А у tsPage1, появилась возможность отображать заголовок и комментарий к странице. TopPanel.Visible := true - говорит, о том, что верхняя панель будет показана.
Итак мы знаем какая страница будет следующей. Начинаем обрабатывать переход.
procedure TDialogWizard.acNextExecute(Sender: TObject);
begin
if AllowChangePage then
begin
pcWizard.ActivePage := PNextPage^;
CheckWhenPageActive;
end;
end;
Функция AllowChangePage проверяет, можно ли переходить к следующей странице. Если она принимает значение TRUE, то переходим к следующей странице. Вот ее код:
type
TDialogWizard = class(TForm)
.....
private
function AllowChangePage: boolean;
.....
end;
function TDialogWizard.AllowChangePage: boolean;
var
PPage : ^TTabSheet;
begin
result := true;
PPage := @(pcWizard.ActivePage);
if PPage^ = tsPage1 then
begin
result := CheckBox1.Checked;
end;
end;
Помните на tsPage1 мы кидали CheckBox. Так вот эта функция проверяет отмечен он или нет, и либо разрешает, либо запрещает переход.
С переходом назад проще. Просто переходим назад.
procedure TDialogWizard.acBackExecute(Sender: TObject);
begin
pcWizard.ActivePage := PPrevPage^;
CheckWhenPageActive;
end;
Осталась кнопка "Отмена/Готово". Тут тоже все просто.
procedure TDialogWizard.acCancelDoneExecute(Sender: TObject);
begin
if pcWizard.ActivePage <> tsFinish then
close
else
begin
// Тут что-то делаем.
close;
end;
end;
Если страница не последняя (tsFinish), то закрываем мастер, а нет можем выполнить отмену произведенных операций к примеру и закрыть.
Ну вот и все. Подведет итог.
Мы имеем 2 процедуры в которых отрабатывается страница:
CheckWhenPageActive - Определяем что показывать, а что нет. + Навигация.
AllowChangePage - Делаем проверку на странице.
Что-то делать в мастере можно по ходу выполнения в процедуре AllowChangePage, либо создать еще страницу, ну скажем tsProgress и делать все на ней. Но опять же в процедуре AllowChangePage. Можно организовать отмену каких-либо операций в процедуре acCancelDoneExecute.
Ну что же, удачи.
Исходник проекта DialogWizard