I am working on a Windows application using MFC and Visual Studio C 17.
I have multiple tabs in the application, one of which is currently implemented using CListBox
and needs to be reimplemented using CCheckListBox
.
CCheckListBox
is a child class of CListBox
.
I have a vector of unique CString
's I want to display in the box.
To start simple, I tried making the tab with CListBox
and by using CListBox::AddString()
, this worked exactly as I wanted it to. It sorted the strings alphabetically, and automatically added a scroll bar on the side when the vector had too many CString
's to display all at once in the list.
However, when swapping the CListBox
variable to a CCheckListBox
variable, I have come across the error when I press run along the lines of:
Debug Assertion Failed! ..... \mfc\winctrl3.cpp Line: 588
I found this GitHub link that has the winctrl3.cpp
file and on line 588
, there is a function called OnLButtonDblClk
which is somewhat explained here.
The trouble is I am unsure of how to swap a variable from a parent class to a child class. Is it so different for Windows classes? In the courses and programs I have taken and written in the past, switching from a parent to child variable was straightforward but this is quite the opposite !
Any help is appreciated, thank you in advance ! :D
CodePudding user response:
There is no assertion in line 588 of the source file in your link. That github upload dates back to 2014. Why not search the winctrl3.cpp source file in your own Visual Studio installation instead? In my own installation, it is in function PreSubclassWindow()
and there is indeed an assertion there:
// CCheckListBoxes must be owner drawn
ASSERT(GetStyle() & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE));
That is the CCheckListBox
must be owner-drawn. Find the CCheckListBox
constructor code above, you will notice that it calls the CListBox
(parent-class) constructor, applying either of the two owner-drawn styles. Instead, the CListBox
constructor calls CWnd::Create()
with the "LISTBOX"
Windows Class-Name as a parameter. That is, it seems to be a MFC-implemented control, overriding the CListBox
class, with an owner-drawn style. There is no mention of a native "Check-ListBox" class or style in the Win32 documentation either. Also the CCheckListBox
documentation (in the link you posted) clearly states: CCheckListBox
is only for owner-drawn controls because the list contains more than text strings.
Therefore:
- If you are creating the control using a resource script, add an owner-drawn style (eg
LBS_OWNERDRAWFIXED
) to the control (or set the Owner-Drawn property in the property editor). - If you are creating the control programmatically make sure you are calling the
CCheckListBox
constructor, not theCListBox
one.
Not sure what you mean about the scroll-bar (and why you mention it), doesn't the list-box display a scroll-bar automatically (WS_VSCROLL
style - or property), do you have to do something on your own?
EDIT:
Forgot to mention, if you are creating the control using a resource script use the Class Wizard to add a member variable (of "Control" type, not "Value") to the dialog class. The new variable must be of type CCheckListBox
(MFC class). This will subclass the control. If the old project already had a CListBox
member variable change it to CCheckListBox
.