Onpaint madness
63q2o4i02 at sneakemail.com
63q2o4i02 at sneakemail.com
Fri Sep 1 18:49:54 PDT 2006
Hi, I'm having troubles with onpaint. XPSP2, wxMSW 2.7.0-1.
I'm getting a zillion OnPaint messages with no luck in trynig to handle
them. My abbreviated code is at the end. Basically I'm trying to get
a wxTimer to periodically poll the USB every second and draw stuff on
the screen. If there is no new data then don't draw. I want to
restart the one-shot timer after the drawing is done, just to make sure
it's not "tripping" on itself once I set the timer to 1ms or something.
This USED to work fine when I drew from OnTimer using a wxClientDC,
but I wanted to do it "properly", and thought it might get rid of
flicker if I did it from OnPaint. Now it's completely hosed and I'm
not sure what to do!!
0. MyApp is the "main thing" here. It creates the frame and the 4
wxPanels. The wxPanels have the frame as parent, but MyApp takes the
timer event and should call Refresh() from there.
1. Even when there is no new data to draw, I'm using a wxPaintDC and
exiting.
2. Calling event.skip() when there is no new data causes the next
OnPaint call to draw properly, but only after I try resizing. It
continues to call itself and draw the same data without ever going to
OnTimer to get new data. I'm not sure how OnTimer is even called the
first time since it stays in OnPaint. Without event.Skip (and just
returning), it draws nothing, ever, and uses up all the CPU.
3. The OnTimer function isn't being called because the thing never
gets out of OnPaint.
4. Even creating a dummy wxPaintDC doesn't seem to work.
5. I'm not sure if/when to do event.Skip when there is no new data and
I just want to keep the old drawing.
---->6. Does the fact that I'm using nested scope with a new wxPaintDC
in each of them make a difference?
7. There was a previous incarnation of this where it was being called
once per second, but immediately erasing itself after drawing. This
occured when I used a wxClientDC I think.
thanks for any input
ms
// Define a new application type, each program should derive a class
from wxApp
class MyApp : public wxApp
{
private:
CTransport *transport;
std::vector<std::string> m_portlist;
MyFrame *m_tframe;
public:
wxTimer *m_timer;
wxTextCtrl *m_textCtrl;
wxPanel *m_graphWin1;
wxPanel *m_graphWin2;
wxPanel *m_graphWin3;
std::vector<_sMouseData *> m_mouseDataList;
bool m_newData;
virtual bool OnInit();
void OnTimer(wxTimerEvent &event);
~MyApp();
DECLARE_EVENT_TABLE()
};
// Define a new frame type: this is going to be our main frame
class MyFrame : public wxFrame
{
public:
// ctor(s)
MyFrame(wxWindow *parent, wxWindowID id, const wxString& title,
const wxPoint &pos=wxDefaultPosition, const wxSize
&size=wxDefaultSize,
long style=wxDEFAULT_FRAME_STYLE, const wxString &name="frame");
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnPaint(wxPaintEvent& event);
private:
// any class wishing to process wxWidgets events must use this macro
DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
EVT_MENU(Minimal_About, MyFrame::OnAbout)
EVT_TIMER(TIMER_ID, MyApp::OnTimer)
EVT_PAINT(MyFrame::OnPaint)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(MyApp, wxApp)
EVT_TIMER(TIMER_ID, MyApp::OnTimer)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
// 'Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
// Create frames, wxPanels, wxSizer, and get USB stuff setup
blablabla
// Start up periodic timer to read results from USB
m_timer = new wxTimer();
m_timer->SetOwner(this, TIMER_ID);
m_timer->Start(TIMER_DELAY, wxTIMER_ONE_SHOT); // call main handler
every 1000ms
m_newData = false;
return true;
}
void MyApp::OnTimer(wxTimerEvent& WXUNUSED(event))
{
// Get USB data and redraw with new information
blablabla
//m_tframe->Refresh(); <-- commented out for now
}
//
----------------------------------------------------------------------------
// main frame
//
----------------------------------------------------------------------------
// frame constructor
MyFrame::MyFrame(wxWindow *parent, wxWindowID id, const wxString&
title,
const wxPoint &pos, const wxSize &size,
long style, const wxString &name)
: wxFrame(parent, id, title, pos, size, style, name)
{
// Standard stuff
}
void MyFrame::OnPaint(wxPaintEvent& event)
{
//if(wxGetApp().m_newData == false)
//{
//event.Skip();
// return;
//}
if(wxGetApp().m_mouseDataList.size() == 0)
{
// event.Skip();
wxPaintDC dc;
return;
}
wxTextCtrl *textCtrl = wxGetApp().m_textCtrl;
wxPanel *graphWin1 = wxGetApp().m_graphWin1;
wxPanel *graphWin2 = wxGetApp().m_graphWin2;
wxPanel *graphWin3 = wxGetApp().m_graphWin3;
std::vector<_sMouseData *> mouseDataList = wxGetApp().m_mouseDataList;
// Define subset of colors to use. wxBrush and wxPen objects
// can use these strings directly.
wxString colors[] = {"red","green","blue",
"cyan","magenta","yellow",
"black","aquamarine","blue violet",
"goldenrod"};
// define total number of colors subset
int soc = sizeof(colors)/sizeof(wxString *);
{
// Stuff sent to textCtrl belonging to frame
// Display last data's text in text control
}
{
// Draw vector (as in direction+speed) on panel
// Clear window, get DC (device context) and window pixel range
wxCoord w,h;
wxPaintDC client_dc(graphWin1);
client_dc.GetSize(&w, &h);
// Stuff to draw to memorydc then blit to panel dc
blablabla
}
{
// Draw bar graphs for each sensor
graphWin2->ClearBackground();
wxPaintDC dc(graphWin2);
wxCoord w,h;
dc.GetSize(&w, &h);
// standard drawing stuff
blabla
}
{
// Draw line graphs for each sensor
graphWin3->ClearBackground();
wxPaintDC dc(graphWin3);
wxCoord w,h;
dc.GetSize(&w, &h);
// standard drawing stuff
blabla
}
wxGetApp().m_newData = false;
wxGetApp().m_timer->Start(TIMER_DELAY, wxTIMER_ONE_SHOT); // call main
handler every 1000ms
}
More information about the wx-users
mailing list