Page 1 of 1

Как дождаться уничтожения wxDialog?

Posted: Tue Sep 09, 2008 7:26 am
by SamSam
wxWindow::Destroy запускает отложеное удаление окна и его элементов. Соответственно функция не ждет уничтожения окна. А хотелось бы. Т.к. продолжают приходить сообщения, например wxEVT_KILL_FOCUS, в обработчиках которых используются классы, удаляемые после wxWindow::Destroy. Собственно вопрос: как дождаться гарантированного уничтожения окна?

Re: Как дождаться уничтожения wxDialo

Posted: Tue Sep 09, 2008 8:12 am
by tan
Привет.
SamSam wrote:wxWindow::Destroy запускает отложеное удаление окна и его элементов. Соответственно функция не ждет уничтожения окна. А хотелось бы. Т.к. продолжают приходить сообщения, например wxEVT_KILL_FOCUS, в обработчиках которых используются классы, удаляемые после wxWindow::Destroy. Собственно вопрос: как дождаться гарантированного уничтожения окна?
Не понимаю проблемы. Собственно Destroy для того и нужен, что бы безопасно убить окно, если у него еще есть необработанные сообщения в очереди. Если, по каким-то причинам необходимо убить окно без этой лабуды существует delete.

Posted: Tue Sep 09, 2008 8:18 am
by T-Rex
Убивать окно через delete нехорошо, в доке по этому поводу вроде было красиво расписано.

Posted: Tue Sep 09, 2008 8:41 am
by tan
T-Rex wrote:Убивать окно через delete нехорошо, в доке по этому поводу вроде было красиво расписано.
Оно конечно так, но если очень хочется (и, главное, сам понимаешь, что делаешь), то можно :)

Posted: Tue Sep 09, 2008 9:25 am
by SamSam
Да не очень-то можно через delete. Ерунда получается. да и обработки сообщений хотелось бы дождаться)))

Posted: Tue Sep 09, 2008 9:53 am
by tan
SamSam wrote:Да не очень-то можно через delete. Ерунда получается. да и обработки сообщений хотелось бы дождаться)))
Так а в чем проблема с Destroy()? Поподробней, плз.

Posted: Tue Sep 09, 2008 9:57 am
by SamSam
Есть класс который создает и уничтожает диалог. Есть объекты неких классов, которые используются в обработчиках сообщений контролов диалога. Диалог уничтожается в диструкторе класа. Далее уничтожаются доп. объекты, но прикол в том что в это время может проскочить каккой-нить event и все испортить(((

Posted: Tue Sep 09, 2008 12:20 pm
by tan
SamSam wrote:Есть класс который создает и уничтожает диалог. Есть объекты неких классов, которые используются в обработчиках сообщений контролов диалога. Диалог уничтожается в диструкторе класа. Далее уничтожаются доп. объекты, но прикол в том что в это время может проскочить каккой-нить event и все испортить(((
Ну типа того, что ли:

Code: Select all

...
    dialog->Destroy();
    delete some_object;
...
и some_object где-то в диалоге употребляется. Так?

Ну это просто дизайн корявый, можно же как-то иначе это делать, ну, например убивать some_object не в деструкторе класса, а в деструкторе самого диалога. Конкретно сказать трудно, вся конструкция неизвестна. Самый простой (не очень элегантный) способ - обнулять указатель на some_object при его удалении (хотя это как посмотреть, может у тебя в диалоге используется некоторая локальная копия указателя на этот объект) и в обработчике диалога проверять его на NULL.
Короче, лучше это просто переделать, что бы диалог не юзал объекты которыми он не владеет и состояния которых он не знает.

Posted: Tue Sep 09, 2008 1:17 pm
by SamSam
Сам понимаю что корявый дизайн. Не я его придумал. Вот сейчас и стараюсь как-нибудь разделить мух и котлеты, да чтоб еще и всю структуру не переделывать.

Posted: Wed Sep 10, 2008 8:39 am
by SamSam
Вообще есть свои странности в wxWidgets. Ибо если при уничтожении wxDialog мы сначала заходим в деструктор, а потом в обработчик wxWindowDestroyEvent, то это, IMHO, баг)))

Posted: Wed Sep 10, 2008 9:03 am
by tan
SamSam wrote:Вообще есть свои странности в wxWidgets. Ибо если при уничтожении wxDialog мы сначала заходим в деструктор, а потом в обработчик wxWindowDestroyEvent, то это, IMHO, баг)))
Не, в WX все правильно. Деструктор диалога вызывается последним. Поэтому самый безопасный способ - удалять объекты, которые юзаются в диалоге, (да это к любому окну относится) в деструкторе самого диалога (ну, либо не удалять их вовсе, если они вообще для диалога внешние, например, глобальные). А у тебя как раз не так :(

Posted: Wed Sep 10, 2008 10:15 am
by SamSam
tan wrote: Не, в WX все правильно. Деструктор диалога вызывается последним. Поэтому самый безопасный способ - удалять объекты, которые юзаются в диалоге, (да это к любому окну относится) в деструкторе самого диалога (ну, либо не удалять их вовсе, если они вообще для диалога внешние, например, глобальные). А у тебя как раз не так :(
Вчера породил класс от wxDialog, внедрил в иерархию, проблема практически решилась. В отладке деструктор класса вызывается раньше, чем обработчик wxWindowDestroyEvent. В винде, во всяком случае. Сомневаешься - проверь ;-) Глюк отладчика допускаю.