Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

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

1.8K
17 декабря 2006 года
Andreww
81 / / 02.01.2004
В процессе написания программы обнаружилось, что нужно создавать на форме неколько (заранее не известно сколько) обьектов Shape. Но как именно это сделать? Книги по Билдеру под рукой к сожалению нет. Пишу что-то типа:

TShape* ToStr = new TShape(this);

ToStr->Visible = true;
ToStr->Enabled =true;
ToStr-> Left = 200;
ToStr-> Top = 200;
ToStr-> Shape = stRectangle;
ToStr-> Pen->Style= psSolid;
ToStr-> Pen->Width=1;
ToStr-> Pen->Color= clBlack;
ToStr-> Pen->Mode=pmCopy;
ToStr->Width = 100;
ToStr->Height = 100;

не работает. Ошибок нет, но и результата нет. Кривое место тут «this» – но как его использовать правильно?
309
17 декабря 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:
Кривое место тут «this» – но как его использовать правильно?


Указатель "на самого себя" this тут используется абсолютно правильно. "Форма" объявляется "владельцем" объекта ToStr - соответственно, если объект вручную не удалить, то он будет удалён при удалении формы.
Но для отображения компонента нужно указать ещё и "родителя", что сделано не было. И совершенно зря, ведь свойство Parent определяет, на каком компоненте будет визуально располагаться объект. Соответственно, все свойства, относящиеся к размерам и отображению объекта, зависят от объекта, на который указывает Parent.

 
Код:
TShape* ToStr = new TShape (this); // Создаём объект
ToStr->Parent = this; // Указываем, отображать на форме
// Или
ToStr->Parent = this->Panel1; // Указываем, отображать на "Panel1"
// Далее указываем размеры компонента и прочие параметры.....
16K
18 декабря 2006 года
AntidotE
45 / / 26.09.2006
Создали... Отобразили... очень хорошо...
Возникает вопрос: как им назначить обработчик?
причём такой, чтобы и с ними же и мог работать...
например, создали кнопку, а при нажатии на неё меняется надпись... скажем, сколько раз она была нажата...
можно код в студию? ;)
З.Ы. мой вопрос уже задавался ув. el scorpio и посредством ПМ и в теме "Я начинающий...", обещалось объяснить...
246
18 декабря 2006 года
GIZMO
1.8K / / 30.07.2004
Цитата: AntidotE
Создали... Отобразили... очень хорошо...
Возникает вопрос: как им назначить обработчик?
причём такой, чтобы и с ними же и мог работать...
например, создали кнопку, а при нажатии на неё меняется надпись... скажем, сколько раз она была нажата...
можно код в студию? ;)
З.Ы. мой вопрос уже задавался ув. el scorpio и посредством ПМ и в теме "Я начинающий...", обещалось объяснить...


См. FAQ's, вопрос № 2
http://forum.codenet.ru/showthread.php?t=26390

16K
19 декабря 2006 года
AntidotE
45 / / 26.09.2006
Цитата: GIZMO
См. FAQ's, вопрос № 2
http://forum.codenet.ru/showthread.php?t=26390



прочитал... но вопросы остались...

2. Как программно присвоить кнопке обработчик события OnClick?
объявление

 
Код:
private:    // User declarations
 void __fastcall LeftFunction(TObject *Sender);
public:     // User declarations
        __fastcall TForm1(TComponent* Owner);

определение
 
Код:
void __fastcall TForm1::LeftFunction(TObject *Sender){
 ShowMessage("Test");
}

присвоение
 
Код:
TForm1->BitBtn2->OnClick = TForm1::LeftFunction;


Повторюсь: КАК изменить обработчиком динамически созданный объект, которому этот обработчик и назначен? Вышеприведённый код не позволяет достучаться до свойств объекта, который вызывает его...
Пожалуйста, покажите, как изменить надпись на динамически созданной кнопке при нажатии на неё?

Мои соображения и приблизительный порядок действий:
1) Создать кнопку
2) Назначить родителем, например нашу форму (кстати, она ведь тоже может быть создана динамически)
3) Присвоить событию ОнКлик наш обработчик
4) В обработчике написать "инкрементировать глобальную переменную Н и присвоить надписи на кнопке, на которую нажали, значение этой переменной"

Вопросов ещё есть у нас...
мы ведь можем несколько кнопок создать динамически... им ведь присвоить обработчик тоже надо... можно ли один и тот же обработчик присваивать разным динамически созданным кнопкам или каждой кнопке - отдельный обработчик?

И не надейтесь, что я отстану с этим вопросом... разве что забаните... или кинете в игнор...
309
19 декабря 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:
Повторюсь: КАК изменить обработчиком динамически созданный объект, которому этот обработчик и назначен? Вышеприведённый код не позволяет достучаться до свойств объекта, который вызывает его...
Пожалуйста, покажите, как изменить надпись на динамически созданной кнопке при нажатии на неё?


Покуда нет одновременного наличия времени/настроения/компьютера на написание полной статьи, даю краткий ответ

 
Код:
void __fastcall TForm1::ButtonClick (TObject *Sender)
{
// Выполняем проверку реального типа объекта Sender
   TButton *btnSender = dynamic_cast <TButton*>  (Sender);
   if (btnSender) // Если Sender действительно TButton, то btnSender будет не NULL
   {
 // Читаем свойство объекта, на который указывает переопределённый Sender
      AnsiString btnCaption = btnSender->Caption;
   }
}
16K
19 декабря 2006 года
AntidotE
45 / / 26.09.2006
уряя!!! хоть какой-то прогресс...
получается изменить кепшн, значит получится изменить и другое...

сейчас у меня проблема с удалением созданных кнопочек...
P.S. и в некотором роде проблема с загрузкой исходников... не получается залить на сервер - постоянно кидает на страницу логина...
16K
19 декабря 2006 года
AntidotE
45 / / 26.09.2006
вдогонку: представим ситуацию... создал я 10 кнопочек на форме и назначил им обработчик, который при нажатии на кнопку меняет кепшины всех созданных кнопок... придётся делать через перебор всех компонент формы или есть более удачный путь?
9.5K
19 декабря 2006 года
ROLpogo
80 / / 22.08.2006
Цитата: AntidotE
вдогонку: представим ситуацию... создал я 10 кнопочек на форме и назначил им обработчик, который при нажатии на кнопку меняет кепшины всех созданных кнопок... придётся делать через перебор всех компонент формы или есть более удачный путь?



Если хочешь, чтобы при нажатии на одну из кнопок менялись бы Caption сразу всех созданных тобой кнопок, то проще создать массив, элементами которого будут указатели на все твои кнопки, а если кнопки создаются не сразу, а по мере надобности, то вместо массива можно использовать список.

16K
20 декабря 2006 года
AntidotE
45 / / 26.09.2006
а можно какой-нибудь примерчик?
9.5K
21 декабря 2006 года
ROLpogo
80 / / 22.08.2006
Цитата: AntidotE
а можно какой-нибудь примерчик?



Допустим заранее известно кол-во создаваемых кнопок (10):

В *.h файле в классе формы:

 
Код:
TBitBtn  **pDimButtons;
void __fastcall MyOnClick(TObject *Sender);
int ButtonCount;


В *.cpp файле:
 
Код:
// Наш обработчик.
void __fastcall TForm1::MyOnClick(TObject *Sender)
{
  TBitBtn  *pBB = (TBitBtn*)Sender;
  for (int i = 0; i < ButtonCount; i++)
    pDimButtons->Caption = pBB->Caption + " was pressed";
}


В *.cpp файле в конструкторе формы или в OnCreate или в любом другом обработчике:
Код:
ButtonCount= 10;
// Объявим массив указателей на кнопки.
  pDimButtons = new TBitBtn*[ButtonCount];

// Создание кнопок.
for (int i = 0; i < ButtonCount; i++)
{
  pDimButtons = new TBitBtn(this);
  pDimButtons->Parent = this;
  pDimButtons->Width = 50;
  pDimButtons->Left = i*(pDimButtons->Width + 10) + 10;
  pDimButtons->Top = 10;
  pDimButtons->Caption = "MyButton" + IntToStr(i+1);
  pDimButtons->OnClick = MyOnClick;
  pDimButtons->Visible = true;
}


В *.cpp файле в OnClose()
 
Код:
if (pDimButtons)
  {
    for (int i = 0; i < ButtonCount; i++)
     delete pDimButtons;
    delete []pDimButtons;
  }


Написал без проверки, может где-то опечатался.
16K
22 декабря 2006 года
AntidotE
45 / / 26.09.2006
хм... на первый взгляд всё ок ;)
бум пробовать...

а если не создавать сразу все 10 кнопок, а по мере необходимости? приблизительно так, как у меня в аттачменте в 7 посте...
т.е. пока мы не знаем, сколько мы насоздавали этих кнопок... а надо поменять их кепшны... ;)
9.5K
22 декабря 2006 года
ROLpogo
80 / / 22.08.2006
Цитата: AntidotE
хм... на первый взгляд всё ок ;)
бум пробовать...

а если не создавать сразу все 10 кнопок, а по мере необходимости? приблизительно так, как у меня в аттачменте в 7 посте...
т.е. пока мы не знаем, сколько мы насоздавали этих кнопок... а надо поменять их кепшны... ;)



Лучше уточни задачу. Исходник качать лениво

16K
22 декабря 2006 года
AntidotE
45 / / 26.09.2006
несмотря на то, что он всего 30к...
ну ладно...
есть форма
на ней 2 кнопки, одна добавляет динамические кнопки, другая удаляет (в обратной последовательности от создания)... один клик - одна кнопка... естественно, никакого массива нет... сколько мне захотелось - столько кнопок и создал...
после создания динамической кнопки при её нажатии меняется её кепшн... хочется, чтобы менялся кепшн всех динамически созданных кнопок при нажатии всего на одну из них...

просто хочется разобраться как оно может действовать, как оно действует и как должно... %) чтобы потом блеснуть знаниями перед собой и написать прогу, которая умеет многое и занимает мало места...
9.5K
22 декабря 2006 года
ROLpogo
80 / / 22.08.2006
Ок, сегодня вечером или завтра прикреплю пример
309
22 декабря 2006 года
el scorpio
1.1K / / 19.09.2006
Цитата:

после создания динамической кнопки при её нажатии меняется её кепшн... хочется, чтобы менялся кепшн всех динамически созданных кнопок при нажатии всего на одну из них...


Легко, просто вместо массива используется список

Код:
TForm1::TForm1 ()
{
   fButtonList = new TList() ; // Поле fButtonList - это указатель
// на список значений void*
}
TForm1::~TForm1()
{
// Деструктор
 delete fButtonList; // Кнопки удалять не надо - они удалятся сами
}

TForm1::AddButton ()
{
   TButton *btn = new TButton (this); // Создаём кнопку
   fButtonList->Add (btn); // Добавляем её в список
/// Указываем параметры для btn
}

TForm1::DelButton (TButtom *btn)
{
   fButtonList->Remove (btn); // Удаляем кнопку из списка
   delete btn; // Производим ручное удаление кнопки
}

TForm1::ChangeButton()
{
TButton *btn = NULL; // Временная переменная
// Изменяем все кнопки в цикле с конца списка
for (int i = fButtonList->Count-1; i >= 0; i--)
{
   btn = dynamic_cast <TButton*> (fButtonList->Items );
   if (btn) // Если не указатель не равен NULL
   {
      btn->Caption = ...; // Изменяем текст кнопки
   }
}
}
9.5K
23 декабря 2006 года
ROLpogo
80 / / 22.08.2006
2 примера
16K
25 декабря 2006 года
AntidotE
45 / / 26.09.2006
Спасибо, бум пробовать вечерком... а то работы много... :(
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог