0

I am using a wxListCtrl in report style in a programming project on Windows 10, using Visual Studio 2017. I noticed that when the program first starts, there are some strange artifacts: the vertical lines between the columns don't move with the headers when I resize them with the mouse. Also, the scrollbar does not move when I drag it but the list jumps to the position when I release the mouse button. Once I resize the window however, everything is fine.

After reducing the program to a minimal example, I found out that turning off double buffering for the frame that contains the list control fixes everything. But I don't really understand why. Can anybody explain this to me?

#include <wx/wx.h>
#include <wx/listctrl.h>

class MainWindow : public wxFrame
{

public:
    MainWindow();
    void updateWidgets();


private:
    wxListCtrl *listCtrl;
        void initWidgets();

};

MainWindow::MainWindow()
{
    // ****************************************************************
    // Set window properties and init the widgets.
    // ****************************************************************

    wxFrame::Create(NULL, wxID_ANY, wxT("wxListCtrl Issue"), wxDefaultPosition,
        wxDefaultSize, wxCLOSE_BOX | wxMINIMIZE_BOX | wxMAXIMIZE_BOX |
        wxSYSTEM_MENU | wxCAPTION | wxRAISED_BORDER | wxRESIZE_BORDER);

    // Comment the following line to fix the list control, but why?
    this->SetDoubleBuffered(true);

    initWidgets();
}

void MainWindow::initWidgets()
{

    listCtrl = new wxListCtrl(this, wxID_ANY, wxDefaultPosition,
        wxDefaultSize, wxLC_REPORT);
    listCtrl->InsertColumn(0, wxT("Col 0"), wxLIST_FORMAT_LEFT, 50);
    for (int i = 0; i < 60; i++)
    {
        long index = listCtrl->InsertItem(0, wxT("Item"));
    }   

}

class wxListCtrl_Issue : public wxApp
{
public:
    virtual bool OnInit();
};

bool wxListCtrl_Issue::OnInit()
{
    MainWindow *mainWindow = new MainWindow();
    mainWindow->Show(true);
    return true;
}

wxIMPLEMENT_APP(wxListCtrl_Issue);

Simon
  • 405
  • 2
  • 8

1 Answers1

1

Generally speaking, you shouldn't interfere with the drawing of native controls and wxListCtrl is native under MSW. Moreover, it already is double-buffered using its own specific mechanism for this (LVS_EX_DOUBLEBUFFER) and so it's not surprising at all that setting WS_EX_COMPOSITED for it unexpectedly (from the controls point of view) breaks it.

I.e. the answer is simple: just don't call SetDoubleBuffered() for it, nor any other native control.

VZ.
  • 21,740
  • 3
  • 39
  • 42
  • Thanks so much for your input and I think this answers my question and confirms that simply turning double buffering off is the best solution. However, I don't fully understand when exactly it would be appropriate to turn double buffering on, then. Because if we're not supposed to mess with the drawing of a native control and wxWidgets generally uses native controls (right?), then in what scenario would you use this option? Or are there some controls that aren't available on all platforms and that are drawn by wxWidgets itself? Sorry if I'm being ignorant, but I'm fairly new to this – Simon Oct 12 '19 at 08:22
  • This is meant for your own windows. I.e. if you create some sort of a plot, for example, it would make sense to explicitly enable double buffering for it (for MSW, anyhow, double buffering is always enabled for GTK 3 and under macOS anyhow). – VZ. Oct 12 '19 at 14:18
  • Okay, now I get it. Thanks for the clarification! – Simon Oct 12 '19 at 14:54