Сергей Горбань дата публикации 16-12-2002 18:47 Правильные диалоги от Борланда
Дополнение от 19.12.02
Почитал тут статью "Пишем правильные диалоги". Гммм.. Все в целом
верно, но неудобно. Не хочу обижать автора, но он изобрел велосипед.
Если покопаться в фирменных "Дельфовых" примерах, можно найти ГОРАЗДО
более удачную конструкцию (которую, кстати, я уже давно использую).
Еще раз подчеркну - это не моя придумка, а ребят из Борланда.
Эта конструкция позволяет:
- Возвращать ЛЮБЫЕ значения;
- ДИНАМИЧЕСКИ создавать форму;
- Еще куча всяких "бонусов", просто лень описывать :-)
Итак, смотрим исходники...
В этом примере я привел два наиболее
типичных случая. 1-й - InputString - просто ввод, без анализа отмены,
второй - MrInputString - с анализом отмены ввода (ModalResult).
Оба случая используют начальные значения. Без них - Еще проще...
В принципе - ваша фантазия ничем не ограничивается. Я, например,
храню последние вводившиеся значения в реестре и читаю их оттуда после
создания формы. Удобно.
Пользователь не мается вводя по 10 раз одно и
то же, а у меня не болит голова с инициализацией полей (есть
специальный класс, который этим занимается, но это отдельная тема...)
ИСХОДНИКИ:
implementation
uses
Dialog;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
ShowMessage('Вы ввели '+InputString('Начальное значение'));
end;
procedure TForm1.BitBtn2Click(Sender: TObject);
Var
Str: String;
begin
Str:='Начальное значение';
If MrInputString(Str) = mrOk Then
ShowMessage('Вы ввели '+Str)
Else
ShowMessage('Вы отменили ввод');
end;
unit Dialog;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, Buttons;
type
TOptionsDlg = class(TForm)
Bevel1: TBevel;
BitBtn1: TBitBtn;
BitBtn2: TBitBtn;
Edit1: TEdit;
Label1: TLabel;
Bevel2: TBevel;
Label3: TLabel;
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
public
end;
var
OptionsDlg: TOptionsDlg;
function InputString(BeginVal: String): String;
function MrInputString(Var Str: String): TModalResult;
implementation
function InputString(BeginVal: String): String;
begin
With TOptionsDlg.Create(Application.MainForm) do
Try
Edit1.Text:=BeginVal;
If ShowModal = mrOk Then
Result:=Edit1.Text
Else
Result:='"Отмена"';
Finally
Free;
End;
end;
function MrInputString(Var Str: String): TModalResult;
begin
With TOptionsDlg.Create(Application.MainForm) do
Try
Edit1.Text:=Str;
Result:=ShowModal;
Str:=Edit1.Text;
Finally
Free;
End;
end;
procedure TOptionsDlg.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
Case Key of
27: ModalResult:=mrCancel;
13: ModalResult:=mrOk;
End;
end;
end.
| |
Не столько в качестве "ответов", сколько в качестве самостоятельного дополнения и пояснения
к статье.
>>Еще куча всяких "бонусов", просто лень описывать
>Никаких других бонусов не наблюдаю.
Ну, что же, перечислю...
Первоначальный вариант Игоря Василенко
with TMyDlg.Create(nil) do
try
if execute then
...
begin
end;
finally
free;
end;
| |
Мой вариант
ShowMessage('Вы ввели '+InputString('Начальное значение')); | |
Другие Бонусы:
-
Лаконичность вызова. Краткая форма - "SomeVar:=InputString;" - что, согласитесь, гораздо
лаконичнее... Если вам нужен ввод данных в одном-двух местах
программы, это особого значения не имеет, но в случае, когда таких мест в
программе 100-150... Экономия 8 строк может показаться весьма ощутимой...
- ДО показа формы определяются начальные значения контролов.
Поверьте, иногда это ОЧЕНЬ важно!
- Возможна работа практически с любым кол-вом и качеством данных.
Видимо не все понимают как это делается. Поясню: например надо
передать 10 строковых переменных (поля какой-нить формы). Делаем
вот так: (пример переехал выше. в первую часть письма :-))
> К тому же проверка правильности введенного значения будет производится,
> как я понял на основе исходников, после выхода из формы диалога.
> Я предпочитаю делать это до, чтобы дать пользователю возможность исправить
> ошибку без повторного открытия диалога.
Итак. Оговорка №1 - это концепт!!! Я специально сидел и удалял
незначащий код! Проверки, защиту от ошибок и т.д.!
Кроме того, а это что???
If ShowModal = mrOk Then
Result:=Edit1.Text
Else
Result:='"Отмена"';
| |
Итак...
Во первых, основная цель написания такого рода диалогов -
СТАНДАРТИЗАЦИЯ процедур и интерфейсов ввода.
Вторая задача - РАЗГРУЗИТЬ код ОСНОВНЫХ модулей программы. Т.е. Чем
короче вызов диалога - тем лучше. Крайне желательно, чтобы основной
модуль получал ТОЛЬКО результат ввода (успех/НЕуспех) и, в случае
успешного ввода - данные. Все. Все проверки, защита и т.д. ДОЛЖНЫ быть
ВЫНЕСЕНЫ из рабочих модулей программы. Если ввод с ограничением
диапазонов и т.д. - пишите диалог, принимающий на вход список ограничений и
реализующий их! Не тащите это в основной модуль!
> Возвращает единственное строковое значение, а зачастую их должно быть
> несколько.
> Что делать? Запихивать все в строку, а после проводить разбор на мой взгляд
> неприемлемо.
Ок. Приведу пример ввода МНОГИХ переменных. Да еще и по именам, да
еще и в разных комбинациях и количествах...
function InputStringsByName(BeginVal: TStrings): TModalResult;
Var
i: Integer;
Cmpnt: TComponent;
begin
With TOptionsDlg.Create(Application.MainForm) do
Try
For i:= 0 to BeginVal.Count - 1 do
begin
Cmpnt:=FindComponent(BeginVal.Names[i]);
If Cmpnt is TEdit Then
(Cmpnt as TEdit).Text:=BeginVal.ValueFromIndex[i]
Else
Try
If Cmpnt is TSpinEdit Then
(Cmpnt as TSpinEdit).Value:=StrToInt(BeginVal.ValueFromIndex[i])
Except
End;
end;
Result:=ShowModal;
If Result = mrOk Then
For i:= 0 to BeginVal.Count - 1 do
begin
Cmpnt:=FindComponent(BeginVal.Names[i]);
If Cmpnt is TEdit Then
BeginVal.ValueFromIndex[i]:=(Cmpnt as TEdit).Text
Else
Try
If Cmpnt is TSpinEdit Then
BeginVal.ValueFromIndex[i]:=IntToStr((Cmpnt asTSpinEdit).Value);
Except
End;
end;
Finally
Free;
End;
end;
| |
Для особо непонятливых можно дописать, что ф-ии проверок, защиты
и конвертации данных следует добавить по вкусу!
добавлено 19.12.02
Скачать:
Исходники - для Delphi 6.
Главное отличие - формат файлов форм... Остальное должно работать "на ура"
[TForm] [Создание компонентов в run-time] [Стандартные диалоги]
Обсуждение материала [ 27-12-2002 09:24 ] 12 сообщений |