Jump to content
СофтФорум - всё о компьютерах и не только

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


aTeos
 Share

Recommended Posts

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

Link to comment
Share on other sites

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

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

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

Edited by Darhazer
Link to comment
Share on other sites

Darhazer

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

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

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

Link to comment
Share on other sites

  • 5 months later...
а как затем удалить созданные объекты?

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

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

194329[/snapback]

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

Button1->Free

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

Link to comment
Share on other sites

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

194468[/snapback]

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

Link to comment
Share on other sites

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

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;
Link to comment
Share on other sites

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

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 *)'

}

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

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

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

Link to comment
Share on other sites

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

void __fastcall TForm1::GridClick(TObject *Sender)

{

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

}

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

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

g1=new TStringGrid(Form1);

g1->OnClick=Form1->GridClick;

}

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

Link to comment
Share on other sites

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;}
Link to comment
Share on other sites

  • 2 months later...

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

TButton OKButton = new TButton(this);

OKButton->Caption = "OK";

OKButton->Parent = this;

Link to comment
Share on other sites

  • 9 months later...

Не знаю почему, у меня в 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 узнать, ничего не вышло. Кто знает помогите!!! :)

Link to comment
Share on other sites

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

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

Link to comment
Share on other sites

Опиши конкретнее, что у тебя не получается? Что находится в 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:

Link to comment
Share on other sites

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

ВОТ МОЙ КОД:

 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:

Link to comment
Share on other sites

  • 2 weeks later...

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

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

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

void __fastcall TGameForm::HeroeClick(TObject *Sender)

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

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

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

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

}

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

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...