Page 1 of 1

drawing wxBitmap: doesn't refresh before every time it draws

Posted: Mon Sep 08, 2014 4:29 pm
by greekfellows

Code: Select all

void bmImage::paintEvent(wxPaintEvent &event) {
	wxPaintDC dc(this);
	render(dc);
}

void bmImage::paintNow() {
	wxClientDC dc(this);
	render(dc);
}

void bmImage::render(wxDC& dc) {
	bitmap = wxBitmap(aswxImage);
	dc.Clear();
	dc.SetUserScale(((bmImageFrame*)this->GetParent())->scale[0], ((bmImageFrame*)this->GetParent())->scale[1]);
	dc.DrawBitmap(bitmap, wxPoint(0, 0), false);
}
bmImage derives from wxPanel. I want the image to be drawn on a clean, refreshed background every time.
But before I scale the loaded image, it looks like this: (the image is clipped because of resized window)
捕获0.PNG
And after I scale the image then resize the window, it looks like this:
捕获1.PNG
How should I fix this so that it redraws the scaled image over clean background? Obviously there is a problem with drawing and clearing canvas here.

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Mon Sep 08, 2014 4:34 pm
by PB
If there are issues with parts of window not being properly painted after its resize, it can be a good idea to create the window in question with wxFULL_REPAINT_ON_RESIZE flag.

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Tue Sep 09, 2014 4:00 am
by eranif
Some tips:
1. Make sure you also capture the. Erase background event. Inside it, clear the paint area by drAwing a rectangle with size of the panel
2. Use wxBufferedPaintDC in In OnPaint event handler and use it to draw
3. Capture the ON_SIZE event and simply call refresh

Eran

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Wed Sep 10, 2014 4:55 pm
by greekfellows
Thanks for answers so far @eranif @PB!

I intercepted the wxEVT_SIZE event and called event.Skip() there so it refreshes every time it draws now, that's fine,
but now I have a flickering white screen (I used white to repaint a full-size rectangle)...

Code: Select all

void bmImage::paintEvent(wxPaintEvent &event) {
	wxBufferedPaintDC dc(this);
	render(dc);
}

void bmImage::paintNow() {
	wxClientDC dc(this);
	render(dc);
}

void bmImage::render(wxDC& dc) {
	bitmap = wxBitmap(aswxImage);
	dc.SetBackground(*wxWHITE_BRUSH);
	dc.Clear();
	wxPoint orgp = dc.GetLogicalOrigin();
	dc.SetLogicalOrigin(((bmImageFrame*)this->GetParent())->scroll[0], ((bmImageFrame*)this->GetParent())->scroll[1]);
	dc.SetUserScale(((bmImageFrame*)this->GetParent())->scale[0], ((bmImageFrame*)this->GetParent())->scale[1]);
	dc.DrawBitmap(bitmap, wxPoint(0, 0), false);
	dc.SetLogicalOrigin(orgp.x, orgp.y);
	dc.SetUserScale(1.0f, 1.0f);
	dc.SetPen(*wxWHITE_PEN);
	dc.DrawText(wxString("w: " + std::to_string(GetSize().GetWidth()) + ", h: " + std::to_string(GetSize().GetHeight()) + "\nx: " + std::to_string(((bmImageFrame*)this->GetParent())->scroll[0]) + ", y: " + std::to_string(((bmImageFrame*)this->GetParent())->scroll[1])), 100, 100);
}

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Wed Sep 10, 2014 6:19 pm
by doublemax
Do you have a wxEraseEvent handler? If yes, it should be completely empty. Do not clear the background, do not call event.Skip().

If you're using wx 3.x, you don't need an wxEraseEvent handler at all, just call wxWindow::SetBackgroundStyle(wxBG_STYLE_PAINT) on the window.

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Wed Sep 10, 2014 7:18 pm
by eranif
1. Make sure you also capture the. Erase background event. Inside it, clear the paint area by drAwing a rectangle with size of the panel
Hmm, I gave a bad advise here...
You should capture the EVT_ERASE_BACKGROUND event, but do nothing in it - this will remove the flickering
Also, avoid using wxClientDC. If you need to force a paint now, simply call 'Refresh()' this will trigger a call to OnPaint/OnErase

So your function 'paintNow'' should look like this:

Code: Select all

void bmImage::paintNow() {
   Refresh(); // triggers a 'OnPaint' event
}
Eran

Re: drawing wxBitmap: doesn't refresh before every time it d

Posted: Thu Sep 11, 2014 10:56 am
by greekfellows
Thanks! @eranif @doublemax

Used Refresh() in paintNow() and called SetBackgroundStyle().
Now it doesn't flicker at all.