Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на Delphi


РАССЫЛКИ ПОРТАЛА RUSFAQ.RU

/ КОМПЬЮТЕРЫ И ПО / Языки программирования / Delphi

Выпуск № 903
от 23.08.2007, 16:35

Администратор:Калашников О.А.
В рассылке:Подписчиков: 470, Экспертов: 81
В номере:Вопросов: 1, Ответов: 3


Вопрос № 98754: Уважаемые эксперты, здравия желаю! Вопрос у меня к Вам появился. Мне надо в программе показывать несколько однотипных окон. Я создал главную форму Form и форму для показа информации FormInf. В опциях проекта форму FormInf перенес в список Availab...

Вопрос № 98.754
Уважаемые эксперты, здравия желаю!
Вопрос у меня к Вам появился. Мне надо в программе показывать несколько однотипных окон. Я создал главную форму Form и форму для показа информации FormInf. В опциях проекта форму FormInf перенес в список Available forms. Затем я в разделе implementation главной формы объявил переменную FormInfChild : TFormInf. Там, где надо появление окна пишу такой код:
===================
FormInfChild:=TFormInf.Create(Application);{}
. . .
{Здесь я задаю различные значения параметров компонентов окна}
. . .
FormInfChild.Show;
===================
Все отлично. Когда надо, может показывается сразу несколько окон. Проблема в том, что при закрытии окна память-то обратно не освобождается. Если создать одну форму таким образом и, не создавая другой, применить к созданной форме метод Free, то тогда все нормально. Однако если этот метод применить после создания нескольких форм, то в памяти освобождается лишь тот участок, который был занят под последнюю созданную форму. Вопрос: как в нужный мне момент (например, когда все созданные формы пользователь закрыл) освободить память от всех созданных форм?
Заранее благодарен.
Зимородкин Александр
Отправлен: 17.08.2007, 21:03
Вопрос задал: Зимородкин Александр (статус: Посетитель)
Всего ответов: 3
Мини-форум вопроса >>> (сообщений: 1)

Отвечает: Сухомлин Кирилл Владимирович
Здравствуйте, Зимородкин Александр!
Все очень просто. Вы указатель на эту область памяти (выделенную для очередного дочернего окна) записываете всегда в переменную FormInfChild. Когда создаете очередную форму, то перезаписываете указатель новым значением, а старое у вас теряется безвозвратно. Сделайте у формы private-поле:
ChildForms: TList;
TList — это тоже объект и его надо создавать.
Впоследствии при создании очередного окна делайте вот такой вызов:
ChildForms.Add(TFormInf.Create(Application));
А если захотите очистить всю память, то используйте вот такой код:
for i := 0 to ChildForms.Count-1 do ChildForms[i].Free;
ChildForms.Clear; // Теперь память очищена и недействительные указатели надо удалить, чтобы случайно не сделать запрос по этой памяти.
Если захотите реализовать какую-то более сложную схему работы — почитайте как работать с TList, в т.ч. в справке.

Можно сделать и массивом. Главное, чтобы сохранять каждый объект (указатель) в отдельную переменную.
---------
Не узнаешь - не попробуешь.
Ответ отправил: Сухомлин Кирилл Владимирович (статус: Специалист)
Ответ отправлен: 17.08.2007, 21:30
Оценка за ответ: 5
Комментарий оценки:
Благодарю за ответ. То что надо. Правда немного его подправил. Во-первых, Delphi ругается на строку
for i := 0 to ChildForms.Count-1 do ChildForms[i].Free;
Я сделал так:
for i := 0 to ChildForms.Count-1 do
begin
FormInfChild:=ChildForms[i];
FormInfChild.Free;
end;
Да и показ созданной формы типа ChildForms[i].Show тоже не идет. Я сделал так:
ChildForms.Add(TFormInf.Create(Application));
FrmInfChild:=ChildForms[ChildForms.count-1];
FrmInfChild.show;
И все получилось. так что, пятерка Ваша.

Отвечает: Виктор Пырлик
Здравствуйте, Зимородкин Александр!

Суть вашего вопроса подводит к использованию дочерних окон – т.е. указать для дочерних окон, в свойстве Formstyle="fsMDIChild." Таким образом, вы будите работать по схеме «документ – представление», т.е. по аналогии с MS Word и т.д. – используя MDI интерфейс (множественный окна).
Тогда, вам будет легко управлять этими окнами, да и логике приложения они будут более соответствовать.

Второй способ, открывать обычные окна (для однотипных окон это неверно, но иногда приемлемо), как вы и делаете. Тогда, эти окна открываются ведь по событию.. например, выбор меню, кнопки и т.д. и каждое окно несёт свою функциональность. В этом случае, достаточно в обработчике дочерней формы OnClose присвоить параметру Action знасение caFree:

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


А в главной форме можно запускать так:

implementation

uses Unit2;
var FormInfChild :TFormInf;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
FormInfChild := TFormInf.Create(self);
frm.Show;
end;


---------
Если ничего не помогло - надо читать инструкцию
Ответ отправил: Виктор Пырлик (статус: Студент)
Ответ отправлен: 17.08.2007, 22:52
Оценка за ответ: 5
Комментарий оценки:
Нет, Виктор. Мое приложение не должно быть MDI. Формы обыкновенные, и появляются в определенное время. Правда закрывает их пользоватьель. Тем не менее, Ваш совет в процедуре TFormInf.FormClose(Sender: TObject; var Action: TCloseAction) присвоить Action значение caFree мне подходит. Поэтому пять стопроцентное.

Отвечает: Mishell
Здравствуйте, Зимородкин Александр!
поместите в FormClose вашей формы (TFormInf) строку
Action:=caFree;
т.е. при закрытии этой формы будут освобождены ресурсы этой формы (только этого экземпляра формы)
Ответ отправил: Mishell (статус: 5-ый класс)
Ответ отправлен: 20.08.2007, 10:53


Отправить вопрос экспертам этой рассылки

Приложение (если необходимо):

* Код программы, выдержки из закона и т.п. дополнение к вопросу.
Эта информация будет отображена в аналогичном окне как есть.

Обратите внимание!
Вопрос будет отправлен всем экспертам данной рассылки!

Для того, чтобы отправить вопрос выбранным экспертам этой рассылки или
экспертам другой рассылки портала RusFAQ.ru, зайдите непосредственно на RusFAQ.ru.


Форма НЕ работает в почтовых программах The BAT! и MS Outlook (кроме версии 2003+)!
Чтобы отправить вопрос, откройте это письмо в браузере или зайдите на сайт RusFAQ.ru.


© 2001-2007, Портал RusFAQ.ru, Россия, Москва.
Авторское право: ООО "Мастер-Эксперт Про"
Email: support@rusfaq.ru, тел.: +7 (926) 535-23-31
Хостинг: "Московский хостер"
Поддержка: "Московский дизайнер"
Авторские права | Реклама на портале
Версия системы: 4.56 beta от 20.08.2007
Яндекс Rambler's Top100
RusFAQ.ru | MosHoster.ru | MosDesigner.ru | RusIRC.ru
Kalashnikoff.ru | RadioLeader.ru | RusFUCK.ru

В избранное