Solved

CCheckListBox error

Posted on 1998-08-19
10
821 Views
Last Modified: 2013-11-20
(Win95,VC 4.0)
I have a little problem in my actual project:
I have a very simple dialog which uses a dynamically created
CListBox(because of reusing the code), and everything works
fine. Now i tried to change that to a CCheckListBox, because
its features would make everything a bit more pretty.
Take a look at this code snippet:
// selectdialog.h
CSelectDialog : public CDialog()
{
 ...
 CCheckListBox m_cSelListBox;
 ...
}
// selectdialog.cpp
CSelectDialog::OnInitDialog()
{
  ...
  cListBox.Create(LBS_STANDARD|WS_CHILD|WS_VISIBLE|
                  WS_VSCROLL,cRect,this,IDC_CELLLIST);
  ...
}
when cListBox' type is CListBox, everything works fine,
but if it is a CCheckListBox i get a gpf, occuring
in CCheckListBox::PreMeasureItem(), and an internal mfc
structure (AFX_CHECK_DATA) contains an invalid pointer.
Does anyone have had an error like this yet?
I am short at time, i hope i'll get soon some hints :o)
Thank you in advance
0
Comment
Question by:snoegler
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
10 Comments
 
LVL 8

Expert Comment

by:Answers2000
ID: 1321005
CheckList boxes have to be Ownerdraw (LBS_OWNERDRAWFIXED) include that in your window style when you create it.

Additionally the doc's say you must derive a class (I'm not sure this is correct as I seem to vaguely remember using it without deriving).  This is a quote :

(begin quote)

CCheckListBox is only for owner-drawn controls because the list contains more than text strings. At its simplest, a checklist box contains text strings and check boxes, but you do not need to have text at all. For example, you could have a list of small bitmaps with a check box next to each item.

To create your own checklist box, you must derive your own class from CCheckListBox. To derive your own class, write a constructor for the derived class, then call Create.

If your checklist box is a default checklist box (a list of strings with the default-sized checkboxes to the left of each), you can use the default CCheckListBox::DrawItem to draw the checklist box. Otherwise, you must override the CListBox::CompareItem function and the CCheckListBox::DrawItem and CCheckListBox::MeasureItem functions.

(end quote)

0
 
LVL 6

Author Comment

by:snoegler
ID: 1321006
Sorry this was a failure of mine - i forgot to include the LBS_OWNERDRAWFIXED in the
code i posted ( i had it included in the real code )
 I have localized the error, it is in the lines

void CCheckListBox::PreMeasureItem(...)
{
  ...
  if (measureItem.itemData != 0)
  {
    AFX_CHECK_DATA* pState = (AFX_CHECK_DATA*)measureItem.itemData;
    measureItem.itemData = pState->m_dwUserData; // <-- **error**
  }
 ...
}

Before these lines they give the following comment:
// WINBUG: Windows95 and Windows NT disagree on what this value
// should be.  According to the docs, they are both wrong
(they refer obviously to this itemData member)
I think this is an internal error of Win95 or MFC, because if i set this value (one-time) manually
to zero, it works greatly.
I would give some more points, but i do not have enough at this time.
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1321007
Yeh I had a look in the sources, good bit hey?

I think setting LBS_HASSTRINGS style would also fix the problem but haven't tried it
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Author Comment

by:snoegler
ID: 1321008
Nope, tried that also. Didn't help.
BTW: Thanks for your efforts, if nothing more interesting comes up, i'll give you the points
0
 
LVL 1

Accepted Solution

by:
guruprasad031298 earned 60 total points
ID: 1321009
If you read the documentation of CCheckListBox, it clearly states that it is an owner-drawn button, meaning the programmer is responsible for drawing and positioning the control.

MFC documentation says :-

"If your checklist box is a default checklist box (a list of strings with the default-sized checkboxes to the left of each), you can use the default CCheckListBox::DrawItem to draw the checklist box. Otherwise, you must override the CListBox::CompareItem function and the CCheckListBox::DrawItem and CCheckListBox::MeasureItem functions. "

Did you make sure you have over-ridden the DrawItem, CompareItem and MeasureItem methods. If not please do so. If you have done that, can you please post the code. I feel there is something wrong in the DrawItem and/or MeasureItem as the error occurs during PreMeasureItem.

Instead an easier way to do this is to derive your own CheckListBox from the CCheckListBox (using the classwizard) and using the default constructor and use the draw scale provided with it.

Please post as much code as necessary to warrant a proper solution.
0
 
LVL 6

Author Comment

by:snoegler
ID: 1321010
>>"If your checklist box is a default checklist box (a list of strings with the default-sized
checkboxes to the left of each), you can use the default CCheckListBox::DrawItem to drawthe
checklist box. Otherwise, you must override the CListBox::CompareItem function and the
CCheckListBox::DrawItem and CCheckListBox::MeasureItem functions. "

My checklist box should be a 'default' checklist box, so i don't need to override any functions
according to your answer - and that's what i am doing.
It is really easy to test: Create a default 'single document' app using AppWizard,
and insert a CCheckListBox to the CView:
// C<app>View.h
class C<app>View : public CView()
{
.
   CCheckListBox m_cCheckListBox;
.
}

//C<app>View.cpp:

.
int CNEditView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CView::OnCreate(lpCreateStruct) == -1)
    return -1;

  // TODO: Add your specialized creation code here
  m_cCheckListBox.Create(LBS_OWNERDRAWFIXED|LBS_STANDARD|WS_CHILD|WS_VISIBLE|WS_VSCROLL,CRect(100,100,200,200),this,IDC_CHECKLISTBOX);
m_cCheckListBox.SetCheckStyle(BS_AUTOCHECKBOX);
m_cCheckListBox.AddString("test");

}

That's all - and it doesn't work. As i said, when tracing, i've set the value measureItem.itemData
to zero and jump over the statement causing the gpf (because the pointer is invalid).
After that it works without any further errors...
0
 
LVL 1

Expert Comment

by:guruprasad031298
ID: 1321011
I found the solution. Please look at the documentation of the CCheckListBox. It says that you have to over-ride the DrawItem and MeasureItem methods and these are called by the CCheckListBox to find out the size and position of your owner-drawn CheckListBox control. Try doing this.

1. Derive your own CheckListBox from CCheckListBox
2. Add the constructor and the Create methods
3. Add two more member functions viz DrawItem and MeasureItem
4. Implement these methods - constuctor is dummy. create calls CheckListBox create and DrawItem and MeasureItem does nothing.
5. Now derive the CheckListBox in your view class from this CMyCheckListBox instead of the CCheckListBox.
6. Do whatever you want to do with that
7. Compile & Run

You should see this check list box embedded in your view without any assertion.

If you don't do these over-riding (of DrawItem & MeasureItem), you will get an assertion. Hit 'Retry' on the dialog. It should take you to something like

// You must override DrawItem and MeasureItem for LBS_OWNERDRAWVARIABLE
ASSERT((GetStyle() & (LBS_OWNERDRAWFIXED | LBS_HASSTRINGS)) ==
      (LBS_OWNERDRAWFIXED | LBS_HASSTRINGS));

This clearly states that you need to over-ride these methods to get it working.

I have a sample and it works (but with some memory leaks). It doesn't do anything, though. If you are still not getting it right, I can send it across to you.

Hope this helps .....
0
 
LVL 1

Expert Comment

by:guruprasad031298
ID: 1321012
I have a fully working sample without the memory leaks now and it adds some text entries to the CheckListBox. Sample is available for you to use ....
0
 
LVL 6

Author Comment

by:snoegler
ID: 1321013
guruprasad, thanks for all.
But another thing: I've been working with MFC for a not short time - and i've traced myself
into that code. I know the code you mean, and that is *not* the problem. I am getting
a *gpf*, not an assertion - retry will cause the prog to crash, and if i manually set the value ( as i
stated above ) it continues working without problem.
I have found that a CListCtrl does solve the UI requirements in my case better. But anyway,
i'll leave this message for 2-3 days open, and after that i think i'll split the points between you
and answers2000. Thanks, guys.
0
 
LVL 6

Author Comment

by:snoegler
ID: 1321014
I'll ask now if they can delete the question, i'll post for each of you a dummy question here.
0

Featured Post

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question