Перейти к содержанию
СофтФорум - всё о компьютерах и не только

Динамическое создание объектов


Рекомендуемые сообщения

Нужно в процессе работы программы создать допустим 10 компонентов TButton. Как это сделать, чтобы потом можно было изменить свойства каждого из них?

Ссылка на комментарий
Поделиться на другие сайты

А ти всегда можеш изменят свойства компонентах, которых поставил в Form Desginer-и. Но если хочеш создат динамически:

var Button1: TButton;beginButton1  := TButton.Create(Form1);Button1.Parent = Form1;Button1.Caption = 'My dynamic Button';...

И так далее. Сложнейшея част это обработка собития динамически созданого компонента. Но и ето можно сделать :)

Изменено пользователем Darhazer
Ссылка на комментарий
Поделиться на другие сайты

Darhazer

Спасибо, на Delphi получилось.

Не подскажешь, как сделать это же, только на C++ Builder? Там по ходу какая-то другая система. Сколько ни пробовал - не выходит.

ps у тебя с клавой что-то :sly:

Ссылка на комментарий
Поделиться на другие сайты

  • 5 месяцев спустя...

а как затем удалить созданные объекты?

я пользуюсь оператором delete, но компонентв остаются на форме.

??? в чем дело :(

Ссылка на комментарий
Поделиться на другие сайты

а как затем удалить созданные объекты?

я пользуюсь оператором delete, но компонентв остаются на форме.

??? в чем дело :)

194329[/snapback]

А пробувал так:

Button1->Free

Я не пользувал Borland C++ Builder, но всегда можеш порпобувать :)

Ссылка на комментарий
Поделиться на другие сайты

Уф... точно не помню... давно до Билдера не добирался. Если не ошибаюсь - что-то вроде:
Form1->RemoveControl(MyButton);delete MyButton;

194468[/snapback]

Ага спасибо - работает

Ссылка на комментарий
Поделиться на другие сайты

возник вопрос - как созданным объектам назначить обработчики событий

196473[/snapback]

Для динамического назначения обработчика надо обьявить процедуру, тип которой (кол-во, тип, и порядок параметров) будут совпадать с типом процедуры-обработчика данного события. Затем после динамического создания обьекта эта процедура назначается в качестве обработчика события. Делается это так. У обьекта есть поля процедурного типа, соответствующие каждому событию, генерируемому этим обьектом. Присваивая этим полям значения, можно назначить обработчики событий.

Фрагменты кода на Делфи, переопределяющие обработку двух событий:

   // Процедура-обработчик для события onClick   procedure BoxClick(Sender: TObject);   // Процедура-обработчик для события onMouseDown   procedure BoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);   procedure createBox();...procedure BoxMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin // обработка события onMouseDownend;procedure BoxClick(Sender: TObject);begin // обработка события onClickend;// Создание нового обьектаprocedure createBox(); Box:=TImage.Create(MainForm); // Назначение обработчиков событий. Box.OnClick:=BoxClick; Box.OnMouseDown:=BoxMouseDown;end;
Ссылка на комментарий
Поделиться на другие сайты

А на Билдере? Я пытаюсь сделать примерно так:

void __fastcall GridClick(TObject *Sender);//эту функцию я хочу назначить

//обработчиком события

//---------------------------------------------------------------------------

void __fastcall GridClick(TObject *Sender)

{

//обработка события OnClick

}

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

g1=new TStringGrid(Form1);

g1->OnClick=GridClick;//в этом месте ошибка:Cannot convert 'void (_fastcall *)(TObject *)' to 'void (_fastcall * (_closure )(TObject *))(TObject *)'

}

как мне изменить код, чтобы типы соответствовали?

Добавлено позже:

сам разобрался - дело в том что функцию, которую надо сделать обработчиком события я объявлял вне класса. Сделав ее методом класса, такой номер прошел.

Ссылка на комментарий
Поделиться на другие сайты

Все правильно, только вот:

void __fastcall TForm1::GridClick(TObject *Sender)

{

//обработка события OnClick

}

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

g1=new TStringGrid(Form1);

g1->OnClick=Form1->GridClick;

}

т.к. обработчик - это клауза, то есть требует точного указания объекта.

Ссылка на комментарий
Поделиться на другие сайты

TButton **__fastcall CreateButtons(DWORD Num){   TButton **Buttons=NULL;   if(Num==0)       return Buttons;   Button=new TButton*[Num];   for(DWORD i=0;i<Num;i++)   {       Buttons[i]=new TButton(Form1); //Owner       Buttons[i]->Name="Button"+IntToStr(i+1);   }   return Buttons;}
Ссылка на комментарий
Поделиться на другие сайты

  • 2 месяца спустя...

Не знаю почему, у меня в C++ Builder 6 динамические объекты появляются только после следующей комбинации строчек кода:

TButton OKButton = new TButton(this);

OKButton->Caption = "OK";

OKButton->Parent = this;

Ссылка на комментарий
Поделиться на другие сайты

  • 9 месяцев спустя...

Не знаю почему, у меня в C++ Builder 6 динамические объекты появляются только после следующей комбинации строчек кода:

TButton OKButton = new TButton(this);

OKButton->Caption = "OK";

OKButton->Parent = this;

Ну не знаю. :)

У меня все нормально. TButton* MyButton = new TButton(<родитель>) и т.д.

Лично у меня другая проблема. Создаю TImage* Heroe[100];

потом динамически обьявляю Heroe = new TImage(0); Heroe->Parent = Form1; и тому подобное.

Для всех Heroe[100] у меня один обработчик void __fastcall HeroeClick(TObject *Sender);

Как я могу узнать в обработчике(клик мышкою) какой именно Heroe вызвал этот обработчик. Пробовал через *Sender узнать, ничего не вышло. Кто знает помогите!!! :)

Ссылка на комментарий
Поделиться на другие сайты

Пробовал через *Sender узнать, ничего не вышло.

Ну, вообще-то это делается именно через Sender, это основное назначение данного параметра. Опиши конкретнее, что у тебя не получается? Что находится в Sender'e в момент вызова?

Ссылка на комментарий
Поделиться на другие сайты

Опиши конкретнее, что у тебя не получается? Что находится в Sender'e в момент вызова?

вобщем - назначение обработчика события

for(i=1; i<=40; i++)

{ Heroe = new TImage(GameForm);//масив картинок прописан раньше TImage* Heroe[160];

Heroe->Parent = GameForm;

...//описание координат, загрузка картинки

Heroe->OnClick = HeroeClick;

}

обработчик:

void __fastcall TGameForm::HeroeClick(TObject *Sender)

{ TImage *Name = (TImage*) Sender; //Как считать имя обьекта нашел на одном сайте програмиста по СИшке.

// Но Name->Name оказываеться пустым

//Пробовал писать "Sender->" и дальше перебирал все функции и параметры,

//но не нашел как узнать имя обьекта

}

У меня ведь обьектов типа картинка 160. Я не могу понять как узнать индекс Героя. Везде по сайтах пишут как это делать, но на примере кнопки. Проверял, дак при использовании кнопки в указателе сендер есть имя обьекта.

Чуствую долго я буду учиться на програмиста :dontgetit:

Ссылка на комментарий
Поделиться на другие сайты

ПОМОГИТЕ ПОЖАЛУЙСТА!!!!

ВОТ МОЙ КОД:

 private{ Private declarations }NextTop: integer;-------------------------------------------var i:integer; newstr: TSpeedButton;--------------------------------------------var NewClass: TPersistentClass;begin strno:=strno+1; NewClass := FindClass('TSpeedButton'); newstr := TSpeedButton(TComponentClass(NewClass).Create(Self)); newstr.Parent := Self; newstr.Name := 'str' + IntToStr(strno);			 //---ВНИМАНИЕ СЮДА!!! ВНИЗУ ВОПРОС... newstr.Top := NextTop; newstr.Left := 24; newstr.Flat:=true; newstr.Caption:='~~~~~~~~~'; newstr.Font.Size:=14; newstr.Height:=22; newstr.Width:=233;//  newstr.OnClick:= NextTop := NextTop + 24;ad.Top:=ad.Top+24;end;

МНЕ необходимо чтобы при нажатии на каждую созданную кнопку открывалась новая форма.

В ней нууу... пусть пользователь будет в Edit'e писать Сaption этой кнопки и после закрытия этой формы этот Caption должен меняться у той кнопки на которую нажали...

:bye1::blushing: :)

Вот такой вопрос... А если в общем как в коде использовать будующее имя новой кнопки?... :blush2:

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Вот такой вопрос... А если в общем как в коде использовать будующее имя новой кнопки?... :D

Вобщем была проблема похожая, но уже и сам разобрался. Обработчик для каждой кнопки можешь создавать отдельный, или же если у них код одинаковый то лучше один. Я в делфи не работал :g: , так что извеняй, даю код для си, кто сможет, то опишите все это только для делфи:

Назначение обработчика NewButton->OnClick = ButtonClick; где в заголовочном файле обьявлено в класе формы(где и остальные обработчики) void __fastcall NewButtonClick(TObject *Sender); а в исполняемом модуле описано код обработчика

void __fastcall TGameForm::HeroeClick(TObject *Sender)

{ AnsiString Name = (TComponent(Sender))->Name; // узнать имя кнопки. Смысл в том, что просто узнать из сендера имя

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

// преобразование - это (тип)<переменная>, и конечно чтобы оно воспринималось как указатель, то берем все еще раз в //скобы

/* В конце имени не обизательно писать ее номер i. Если у тебя есть такое свойство, которое не используеться в языке, //например в си это Tag, то можно заносить туда индекс кнопки

}

Вот и все вроде что могу посоветовать. :D

Ссылка на комментарий
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...