This article is a companion article to my article
re-creating a combo box. Similarly to the combo box, I frequently find myself
needing to switch a list box to or from sorted, or to or from multi select. As
with the combo box, changing these styles after creation is something that a listbox
does not support. The function presented here will recreate the list box so that
style changes take effect. The function will retain all list items, with item
data, and the currently selected items.
When the style is modified on a listbox to include or remove the
LBS_SORT for example,
it can be seen (by using
GetStyle(), or using a tool such as Spy++) that the control
does in fact have the new style, and yet the control's behaviour has not changed.
The function here simply gets the current info from the control, i.e. styles, font etc,
and recreates the control using these values.
How to use
I originally had a
CListBox-derived class which one member function
to recreate the controls, but decided that this was more trouble than it was worth, as
I usually use controls derived from other bases. Therefore I have presented this as a single
function, which should be included in a global library file, so that you can invoke it
on any listbox at any time.
In order to change the style of a listbox, you should perform the usual method of
setting the new style e.g.
and then after than call your should call:
The function takes an optional void pointer,
lpParam, which is passed to
recreating the control. If you have special requirements when creating your controls,
and you normally pass in some data for the creation parameters, then you should pass the
same info in here. Most developers can simply ignore this parameter.
The function to recreate the listbox is below:
BOOL RecreateListBox(CListBox* pList, LPVOID lpParam)
if (pList == NULL)
if (pList->GetSafeHwnd() == NULL)
CWnd* pParent = pList->GetParent();
if (pParent == NULL)
DWORD dwStyle = pList->GetStyle();
DWORD dwStyleEx = pList->GetExStyle();
pParent->ScreenToClient(&rc); UINT nID = pList->GetDlgCtrlID();
CFont* pFont = pList->GetFont();
CWnd* pWndAfter = pList->GetNextWindow(GW_HWNDPREV);
if (! listNew.CreateEx(dwStyleEx, _T("LISTBOX"), _T(""), dwStyle,
rc, pParent, nID, lpParam))
int nNumItems = pList->GetCount();
BOOL bMultiSel = (dwStyle & LBS_MULTIPLESEL || dwStyle & LBS_EXTENDEDSEL);
for (int n = 0; n < nNumItems; n++)
int nNewIndex = listNew.AddString(sText);
if (bMultiSel && pList->GetSel(n))
if (! bMultiSel)
int nCurSel = pList->GetCurSel();
if (nCurSel != -1)
HWND hwnd = listNew.Detach();
pList->SetWindowPos(pWndAfter == NULL ? &CWnd::wndBottom
: pWndAfter, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- Version 1 - 26 Jul 2002 - First version
- Version 2 - 30 Jul 2002 - modified to include changes suggested by Jean-Michel LE FOL and Davide Zaccanti
Originally from an electronics background, I moved into software in 1996, partly as a result of being made redundant, and partly because I was very much enjoying the small amount of coding (in-at-the-deep-end-C) that I had been doing!
I swiftly moved from C to C++, and learned MFC, and then went on to real-time C on Unix. After this I moved to the company for which I currently work, which specialises in Configuration Management software, and currently program mainly in C/C++, for Windows. I have been gradually moving their legacy C code over to use C++ (with STL, MFC, ATL, and WTL). I have pulled in other technologies (Java, C#, VB, COM, SOAP) where appropriate, especially when integrating with third-party products.
For developing, I mainly use Visual Studio 2010, along with an in-house-designed editor based on Andrei Stcherbatchenko's syntax parsing classes
, and various (mostly freeware) tools. For website design, I use Dreaweaver CS3.
When not developing software, I enjoy listening to and playing music, playing electric and acoustic guitars and mandolin.