Ticket #11648 (closed defect: invalid)
wxTimer fails on wxMSW if EVT_PAINT handler (wxPaintEventHandler) does not create wxPaintDC
| Reported by: | m0nstr42 | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | base | Version: | 2.8.10 |
| Keywords: | wxTimer EVT_PAINT wxPaintEventHandler wxPaintEvent wxPaintDC wxMSW | Cc: | |
| Blocked By: | Patch: | no | |
| Blocking: |
Description
Using wxMSW, if an application uses a timer and has an EVT_PAINT event, the event handler function MUST create a wxPaintDC (e.g. include the line wxPaintDC dc(this);). If this is omitted, the timer ceases to trigger events.
Specific Situation: My application uses a wxTimer-derived class to trigger regular events. One of those events is to Refresh a wxGLCanvas-derived animation window. The wxGLCanvas has it's EVT_PAINT connected to a member function called OnPaint. If the line "wxPaintDC" is not in that function, the timer ceases to operate at all.
What I would expect: Without knowing the gory details of windows programming, I'd expect omission of that line to cause a failure to draw whatever it is I want to render. I'd expect the timer to continue to run, thus running all of the other timed events driven by it. In the limit, I'd expect that if my OnPaint function was empty, my program would continue to run normally except that the drawing would not happen.
What happens: The timer stops working completely. This happens in wxMSW, but not wxMAC.
I don't want to attach code because the project is huge. You can, however, test it fairly easily by taking any of the animation rendering tutorials that use wxTimer and commenting out the wxPaintDC line (but still, for example, printf something every time the timer goes off). I was able to confirm this by adding a simple timer to the penguin sample program.
I'm using a wxGLCanvas, but I found this forum post with someone experiencing similar problems but not using OpenGL: http://wxforum.shadonet.com/viewtopic.php?t=13295&highlight=
I don't know if this is exactly a bug, but the way in which things are implemented makes this problem VERY hard to debug. I suspected problems with my timer, ID clashes, something.. not that my OnPaint function was missing a line. After a couple days I figured out that commenting out the EVT_PAINT entry in the event table caused the timer to start working again. That was a big revelation but I was no closer to solving my problem!
I also know (in retrospect) that all of the examples include the wxPaintDC line, some with comments like "This must be here", but there's no explanation why. A reasonable person might expect that the drawing would simply stop working.
So - even if this isn't fixed in code, I think it could be documented better. The wxPaintEvent documentation has the line "Note that In a paint event handler, the application must always create a wxPaintDC object, even if you do not use it. Otherwise, under MS Windows, refreshing for this and other windows will go wrong." but, to go with my theme, this does not lead me to believe that the timer would stop working - not to mention if my timer stops working I don't go to the wxPaintEvent documentation immediately :-P It's not mentioned at all in the wxTimer documentation.
I got this working with the 2.9 svn release, but also tried 2.9.0 and originally encountered problems with 2.8.10.
