0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32

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

27.09.2014, 19:28. Показов 10545. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Не получается сделать программу на C++ Bilder

Разработать приложение, которое динамически создает и удаляет объекты VCL.

На форме размещены 3 компонента TGroupBox. Под каждым компонентом TGroupBox размещен компонент TCheckBox. Внизу формы размещены кнопки «Добавить» и «Удалить».

По нажатию на кнопку «Добавить» в выбранных TGroupBox на свободном месте создать объект на основе TPanel и размещенных внутри ее компонентов TLabel и TEdit. В Label записать номер TGroupBox, а в TEdit – координаты созданного компонента – X и Y.

При нажатии на кнопку «Удалить» – удалить все компоненты с выбранных TGroupBox.

Количество компонентов не ограничено.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.09.2014, 19:28
Ответы с готовыми решениями:

Динамическое создание VCL-объектов из dll
Тренируюсь использовать динамически dll. Пока все вроде получается, но есть одна неясность. Задача примерно такая: сделать из dll...

VCL удаление динамически созданых объектов с формы
Написал игру ханойские башни, так чтобы можно было задавать любое количество колец. Я делаю такой цикл for( int i = 0 ; i<count...

Создание собственного VCL компонента. Динамическое изменение количества колонок в зависимости от размера объекта
Доброго времени суток всем. Решил при создании своего компонента на основе TStringGrid инкапсулировать в него ряд свойств. Хочется...

33
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 17:49  [ТС]
Студворк — интернет-сервис помощи студентам
У меня проблема в том , что при повторном нажатии на кнопку добавить выскакивает ошибка A component named Panel0 already exists, а не создает еще одну панель

Добавлено через 4 минуты
Извиняюсь, понял в чем дело
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 17:52
Цитата Сообщение от andrei1994 Посмотреть сообщение
выскакивает ошибка A component named Panel0
А попробовать показанные уточнения не судьба?
Цитата Сообщение от BRcr Посмотреть сообщение
C++
1
P->Name = "";
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 17:59
Что касается удаления:

C++
1
2
3
4
5
6
7
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
  while(GroupBox1->ControlCount)
     delete GroupBox1->Controls[0];
}
//---------------------------------------------------------------------------
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 18:50
Ну, и что касается удаления - зачем все подряд-то? Такого условия не было.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 19:09  [ТС]
может кто знает как это делать "Хочешь четко по заданию - размещай панельки одну рядом с другой, как клетки шахматной доски"?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 19:10
Цитата Сообщение от BRcr Посмотреть сообщение
Между "индитификацией" и идентификацией нет ничего общего. Надо же, только после ссылки на вики я наконец поимел счастье понять оппонента...
Про dynamic_cast и type_id я знаю. Какое отношение это имеет к теме?
К тому что нет смысла что-то к чему-то кастовать перед вызовом delete, ибо очевидно что иерархия типов VCL cама собой подразумевает наличие виртуальных деструкторов, иначе бы наследование было бы невозможным.

Цитата Сообщение от BRcr Посмотреть сообщение
Ну, и что касается удаления - зачем все подряд-то? Такого условия не было.
Читаем вслух и про себя:
Цитата Сообщение от andrei1994 Посмотреть сообщение
При нажатии на кнопку «Удалить» – удалить все компоненты с выбранных TGroupBox.
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
28.09.2014, 21:42
Цитата Сообщение от Avazart Посмотреть сообщение
К тому что нет смысла что-то к чему-то кастовать перед вызовом delete, ибо очевидно что иерархия типов VCL cама собой подразумевает наличие виртуальных деструкторов, иначе бы наследование было бы невозможным.
Мне - было бы совершенно неочевидно, при условии, что я не копался бы особо в библиотеке.

Вот пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class base
{
    char * c_arr;
 
public:
    base( )
    {
        c_arr = new char[ 20 ];
        ShowMessage( "base constr" );
    }
 
    ~base( )
    {
        delete[ ]c_arr;
        ShowMessage( "base destr" );
    }
} ;
 
class der1 : public base
{
    int * i_arr;
 
public:
    der1( ) :
        base( )
    {
        i_arr = new int[ 20 ];
        ShowMessage( "der1 constr" );
    }
 
    ~der1( )
    {
        delete[ ]i_arr;
        ShowMessage( "der1 destr" );
    }
} ;
 
class der2 : public der1
{
} ;
 
//...
 
    der2 * d2 = new der2( );
    base * bs = reinterpret_cast < base * > ( &d2 );
    delete bs;
Возможно ли наследование в данном случае? Чем эта иерархия принципиально отличается от VCL? Будет ли вызван деструктор der1?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 21:57
Цитата Сообщение от BRcr Посмотреть сообщение
Возможно ли наследование в данном случае?
Очевидно что нет.
Ошибка новичка к примеру наследоваться от STL контейнеров типа std::vector<> которые не предназначены для наследования.
Или вы думаете что разработчики совершают часто такие ошибки, что нужно разводить параною ?
Цитата Сообщение от BRcr Посмотреть сообщение
Мне - было бы совершенно неочевидно, при условии, что я не копался бы особо в библиотеке.
Ну так возьмите и загляните в чем проблема?
Тем более что само собой разумеется что VCL объекты в основе своей создаются только динамически.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
28.09.2014, 23:20  [ТС]
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
28.09.2014, 23:27
Цитата Сообщение от andrei1994 Посмотреть сообщение
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
Запоминать положение/ширину предыдущей панели и следующую располагать чуть ниже.
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
29.09.2014, 06:42
Цитата Сообщение от BRcr Посмотреть сообщение
По условию принципа ООП мы знать не знаем о реализации деструкторов в иерархии TControl => TPanel. Поэтому, если деструктор родительского класса не виртуальный, то деструктор TPanel вызван не будет.
Виртуальность деструктора к его реализации не имеет никакого отношения. Виртуальность деструктора являеются частью описания класса, а описание, по условию принципа ООП, знать не запрещается. Поэтому, можно легко глянуть в справку билдераи и не кастовать каждый раз к TPanel, так как деструктор в TControl виртуальный, как и деструкторы во всей иерархии TControl = > TPanel.
2
Модератор
 Аватар для D1973
9966 / 6500 / 2464
Регистрация: 21.01.2014
Сообщений: 27,511
Записей в блоге: 3
29.09.2014, 09:10
Ну а пока мэтры ломают копья в решении высокоэмперических проблем, мы вернемся к нашим баранам, т.е. ГрупБоксам...
Предлагаю следующий вариант...
*.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TGroupBox *GroupBox1;
    TButton *Button1;
    TButton *Button2;
    TGroupBox *GroupBox2;
    TCheckBox *CheckBox1;
    TCheckBox *CheckBox2;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall Button2Click(TObject *Sender);
private:    // User declarations
    int nPanel, nLabel, nEdit; //Переменные имен компонент
    int dh, dw, dl, dt; //Переменные начального размещения панели
    int aPos[4][2]; //Массив переменных размещения панели (второй индекс - количество GroupBox-ов)
    void __fastcall CreatePanel(TGroupBox *G, int numG);
    void __fastcall DeletePanel(TGroupBox *G);
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif


*.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::CreatePanel(TGroupBox *G, int numG)
{
//Создаем панель
  TPanel *P = new TPanel(G);
  if(G->ControlCount == 0)
   {
     aPos[0][numG] = dh; aPos[1][numG] = dw; aPos[2][numG] = dl; aPos[3][numG] = dt;
   }
  P->Parent = G;
  P->Name = "Panel" + IntToStr(nPanel++);
  P->Caption = "";
  P->Left = aPos[2][numG];
  P->Top = aPos[3][numG];
  P->Width = aPos[1][numG];
  P->Height = aPos[0][numG];
  aPos[2][numG] = P->Left + P->Width + 2;
  if(aPos[2][numG] > G->Width)
   {
     aPos[2][numG] = dl;
     aPos[3][numG] = P->Top + P->Height + 2;
   }
//Создаем метку
  TLabel *L = new TLabel(P);
  L->Parent = P;
  L->Name = "Label" + IntToStr(nLabel++);
  L->AutoSize = true;
  L->Caption = String().sprintf(L"%s на %s", P->Name, P->Parent->Name);
  L->Left = 6;
  L->Top = 3;
//Создаем Едит
  TEdit *E = new TEdit(P);
  E->Parent = P;
  E->Name = "Edit" + IntToStr(nEdit++);
  E->Top = L->Top + L->Height + 4;
  E->Left = L->Left;
  E->Text = String().sprintf(L"%s: X = %d, Y = %d", P->Name, P->Left, P->Top);
  G->Caption = String().sprintf(L"%s содержит %d компонентов", G->Name, G->ControlCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  if(CheckBox1->Checked) CreatePanel(GroupBox1, 1);
  if(CheckBox2->Checked) CreatePanel(GroupBox2, 2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  nPanel = nLabel = nEdit = 1;
  dh = 50; dw = 180; dl = 8; dt = 20;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::DeletePanel(TGroupBox *G)
{
  TPanel *P;
  for(int i(0); i < G->ControlCount;)
   {
     if (P = dynamic_cast <TPanel*>(G->Controls[i]))
      delete P;
     else ++i;
   }
  G->Caption = String().sprintf(L"%s содержит %d компонентов", G->Name, G->ControlCount);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
  if(CheckBox1->Checked) DeletePanel(GroupBox1);
  if(CheckBox2->Checked) DeletePanel(GroupBox2);
}
//---------------------------------------------------------------------------
Миниатюры
Динамическое создание и удаление объектов VCL  
0
 Аватар для kodv
1449 / 1121 / 347
Регистрация: 11.04.2011
Сообщений: 2,621
29.09.2014, 11:08
Цитата Сообщение от andrei1994 Посмотреть сообщение
Кто-нибудь знает как сделать чтобы не налаживалась Panel одна на одну , а только на свободном месте??
Немножко поковырял билдер. Следующая функция возвращаетс случайные координаты места в объекте наследника TWinControl (TGroupBox, TRadioGroup), в которое можно вписать объект наследника TControl. Чтобы программка не зависала, выполняется ограниченное количество попыток поиска, по истечению которых вываливается исключение.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
TPoint FindFreePlace(TWinControl* winControl, TControl* control, int tryCount = 1000)
{
        randomize();
        bool success;
        TPoint ret;
        do
        {
                ret.x = random(winControl->Width - control->Width);
                ret.y = random(winControl->Height - control->Height);
                if(!(success = !winControl->ControlCount))
                {
                        success = true;
                        for(int i(0); i < winControl->ControlCount; ++i)
                                success &= winControl->Controls[i]->Left > (ret.x + control->Width)
                                        || winControl->Controls[i]->Top > (ret.y + control->Height)
                                        || ret.x > (winControl->Controls[i]->Left + winControl->Controls[i]->Width)
                                        || ret.y > (winControl->Controls[i]->Top + winControl->Controls[i]->Height);
                }
                if(!--tryCount)
                        throw Exception("Превышено число попыток найти свободного место для размещения контрола");
        }
        while(!success);
        return ret;
}
PS: функции с неслучайным размещеним добавляемых контролов есть выше.
0
0 / 0 / 0
Регистрация: 19.09.2014
Сообщений: 32
29.09.2014, 22:51  [ТС]
D1973 я пробую запустить твой код и не получается, косяк в том что при нажатии на кнопку пишется что создается но не отображается в GroupBox в чем проблема??

Добавлено через 3 часа 30 минут
С большего разобрался , всем большое спасибо!)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.09.2014, 22:51

Динамическое создание объектов
Здравствуйте, подскажите пожалуйста как решить задачку... Пусть известно кол-во строк = 10 как сделать так чтоб в одной строке было:...

Динамическое создание объектов
Всем привет! Задача По нажатию кнопки &quot;Create&quot; создается двумерный массив элементов TCheckBox и располагается на форме. По...

Динамическое создание объектов класса
Всем привет. При компиляции выдает ошибку Unit1.cpp(26): E2451 Undefined symbol 'product' и Unit1.cpp(43): E2451 Undefined symbol...

Динамическое создание и удаление компонентов.
Понадобилось динамическое создание нескольких компонентов, при нажатии на кнопку. Несколько нажатий - несколько раз создаются компоненты....

HELP::Создание->удаление динамических объектов
Доброй ночи! У меня возникла такая проблема я динамически создаю объекты типа кнопка: void __fastcall TMainForm::Button1Click(TObject...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Опции темы

Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru