My app displays a modal dialog. The dialog has only a sizer and two controls. I've defined a handler method for paint events and added the EVT_PAINT entry to the events table, but my handler method is only invoked when the ShowModal() method is invoked or if I minimize and maximize my app. Other actions, such as moving another application window over the dialog window, even hiding it totally, never triggers a paint event (or my handler is not invoked). What should I do to receive paint events when the dialog window is exposed?
Working on Linux, with wxWidgest 2.8.12
Thank you,
Cecilio
How to receive paint events in wxDialog Topic is solved
Re: How to receive paint events in wxDialog
Do you have a wxPanel as background for the controls? Then you have to catch the paint event for that panel, not the dialog.
If that's not it, please show some code.
If that's not it, please show some code.
Use the source, Luke!
Re: How to receive paint events in wxDialog
Thanks doublemax. The dialog has a sizer and two controls on it: an static text and a gauge. This is the code:
I'm using an wxExtHelpController to display help in a browser. But as it takes some time since the user clicks on 'Help' button until the browser opens, I'm trying to create a pop-up window (this dialog) witha gauge to somehow inform the user that something is going on. My idea is to remove this dialog as soon as I detect that the browser has opened. For this, I tried to use the kill focus event (rationale: if the browser gets the focus, this dialog should lose it, but this doesn't work) and now I'm exploring the paint event: the browser will hide this dialog, therefore as soon as the user returns to the application the dialog will receive a paint event and I will detect this and close the dialog. Any ideas about why it is not receiving paint events? Any other ideas for closing the dialog?
Thank you,
Cecilio
Code: Select all
const long k_id_timer = wxNewId();
//---------------------------------------------------------------------------------------
class HelpDlg : public wxDialog
{
protected:
wxStaticText* m_pMsg;
wxGauge* m_pGauge;
wxTimer m_timer;
int m_numPaints;
public:
HelpDlg(wxWindow* pParent = NULL);
~HelpDlg();
void create_controls();
// event handlers
void on_focus_lost(wxFocusEvent& WXUNUSED(event));
void on_timer_event(wxTimerEvent& WXUNUSED(event));
void on_paint(wxPaintEvent& WXUNUSED(event));
protected:
DECLARE_EVENT_TABLE()
};
//=======================================================================================
// HelpDlg implementation
//=======================================================================================
BEGIN_EVENT_TABLE(HelpDlg, wxDialog)
EVT_TIMER (k_id_timer, HelpDlg::on_timer_event)
EVT_KILL_FOCUS (HelpDlg::on_focus_lost)
EVT_PAINT (HelpDlg::on_paint)
END_EVENT_TABLE()
//---------------------------------------------------------------------------------------
HelpDlg::HelpDlg(wxWindow* pParent)
: wxDialog(pParent, wxID_ANY, _("Help system"),
wxDefaultPosition, wxSize(400,150),
wxDEFAULT_DIALOG_STYLE)
, m_timer(this, k_id_timer)
, m_numPaints(0)
{
create_controls();
m_pGauge->SetRange(100);
m_pGauge->SetValue(0);
CentreOnScreen();
m_timer.Start(200, wxTIMER_CONTINUOUS); //200ms
}
//---------------------------------------------------------------------------------------
HelpDlg::~HelpDlg()
{
m_timer.Stop();
}
//---------------------------------------------------------------------------------------
void HelpDlg::create_controls()
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* pMainSizer;
pMainSizer = new wxBoxSizer( wxVERTICAL );
pMainSizer->Add( 0, 0, 1, wxEXPAND, 5 );
m_pMsg = new wxStaticText( this, wxID_ANY, _("Opening Internet browser. Please wait ..."), wxDefaultPosition, wxDefaultSize, 0 );
m_pMsg->Wrap( -1 );
pMainSizer->Add( m_pMsg, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
m_pGauge = new wxGauge( this, wxID_ANY, 100, wxDefaultPosition, wxDefaultSize, wxGA_HORIZONTAL );
pMainSizer->Add( m_pGauge, 0, wxALL|wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
pMainSizer->Add( 0, 0, 1, wxEXPAND, 5 );
this->SetSizer( pMainSizer );
this->Layout();
}
//---------------------------------------------------------------------------------------
void HelpDlg::on_timer_event(wxTimerEvent& WXUNUSED(event))
{
int value = m_pGauge->GetValue();
m_pGauge->SetValue( value == 100 ? 0 : value + 2 );
}
//---------------------------------------------------------------------------------------
void HelpDlg::on_focus_lost(wxFocusEvent& WXUNUSED(event))
{
EndModal(wxID_CANCEL);
}
//---------------------------------------------------------------------------------------
void HelpDlg::on_paint(wxPaintEvent& event)
{
wxPaintDC dc(this);
m_numPaints++;
event.Skip(true);
}
Thank you,
Cecilio
Re: How to receive paint events in wxDialog
I'm not sure why you don't receive any paint event in that case. If you receive a paint event when you resize the window, the code should be correct. Maybe the OS buffered the content, because it could not have changed.
But in any case the whole thing seems a bit "hackish" to me. Is it really necessary to display some kind of busy information? Even if it takes 1-2 seconds until the browser opens, the user will be surprised only when it happens at the first time (if ever).
If you really want to pursue this, try catching wxActivateEvent, it should be triggered when a toplevel window becomes active/inactive.
But in any case the whole thing seems a bit "hackish" to me. Is it really necessary to display some kind of busy information? Even if it takes 1-2 seconds until the browser opens, the user will be surprised only when it happens at the first time (if ever).
If you really want to pursue this, try catching wxActivateEvent, it should be triggered when a toplevel window becomes active/inactive.
Use the source, Luke!
Re: How to receive paint events in wxDialog
Yes, I receive paint events but only the first one or when the app is minimized and then maximized. The dialog is not resizable. I do not understand why it doesn't receive paint events after another window moves over the dialog. But, nevertheless, I will look for other solutions, as your suggesstion of catching wxActivateEvent. Thanks for this idea! Others are also welcomed
And, yes, the whole thing is a bit "hackish", but I think it is necessary as it is not 1-2 seconds but 6-8 secs. Of course depends on the machine, the workload, and if the browser is already running or not. In my machine with the browser closed, times go from 2 secs to 8 secs. If it were only 1-2 secs I will agree with you and do nothing, but as I have experienced longer delays I would prefer to ensure that the user gets any feedback.
Thank you,
Cecilio
And, yes, the whole thing is a bit "hackish", but I think it is necessary as it is not 1-2 seconds but 6-8 secs. Of course depends on the machine, the workload, and if the browser is already running or not. In my machine with the browser closed, times go from 2 secs to 8 secs. If it were only 1-2 secs I will agree with you and do nothing, but as I have experienced longer delays I would prefer to ensure that the user gets any feedback.
Thank you,
Cecilio