Форум: "Основная";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];
ВнизКакой вариант использования форм наиболее оптимален? Найти похожие ветки
← →
lipskiy (2002-11-01 01:24) [0]Мне известны три варианта использования форм со своими контролами. Первый - создать все в дизайн-тайме и не париться. Но при этом вся форма (а мне нужна форма настроек программы - с кучей контролов) всегда сидит в памяти и кушает ресурсы. Второй вариант - также создать форму в дизайн-тайме, но отменить автокрейт и крейтить при вызове, а при гашении освобождать. При этом в ехешник будут скомпилированы все свойства контролов со значениями по умолчанию, даже если я их не использую, получается лишний объем ехе-файла. Третий вариант - создавать форму полностью динамически, ничего не рисуя в дизайн-тайме. Это, имхо, наиболее экономично но жутко неудобно.
Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами формы, которые редко вызываются при работе?
Плюс к этому я хочу на форме настроек переключать множество вкладок с группами настроек, и при этом чтобы в памяти в данный момент сидели только те контролы, которые отображаются, а контролы других вкладок не существовали бы (самих вкладок не видно, это стиль формы настроек с выбором групп посредством TreeView).
И вот еще. Не могу понять, в чем ошибка при создании формы.
В отдельном юните описано:
type
TFormTunes = class (TForm)
end;
var FormTunes : TFormTunes;
В главном юните по кнопке вызываю:
Application.CreateForm(TFormTunes, FormTunes);
Или так:
FormTunes:= TFormTunes.Create(nil);
Вылетает эксепшен - типа ресурс TFormTunes не найден.
Чего я не верно сделал-то?
← →
Dr_Mike (2002-11-01 02:29) [1]Описания класса и обявление переменной класса должны быть в интерфейсном разделе подчиненного модуля.
Во-вторых, просто не стоит забывать в главном модуле в uses указывать имя используемого модуля.
← →
Aleks1 (2002-11-01 02:49) [2]> Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами >формы, которые редко вызываются при работе?
Правильно - это так, чтоб выбранный способ давал наименьшее количество ошибок для конкретного автора. Все разговоры о размерах занимаемой памяти и ресурсах - это либо разговоры о программах на чистом API, либо о "дурацком" использовании ресурсов. ИМХО, однако.
← →
evgeg (2002-11-01 08:18) [3]> Все разговоры о размерах занимаемой памяти и ресурсах - это либо разговоры о программах на чистом API, либо о "дурацком" использовании ресурсов.
Ничего подобного. Программа с десятком статичных форм может запросто отказаться запускаться под Windows 98.
← →
Alex4444444444 (2002-11-01 10:07) [4]TForm.Create pytaetsya najti ressursy formy. Esli ih net, nuzhno ispol"zovat" CreateNew (kazhetsya).
← →
Dr_Mike (2002-11-01 10:20) [5]Хм...действительно, Alex4444444444 правильно акцентировал внимание :)))
Есть ли утебя вообще .DFM файл для FormTunes???
← →
lipskiy (2002-11-01 13:09) [6]Нет dfm файла. Я чисто руками хочу сделать форму целиком. Так мне кажется наиболее оптимально.
> Описания класса и обявление переменной класса должны быть
> в интерфейсном разделе подчиненного модуля.
Так и сделано.
> Во-вторых, просто не стоит забывать в главном модуле в uses
> указывать имя используемого модуля.
Естественно, иначе бы и компилятор не пропустил.
> Программа с десятком статичных форм может запросто отказаться
> запускаться под Windows 98.
Именно эту цель я и преследую - обеспечить нормальную работу под 98-ой, а НТишные осы имеют нормальные менеджеры графических ресурсов.
> TForm.Create pytaetsya najti ressursy formy. Esli ih net,
> nuzhno ispol"zovat" CreateNew (kazhetsya).
А почему это он не находит ресурсы? Главная-то форрма создается как обычно автоматом. Почему я не могу так же создать новую форму? Какжется просто у меня тупняк какой-то, где-то что-то упустил, но не могу найти...
← →
reonid (2002-11-01 13:41) [7]Если без дфм - то действительно надо пользоваться CreateNew.
Потому что Create пытается загрузить одноимённый ресурс.
А насчёт главной формы - она обычно создана в дизайнере и имеет дфм.
(И в её модуле стоит {$R *.DFM} - попробуй, убери :-Р )
Если у тебя много форм похожего внешнего облика и функциональности -
то ты можешь сделать одну заготовку
и специальный объект - менеджер внешнего облика(и поведения),
который будет настраивать форму для конкретного применения,
создавать при необходимости доп. контролы и устанавливать
обработчики.
Насчёт вкладок и тривью - ты можешь сделать каждую
вкладку на отдельной форме, по нажатию на соответствующий
узел создавать нужную форму (уничтожив предыдущую),
загружать в эту форму соответствующие данные и делать её парентом основную форму (на которой лежит тривью).
← →
Андрей Прокофьев (2002-11-01 13:47) [8]2 lipskiy © (01.11.02 01:24)
Есть еще один вариант - запихать эту форму в DLL или package
← →
NailS (2002-11-01 15:14) [9]Господа, а из-за чего собственно сыр-бор разгорелся?
Если я понял, то lipskiy © имеет желание сэкономить GUI-ресурсы пользователя. Желание похвальное, но, честно говоря, я не понимаю каким образом этому начинанию может помочь создание всех компонентов формы в run-time. Ведь оттого что компоненты создались в run-time они меньше ресурсов жрать не станут. Т.е. для экономии GUI-ресурсы достаточно динамически создавать и удалять форму использовав при этом все прелести визуального построения формы и не замарачиваться с созданием руками всей формы.
Если я что-то неправильно понял и(или) вы преследуете еще какие-то цели, объясните пожалуста.
← →
han_malign (2002-11-01 15:30) [10]> При этом в ехешник будут скомпилированы все свойства контролов со значениями по умолчанию, даже если я их не использую, получается лишний объем ехе-файла. Третий вариант - создавать форму полностью динамически...
Полностью согласен с NailS т.к. при третьем подходе в ехешник будут скомпилированны не только все свойста, но и код их занесения в контролы, и код создания контролов, и etc, тогда как "загрузчик свойств"(методы TPersistent) никуда не денутся.
З.Ы. А чтобы не искался ресурс у формы не должно быть ни одного published поля и пропертей(наследоваться от TCustomForm), и все контролы опять таки создавать ручками в конструкторе формы, потому как без DFM никто их за вас не создаст.
← →
Andre V. (2002-11-01 17:02) [11]А. Прокофьеву! Те же я..ца, только сбоку. ДЛЛ всё равно ведь надо грузить в память. Если это делать прямо перед вызовом нужной формы, то сколько времени такое удовольствие займет.
С другой стороны, сколько стоит та же память и надо ли себе портить жизнь. У меня в программе около 30 форм, штук 5 имеют по несколько страниц и всё это работает (включая МДИ-окна с данными
← →
KSergey (2002-11-01 17:10) [12]В принципе люди сказали уже многое, но, если позволите, и от себя добавлю.
> lipskiy © (01.11.02 01:24)
> Мне известны три варианта использования форм со своими контролами.
Так, вначале с терминами определимся. Не претендую на абсолютную истину, просто пусть в этом посте это будет так. Под созданием будам понимать создание формы в запущеном приложении. Что мы в этот момент имеем? Съедается память на хранение компонентов-контрлов (1), съедаются ресурсы GDI (2). Теперь смотрим на это и понимаем, что как бы форма не создавалась, эти ресурсы отъедятся неизменно и в любом случае, и отъедены они будут на все время существования формы в полном объеме. Не зависимо ни от установленных/не установленных значений внутренних полей компонент на форме и самой формы, ни от их начальных значений. Это будет съедено всегда, пока форма существует. При этом существование формы и ее видимость - не оджно и тоже. Невидимая форма может существовать, несуществующая форма не может быть видимой ;)
Где что у нас еще вылезает? Ага, есть код создания формы и код заполнения полей значениями по умолчанию (3) (память под код, оно же место в exe-файле), есть возможно некое описание формы в данных (тут видимо оно же всегда является ресурсами; имеется в виду конкретный случай) (4).
А теперь давайте рассмотрим различия в предлоенных вами "методах создания".
> Первый - создать все в дизайн-тайме и не париться. Но при
> этом вся форма (а мне нужна форма настроек программы - с
> кучей контролов) всегда сидит в памяти и кушает ресурсы.
Так, какую память мы тут кушаем? 1+2+3+4, причем на протяжении выполнения всего прилжения. Если форм несколько и все автокрейтные - эта память отъедается для всех форм всегда. Ну немного может будет отъедаться разные ресурся GDI при видимой/невидимой форме, но все компоненты присутствуют всегда.
> Второй вариант - также создать форму в дизайн-тайме, но
> отменить автокрейт и крейтить при вызове, а при гашении
> освобождать.
Так, что мы тут меем? А опять же 1+2+3+4. Разница лишь в том, что составляющие 1 и 2 будут захватываться/освобождаться при создании/уничтожении формы.
>При этом в ехешник будут скомпилированы все
> свойства контролов со значениями по умолчанию, даже если
> я их не использую, получается лишний объем ехе-файла.
А вот это будет всегда, что при первом, что при врором варианте. Т.е. составляющие 3 и 4 в обоих вариантах будут отъедаться абсолютно одинаковые!
При этом есть еще нюанс: код заполнения св-ств формы значениями по умолчанию (и настроенными в Object Manager"е) будет храниться в exe один раз (он из библиотеки VCL) и он будет читать данные из ресурсов. В ресурсах - код для каждой формы, код ее создания - один (метод Create класса TForm и родительских).
← →
KSergey (2002-11-01 17:10) [13]>Третий
> вариант - создавать форму полностью динамически, ничего
> не рисуя в дизайн-тайме. Это, имхо, наиболее экономично
> но жутко неудобно.
Так, а в этом варианте что мы имеем после того, когда форма создана и показана? Компоненты создаются - да. Форма видна, т.е от GDI мы откусили? Да. Какие-то значения полям формы и контрлов на ней мы присвоить хотим (размер, местоположение, цвет, надписи и т.д.)? Да. Ну разве что в ресурсах ничего нет. Но очевидно, что код присваивания значений полям класса формы и контрлов будет весьма велик, причем рискну утверждать, что он превысит составляющую 4. (из чего состоит код присвоения значений полей в первом и втором случае? циклик, считавает из ресурсов попарно элементы имя поля-значение, имя поля-значение. Циклик сам по себе не большой, согласитесь и записанный один раз на абсолютно все случаи жизни (почему это можно сделать так? не забываем, что все, что можно настроить в Object Inspektor"е - это published поля; если мы настраиваем кроме того и не published поля, то этот код будет вообще константным для всех трех вариантов) [все что тут есть про циклик - это мои личные выдумки, я не знаю как имено это сделано в VCL, но сильно подозреваю что именно так. Во всяком случае я бы сделал так.]. Из чего состоият сами эти значения? Да свалено в кучу в памяти имя=значение и т.д. [опять же мои выдумки; базируются на аргументах выше и на том, что в ресурсах дельфи-приложения нет стандартного описания жиндовских диалогов, следовательно формы создаются, думаю, каким-то таким методом, т.е. динамически а не на основе API-шаблона в ресурсах]). Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что в случае третьего варианта она явно больше выше описанной в скобках методы (т.к. тут конструкции исходного текста вида поле=значение скомпилируются в команду запихивания значения в поле класса). Впрочем, возможно я зря драматизирую, но уверен, что во всяком случае как минимум составляющие 3 4 первых двух вариантов буду эквивалентны составляющей 3 третьего варианта.
Таким образом получаем, что при созданной форме мы имеем одинаковое расходование ресурсов во всех трех вариантах!
А значит если ставить вопрос
> Как же все-таки ПРАВИЛЬНО создавать изобилующие контролами
> формы, которые редко вызываются при работе?
то - сиренево!
Единственная тут разница между первым и вторым вариантом. Понятно, что они отличаются для случая, когда форм в приложении много, и в каждый момент времени нужна только одна из них. Вот и все. Т.е. едиственное чте тут можно сказать - если форма не нужна посттоянно - есть серьезные основания создавать ее динамически, при этом под динамикой понимается как второй, так и третий вариант, т.к. они абсолютно идентичны, более того - еще не известно какой из них "легче" по пожирательству.
> Плюс к этому я хочу на форме настроек переключать множество
> вкладок с группами настроек, и при этом чтобы в памяти в
> данный момент сидели только те контролы, которые отображаются,
> а контролы других вкладок не существовали бы (самих вкладок
> не видно, это стиль формы настроек с выбором групп посредством
> TreeView).
И теперь представьте что это за геморой? Вкладка не видима - уничтожили контролы с нее, но при этом (заметьте!) надо где-то сохранить состояние их, т.к. ползователь там возможно что-то понастраивал, на что память уйдет, верно? Теперь перешли на вкладку - создали контролы, восстановили их значения, контролы с предыдущей удалили, сохранив и их значение. Где тут выигрыш?! Такое впечатление, что процессор у вас пентиум 6, а памяти - 640 килобайт (котрой, по идее, должно хватить на все, согласно известному утверждению Билла Гейтса;) и которую вы упорно экономите. Тут пожалуй действительно тот случай, когда ползователю можно смело сказать: извини, но мое окно настроек не запускается на твоей машине, давай увеличивай ее ресурсы (ну я имею в виду, когда все сделано грамотно;) поберегие помидоры;). Ведь никого же не возмущает необходимость 3D-ускорителей для игр? Причем именно необходимость.
Уфф... Сразу видно, что сегодня я еще ничего не постил... ;)
Надеюсь, что теперь вы поняли, что нет разницы между вашими методами никакой. Ну кроме того, что не надо держать в автокрейте те формы (и даже вредно!), которые не используются постоянно и одновременно. А сэкономить что-то при активной форме - невозможно.
← →
NailS (2002-11-01 17:21) [14]
> KSergey ©
> Где тут выигрыш?!
Ну вообще-то выигрыш на мой взгляд вполне очевиден. Визуальные контролы нужны только для ОТОБРАЖЕНИЯ и ИЗМЕНЕНИЯ значения параметров, но никак не для хранения их значений.
> и при этом чтобы в памяти в
> данный момент сидели только те контролы, которые
>отображаются, а контролы других вкладок не существовали бы
Я бы реализовывал это при помощи фреймов, просто и удобно. Перешел по дереву - убил один фрейм - создал другой - отобразил параметры. И TPageControle сэкономил ;)
← →
KSergey (2002-11-01 17:23) [15]Поправочки ;) и дополнения
KSergey © (01.11.02 17:10)
В ресурсах - код для каждой формы, код ее создания - один (метод Create класса TForm и родительских).
Читать:
В ресурсах - значения полей, а код ее создания храниться один раз (метод Create класса TForm и родительских).
KSergey © (01.11.02 17:10)
жиндовских диалогов = виндовских диалогов
Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что в случае третьего варианта она явно больше выше описанной в скобках методы
Читать:
Отвлекся, вспомним про вариант три и составляющую 3 и увиидм, что (на основании описанного выше в скобках крупного куска) в случае третьего варианта она явно больше для вариантов первых двух вариантов
при этом под динамикой понимается как второй, так и третий вариант, т.к. они абсолютно идентичны, более того - еще не известно какой из них "легче" по пожирательству.
Уточнение:
при этом под динамикой понимается как второй, так и третий вариант, т.к. они абсолютно идентичны, более того - еще не известно какой из них "легче" по пожирательству. А потому не понятно есть ли смысл выпендриваться, создавая форму ручками, если ее вид полностью известен на этапе создания приложения.
← →
KSergey (2002-11-01 17:29) [16]> NailS © (01.11.02 17:21)
>
> > KSergey ©
> > Где тут выигрыш?!
>
> Ну вообще-то выигрыш на мой взгляд вполне очевиден. Визуальные
> контролы нужны только для ОТОБРАЖЕНИЯ и ИЗМЕНЕНИЯ значения
> параметров, но никак не для хранения их значений.
Ага, а проваливание скорости при простой операции смены вкладок? Впрочем, я могу согласиться, что иногда это может и нужно (динамическое изменение вида вкладок в зависимости от значений полей ввода на других, например), но при полной статичности вида - нет уж, увольте. Если некуда девать энергию - лучше побегать по стадиону ;) Для здоровъя всяко полезнее. (еще раз скажу: все, конечно же, зависит от конкретной ситуации; когда это необходимо - это надо длать, когде необходимости нет - и не надо).
> > и при этом чтобы в памяти в
> > данный момент сидели только те контролы, которые
> >отображаются, а контролы других вкладок не существовали
> бы
>
> Я бы реализовывал это при помощи фреймов, просто и удобно.
> Перешел по дереву - убил один фрейм - создал другой - отобразил
> параметры. И TPageControle сэкономил ;)
Ну а это уже просто детали реализации, при этом никакой экономии памяти (о которой так печется автор вопроса) тут не произойдет, верно?
← →
reonid (2002-11-01 17:38) [17]KSergey © (01.11.02 17:29)
>Ну а это уже просто детали реализации, при этом никакой >экономии памяти (о которой так печется автор вопроса) тут не >произойдет, верно?
Это то есть как же?
Наоборот, в каждый конкретный момент времени в
памяти будет находиться только один фрейм,
а не все 25.
Объём экзешника, конечно, это не уменьшит, но
экономия оп. памяти и объектов ГДИ может быть велика.
← →
NailS (2002-11-01 17:44) [18]
> Ну а это уже просто детали реализации, при этом никакой
> экономии памяти (о которой так печется автор вопроса) тут
> не произойдет, верно?
Автор беспокоился в первую очередь о GUI-ресурсах, если я его правильно понял, и при этом он их реально сбережет пользователю.
← →
han_malign (2002-11-01 17:44) [19]Кстати насчет отжирания памяти - все равно долго не использующуюся память VMM выгружает на диск, освобождая физическую, скорость подкачи страниц сравнима со скоростью создания контролов(если не быстрее т.к. на нулевом кольце)
← →
NailS (2002-11-01 17:46) [20][off]Начинает отдавать пятничным флеймом ;))) Пожалуй пора завязывать ;)[/off]
← →
Юрий Зотов (2002-11-01 18:47) [21]Да... уж... проблема... выеденного яйца...
1. Если форма требует N ресурсов - то она их отожрет, и никуда от этого не денешься. Как уменьшить N - это уже другой вопрос.
2. Чтобы она не отжирала их постоянно, создавайте ее ручками, непосредственно перед тем, как она становится нужна (но не с нуля, а просто вызовом конструктора). И убивайте сразу, же как только она становится не нужна. И так с КАЖДОЙ формой, кроме главной.
3. Чтобы не "париться", спокойно проектируйте любую форму в design-time. Только не забудьте убрать ее из AutoCreate (кроме главной). Хороший стиль - сразу же удалить из модуля формы объявление глобальной ссылки на нее (кроме главной).
4. Для настройки формы перед ее показом существуют события. Вот там и пишите нужный код.
← →
evgeg (2002-11-01 19:06) [22]Когда форма загружается из dfm, dfm прилинковывается к исп. файлу, что увеличивает его размер. Будет ли экономия размера исп. файла, если присваивать сво-ва кодом, а не читать из dfm? Да, будет и вот почему:
В dfm-е сво-ва храняться грубо говоря в формате:
имя_свойства: значение_свойства.
Причем имя свойства -- это строка. И если класс имеет свойство:
MyVeryImpotentProperty, то в dfm-е будет храниться строка "MyVeryImpotentProperty". В этом легко убедится, открыв двоичный dfm в текстовом редакторе. Таким образом имя свойства занимает довольно приличный размер в исп. файле, зачастую гораздо больше, чем значение.
Но экономится только размер файла, а не ресурсы системы. А для поставленной задачи: запускать под W98, важна именно экономия ресурсов.
> lipskiy
Ссылка по теме: http://www.delphikingdom.com/stones/stone_21.htm
← →
Дмитрий Баранов (2002-11-01 19:55) [23]Кстати, про PageControl -
совершенно случайно полазил Spy++ по окнам своей поделки - так вот, например, PageControl, содержащий, к примеру, 4 закладки, при запуске программы явно создает только одно дочернее окно - окно ВИДИМОЙ закладки, остальные же - динамически, по мере того, как юзер по ним щелкает. Это еще один плюс в пользу того, насколько грамотно написана VCL. Так что в Борланде тоже любят на ресурсах поэкономить, и в данном случае, польза явная.
← →
lipskiy (2002-11-01 21:14) [24]Ого! Не ожидал, спасибо всем за обилие полезной инфы, в особенности KSergey.
> Надеюсь, что теперь вы поняли, что нет разницы между вашими
> методами никакой
Да, практически понял все.
Подчеркну лишь, что я действительно желаю сэкономить именно GDI ресурсы (а не просто память), и размер ехешника менее важен. Даже больше скажу - мне кажется (но я не уверен), что нужно экономить GDI ресурсы, чтобы обеспечить устойчивую работу под 98-ой. Может нужно и что-то иное делать.
Насчет хранения настроек.
Я начал с того, что хранил их именно в свойствах контролов, которые существовали у меня всегда. Это довольно удобно.
Теперь, если я убираю форму из AutoCreate, то мне необходимо создавать массив настроек. Думаю, что это все же лучше, так как массив настроек все же не ест графических ресурсов.
> Да... уж... проблема... выеденного яйца...
Юрий! Я снимаю шляпу перед вашим опытом и знаниями, но для моего уровня эта проблема чуть ли не высшего порядка :)
Ваши комментарии понятны (и полезны), так и буду делать.
> Это еще один плюс в пользу того, насколько грамотно написана
> VCL
ТАК ПОЧЕМУ ЖЕ ОНО ТАК ГЛЮЧИТ ПОД 98-МИ-ТО?????? Тудыть их. Забыть давно пора эти 98-е к черту. Но ведь юзвери всегда наровят программерам проблемы устроить :)
← →
lipskiy (2002-11-01 21:27) [25]
> evgeg © (01.11.02 19:06)
Спасибо за ссылку. Коротковато конечно, но полезно.
← →
Dr_Mike (2002-11-02 00:39) [26]>Дмитрий Баранов © (01.11.02 19:55)
Здесь дело совсем не в грамотности написания VCL ! :-))))
Просто все видимые элементы в VCL создаются путем вызова соответствующих функций WinAPI, а так как в винде нет такого элемента, как PageControl (то есть чего-то с закладками поверху и соответствующим им страницами) - то это все так и реализовывается, как вы сами увидели - сверху лежит TabControl, а так называемая "страница" всего одна.
← →
Юрий Зотов (2002-11-02 10:22) [27]Еще об экономии ресурсов (наверное, это и есть самое главное).
5. Продумать юзерский интерфейс программы так, чтобы на любом этапе ее работы количество одновременно показанных окон было сведено к минимуму.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.11.11;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.008 c