?
Solved

Initialising a Listbox on a dialog

Posted on 1999-12-07
18
Medium Priority
?
540 Views
Last Modified: 2008-02-26
I have a ListBox on a dialog which has a CListbox member variable m_listbox.

The following code causes a debug assertion in CListBox::ResetContent.

CMyDialog dlg;
dlg.m_listbox.ResetContent();
dlg.m_listbox.AddString("test");
dlg.DoModal();
etc

I am modifying a project that was created by somebody else, so I created a small test app which does the above purely for debugging purposes and in my test project there is no assertion and the string appears in the listbox.

Are there any project properties which might cause this sort of behaviour?
0
Comment
Question by:mark_s
  • 10
  • 6
  • 2
18 Comments
 
LVL 32

Accepted Solution

by:
jhance earned 400 total points
ID: 2262438
This is not how this is done.  The listbox is NOT a member of the CMyDialog class and so you can't call it's member functions like this.

It has an ID, let's say IDC_LIST.  In your CMyDialog's OnInitDialog() member function, do this:

CListBox *pList = (CListBox*)GetDlgItem(IDC_LIST);
pList->ResetContent();
pList->AddString("test);

Your original InitInstance() function should just be:

CMyDialog dlg;
dlg.DoModal();

The OnInitDialog() get called by DoModal before the dialog is displayed.
0
 

Author Comment

by:mark_s
ID: 2264684
jhance,

thanks for your answer, but I don't see the point of using the class wizard to assign a CListBox member to the control ID of the listbox if you can't access it? Aren't they used by the data exchange mechanisms?

So in OnInitDialog, couldn't I access m_listbox directly?

Mark
0
 
LVL 32

Expert Comment

by:jhance
ID: 2264772
How have you created the dialog?  In the dialog editor?  If so, use the control ID.

Let me ask you this:  How does your CMyDialog get a member variable m_listbox?  Have you declared it in the class declaration for CMyDialog?  If so, then you do have a m_listbox class instantiated in your CMyDialog but how then do you get it to appear in the dialog window?

If you are doing something strange here, please post some of your code.  In general, however, you just create the CListBox item in your dialog eith the dialog editor and then operate on it like I've shown after getting it's handle using GetDlgItem.
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
LVL 32

Expert Comment

by:jhance
ID: 2264851
I've been rereading your question trying to understand what you are doing.

I gather that you have something like this:

class CMyDialog : public CDialog{
....
  CListBox m_ListBox;
....
};

If so, this does create an instance of a CListBox class in your dialog class but it does not create a CListBox window in your dialog window.  Don't miss the distinction between "class" and "window", they are NOT the same thing.  Now it is possible to cause such a box to be displayed, but you must call it's Create member function first at some point in your program AFTER the dialog window has been created.

I think you are calling ResetContent BEFORE there is a CListBox window existing to handle the message that is sent to it for the reset.
0
 

Author Comment

by:mark_s
ID: 2265161
jhance,

more info for you...

I created the dialog in the dialog editor, and dropped a listbox onto it (IDC_MYLISTBOX).

I then used class wizard, member variables tab, Add Variable button to attach a member variable  m_listbox ( category Control, variable type CListBox) to IDC_MYLISTBOX.

Classwizard adds the following to my class definition

// Dialog Data
//{{AFX_DATA(CMyDialog)
enum { IDD = IDD_MYDIALOG };
CListBox      m_listbox;
//}}AFX_DATA

and the following to my .cpp

void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMyDialog)
DDX_Control(pDX, IDC_MYLISTBOX, m_listbox);
//}}AFX_DATA_MAP
}

so I don't understand why in CMyDialog's OnInitDialog() I should use

CListBox *pList = (CListBox*)GetDlgItem(IDC_LIST);
                                    pList->ResetContent();

when I could just use

m_listbox.ResetContent();

 
I have successfully used m_listbox in a small test app, but am having difficulty modifying somebody else's project (see initial question)

thanks,
Mark
0
 
LVL 32

Expert Comment

by:jhance
ID: 2265305
You cannot do m_listbox.ResetContent() in your OnInitDialog because m_listbox does NOT refer to the listbox control that you've added to the dialog in the dialog editor.  Please go back and re-read my earlier comments on windows vs. classes.  If you want to call ResetContent on the one that is in the dialog, then you use GetDlgItem to get a pointer to it and then you can call ResetContent on it:

CListBox *pList = (CListBox*)GetDlgItem(IDC_LIST);
                                    pList->ResetContent();

Again, there is NO inherent or implied relationship between a CListBox class that you add to your CMyDialog class and a listbox control you add to your dialog in the dialog editor.  Remember classes are not windows and windows are not classes.  A CListBox class just provides a convenient way to send window messages to a list box control but you must get the CListBox class pointer to point to a valid listbox control window before you can do anything with it.

0
 

Author Comment

by:mark_s
ID: 2265773
jhance,

>You cannot do m_listbox.ResetContent() in your OnInitDialog

but I'm doing it and it works.
0
 
LVL 32

Expert Comment

by:jhance
ID: 2265848
You said:

The following code causes a debug assertion in CListBox::ResetContent.

That tell me it's not working!  

Is there more to this tale than you're telling?
0
 
LVL 32

Expert Comment

by:jhance
ID: 2265893
Another note.  If you were to examine the cause of the assertion you are seeing, you will discover that it is due to sending a LB_RESETCONTENT message to a non-existent window.  MFC traps such calls for you when you have linked with the debug library.  If you run this code with the release libs, you will get a fatal exception.
0
 

Author Comment

by:mark_s
ID: 2266048
jhance,

This is my problem exactly. For the project that I'm modifying I get the assertion.

I knocked up a small test app for debugging purposes and m_listbox.ResetContent() (and AddString()) work OK - no assertion, and the string I've added is in the Listbox on my dialog when it appears.

My original question was what might be the difference in the project properties.
0
 
LVL 32

Expert Comment

by:jhance
ID: 2266366
I don't know.  Without seeing the code in your test app, I can't say for sure why it works.
0
 
LVL 32

Expert Comment

by:jhance
ID: 2266470
How about you send me the code for your test project that does work and I'll see if I can figure out what you did right.

My email is jwh20@hotmail.com
0
 

Author Comment

by:mark_s
ID: 2266525
OK, I'll send you the project when I get into work tomorrow. thanks.
0
 
LVL 3

Expert Comment

by:GlennDean
ID: 2267119
jhance is 100% correct.  BUT here is some info that may be related to your question.  First note that CListBox inherits CCmdTarget, so that's your clue m_listbox is associated with a window (and a window that accepts messages).
  The reason you're getting the debug assertion when you call ResetContent appears to be because you have not attached a window to m_listbox.  To do this you must call
  m_listbox.Create(dwStyle,rect,"parent window",id).  
   Follow this by a call to InitStorage to allocate space for the entries in your listbox.
   But, as jhance said, actually doing the above will do nothing to relate your m_listbox to the list box window on the dialog.
   If I read the series of comments correctly, it sounded like you got a string to appear on the screen - that can't be right?
       Glenn
0
 
LVL 3

Expert Comment

by:GlennDean
ID: 2267130
Forgot to put this in the above comment. I tried the above code, i.e. adding a call to Create and InitStorage, and then called ResetContent and AddString and it worked.  BUT, as soon as I went dlg.DoModal() an exception was thrown.
0
 
LVL 32

Expert Comment

by:jhance
ID: 2268146
Mark,

In the project you sent, here is why it works:

void CMyDialog::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CMyDialog)
      DDX_Control(pDX, IDC_LIST1, m_listbox);
      //}}AFX_DATA_MAP
}

The DDX_Control creates the releationship between the IDC_LIST1 dialog control and the m_listbox CListBox class in your dialog implicitly.  You probably did this in the ClassWizard.

The next effect between:

DDX_Control(pDX, IDC_LIST1, m_listbox);

and

CListBox *pList = (CListBox *)GetDlgItem(IDC_LIST1);

is virtually identical.  In either case, you now have the class (or pointer to the class) associated with the IDC_LIST1 control in your dialog.

Regards,

Joe
0
 

Author Comment

by:mark_s
ID: 2268427
Joe,

Thanks for your help.

Mark
0
 
LVL 32

Expert Comment

by:jhance
ID: 2268542
Thanks.

So what was the bottom line on the project that _didn't_ work?
0

Featured Post

[Webinar] Kill tickets & tabs using PowerShell

Are you tired of cycling through the same browser tabs everyday to close the same repetitive tickets? In this webinar JumpCloud will show how you can leverage RESTful APIs to build your own PowerShell modules to kill tickets & tabs using the PowerShell command Invoke-RestMethod.

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

600 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