После метода Show формы нужно сделать "некоторые действия". Эта форма также должна быть модальной. Какие есть решения данного вопроса? Callback функция - тяжеловатое решение: не хочется создавать тип функции, хранить параметры ф-ии, условие вызова (т.к. не всегда после show нужно выполнять "некоторые действия"). Есть ли какая-то информация по Callback методам? Или надо сделать фиктивную ф-ию, содержащую данный метод?
IUnknown
23.06.2012 5:55
Цитата
Callback функция - тяжеловатое решение: не хочется создавать тип функции, хранить параметры ф-ии, условие вызова (т.к. не всегда после show нужно выполнять "некоторые действия").
Не надо ничего этого делать. Просто там, где нужно делать что-то при показе формы, после создания формы назначь обработчику OnShow адрес метода, который будет делать нужные вещи. Скажем:
procedure TForm1.DoMyAction(Sender : TObject); begin // Тут делаешь то, что нужно. Sender содержит указатель на форму, // которая показывается модально, так что и к свойствам этой формы // у тебя отсюда есть доступ через (Sender as TForm2).свойство end;
procedure TForm1.Button24Click(Sender: TObject); begin with tform2.Create(self) do begin OnShow := DoMyAction; ShowModal; end; end;
Можно то же самое переложить на конструктор (т.е, когда надо вызывать что-то дополнительное - то создавать форму вторым конструктором, который сам будет делать это присвоение OnShow, но тогда без описания типа для функции/процедуры уже не обойдется). Было бы больше информации (скажем, какого типа операции надо делать при показе формы, как вообще форма создается, почему именно модальной она должна быть) - был бы более развернутый ответ.
sheka
25.06.2012 17:46
2 формы создаются статически: Главная и Модальная. Модальная показывается только из Главной, именно поэтому она должна быть модальной. FormShow устанавливает какие-то начальные значения для Модальной формы. Так как в Модальной форме func(param); при показе, но уже работая с начальными данными, должна выполняться не всегда, а только по заказу - появился такой вопрос. Вот такое получилось: Как можно "культурно" передать параметр?
public param: string; procedure ShowWithFunc(Sender: TObject);
procedure ModalForm.ShowWithFunc(Sender: TObject); begin FormShow(Self); func(param); Self.OnShow := FormShow; end;
procedure TfrmViewMap.FormShow(Sender: TObject); begin // end;
IUnknown
25.06.2012 18:38
Цитата
2 формы создаются статически: Главная и Модальная.
Очень плохо. В этом случае у тебя модальная форма при втором запуске будет содержать все изменения, которые были внесены в состояние ее контролов при первой сессии работы с ней. Чтобы формы при всех запусках были одинаковы - надо создавать их динамически. Смотри что получается: положил я на форму твою BitBtn, которая передает '123' и делает какое-то действие при показе модальной формы. А действие сделал очень простое: изменить заголовок на этот самый параметр, т.е, на '123'. И рядом положил еще одну кнопку, которая просто показывает модально форму:
procedure MainForm.Button1Click(Sender: TObject); begin ModalForm.ShowModal; end;
Запускаю программу, и нажимаю сначала твою кнопку. Все прекрасно, заголовок изменился. Закрываю модальную форму, и жму свою кнопку. И чего я увижу в заголовке? А ведь я не просил этого, я хочу просто показать форму безо всяких действий. Понимаешь, о чем я? Со стороны-то выглядит так, как будто действие опять выполнено...
sheka
25.06.2012 20:28
Спасибо за подсказку, но мне как раз надо (наверное ), чтобы форма была таковой.
IUnknown
25.06.2012 23:58
Цитата(sheka @ 25.06.2012 16:28)
мне как раз надо (наверное ), чтобы форма была таковой.
Странное желание, но тебе виднее. Я бы не стал делать так, как делаешь ты. Если надо передавать параметры - делал бы вот так:
Модальная форма:
type TParams = class private p : string; public constructor Create(param : string); end;
// Магия - если надо стандартное поведение - вызываем DoShowModal без параметров // если надо что-то добавить - добавляем. Ниже увидишь, как. function DoShowModal (Params : TParams = nil) : Integer; end;
// ...
{ TModalForm } procedure TModalForm.func(s: string); // Это будет выполняться после Show begin Edit1.Text := s; end;
procedure TModalForm.ShowWithFunc(Sender: TObject); // Ну, это твоя функция begin FormShow(Self); func(param); Self.OnShow := FormShow; end;
function TModalForm.DoShowModal(Params: TParams): Integer; begin if Assigned(Params) then // Что-то передали? Значит, делаем доп. действия begin param := Params.p; OnShow := ShowWithFunc; end;
ShowModal;
if Assigned(Params) then // не забываем очистить память иначе будет утечка Params.Free; end;
procedure TModalForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caHide; // Чтобы быть уверенным, что форма не разрушится, а только скроется end;
procedure TModalForm.FormShow(Sender: TObject); begin // end;
{ TParams } constructor TParams.Create(param: string); begin p := param; // Собственно, ты можешь сделать гораздо больше одного конструктора // и передавать любые данные, включая и процедуры обработки тоже end;
А вот как это выглядит из главной формы:
// Это вызывает доп. действие после Show procedure TForm1.BitBtn1Click(Sender: TObject); begin ModalForm.DoShowModal(TParams.Create('123')); end;
// Это - вызовет только стандартный метод ShowModal procedure TForm1.Button1Click(Sender: TObject); begin ModalForm.DoShowModal; end;
Идея понятна?
sheka
27.06.2012 3:36
Да, спасибо, идея понятна.
sheka
17.07.2012 15:10
Как ни как параметры все равно надо хранить в описании класса формы, чтобы OnShow их оттуда поджирало, правильно? Другого выхода нет?
IUnknown
17.07.2012 15:55
Где-то же их все равно надо хранить, правда? А где, если у тебя форма показывается модально, то есть, после того, как она показана, управления она не вернет до тех пор, пока не завершится работа функции ShowModal? Только в классе формы.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.