fejes
asked on
Changing CCheckListBox/CListBox text
I am trying to change the text in a CCheckListBox
depending on whether the box is checked or not. I
have it working partially, but, there seems to be
a 'Reflection" problem. To recreate the problem,
I made an MFC dialog app, inserted a listbox item,
gave it the following prperties:
Selection:Single
OwnerDraw:Fixed
HasStrings:TRUE
Sort:False
then in the dialog class I declared the control:
class CChecklistDlg : public CDialog
{
CCheckListBox m_ctlList;
//etc...
};
Then in the implementation file added the following:
BEGIN_MESSAGE_MAP(CCheckli stDlg, CDialog)
ON_LBN_SELCHANGE(IDC_LIST1 , OnSelchangeList1)
// etc.
END_MESSAGE_MAP()
void CChecklistDlg::DoDataExcha nge(CDataE xchange* pDX)
{
CDialog::DoDataExchange(pD X);
DDX_Control(pDX, IDC_LIST1, m_ctlList);
}
BOOL CChecklistDlg::OnInitDialo g()
{
CDialog::OnInitDialog();
// etc.
CString str;
int i;
m_ctlList.SetCheckStyle(BS _AUTOCHECK BOX);
m_ctlList.ResetContent();
for (i=0; i < 10; i++)
{
str.Format("Line Number %d", i);
m_ctlList.AddString(str);
}
UpdateData(FALSE);
return TRUE;
}
void CChecklistDlg::OnSelchange List1()
{
CString str;
int cursel;
UpdateData(TRUE);
cursel = m_ctlList.GetCurSel();
m_ctlList.GetText(cursel, str);
m_ctlList.DeleteString(cur sel);
str.MakeReverse();
m_ctlList.InsertString(cur sel, str);
m_ctlList.SetCheck(cursel, check);
m_ctlList.SetCurSel(cursel );
UpdateData(FALSE);
}
The above code works on Windows 95. Well, unless you doubleclick a selection quickly, then the box checks and unchecks, but the text changes only once. In WinCtrl3.cpp it says Click and DblClick should behave the same.
In Windows NT 3.51 and 4.0 checkboxes 5-9 work fine (except dbl clk problem above). 1-4 are intermittent for changing text, and item 0 causes the app to crash.
Any suggestions?
tom.
tom.fejes@sofkin.ca
depending on whether the box is checked or not. I
have it working partially, but, there seems to be
a 'Reflection" problem. To recreate the problem,
I made an MFC dialog app, inserted a listbox item,
gave it the following prperties:
Selection:Single
OwnerDraw:Fixed
HasStrings:TRUE
Sort:False
then in the dialog class I declared the control:
class CChecklistDlg : public CDialog
{
CCheckListBox m_ctlList;
//etc...
};
Then in the implementation file added the following:
BEGIN_MESSAGE_MAP(CCheckli
ON_LBN_SELCHANGE(IDC_LIST1
// etc.
END_MESSAGE_MAP()
void CChecklistDlg::DoDataExcha
{
CDialog::DoDataExchange(pD
DDX_Control(pDX, IDC_LIST1, m_ctlList);
}
BOOL CChecklistDlg::OnInitDialo
{
CDialog::OnInitDialog();
// etc.
CString str;
int i;
m_ctlList.SetCheckStyle(BS
m_ctlList.ResetContent();
for (i=0; i < 10; i++)
{
str.Format("Line Number %d", i);
m_ctlList.AddString(str);
}
UpdateData(FALSE);
return TRUE;
}
void CChecklistDlg::OnSelchange
{
CString str;
int cursel;
UpdateData(TRUE);
cursel = m_ctlList.GetCurSel();
m_ctlList.GetText(cursel, str);
m_ctlList.DeleteString(cur
str.MakeReverse();
m_ctlList.InsertString(cur
m_ctlList.SetCheck(cursel,
m_ctlList.SetCurSel(cursel
UpdateData(FALSE);
}
The above code works on Windows 95. Well, unless you doubleclick a selection quickly, then the box checks and unchecks, but the text changes only once. In WinCtrl3.cpp it says Click and DblClick should behave the same.
In Windows NT 3.51 and 4.0 checkboxes 5-9 work fine (except dbl clk problem above). 1-4 are intermittent for changing text, and item 0 causes the app to crash.
Any suggestions?
tom.
tom.fejes@sofkin.ca
Could you try single/double click messages instead of selection change? You probably has to subclass the window procedure.
ASKER
Thanks for your idea.
Listbox derived classes receive LB_ notification messages, not BN_ messagees. That wouldn't solve the problem because I'd still be sending messages to the listbox and it would assert in the same place.
My current solution is to ResetContent the listbox and redraw all the list items. Not very elegant, but good thing the list is small. I get an assertion error in CCheckListBox:: PreDrawItem() because drawItem is -1 (MFC checks its status against NULL). The assertion occurs just after the UpdateData(FALSE) in OnSelChange.
Listbox derived classes receive LB_ notification messages, not BN_ messagees. That wouldn't solve the problem because I'd still be sending messages to the listbox and it would assert in the same place.
My current solution is to ResetContent the listbox and redraw all the list items. Not very elegant, but good thing the list is small. I get an assertion error in CCheckListBox:: PreDrawItem() because drawItem is -1 (MFC checks its status against NULL). The assertion occurs just after the UpdateData(FALSE) in OnSelChange.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Mike.
I've decided to stick with my ResetContent solution. It's the most readable solution that isn't version dependant. I couldn't find any info in MSDN or the KB, only the old article you wrote last year on the MFC-L archives, basically saying "it's a bug".
BTW, I tried this on Win95 original with MSDEV 4.2, Win95 OSR 2 with MSDEV 5.0 (unpatched and patched), WinNT 3.51 original with MSDEV 4.2, WinNT 4.0 2 with MSDEV 5.0 (unpatched and patched). Again, it worked on Win95, but neither NT, always reverting to
that -1 return problem.
I've decided to stick with my ResetContent solution. It's the most readable solution that isn't version dependant. I couldn't find any info in MSDN or the KB, only the old article you wrote last year on the MFC-L archives, basically saying "it's a bug".
BTW, I tried this on Win95 original with MSDEV 4.2, Win95 OSR 2 with MSDEV 5.0 (unpatched and patched), WinNT 3.51 original with MSDEV 4.2, WinNT 4.0 2 with MSDEV 5.0 (unpatched and patched). Again, it worked on Win95, but neither NT, always reverting to
that -1 return problem.