Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];

Вниз

Господа, подскажите, как правидьно организовать большой проект   Найти похожие ветки 

 
Layner   (2003-11-10 13:18) [0]

(Для кого то может и не большой) в общем есть главная форма, а от неё показываются модальные (и не модальные) формы настроек и др. Почти на каждой второстепенной форме есть связь с БД, отображение таблиц в DBGrid. Второстепенные вызываю так form2.show...; Форм скопилось много, не сказать, чтобы экзешник вырос, но вот программа в памяти занимает почти столько же, сколько и WORD 2000, около 12мег. А если я ещё добавлю несколько, то думаю занимаемая память ещё вырастет. Вопрос, как правильно хранить и показывать формы? Т.е. я просто добавляю формы в проект по необходимости, и показываю их при необходимости, но выходит, что они создаются на этапе запуска, поэтому столько памяти и занимают? Файл DPR такой:

uses
Forms,
main in "main.pas" {mf},
tov in "tov.pas" {ft},
vid in "vid.pas" {fv},
ed in "ed.pas" {fe},
kl in "kl.pas" {fk},
ps in "ps.pas" {fp},
izd in "izd.pas" {fi},
pr in "pr.pas" {fpr},
ras in "ras.pas" {fra},
test in "test.pas" {ftest},
mthread in "mthread.pas",
status in "status.pas" {fstatus},
report in "report.pas" {frp},
nast in "nast.pas" {fn},
nr in "nr.pas" {fnr},
uHtmlHelp in "uHtmlHelp.pas",
scl in "scl.pas" {fs},
dm in "dm.pas" {dat: TDataModule},
temp in "temp.pas";

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(Tmf, mf);
Application.CreateForm(Tft, ft);
Application.CreateForm(Tfv, fv);
Application.CreateForm(Tfe, fe);
Application.CreateForm(Tfk, fk);
Application.CreateForm(Tfp, fp);
Application.CreateForm(Tfi, fi);
Application.CreateForm(Tfpr, fpr);
Application.CreateForm(Tfra, fra);
Application.CreateForm(Tftest, ftest);
Application.CreateForm(Tfstatus, fstatus);
Application.CreateForm(Tfrp, frp);
Application.CreateForm(Tfn, fn);
Application.CreateForm(Tfnr, fnr);
Application.CreateForm(Tfs, fs);
Application.CreateForm(Tdat, dat);
Application.Run;
end.


 
Layner   (2003-11-10 13:38) [1]

Ну хоть кто нибудь :(


 
Юрий Федоров   (2003-11-10 13:40) [2]

Создавай формы не сразу, а по мере необходимости


 
han-bratan   (2003-11-10 13:45) [3]

Идешь в свойства проекта и убираешь все формы кроме главной из колонки AutoCreate. А потом когда ты жмешь на кнопку показа какогто диалога то создаешь окно динамически:
MyDialog := TMyDialog.Create;
MyDialog.ShowModal;

или если он не модальный то:
var MyDialog: TMyDialog; - глобальная (или как аттрибут главного окна)

procedure ShowDialog;
begin
if not Assigned(MyDialog) then
MyDialog := TMyDialog.Create(...);
MyDialog.Show;
end;

соответственно на OnClose MyDialog должно быть
Action := caFree;

ну и всякое такое...


 
Anatoly Podgoretsky   (2003-11-10 13:46) [4]

Ты так больше не делай
Application.CreateForm(Tmf, mf);
Application.CreateForm(Tft, ft);
Application.CreateForm(Tfv, fv);
Application.CreateForm(Tfe, fe);
Application.CreateForm(Tfk, fk);
Application.CreateForm(Tfp, fp);
Application.CreateForm(Tfi, fi);
Application.CreateForm(Tfpr, fpr);
Application.CreateForm(Tfra, fra);
Application.CreateForm(Tftest, ftest);
Application.CreateForm(Tfstatus, fstatus);
Application.CreateForm(Tfrp, frp);
Application.CreateForm(Tfn, fn);
Application.CreateForm(Tfnr, fnr);
Application.CreateForm(Tfs, fs);
Application.CreateForm(Tdat, dat);


 
Layner   (2003-11-10 13:46) [5]

Юрий, спасибо, ответ понятен, я бы хотел посмотреть, как это делается, если есть в поставке delphi7,0 пример, то как его название.
А если второстепенные формы с 30 метками, 30 Edit и т.п. Это все руками описывать? Как потом к ним обращатся ? Но с этим разберусь, пример бы посмотреть..


 
Layner   (2003-11-10 13:49) [6]

Ты так больше не делай
Занать бы как правильно... Или в PAS описывать почти полностью список файла DFM?
.........
object mf: Tmf
Left = 236
Top = 114
Width = 730
Height = 591
Caption = #1057#1082#1083#1072#1076
Color = clBtnFace
Constraints.MinHeight = 591
Constraints.MinWidth = 730
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
Menu = mm
OldCreateOrder = False
Position = poDefault
OnClose = FormClose
OnCreate = FormCreate
OnResize = FormResize
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 442
Top = 29
.......


han-bratan спасибо, но это только с диалогами легко, а если на форме много элементов !?


 
Юрий Федоров   (2003-11-10 13:53) [7]

>>Layner © (10.11.03 13:49) [6]
Ты не понял, никто у тебя не отнимает возможности визуального редактора форм, речь идет всего лишь о экземплярах классов в run-time.

Application.Initialize;
Application.CreateForm(<главная форма>);
Application.Run;


 
Layner   (2003-11-10 13:53) [8]

А, в смысле вместо MyDialog можно использовать любую мою готовую форму? А обращение к элементам по их названию (Edit5, Edit6, Edit7..) формы сохранится?


 
mOOx_   (2003-11-10 13:56) [9]

Да, все так же, как если бы ты создат все вместе. Только Одна строка передиспользованием формы добавляется:

MyDialog := TMyDialog.Create(...);//где TMyDialog - предворительно созданная во время дизайна форма

Вот и все :).


 
Layner   (2003-11-10 13:59) [10]

Друзья спасибо!!! Что бы я делал без такой помощи, писал бы и дальше приложения, "тяжеловесы" :)
Классно!!


 
Anatoly Podgoretsky   (2003-11-10 14:06) [11]

Layner © (10.11.03 13:49) [6]
Близкое к идеалу описано здесь han-bratan (10.11.03 13:45) [3], я бы только рекомендовал отказаться от использования глобальных переменных, а обнаруживать форму в массиве Screen.Forms это сильно повысит надежность программ и еще допольнительно уменьшит потребность в ресурсах, но первое важнее.


 
mOOx_   (2003-11-10 14:13) [12]

Теперь я не догоняю: Screen.Forms - видимые формы. А тут форма не создана даже. Просто есть описание ее класса. Зачем использовать этот массив? Приведите пример, пожалуйста, или расскажите хоть.


 
Anatoly Podgoretsky   (2003-11-10 14:15) [13]

Созданные!!!
А твое желание никак не влиляет на это, массив существует независимо от твоего желания и плодить сущности ни к чему.


 
mOOx_   (2003-11-10 14:20) [14]

Ну, созданные. То есть, все равно сначала нужно создать экземпляр, а уж потом к нему обращаться. О каких сущностях Вы говорите?


 
BizonWar   (2003-11-10 15:23) [15]

Я хотел бы внести несколько соображений более общего характера.
Надеюсь, не оффтопик.
Большой проект (не проект Делфи, а типа "Склад" или "Предприятие") необходимо разбить на несколько т.н. "рабочих мест". Получится несколько не очень больших проектов (на Делфи). Часто оказывается, что огромное количество форм в проекте никому не нужно. Каждому пользователю нужны какие-то свои, но крайне редко все. Поэтому можно подумать на счет разбиения единого проекта на отдельные рабочие места.


 
Murad   (2003-11-10 15:46) [16]

Странно почему Юра Федоров ничего не сказал по этому поводу...
У тебя безобразное именование Форм и модулей! Исправь, а то потом будешь путаться.


 
Layner   (2003-11-10 16:41) [17]

Почему безобразное, начинается с f. далее, пара букв. т.к. слишком длинное имя неудобно писать в др. формах если обращаюсь из др. к ней. Главное, что понял в чем ошибка проектирования.


 
Sandman25   (2003-11-10 16:49) [18]

[17] Layner © (10.11.03 16:41)

Даже длинное имя файла показывается при нажатии Ctrl+space.
Пример. Набираеш fGet, жмешь Ctrl и пробел и из открывающегося списка с помощью Enter выбираешь fGetParamsForConnectToDatabase :)


 
Anatoly Podgoretsky   (2003-11-10 16:57) [19]

mOOx_ © (10.11.03 14:20) [14]
Двблирование ссылок и в массиве и в переменной, не нужны они в большинстве случаев, к тому же резко увеличивают количество ошибок, провоцируют к повторному использованию переменных.


 
Murad   (2003-11-10 17:02) [20]

2Layner
Не обижайся, но оно действительно безобразное... В проекте
(особенно в большом) просто НЕОБХОДИМО, чтобы названия были
говорящие...


 
Skier   (2003-11-10 17:05) [21]


> слишком длинное имя неудобно писать в др. формах если обращаюсь
> из др. к ней.

Но если оставить короткие имена, то потом будет слишком неудобно
разбираться в твоём проекте, особенно сторонним программистам.


> Главное, что понял в чем ошибка проектирования.

Такие (как у тебя) имена форм тоже являются ошибкой проектирования.


 
Anatoly Podgoretsky   (2003-11-10 17:13) [22]

Skier © (10.11.03 17:05) [21]
При том более страшной


 
Murad   (2003-11-10 17:22) [23]

Так просто вспомнилось насчет именования...
На старой работе был программист у которого все строковые поля были s1, s2, ss1, ss2, s....sN и т.п. Но самое главное чем он запомнился это модальным диалогом с 2мя кнопками OK, причем по каждой из них выполнялись разные действия :))))


 
Layner   (2003-11-13 11:20) [24]

При повторном вызове Form2 - ошибка в адресе ????? , и не освобождается память при закрытии Form2. :(
Form1:
uses Unit2;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(Form2) then
Form2 := TForm2.Create(nil);
Form2.Show;
end;


Form2:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;


 
HSolo   (2003-11-13 12:25) [25]

Естественно, будет ошибка.

Шаг 1. Сработало
Action := caFree;
Форму Вы уничтожили, но указатель на нее - пер-я Form2 - какая была, такая и осталась. И указывает все на то же место в памяти, только теперь там не экземпляр TForm2 сидит, а неизвестно что.

Шаг 2. Вызываем ф-ю Assigned. Она честно возвращает true, ибо никто пер-й Form2 nil не присвоил. Результат -
Form2 := TForm2.Create(nil);
не выполняется

Шаг 3.
Form2.Show;
А Form2-то указывает на мусор

Лучше в такой ситуации не пользуйтесь Assigned, а ищите форму в Screen.Forms; если не нашли - создайте, а потом спокойно показывайте.


 
Anatoly Podgoretsky   (2003-11-13 12:54) [26]

Основная ошибка в том, что используется глобальная переменная Form2 отсюда и все последствия.


 
Anatoly Podgoretsky   (2003-11-13 12:55) [27]

Глобальные переменные можно использовать, но тогда надо побеспокоить об их правильном и бесконфликтном использовании.


 
Vic   (2003-11-13 13:11) [28]

Если для TForm2 использовать только глобальную Form2

Form2:
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
Form2:=nil;
end;


 
Layner   (2003-11-13 13:15) [29]

Спасибо большое, разобрался.


 
MMF   (2003-11-13 13:30) [30]

>Vic (13.11.03 13:11) [28] А не в FormDestroy?


 
Silver Alex   (2003-11-13 13:33) [31]


> Layner © (13.11.03 11:20) [24]
> При повторном вызове Form2 - ошибка в адресе ????? , и не
> освобождается память при закрытии Form2. :(


попробуй это :))

function IsFormFoundEx(AFormClass :TFormClass) : boolean;
var
i:integer;
begin
Result:=False;

for i:=0 to Screen.FormCount - 1 do
if (Screen.Forms[i] is AFormClass) then begin
(Screen.Forms[i] as TForm).BringToFront;
Result:=True;
break;
end;
if not Result then
AFormClass.Create(Application);
end;


 
Zacho   (2003-11-13 13:35) [32]

Не стоит советовать начинающим использовать в методах класса глобальные переменные-указатели на экземпляр того же класса, ох не стоит.. А то привыкнет человек так делать, а понадобится ему несколько экземпляров TForm2 (особенно в MDI-приложении это частенько надо) и посыпяться вопросы: почему глючит ?


 
Zacho   (2003-11-13 13:39) [33]


> Silver Alex © (13.11.03 13:33) [31]

Поддерживаю. Делать примерно так - лучше всего.


 
Anatoly Podgoretsky   (2003-11-13 14:02) [34]

Да примерно так, но только лучше возвращать форму если есть или nil если нет. Сути не меняет, но происходит неторое избавление от зависимостей. Но это как вариант.


function FindForm(FormName: string): TForm;
var
I: Integer;
begin
for I := 0 to Screen.FormCount - 1 do begin
if Screen.Forms[I].Name = FormName then begin
Result := Screen.Forms[I];
Exit;
end;
end;
Result := nil;
end;


 
Silver Alex   (2003-11-13 14:10) [35]


> Anatoly Podgoretsky © (13.11.03 14:02) [34]



> for I := 0 to Screen.FormCount - 1 do begin
> if Screen.Forms[I].Name = FormName then begin
> Result := Screen.Forms[I];
> Exit;
> end;
> end;
> Result := nil;


ну во первых перед циклом надо Result := nil; раз уж там Exit;
а что в моем примере не верно, вроде все просто написал одну процедуру и все, юзай себе, только классы форм подставляешь и ничего больше дописывать не надо, а в Вашем случае потом все равно нужно создавать экземпляр класса


 
Anatoly Podgoretsky   (2003-11-13 14:19) [36]

Если сделать так, то функция не будет работать, поскольку если будет найдено, то будет возвращено nil, а нужна форма и то же самое если не найдено.

Во вторых нужно будет создавать или нет, зависит от задачи, все остальные подобные Find работают на основе той же идеологии.

И в третьих, ты пропустил главное " Но это как вариант", то есть никак не исключает другой вариант. Я же предпочитаю этот как преемственный с VCL. Но ни как не мешаю использовать твой.

Зависимости следующие,
1. создание формы если ее нет
2. перевод на передний план если есть

Чтоже писать еще одну функцию, что бы этого не делать? Ну ни надо мне переводить на передний план, я буду использовать только ее свойство и создавать не хочу в некоторых случая, мне надо узнать есть она еще/уже или нет.
Зато в тех случая, как и с другими Find я могу делать и то и то.

Но вот непонятно почему ты обиделся, стал в чем то подозревать, неужели ни кто кроме тебя не имеет права предложить другой вариант?


 
Silver Alex   (2003-11-13 14:24) [37]


>
> Но вот непонятно почему ты обиделся, стал в чем то подозревать,
> неужели ни кто кроме тебя не имеет права предложить другой
> вариант?


ни в коем случае,даже не было такой мысли, просто общаюсь и пытаюсь подчерпнуть что-то полезное для себя :))


 
Anatoly Podgoretsky   (2003-11-13 14:28) [38]

А исходил я из этого "а что в моем примере не верно", вроде не давал повода к этому.


 
Vic   (2003-11-13 15:23) [39]

>Silver Alex
Попробовал использовать Вашу ф-цию - не могу понять как отобразить созданную форму. Где нужно применять метод Show?

unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses unit2;
{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);

function IsFormFoundEx(AFormClass :TFormClass) : boolean;
var
i:integer;
begin
Result:=False;
for i:=0 to Screen.FormCount - 1 do begin
if (Screen.Forms[i] is AFormClass) then begin
(Screen.Forms[i] as TForm).BringToFront;
Result:=True;
break;
end;
end;
if not Result then
AFormClass.Create(Application);
end;

begin
IsFormFoundEx(TForm2);
end;

end.

unit Unit2;

interface

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

type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

{$R *.DFM}

end.


 
OlegGashev   (2003-11-13 16:04) [40]

Не сказано было. Если форма модальная, а их большинство в проекте, проще сразу освобожать память после закрытия формы.
То есть что-то в таком роде:


procedure TSDIAppForm.HelpAbout1Execute(Sender: TObject);
var AboutBox:TAboutBox;
begin
AboutBox:=TAboutBox.Create(self);
AboutBox.ShowModal;
AboutBox.Free;
end;


 
Silver Alex   (2003-11-13 16:06) [41]

понял, этот пример просто для MDI-форм, потому что они как Create так сразу и Show, перепиши чуть-чуть здесь

> if not Result then
> AFormClass.Create(Application);

if not Result then
with AFormClass.Create(Application) do
Show;


 
Anatoly Podgoretsky   (2003-11-13 16:18) [42]

OlegGashev © (13.11.03 16:04) [40]
Для данного случае еще более правильнее слежующее


procedure TSDIAppForm.HelpAbout1Execute(Sender: TObject);
begin
with TAboutBox.Create(self) do
try
ShowModal;
finally
Free;
end;
end;



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.011 c
1-79047
NewD
2003-11-13 09:42
2003.11.24
Как в меню и в надписи формы отобразить техт пр. шрифта?


1-78941
jack128
2003-11-12 11:05
2003.11.24
Invalid Pointer Operation


4-79234
plyaznik
2003-09-28 02:07
2003.11.24
Как реализовать Application.ProcessMessages на WinApi?(-)


6-79097
boband
2003-09-30 11:36
2003.11.24
Продвинутая работа с web страницами


14-79186
mip
2003-10-29 10:01
2003.11.24
Где купить лицензионный Delphi подешевле ?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский