[wxMSW] How to force a wxStaticBitmap drawing update. 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.
Post Reply
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

[wxMSW] How to force a wxStaticBitmap drawing update.

Post by tomay3000 »

Hello,

Have a look at this minimal patch
minimal1.patch
(5.76 KiB) Downloaded 93 times
.

I need to force the wxStaticBitmap to update just after I select an Image from the wxFilePickerCtrl.
It is happening only when I drag the splitter window sash manually.

TIA.
User avatar
doublemax
Moderator
Moderator
Posts: 19116
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: [wxMSW] How to force a wxStaticBitmap drawing update.

Post by doublemax »

Use Refresh() instead of update. As it's possible that the size of the bitmap is different to the previous one, you should also call Layout() to force a sizer layout.
Use the source, Luke!
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

Re: [wxMSW] How to force a wxStaticBitmap drawing update.

Post by tomay3000 »

Nothing helped.
Neither Refresh(), Update(), Layout() nor all of them.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: [wxMSW] How to force a wxStaticBitmap drawing update.

Post by PB »

FWIW, the following code shows that just wxGenericStaticBitmap::SetBitmap() correctly updates the bitmap on MSW with wxWidgets 3.1.6 (I am not aware of any relevant changes since 3.1.5):

Code: Select all

#include <wx/wx.h>
#include <wx/generic/statbmpg.h>

wxBitmap CreateBitmap(const wxColour& clr, bool isSmall = true)
{
    wxImage img(isSmall ? wxSize(16, 16) : wxSize(64, 64));

    img.SetRGB(wxRect(img.GetSize()), clr.Red(), clr.Green(), clr.Blue());
    return wxBitmap(img);
}

class MyDialog : public wxDialog
{
public:
    MyDialog() : wxDialog(nullptr, wxID_ANY, "Test")
    {
        const wxColour colors[] = {*wxRED, *wxGREEN, *wxBLUE};

        wxButton*   button    = nullptr;
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

        for ( const auto& c: colors )
        {
            button = new wxBitmapButton(this, wxID_ANY, CreateBitmap(c));
            mainSizer->Add(button, wxSizerFlags().Expand().Border());
            button = new wxBitmapButton(this, wxID_ANY, CreateBitmap(c, false));
            mainSizer->Add(button, wxSizerFlags().Expand().Border());
        }

        wxGenericStaticBitmap* bmp = new wxGenericStaticBitmap(this, wxID_ANY, CreateBitmap(*wxYELLOW, false));
        mainSizer->Add(bmp, wxSizerFlags().Expand().TripleBorder());

        SetSizerAndFit(mainSizer);

        Bind(wxEVT_BUTTON, [bmp](wxCommandEvent& evt)
        {
            wxBitmapButton* button = dynamic_cast<wxBitmapButton*>(evt.GetEventObject());

            if ( button )
                bmp->SetBitmap(button->GetBitmap());
        });
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit() override
    {
        MyDialog().ShowModal();
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);
So if you have an issue, it is either platform or version specific (can be tested with the code above), or there is something wrong in your code. The diff you posted has way too much noise. I would start cutting it to the minimum and see if it helps.

I assume you verified that MyFrame::OnFilePickerCtrl1FileChanged() is actually called and the image is properly loaded and also that it can be set to wxStaticBitmap some other way...
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

Re: [wxMSW] How to force a wxStaticBitmap drawing update.

Post by tomay3000 »

The problem was because of the child wxPanels.
This answered my question:
viewtopic.php?t=32912
Victory wrote: Mon Dec 05, 2011 1:03 pm Suppose a window has a wxPanel inside, which in turn contains some other wxPanels, and so on. It seems like calling Layout() for the outermost window does not call the Layout method for the panels embedded inside.

So, are we responsible for explicitly calling the Layout() method for each of the panels ourselves? Is there a helper function in wxWidgets to do this automatically? What is the order in which we are supposed to call the Layout() method, i.e., should the method first be called for the containing (i.e., parent) panel or the contained (i.e., child) panel?

Thanks.
I had to explicitly call Layout() for any child wxPanel.
Because Calling if from the main frame is not sufficient.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: [wxMSW] How to force a wxStaticBitmap drawing update.

Post by PB »

So to conclude: The issue was not related to wxStaticBitmap at all.

That is why people are supposed to provide the minimal possible example so other factors are easily excluded.
Post Reply