Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594

Самоуничтожение панели

10.10.2013, 16:20. Показов 2487. Ответов 25
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
- Здравствуйте Форумчане! У меня возник такой вопрос:
В моей программе сделан VCL-компонент на базе TPanel (TMy_Panel). На ней, в свою очередь, динамически
создается TComboBox.
- Создавать и удалять эту МоюПанель ИЗВНЕ конечно просто:
C++
1
2
3
4
5
6
7
8
9
10
  // указатель на МоюПанель.
  TMy_Panel*  My_Panel;
 
  // создание и вывод на экран МоейПанели.
  My_Panel = new  TMy_Panel( this );
  My_Panel->Parent = this;
 
  // удаление МоейПанели с экрана и вообще.
  delete  My_Panel;
  My_Panel = NULL;
- Но часто бывает очень удобно при вводе "Enter" в КомбоБоксе МоейПанели сразу:
a) - передавать выбранное значение (строку) КомбоБокса в основную программу;
b) - уничтожать саму МоюПанель (за дальнейшей ненадобностью).
- Т.е. как уничтожить МоюПанель из кода самой МоейПанели ? ...
Заранее благодарен всем!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.10.2013, 16:20
Ответы с готовыми решениями:

Самоуничтожение программы
Всем доброго вечера. Помню, год назад примерно в журнале "Хакер" была задача, заключающаяся в том, чтобы сделать программу,...

Самоуничтожение файла
Как сделать штоб файл самоуничтожалса

Самоуничтожение объекта класса
Всем доброго дня!!! Подскажите пожалуйста как лучше поступить: есть игровое поле (условно просто матрица указателей на клетки, которые в...

25
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
10.10.2013, 16:22
C++
1
2
delete  My_Panel;
  My_Panel = NULL;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
10.10.2013, 16:43
Цитата Сообщение от Staut Посмотреть сообщение
как уничтожить МоюПанель из кода самой МоейПанели ? ...
Никак. Не надо этого делать... Чревато.
1
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
10.10.2013, 16:50
Т.е из метода твоего комбобокса?
А если так?
C++
1
2
3
4
static AnsiString A;
A = Text; // Или как-то еще
delete this;
return A;
0
Практикантроп
 Аватар для nick42
4841 / 2726 / 534
Регистрация: 23.09.2011
Сообщений: 5,798
10.10.2013, 16:52
Практически это можно осуществить, но только через Try - __finally , а вообще - не следует так вольно с компонентами... .
1
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
10.10.2013, 17:43
Цитата Сообщение от UI Посмотреть сообщение
Чревато.
чем? я у себя попробовал - всё ок.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33371 / 21497 / 8234
Регистрация: 22.10.2011
Сообщений: 36,893
Записей в блоге: 12
10.10.2013, 17:45
AV. Этого достаточно (по крайней мере, для меня), чтобы не пилить сук, на котором сидишь...
0
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
10.10.2013, 17:49
Цитата Сообщение от UI Посмотреть сообщение
AV. Этого достаточно (по крайней мере, для меня), чтобы не пилить сук, на котором сидишь...
не понял, конкретнее пожалуйста.

вот какой код у себя проверял:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        TPanel *panel = new TPanel(this);
        panel->Width = 200;
        panel->Height = 100;
        panel->Left = 100;
        panel->Height = 100;
        panel->Parent = this;
        panel->OnDblClick = OnPanelDblClick;
 
        TComboBox *combo = new TComboBox(panel);
        combo->Parent = panel;
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::OnPanelDblClick(TObject *Sender)
{
        TPanel *panel = dynamic_cast<TPanel*>(Sender);
        if (panel)
        {
                delete panel;
        }
}
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
10.10.2013, 22:30
kzru_hunter, метод OnPanelDblClick является методом класса формы. Он не имеет прямого отношения к классу панели, который ты даже и не наследовал. Пример некорректный.

Попробуй погонять такой код, причем многомного раз.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class pnl : TPanel
{
    public:
        TComboBox *combo;
        
        __fastcall pnl( TObject *own ) : TPanel( own ) 
        {
            combo = new TComboBox( this );
            combo->Parent = this;
            OnDblClick = & OnPanelDblClick;
        }
        void __fastcall OnPanelDblClick( TObject * Sender )
        {
            TPanel * panel = dynamic_cast< TPanel * >( Sender );
            if ( panel )
            {
                delete panel;
            }
        }
}
2
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
10.10.2013, 23:27
Цитата Сообщение от BRcr Посмотреть сообщение
Он не имеет прямого отношения к классу панели, который ты даже и не наследовал.
Тут меня вот это смутило
Цитата Сообщение от Staut Посмотреть сообщение
как уничтожить МоюПанель из кода самой МоейПанели ? ...
Ну и я конечно решил, что где-то есть класс, наследуемый от TPanel, и у него переопределены какие-то методы... Короче, вопрос поставлен не полно и не корректно
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
10.10.2013, 23:29
Ну стоит последней строкой в методе delete this, и что? Это же последняя строка, больше к св-вам this мы в этом методе мы не обращаемся. Откуда взяться ошибкам?
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
11.10.2013, 00:00
Цитата Сообщение от Staut Посмотреть сообщение
Создавать и удалять эту МоюПанель ИЗВНЕ конечно просто
Так я не понимаю, чего огород городить? Бюльдер так устроен специально нам в помощь, что события компонентов передаются в методы формы. И нужно уж преследовать какие-то нестандартные цели, чтобы идти на подобные извращения.
Вот мне, кажется, еще ни разу не приходилось наследовать что-то кроме TForm. Но это, возможно, объясняется тем, что я решаю достаточно тривиальные задачи. Вот на BC 502 (если кто помнит) мне приходилось наследовать буквально все стандартные компоненты.

Добавлено через 13 минут
Вот сейчас буквально ради любопытства grep-ом посмотрел все свои Бюльдеровские проекты. Однажды пытался унаследовать кнопку, дабы изменить ее цвет. Не получилось - бросил. А так - только TForm.
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.10.2013, 00:12
Цитата Сообщение от Байт Посмотреть сообщение
Но это, возможно, объясняется тем, что я решаю достаточно тривиальные задачи.
Так и есть.
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
11.10.2013, 16:09  [ТС]
- Прошу прощения за отсутствие, должен был уехать на время ...
- nick42, через try - __finally - не догадался! Надо будет подумать ...
- Варианты kzru_hunter и BRcr тоже надо попробовать. Они отличаются тем, что
в 1-м обработчик двойного щелчка динамической Панели является ВНЕШНИМ для Панели методом
(методом Основной Формы), а во 2-м ВНУТРЕННИМ для Панели методом.
- Я уже делал когда-то вариант (правда не для Панели а для Формы) и нечто среднее между этими
двумя вариантами. Делал метод Основной Формы - "удалитель" динамической вспомогательной Формочки.
Передавал указатель на него через параметры конструктора при создании динамической Формочки. И
там, внутри динамической Формочки, когда было нужно удалить динамическую Формочку, запускал
этот метод. Этот вариант у меня благополучно работал. К сожалению никак не могу найти этот небольшой
проект, а то бы выложил.
- В моем-же варианте с Панелью я делаю примерно то-же, что описал выше, но получаю все время
исключение: - "Control has no parent window", что не так уж и далеко от AV. Можете посмотреть сами этот
проект, кто захочет в прикрепленном архиве.
- Но, видимо, правы UI и nick42: - "Незачем дразнить гусей !" Видимо лучше создавать
МоюПанель один раз (и как невидимую). А ее видимостью легко управлять и ИЗВНЕ, и ИЗНУТРИ
МоейПанели. Сэкономить хотел на размере загрузочника ...
- Всем, всем большое спасибо за участие !
Вложения
Тип файла: rar test_MyPanel.rar (34.0 Кб, 9 просмотров)
0
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.10.2013, 16:32
Скачал test_MyPanel.rar. Открыл, скомпилил, запустил. Нажал кнопку "открыть", нажал кнопку "закрыть". Повторил несколько раз. Никаких ошибок. Builder XE. Что я делаю не так?
0
98 / 81 / 14
Регистрация: 26.07.2013
Сообщений: 594
11.10.2013, 16:57  [ТС]
- Простите gumi250, говорил очень много и забыл дать инструкцию по пользованию:
a) - нажмите кнопку - "Открыть";
b) - Введите какое-либо значение из списка КомбоБокса или наберите новую строку в нем;
c) - нажмите "Enter" для принятия этой строки;
и далее все удовольствия ...
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
11.10.2013, 17:14
Я вижу, что напутал с контекстом обращения, и пост мой был понят неправильно, за что прошу простить.

Staut, то, что выложил я, это не вариант - это демонстрация того, как делать не надо. И предложен код был, только чтобы кто-нибудь смог убедиться в ненадежности данного подхода.
1
 Аватар для kzru_hunter
1124 / 795 / 101
Регистрация: 01.02.2011
Сообщений: 1,887
Записей в блоге: 1
11.10.2013, 17:16
К сожалению, в первый раз встречается в глаза ситуация с самоудалением экземпляра класса. Поэтому не совсем понял проблему.

Но в принципе тот код, что я до этого приводил, вполне легален. Is it legal (and moral) for a member function to say delete this? Поэтому, коде BRcr также не должен вызывать исключений (проверял у себя).

Но вот если ещё усложнить код, например, так:
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
class TMyPanel : public TPanel
{
    public:
        TComboBox *combo;
        
        __fastcall TMyPanel( TObject *own ) : TPanel( own )
        {
            this->Parent = (TWinControl*)own;
            this->Left = 100;
            this->Top = 100;
            this->Width = 100;
            this->Height = 100;
            combo = new TComboBox( this );
            combo->Parent = this;
            combo->OnKeyPress = OnComboKeyPress;
        }
 
        void __fastcall OnComboKeyPress(TObject *Sender, char &Key)
        {
                TComboBox *combo = dynamic_cast<TComboBox*>(Sender);
                if (combo)
                {
                        delete combo->Parent;
                }
        }
 
        void destroy_self()
        {
                OnComboKeyPress(combo, 13);
        }
};
 
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 
}
//---------------------------------------------------------------------------
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        // èñêëþ÷åíèé íåò
        TMyPanel *panel = new TMyPanel(this);
        panel->destroy_self(); // íî åñëè ðàñêîììåíòèðîâàòü ýòó ñòðî÷êó,
                               // òî ïðè íàæàòèè ëþáîé êëàâèøè â ComboBox âûëåçåò îøèáêà "Control has no parent window",
                               // ïî÷åìó âûëåçàåò ýòà îøèáêà?
}
То будет вылезать ошибка "Control has no parent window" (такая же как у Staut) при нажатии любой клавиши в ComboBox . Почему?

Из-за этого я решил, что проще заставить кого-то другого удалить этот самый panel. Никаких идей не приходило в голову, кроме как отправлять сообщение, например в очередь главного потока, что обработчик смог его обработать и удалить этот самый объект(panel):

C++
1
2
3
4
5
6
7
8
9
10
11
12
PostMessage(FormHandle, WM_USER+2, (UINT)panel, 0); // отправляем сообщение на обработку с целью удаления объекта
 
// Для этого обработчика нужно поместить компонент ApplicationEvents на форму
void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,
      bool &Handled)
{
        if (Msg.message == WM_USER+2)
        {
                TControl *control = (TControl*)Msg.wParam;
                if (control != NULL) delete control;
        }
}
1
 Аватар для gumi250
435 / 402 / 57
Регистрация: 06.02.2012
Сообщений: 1,384
11.10.2013, 17:33
Когда у меня возникла такая проблема, тоже пользовался WM_USER. На сколько я понимаю тут проблема вовсе не в самоудалении класса, а в удалении комбобокса из функции-обработки его нажатия. В этом легко убедится если не удалять панель, а удалить только комбобокс.
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
11.10.2013, 17:40
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Почему?
Ответ кроется в том же факе:
You must be absolutely 100% positively sure that your member function will be the last member function invoked on this object.
После завершения выполнения строчки
C++
1
OnComboKeyPress(combo, 13);
управление передается обратно в метод destroy_self(), однако экземпляр класса, которому принадлежит данный метод, уже разрушен. Видимо, на этом месте и происходит сбой.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
11.10.2013, 17:40
Помогаю со студенческими работами здесь

Самоуничтожение экземпляра
Как самоуничтожить мувик когда все кадры его доходят до конца? В примере по AS2 в последнем кадре писали: this.removeMovieClip(); А...

Самоуничтожение базы... :)
Можно ли в Акцессе создать код который уничтожил бы все таблицы в указанную дату? кто нибудь пробывал? ну или хотя бы думал об этом?

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

Самоуничтожение объекта
Здравствуйте. Может ли объект (Экземпляр класса) самостоятельно удаляться? Потому что чтобы удалить объект, нужно в его параметр послать...

Самоуничтожение данных на диске
На удалённой машине (Windows 7) с доступом по TeamViewer нужно создать &quot;кнопку самоподрыва&quot; для возможности уничтожения данных и самой...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru