Компоненты DelphiДинамическое создание компонентов в Delphi |
Уроки Delphi
1. Первая программа
2. Использование компонентов
3. События Delphi
4. Типы данных Delphi
5. Создание своих типов данных
6. Выражения и операторы
7. Работа с файлами в Delphi
8. Дополнительные формы
9. Подпрограммы в Delphi
10. Исключительные ситуации
11. Взаимодействие приложения с пользователем
12. Указатели в Delphi
13. Обзор компонентов
14. Работа со строками
15. Создание интерфейса
16. Графика в Delphi
17. Многопоточность в Delphi
18. Динамическое создание
компонентов Поиск по сайту Это важно:
Метод Application.ProcessMessages;
Это полезно:
Параметр Sender в обработчиках событий;
Бояться не надо |
Динамически создаваемые компоненты - это компоненты, место в памяти под которые выделяется по мере необходимости в процессе работы приложения. Этим они и отличаются от компонентов, которые помещаются на Форму при проектировании приложения. Возможность создавать компоненты динамически это очень большое удобство для программиста. Например, можно создавать в цикле сразу много однотипных компонентов, формируя из них массив, которым в дальнейшем очень просто управлять.
Есть ещё свойство Name! По умолчанию Delphi присвоит ему типовое имя с присвоением очередного порядкового номера: Memo1. Программист при создании компонента также может присвоить свойству Name нужное значение, например:
Memo.Name:='DynamicallyCreatedMemo';
К данному компоненту можно обращаться как по этому имени, так и с указанием переменной, с помощью которой он был создан: Memo. Естественно, в последнем случае переменная должна быть глобальной. Теперь хочу обратить ваше внимание на один нюанс. Создайте новый проект. Создайте-создайте, а то не получите того эффекта, на который я рассчитываю. В новом проекте создавать тот же компонент Memo мы будем в обработчике OnCreate Формы, чтобы Форма появлялась уже с нашим компонентом. Для пустой Формы создайте обработчик события OnCreate и наполните его вышеприведённым кодом. И что же - при попытке исполнить приложение мы получим от компилятора ошибку! А дело вот в чём. Посмотрите в свежесозданном проекте, ещё до добавления компонентов, на список перечисленных в операторе uses стандартных модулей:
unit Unit1;
Теперь возьмите в Палитре компонентов компонент Memo или ту же кнопку Button, положите на Форму и опять посмотрите на список модулей:
uses
Подчёркиванием я выделил модуль, который автоматически добавил Delphi к списку необходимых модулей. Перед выполнением приложения компилятор просматривает установленные компоненты и добавляет в список uses модули, необходимые для работы этих компонентов. Так что даже если вы полностью сотрёте этот список ( оставьте только "uses Forms; "), Delphi его восстановит в том минимальном виде, который нужен для функционирования компонентов.Поэтому естественно, что мы получили ошибку в предыдущем варианте - не хватало нужных модулей. Теперь смело жмите Run! Также становится понятно, почему приложение, создающее Memo через нажате кнопки, сразу заработало. Для работы компонентов Button и Memo необходим один и тот же модуль StdCtrls, описывающий компоненты, расположенные на вкладке Standart. Поэтому, когда мы положили на Форму компонент Button, Delphi добавил этот модуль, что обеспечило работу также и Memo. Так вот что нужно делать, чтобы подобная ошибка не появлялась! Просто положите на Форму из палитры компонентов компонент, который вы создаёте динамически, и жмите Run. Всё, после компиляции компонент можно удалять за ненадобностью - модуль, необходимый для его работы, Delphi затирать не станет! И ваш динамически создаваемый компонент будет работать. Можно, конечно, обойтись и без добавления на Форму и последующего удаления компонентов, которые мы в программе будем создавать динамически. Посмотрите - при наведении мышки на любой компонент в Палитре Компонентов всплывает подсказка с названием модуля, в котором он описан. Добавьте это название в список uses, и всё! Но если ошибётесь в какой буковке - пеняйте тогда на себя. Теперь возникает вопрос, как можно создать приложение аналогичное первому, где компонент Memo создавался динамически по нажатию кнопки, но чтобы кнопка тоже была создана динамически! Динамически создать кнопку мы можем в обработчике OnCreate Формы, точно так же, как и компонент Memo. Однако она не будет работать - создавать компонент Memo. Естественно, ведь обработчика OnClick для неё мы не создали! Давайте сделаем это. Естественно, проще всего создать обработчик для динамически создаваемого компонента, воспользовавшись готовым компонентом из палитры. Создаём для него нужный обработчик, а затем этот компонент просто удаляем. А теперь достаточно присвоить имя созданного обработчика соответствующему свойству динамического компонента. Название этого свойства будет совпадать с названием соответствующего события в Инспекторе Объектов. Например, для события OnClick пишем так:
Button.OnClick:=Button1Click;
Естественно, имя обработчика может быть любым, просто в данном случае я воспользовался тем обработчиком, что создал Delphi для кнопки из палитры. Если оно вам не нравится, можно смело переименовать процедуру, только не забудьте изменить её название также и в описании типа Формы.Теперь мы умеем создавать компоненты динамически, и можем наделать компонентов столько, сколько нам требуется. Но такие уж они, динамически создаваемые компоненты, что надобность в них как появляется, так и исчезает - динамически! Иногда нужно и уничтожить компонент. Для уничтожения компонента есть простой метод: Free.
Component.Free;
Вот и всё. Все ресурсы, выделенные для функционирования компонента, будут освобождены. Останется только созданная переменная, указывающая на уже несуществующий в памяти объект. Её тоже неплохо бы уничтожить. Это делается присвоением переменной значения nil. Есть процедура, выполняющая оба эти действия, уничтожение и объекта и переменной: FreeAndNil:
FreeAndNil(Component);
И это относится не только к динамически созданному - к любому компоненту и объекту в памяти.
Вопросы и комментарии (64) Решение задач в Delphi
Андрей, добавлено 17.01.12, 02:19:46
Большое спасибо за информацию - очень помогла мне при написании моей программы! Николай, добавлено 20.01.12, 20:13:40 Хорошая статья для новичка! вика, добавлено 20.01.12, 23:58:25 отлично! Оля, добавлено 4.02.12, 15:38:12 Здравствуйте, у меня вопрос, как сделать матрицу из компонентов Edit, причем количество строк и столбцов задается вручную.. Я смогла вывести определенное количество Edit-ов в строку, а вот при переходе на 2,3,4-ю строчку я застопорилась, не могу сообразить как это сделать, мой код выглядит так: А - это количество столбцов.. var Form4: TForm4; edit : TEdit; n : integer =0; n1: Integer =3; implementation uses Unit1; {$R *.dfm} procedure TForm4.Image3Click(Sender: TObject); var i:Integer; a:Integer; begin Label3.Visible:=True; A:=StrToInt(Edit1.text); for i := 1 to a do begin edit := TEdit.Create(Form4); edit.Parent := self; edit.Name := 'Edit' + IntToStr(n1); edit.Left := 90+n; edit.Top := 150; edit.Height:=33; edit.Width:=45; edit.Text:='0'; n := n +90; Inc(n1); End; End. Автор, добавлено 4.02.12, 16:58:33 Вы создаёте несколько компонентов: Edit1, Edit2 и так далее. Если вы хотите, чтобы эти компоненты были выстроены в несколько строк, то нужно два вложенных цикла. Добавьте перед вашим ещё один: B:=StrToInt(Edit2.text); for j:=0 to B-1 do и в цикле измените edit.Top := 150+j*50;// 50 - расстояние между строками (выберите сами) Оля, добавлено 4.02.12, 17:45:19 Спасибо большое.. вот бывает же, вроде тоже самое делала) только в одном месте ошиблась) в месте Edit.Top . Огромное спасибо) Оля, добавлено 4.02.12, 18:17:29 Можно вас еще немного побеспокоить.. когда пишешь edit.Top := 150+j*50; он edit лесенкой строит, а не друг под другом.. Автор, добавлено 4.02.12, 18:42:29 А это потому что у вас Left привязан не к переменной цикла, а к какой-то n. Замените Edit.Left:=90*i; n вообще не нужен, уберите его. Оля, добавлено 4.02.12, 18:49:17 Я его писала для того чтобы он расстояние друг от друга делал, а не лепил их вместе.. а когда ставишь i, то получается что он их друг на друга накладывает Автор, добавлено 4.02.12, 19:11:54 Ничего подобного. Отписались, и даже наверное не попробовали: procedure TForm1.Button1Click(Sender: TObject); var i, j:Integer; a, b:Integer; begin Label3.Visible:=True; A:=5{StrToInt(Edit1.text)}; B:=3; for j := 0 to b-1 do for i := 1 to a do begin edit := TEdit.Create(Form1); edit.Parent := self; edit.Name := 'Edit' + IntToStr(n1); edit.Left := 90*i{+n}; edit.Top := 150+j*50;; edit.Height:=33; edit.Width:=45; edit.Text:='0'; // n := n +90; Inc(n1); End; end; Это обработчик нажатия на кнопку, ну да какая разница. n не используется. Оля, добавлено 4.02.12, 19:34:27 То что пробовала это правда, но не могу понять, вроде проверила все тоже самое что и у Вас было. Не поняла в чем разница, скопировала Ваш текст, работает.. Извините за беспокойство, спасибо за помощь! Игорь, добавлено 18.03.12, 02:02:45 Спасибо за хорошую статью. У меня вопрос. Как уничтожить визуальный компонент, так чтобы он исчез с формы? Автор, добавлено 18.03.12, 07:12:07 Component.Free; Надо бы добавить в текст статьи. Спасибо! Аноним, добавлено 5.04.12, 08:45:00 Добрый день. Нужна помощь в следующей ситуации. На Form1 в процессе проектирования создаетя Edit1 и Edit2. Далее по нажатию кнопки динамически создаются Edit3, Edit4 и т.д. Procedure TForm1.Button1Click (Sender: TObject); var Edit: TEdit; begin Edit:=TEdit.Create(Form1); Edit.Parent:=Form1; Button1.Top:=Button1.Top+40; Edit.left:=50; Edit.top:=Button1.Top-40; Edit.Width:=200; Edit.Height:=25; k:=k+1; {k:integer; k:=2 задается ранее} Edit.text:='Игрок'+IntToStr(k); end; После в Form2: StringGrid1.Cells[1,0]:=Form1.Edit1.Text; StringGrid1.Cells[2,0]:=Form1.Edit2.Text; Подскажите, пожалуйста, как задать другим ячейкам содержание Text динамически созданных Edit3, Edit4,... из Form1? Автор, добавлено 5.04.12, 09:03:42 Не вижу разницы с первыми эдитами. Имена им присваиваются Delphi по умолчанию порядковые: Edit3, 4, 5 и т.д. причём у вас этот номер равен k. Но вам, кстати, вообще не нужно содержание этих едитов, т.к. оно заранее задано: Игрок3, 4, 5 и т.д. (если я правильно понял). Можно просто: Stringgrid1.Cells[k, 0]:='Игрок'+IntToStr(k); Но я в таких случаях создаю не отдиночный Edit, а глобальный динамический массив типа TEdit:
И так далее. Теперь просто получить доступ к любому Edit'у: его номер будет k-3. Аноним, добавлено 5.04.12, 10:46:38 Дело в том, что содержание этих динамически созданных эдитов нужно, т.к. изначальное их содержание это имена игроков по умолчанию, которые в процессе работы первой формы пользователь изменяет (может изменить). При этом пользователь и задает колличество игроков (к), минимум может учавствовать 2 игрока (по этому 1й и 2й эдиты созданы статически), дополнительные игроки добавляются по необходимости нажатием кнопки Button1. Затем окно "обзывания игроков" закрывается и появляется окно Form2. Проблема в том, что когда я присваиваю ячейкам СтрингГрид второй формы содержание эдитов с первой формы, первые два присваиваются без проблем, а остальные не знаю как. Пытаясь присвоить так же как и первые два, компилятор выдает ошибку. Может их (динамические эдиты 3й 4й и т.д.) надо как-то описать в Unit2? Автор, добавлено 5.04.12, 10:57:53 Ну я же написал: создавайте динамический массив эдитов, их адресация будет Edit[k-3] Дмитрий, добавлено 11.04.12, 09:36:43 Зачетно, как раз это и искал. Спасибо Автор, добавлено 11.04.12, 09:57:56 Да, читаю и самому нравится! Вадим Мошев, добавлено 13.04.12, 14:25:26 Хочется внести небольшое предложение по поводу вот чего. СмотрИте, у вас написано "Так вот что нужно делать, чтобы подобная ошибка не появлялась. Просто положите на Форму из палитры компонентов компонент, который вы создаёте динамически, и жмите Run. Всё, после компиляции компонент можно удалять за ненадобностью - модуль, необходимый для его работы, Delphi затирать не станет! И ваш динамически создаваемый компонент будет работать.". Зачем так извращаться? Ведь можно просто навести указатель мыши на нужный компонент из палитры компонентов, рядом с названием в скобочках появится название модуля, например, Memo (StdCtrls). [могу ошибаться, конечно, но в Delphi 7 так и есть]. Автор, добавлено 13.04.12, 14:45:28 Вадим, всё так и есть. Я, пожалуй, добавлю инфу о том, что при наведении мышки на компонент мы можем видеть название его модуля. Но ваше предложение означает, что что-то нужно будет написать ручками, отсюда появляется возможность ошибки. А так эта возможность исключена. Всё же сайт для новичков. В общем, сделаем так: выбор будет за читателем. Вадим Мошев, добавлено 14.04.12, 12:06:31 Кстати, Андрей, извините за тон предыдущего сообщения, я не хотел вас обидеть... Автор, добавлено 14.04.12, 12:22:11 Без проблем! За окном хорошая погода - это важнее :) Андрей, добавлено 14.04.12, 13:55:47 У меня вопрос: я создаю игру сапера на делфи и такая проблема у меня при создании динамических кнопок они появлются в верхнем углу формы а мне нужно их перенести на центр как это сделать?Вот код:
Автор, добавлено 14.04.12, 14:19:31 Введите переменные Xo и Yo и прибавляйте к кординатам кнопок: With MasButton[i, j] do begin Left := VarLeft*i+Xo; Top := VarTop * j+Yo; Значения подберите экспериментально или вычислите... Аноним, добавлено 14.04.12, 14:36:53 спасибо сечас попробую Виталий, добавлено 14.10.12, 20:02:19 Ошибка при нажатии на кнопку: A component named Button1 already exists Автор, добавлено 14.10.12, 23:23:00 Утром вернусь, проверю что у вас не так, тогда отвечу. Автор, добавлено 15.10.12, 09:04:55 Всё ясно. У вас на Форме уже есть компонент с именем Button1, и другой компонент с таким же именем вы динамически создать не сможете. Иван, добавлено 14.04.13, 10:28:37 Я создаю тест на Delphi (для проверки знаний), читается вопрос из файла, читаются варианты ответа и в зависимости от их количества динамически создаются компоненты memo и заносятся в динамический массив. При нажатии кнопки идет проверка ответов и компоненты удаляются. Проблема в том, что в какой-то момент они перестают удаляться и остаются на форме. Автор, добавлено 14.04.13, 15:36:05 Как удаляете? Можно ведь удалять как компоненты Формы, а можно как переменные... Ямиль, добавлено 15.04.13, 05:45:56 Огромное спасибо !!!!!! иван, добавлено 15.04.13, 10:08:11 как компонент, храниться в массиве компонентов Автор, добавлено 15.04.13, 10:56:51 Опубликуйте ваши процедуры создания и удаления, посмотрим. А так не угадаешь. Иван, добавлено 15.04.13, 15:03:22 Вот они: //******************************************************** //Процедура удаления компонентов //******************************************************** procedure Tstudent.BitBtn3Click(Sender: TObject); var i:Integer; begin for i:=0 to Length(checks)-1 do checks[i].free;// checks - Глобальный массив типа Tcheckbox (динамический) checks:=nil; for i:=0 to Length(mems)-1 do mems[i].free;//mems - Глобальный массив типа Tmemo (динамический) mems:=nil; test; //вызов процедуры для создания новых компонентов end; //******************************************** //Создание мемо и занеесение их в массив //Создание чекбоксов и занесение их в массив //******************************************** Procedure tstudent.testcreate; var memo:Tmemo; check:Tcheckbox; s:string; i,k,left:integer; begin k:=0; setlength(mems,1);//Расширяем массивы на еденицу setlength(checks,1);//**************************** memo:=Tmemo.create(self);//Создаем компоненты и заносим их в массивы memo.Parent:=groupbox2;// memo.Hide;// mems[k]:=memo;// check:=Tcheckbox.Create(self);// check.Parent:=groupbox2;// check.Hide;// checks[k]:=check;//************************************* tabbedNotebook1.PageIndex:=2; for i:=1 to length(quest.Answer) do//Извлечение текста и запись его в нужный memo begin if quest.Answer[i]<>'%' then if quest.Answer[i]<>'|' then s:=s+quest.answer[i] else begin mems[k].Lines.Add(s); s:=''; end else begin inc(k); setlength(mems,length(mems)+1); setlength(checks,length(checks)+1); memo:=Tmemo.Create(groupbox2); memo.Parent:=groupbox2; memo.Hide; mems[k]:=memo; check:=Tcheckbox.Create(groupbox2); check.Parent:=groupbox2; check.Hide; checks[k]:=check; end;//*************************************************************************** end; k:=0;//Дальше идет просто размещение в нужных местах left:=50; for i:=0 to length(mems) - 2 do begin if (i = 8) or (i=16) then k:=0; if (i>=8) and (i<17) then left:=300; if i>17 then left:=500; mems[i].Left:=left; mems[i].Height:=45; mems[i].top:=k*45+15; mems[i].Show; checks[i].Top:=k*45+15; checks[i].Width:=15; checks[i].Left:=left-25; checks[i].Show; inc(k); end;//*************************************************** end; Иван, добавлено 15.04.13, 15:54:55 При пошаговом выполнении видно как удаляются checkbox-ы, обнуляется массив все хорошо, при переходе на следующую строчку все checkbox-ы появляются Алексей, добавлено 3.08.13, 14:45:54 Уважаемый Автор, подскажите можно ли назначить динамически созданному RichEdit[x] событие OnResizeRequest, для обычно созданного RichEdit1 в событии OnResizeRequest(Sender: TObject; Rect:TRect), Rect-размеры поля RichEdit1 Автор, добавлено 3.08.13, 15:05:18 Можно, а в чём проблема, что не получается? Для динамически созданного Reсt будет его поле... Алексей, добавлено 6.08.13, 00:55:14 Все получилось, спасибо, не внимательно прочитал выше изложенный текст, сделал как вы написали: создал RichEdit2, назначил ему событие OnResizeRequest2, и удалил RichEdit2, а его событие назначил динамически создаваемым RichEdit[x], просто до этого я делал так: RichEdit[x].OnResizeRequest:=Res(); и описывал в Privat procedure Res(Sender: TObject; Rect:TRect); это вызывает ошибку наверное т.к. в Res() я не передаю парамерт Rect... я так понял мой вариант работает только когда на событие назначается процедура в которую передается один параметр Sender, напр OnClick. Алексей, добавлено 6.08.13, 01:46:57 Уважаемый Автор, прошу помощи, пишу проект для себя, такого плана: ресторанное меню в нем два поля (и панель управления) слева меню в виде дерева, справа (при выборе слева) открывается содержание блюда в котором и текст и картинки и желательно видео ролики, работает меню в режиме просмот и редактирования (для администратора), задача моя такая: надо чтобы всё меню хранилось в одном файле, и все блоки (блюда) файла были доступны для просмотра редактирования, перезаписи. Такой вопрос: какие компаненты использовать? Для вывода содержания меню наверное TTreeView или TListView, самое трудное для просмотра/редактирования блюда, как я вижу содержание блюда должно быть похоже на веб страницу, пролистываешь ее вверх вних, читаешь и смотришь картинки и видео, пришел администратор нажал редактирование ввел пароль и можно изменять текст, загружать другие картинки и видео и соответственно перезаписать это блюдо, какой сюда компанент для просмотра/редактирования содержания блюда TRichEdit в который вставлять фото и видео или собирать из нескольких компанентов TRichEdit,TImage или TWebBrowser. Все это не по теме! Если можете помогите в каком направлении копать, заранее спасибо. Андрей, добавлено 7.11.13, 11:56:31 Как мне сохранить динамичиске создан объект на форме чтобы использовать его в следующий запуск программы ? Автор, добавлено 7.11.13, 12:05:23 Динамически созданный объект он на то и динамически созданный, чтобы не сохраняться, а каждый раз создаваться заново. Иначе используйте обычный объект, из палитры компонентов. Возможно, я вас не совсем понял. В таком случае, приведите пример того, что вы имеете в виду. Андрей, добавлено 7.11.13, 13:52:01 Мне нужно чтобь при выполнении программы создавался объект и сохранялся при закрытии программы ,чтобы можно было его использовать постоянно. Типа мне нужно добавить Label ,а текст и место положение задавать при выполнении программы , но чтобь когда програма закончится он был там где создавалса Андрей, добавлено 7.11.13, 13:54:00 Когда я открою заново програму Лейбел был там где его создали при прошлом выполнении программы Автор, добавлено 7.11.13, 14:08:37 Параметры программы, в том числе расположение компонентов, значение переменных, текст и другие вещи нужно при закрытии сохранять в файл, а при последующем открытии считывать этот файл, и присваивать переменным эти значения. Для чего, вы думаете, существуют файлы типа *.ini? Ну да тип файла неважен. Структура файла это запись типа Tini = Record Left, Top: Integer; Caption: String[100];//100 - максимальная длина текста в Label end; Создаём глобальные переменную и файловую переменную: var Ini: Tini; Fini: File of Tini; При закрытии программы (обработчик OnClose) пишем: begin ini.Left:=Label.Left; ini.Top:=Label.Top; ini.Caption:=Label.Caption; AssignFile(Fini, 'label.ini'); Rewrite(Fini, ini); end; А при открытии программы в обработчике OnCreate Формы пишем: begin //создаём Label: Label:=TLabel.Create(Form1); Label.Parent:=Form1; //считываем файл (вначале проверив на его существование): if FileExists('label.ini') then begin AssignFile(Fini, 'label.ini'); Reset(Fini); Read(Fini, ini); //присваиваем значения: Label.Left:=ini.Left; Label.Top:=ini.Top; Label.Caption:=ini.Caption; end; end; Андрей, добавлено 7.11.13, 14:24:09 Я так и думал просто не знал как ето сделать . Большое Спасибо !!!! Автор, добавлено 7.11.13, 14:39:41 Пожалуйста. Но я тут подумал, что создавать Label нужно не сразу, а перед if FileExists('label.ini') then . А сохранять параметры не при закрытии программы, а в той процедуре, где эти значения присваиваются созданной Label, иначе при каждом закрытии программы файл будет пересоздаваться, а если параметры больше не меняются, то какой смысл... Андрей , добавлено 7.11.13, 14:46:43 О спасибо и за ето ) Автор, добавлено 7.11.13, 14:53:18 А-а-а, блин, не перед FileExists а после. То есть если файл существует, то нужно создать Label, а если не существует, то вся эта конструкция пропускается. Александр, добавлено 2.12.13, 18:19:34 Помогите создать динамический объект из dll при нажатии на кнопку Автор, добавлено 2.12.13, 20:52:01 А какие самостоятельные результаты? В смысле, сам пробовал? Что не выходит? Святослав, добавлено 5.01.14, 21:33:04 Как сделать, чтобы созданные объекты оставались и при следующем заходе в программу Святослав, добавлено 5.01.14, 21:35:06 Как сделать, чтобы созданные объекты оставались и при следующем заходе в программу Автор, добавлено 5.01.14, 23:39:03 Никак. Но соответствующего эффекта добиться можно. Нужно сохранять в файл перечень объектов которые должны быть созданы, при старте программы считывать этот файл, и пересоздавать их заново. Конечно, объём сохраняемой информации большой, но иначе нельзя. Александр, добавлено 9.01.14, 01:50:48 Автор, а можно динамически созданной кнопки применить событие открывание вот так: button[n].OnClick:=Button1Click(n); ? Александр, добавлено 9.01.14, 01:53:40 Автор, а можно динамически созданной кнопки применить событие открывания вот так: button[n].OnClick:=closepanel(n); ? P.S. "closepanel(n:byte)" это уже созданная процедура Автор, добавлено 9.01.14, 06:04:48 Нет, так нельзя, потому что не совпадают параметры. В процедуре OnClick используется параметр Sender. Но можно создать для OnClick стандартную процедуру, в которой будет вызываться ваша процедура. Антон, добавлено 2.02.14, 16:39:12 Здравствуйте. При написании программы столкнулся со следующей проблемой: При открытии формы на ней динамически в цикле создаются несколько компонентов Memo, рядом с каждым из них - кнопки Button. Кнопки необходимы для удаления соответствующих им Memo. Но сам механизм удаления реализовать немогу. Не знаю даже как подступиться. Ведь если я буду по событию OnClick вызывать процедуру Component.Free удалится последний созданный Memo, а не соответствующий нажатой кнопке. Как же объяснить программе, какой Memo надо удалять? Заранее спасибо. Автор, добавлено 2.02.14, 17:27:06 А почитайте про параметр Sender! Страница так и называется: sender.php Но при создании нужно каждой паре Memo-кнопка присваивать свой уникальный параметр Tag. По нему и определим что удалять. Можно, конечно, непосредственно имя компонента определять - без разницы, но по Tag удобнее. У вас, возможно, компоненты создаются как элементы массива (я бы так делал). Вот и присваивайте индекс параметру Tag. Потом смотрите (Sender as TButton).Tag - это будет индекс элемента массива, и удаляете этот элемент. Антон, добавлено 2.02.14, 18:00:47 Большущее, вам спасибо. И за Sender и за идею с массивом, как-то раньше до этого не додумался. Святослав, добавлено 16.02.14, 19:38:27 Здравствуйте! А как можно сохранить в ini файл неизвестное количество динамически созданных объектов(объекты однотипны TEdit) Автор, добавлено 16.02.14, 22:08:28 Точно также как и один, просто неизвестно сколько раз. Макс, добавлено 21.02.14, 22:17:42 можете подсказать, как создать массив из пяти объектов label, расположенных друг под другом, при нажатии кнопки. Как именно создать и объявить этот массив Автор, добавлено 21.02.14, 22:34:16 Обычный массив:
|
|