Change wxPaintDC to wxBufferedPaintDC Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

these were two windows wxScrolledWindow in wxFrame.
I have removed them and it does not work.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7477
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Change wxPaintDC to wxBufferedPaintDC

Post by ONEEYEMAN »

Hi,
Can you post the constructor of the frame and the EVT_PAINT handler from the new code?

Thank you.
User avatar
doublemax
Moderator
Moderator
Posts: 19159
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Change wxPaintDC to wxBufferedPaintDC

Post by doublemax »

palikem wrote:these were two windows wxScrolledWindow in wxFrame.
I have removed them and it does not work.
I think PB almost confirmed with his test, that this is most likely a bug. Please open a ticket at http://trac.wxwidgets.org
Use the source, Luke!
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

I need to resolve it as soon as possible.
I have to find another solution.
Everything that I draw, I have to recalculate.

My English is not so good, to report bugs in trac.wxwidgets.org
User avatar
doublemax
Moderator
Moderator
Posts: 19159
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Change wxPaintDC to wxBufferedPaintDC

Post by doublemax »

Try this as a workaround:

Old code:

Code: Select all

wxPaintDC dc(this);

// start drawing code
dc.Clear();

dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1 );
dc.SetAxisOrientation(true, true);

dc.DrawLine(0, 0, 100, 100);
dc.DrawText("Test Frame", 100, 100);
// end drawing code
New code:

Code: Select all

wxPaintDC pdc(this);

wxBitmap buffer( GetClientSize().x, GetClientSize().y, 24 );
wxMemoryDC dc(buffer);
dc.CopyAttributes( pdc );

// start drawing code (doesn't need to be changed. same as before)
dc.Clear();

dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1);
dc.SetAxisOrientation(true, true);

dc.DrawLine(0, 0, 100, 100);
dc.DrawText("Test Frame", 100, 100);
// end drawing code

dc.SelectObject( wxNullBitmap );
pdc.DrawBitmap( buffer, 0, 0 );
Use the source, Luke!
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

Thanks it works.

Will not blink with Refresh () ?
User avatar
doublemax
Moderator
Moderator
Posts: 19159
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Change wxPaintDC to wxBufferedPaintDC

Post by doublemax »

palikem wrote:Will not blink with Refresh () ?
It shouldn't.

If it flickers it's because the background of the window is still cleared by the OS. You can suppress that by having an empty wxEVT_ERASE_BACKGROUND event handler. Or by calling SetBackgroundStyle( wxBG_STYLE_PAINT ) after constructing the window.
Use the source, Luke!
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

Thanks to doublemax.

Using SetBackgroundStyle (wxBG_STYLE_PAINT) not blinking.
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

doublemax wrote:Try this as a workaround:

Old code:

Code: Select all

wxPaintDC dc(this);

// start drawing code
dc.Clear();

dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1 );
dc.SetAxisOrientation(true, true);

dc.DrawLine(0, 0, 100, 100);
dc.DrawText("Test Frame", 100, 100);
// end drawing code
New code:

Code: Select all

wxPaintDC pdc(this);

wxBitmap buffer( GetClientSize().x, GetClientSize().y, 24 );
wxMemoryDC dc(buffer);
dc.CopyAttributes( pdc );

// start drawing code (doesn't need to be changed. same as before)
dc.Clear();

dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1);
dc.SetAxisOrientation(true, true);

dc.DrawLine(0, 0, 100, 100);
dc.DrawText("Test Frame", 100, 100);
// end drawing code

dc.SelectObject( wxNullBitmap );
pdc.DrawBitmap( buffer, 0, 0 );
There is a problem.
So twice a day that kind of problem pops up.
And the new code destroys my bookmarks.
frame.jpg
I found the line.
frame1.jpg
Drawing bookmarks through old code.
Soft.jpg
Bookmarks draw through drawLine and drawarc.
User avatar
doublemax
Moderator
Moderator
Posts: 19159
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Change wxPaintDC to wxBufferedPaintDC

Post by doublemax »

Regarding the assert message: There is definitely no leak in the code i posted, but it's still better to use a static bitmap for the buffer, instead of creating a new one each time.

You need to add a member variable "wxBitmap m_buffer;" to the class this method belongs to.

Code: Select all

wxPaintDC pdc(this);

if( !m_buffer.IsOk() || m_buffer.GetWidth() != GetClientSize().x || m_buffer.GetHeight() != GetClientSize().y )
{
  // you can also try depth=32 and check if it makes any difference
  m_buffer = wxBitmap( GetClientSize().x, GetClientSize().y, 24 );
}

wxMemoryDC dc(buffer);
Regarding the broken arcs, i'd need some code to reproduce the issue. But it looks like a bug.
Use the source, Luke!
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

Using wxPaintDC.

Code: Select all

void testbuffFrm::testbuffFrmPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
    
    /*if( !m_buffer.IsOk() || m_buffer.GetWidth() != GetClientSize().x || m_buffer.GetHeight() != GetClientSize().y )
    {
        // you can also try depth=32 and check if it makes any difference
        m_buffer = wxBitmap( GetClientSize().x, GetClientSize().y, 24 );
    }

    wxMemoryDC dc(m_buffer);
    dc.CopyAttributes( pdc );*/
    
    dc.SetBackground(*wxWHITE_BRUSH);
    dc.Clear();
    
    //dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1);
    //dc.SetAxisOrientation(true, true);
    
    dc.DrawLine(0, 61, 5, 61);
    dc.DrawLine(5, 61, 5, 41);
    dc.DrawArc(11, 37, 5, 43, 12, 44);
    dc.DrawLine(11, 37, 50, 37);
    
    //dc.SelectObject( wxNullBitmap );
    //pdc.DrawBitmap( m_buffer, 0, 0 );
	
}
frame.jpg
Using wxMemoryDC.

Code: Select all

void testbuffFrm::testbuffFrmPaint(wxPaintEvent& event)
{
    wxPaintDC pdc(this);
    
    if( !m_buffer.IsOk() || m_buffer.GetWidth() != GetClientSize().x || m_buffer.GetHeight() != GetClientSize().y )
    {
        // you can also try depth=32 and check if it makes any difference
        m_buffer = wxBitmap( GetClientSize().x, GetClientSize().y, 24 );
    }

    wxMemoryDC dc(m_buffer);
    dc.CopyAttributes( pdc );
    
    dc.SetBackground(*wxWHITE_BRUSH);
    dc.Clear();
    
    //dc.SetDeviceOrigin(0, dc.GetSize().GetHeight()-1);
    //dc.SetAxisOrientation(true, true);
    
    dc.DrawLine(0, 61, 5, 61);
    dc.DrawLine(5, 61, 5, 41);
    dc.DrawArc(11, 37, 5, 43, 12, 44);
    dc.DrawLine(11, 37, 50, 37);
    
    dc.SelectObject( wxNullBitmap );
    pdc.DrawBitmap( m_buffer, 0, 0 );
	
}
frame1.jpg
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

doublemax wrote:Regarding the assert message: There is definitely no leak in the code i posted, but it's still better to use a static bitmap for the buffer, instead of creating a new one each time.

You need to add a member variable "wxBitmap m_buffer;" to the class this method belongs to.

Code: Select all

wxPaintDC pdc(this);

if( !m_buffer.IsOk() || m_buffer.GetWidth() != GetClientSize().x || m_buffer.GetHeight() != GetClientSize().y )
{
  // you can also try depth=32 and check if it makes any difference
  m_buffer = wxBitmap( GetClientSize().x, GetClientSize().y, 24 );
}

wxMemoryDC dc(buffer);
Regarding the broken arcs, i'd need some code to reproduce the issue. But it looks like a bug.
It did not help.
But I know when the program will do it.
When I give him to minimize and I'll open a directory on the desktop.
It is interesting, when I open the any file on the desktop, then it will not do it.
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

I added :

Code: Select all

void AdcFrm::AdcFrmPaint(wxPaintEvent& event)
{
   if(wxGetActiveWindow() == this){
        ;
   }else{
        return;
   }
   .......
It helped.
I just do not know if it's right :?:
User avatar
doublemax
Moderator
Moderator
Posts: 19159
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Change wxPaintDC to wxBufferedPaintDC

Post by doublemax »

That doesn't look right.

Regarding the initial problem with the incorrect drawing of the arc, add one line before it, then it should look ok.

Code: Select all

    dc.SetBrush( *wxTRANSPARENT_BRUSH );		/// new line
    dc.DrawLine(0, 61, 5, 61);
    dc.DrawLine(5, 61, 5, 41);
    dc.DrawArc(11, 37, 5, 43, 12, 44);
    dc.DrawLine(11, 37, 50, 37);
Use the source, Luke!
palikem
Experienced Solver
Experienced Solver
Posts: 69
Joined: Sat Oct 28, 2017 9:33 am
Location: Slovensko

Re: Change wxPaintDC to wxBufferedPaintDC

Post by palikem »

Thank you doublemax.
I have already solved the problem with the arc.

Now I need to solve this problem:
frame.jpg
It will do so only when I minimize the program and open some directory on the desktop.
I can send a video, but where to insert the video?
Post Reply