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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

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