Discussion:
wxTimer advice: how to stop it in the destructor
Marian 'VooDooMan' Meravy
2014-09-09 13:09:52 UTC
Permalink
Greetings,

I am having constant problem with wxTimer not allocated dynamically, but
initialized in constructor of wxPanel/wxFrame with proper windows ID,
and in the constructor, assigned period of repetition (.Start()) of
timer triggering (like 200 milliseconds, e.g.).

The problem is, when in the destructor of the class, I explicitly call
"<m_timer>.Stop();", but it still trigger and call "OnTimer" event on
already destructed class (wxPanel mostly, sometimes wxFrame)-derived class.

I have very ugly workarounds, but I want you to tell me what I am
missing, since AFAIK events on deleted object are not sent any more, but
it looks like, in my case, they are.

TIA!
vdm
.
'Catalin' via wx-users
2014-09-09 13:24:51 UTC
Permalink
Hi,
Post by Marian 'VooDooMan' Meravy
I am having constant problem with wxTimer not allocated dynamically, but
initialized in constructor of wxPanel/wxFrame with proper windows ID,
and in the constructor, assigned period of repetition (.Start()) of
timer triggering (like 200 milliseconds, e.g.).
The problem is, when in the destructor of the class, I explicitly call
"<m_timer>.Stop();", but it still trigger and call "OnTimer" event on
already destructed class (wxPanel mostly, sometimes wxFrame)-derived class.
Disconnect the event handler(s) for wxTimerEvent in the destructor.

Regards,
C
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Marian 'VooDooMan' Meravy
2014-09-09 13:49:06 UTC
Permalink
Greetings,
Post by 'Catalin' via wx-users
Hi,
[...]
Post by 'Catalin' via wx-users
Disconnect the event handler(s) for wxTimerEvent in the destructor.
I am using static binding, like in .cpp unit:

BEGIN_EVENT_TABLE(c_gui_equalizer_panel, c_gui_panel_base)
[...]
EVT_TIMER(BOX_EQUALIZER_TIMER2, c_gui_equalizer_panel::OnTimer2)
END_EVENT_TABLE()

AFAIK "static" binding cannot be unbind...

best,
vdm
.
David Connet
2014-09-09 13:55:54 UTC
Permalink
Post by Marian 'VooDooMan' Meravy
Greetings,
Post by 'Catalin' via wx-users
Hi,
[...]
Post by 'Catalin' via wx-users
Disconnect the event handler(s) for wxTimerEvent in the destructor.
BEGIN_EVENT_TABLE(c_gui_equalizer_panel, c_gui_panel_base)
[...]
EVT_TIMER(BOX_EQUALIZER_TIMER2, c_gui_equalizer_panel::OnTimer2)
END_EVENT_TABLE()
AFAIK "static" binding cannot be unbind...
Can you stop it in WM_DESTROY instead? I find that's usually the best
place for windows-related cleanup (as opposed to class-related).

Dave
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Marian 'VooDooMan' Meravy
2014-09-09 14:11:10 UTC
Permalink
Greetings,

On 2014-09-09 15:55, David Connet wrote:
[...]
Post by David Connet
Can you stop it in WM_DESTROY instead? I find that's usually the best
place for windows-related cleanup (as opposed to class-related).
Can you please be more specific? like a code snippet?

best,
vdm
.
David Connet
2014-09-09 14:30:01 UTC
Permalink
Post by Marian 'VooDooMan' Meravy
Greetings,
[...]
Post by David Connet
Can you stop it in WM_DESTROY instead? I find that's usually the best
place for windows-related cleanup (as opposed to class-related).
Can you please be more specific? like a code snippet?
Sorry, meant to say wxEVT_DESTROY (had my full-Windows hat on -
WM_DESTROY is the Win32 message that is sent)

void <yourclass>::OnDestroy(wxWindowDestroyEvent& evt)
{
<m_timer>.Stop();
}

You can either add that to the map you already have:
EVT_DESTROY(<yourclass>::OnDestroy)

or bind it dynamically.

Dave
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Marian 'VooDooMan' Meravy
2014-09-09 14:57:17 UTC
Permalink
Greetings,
Post by David Connet
EVT_DESTROY(<yourclass>::OnDestroy)
or bind it dynamically.
with small correction to your suggestion "EVT_WINDOW_DESTROY" didn't helped.

I guess I have bug in my code at somewhere else place that is causing
this error (My first guess is multithreading and data races... Or
calling WX from non-main thread... ...in the first place).

Anyways, thank you for your suggestions.

best,
vdm
.

Vadim Zeitlin
2014-09-09 14:01:57 UTC
Permalink
On Tue, 09 Sep 2014 15:09:52 +0200 Marian 'VooDooMan' Meravy wrote:

MVM> I am having constant problem with wxTimer not allocated dynamically, but
MVM> initialized in constructor of wxPanel/wxFrame with proper windows ID,
MVM> and in the constructor, assigned period of repetition (.Start()) of
MVM> timer triggering (like 200 milliseconds, e.g.).
MVM>
MVM> The problem is, when in the destructor of the class, I explicitly call
MVM> "<m_timer>.Stop();", but it still trigger and call "OnTimer" event on
MVM> already destructed class (wxPanel mostly, sometimes wxFrame)-derived class.
MVM>
MVM> I have very ugly workarounds, but I want you to tell me what I am
MVM> missing, since AFAIK events on deleted object are not sent any more, but
MVM> it looks like, in my case, they are.

They are not supposed to, wxMSW code explicitly checks that the timer is
still alive before generating the timer event. I don't know what happens in
your case, the only guess I can venture is that your object is destroyed
from wxEVT_TIMER handler itself. As usual, if you can reproduce the problem
with a small patch to the minimal sample, it would help a lot with
understanding it.

Regards,
VZ
--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/
Marian 'VooDooMan' Meravy
2014-09-09 14:09:23 UTC
Permalink
Greetings,
Post by Vadim Zeitlin
still alive before generating the timer event. I don't know what happens in
your case, the only guess I can venture is that your object is destroyed
from wxEVT_TIMER handler itself. As usual, if you can reproduce the problem
No, I destroy WX classes by calling ->Destroy() and hope WX will call
~destructor() on the next running of loop.

best,
vdm
.
Eric Jensen
2014-09-09 14:16:13 UTC
Permalink
Hello Marian,

Tuesday, September 9, 2014, 4:09:23 PM, you wrote:

MVM> Greetings,
Post by Vadim Zeitlin
still alive before generating the timer event. I don't know what happens in
your case, the only guess I can venture is that your object is destroyed
from wxEVT_TIMER handler itself. As usual, if you can reproduce the problem
MVM> No, I destroy WX classes by calling ->Destroy() and hope WX will call
MVM> ~destructor() on the next running of loop.

AFAIK only toplevel windows are destroyed delayed. All others are
delete(d) immediately.

Eric
--
Please read http://www.wxwidgets.org/support/mlhowto.htm before posting.

To unsubscribe, send email to wx-users+***@googlegroups.com
or visit http://groups.google.com/group/wx-users
Marian 'VooDooMan' Meravy
2014-09-09 14:31:39 UTC
Permalink
Greetings,
Post by Eric Jensen
Hello Marian,
MVM> Greetings,
Post by Vadim Zeitlin
still alive before generating the timer event. I don't know what happens in
your case, the only guess I can venture is that your object is destroyed
from wxEVT_TIMER handler itself. As usual, if you can reproduce the problem
MVM> No, I destroy WX classes by calling ->Destroy() and hope WX will call
MVM> ~destructor() on the next running of loop.
AFAIK only toplevel windows are destroyed delayed. All others are
delete(d) immediately.
IMO I can't escape feeling I got bug somewhere.

Maybe, When I found the bug in my code I hope I will create patch with
asserts due to invalid conditions, to alert developers, when they will
do such mistake.

But still I think it is strange error. I believe not in WX, but in my
code. My wish.

best,
vdm
.
Loading...