[RESOLVED] CDialog:ListBox in Doc/View
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: [RESOLVED] CDialog:ListBox in Doc/View

  1. #1
    Join Date
    Mar 2006
    Posts
    63

    [RESOLVED] CDialog:ListBox in Doc/View

    Instantiating a dialog in a Doc function, I can update an Edit box in the dialog, but when I try to use AddString on a Listbox (using "simple text"), I get an Assertion Failure.
    Using VC++6; to illustrate the problem in the simplest app, I created an SDI Doc/View app, added a Dialog class, added a new menu item to invoke the dialog, then added an Editbox (with member variable)and a CListbox (with control member variable) to the dialog. The fact that I can write to the Editbox suggests that the invocation of the Dialog is ok, but the Assertion Error for the List box is a puzzle. I can add data using AddString in an InitDialog function, but this is useless, since I want to add data to the ListBox at runtime. Must be a simple omission somewhere........

  2. #2
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,046

    Re: CDialog:ListBox in Doc/View

    More than likely you're calling AddString before the control has been created or after it's been destroyed. What is the ASSERT code telling you?

  3. #3
    Join Date
    Mar 2006
    Posts
    63

    Re: CDialog:ListBox in Doc/View

    Debug assertion failure message shows:

    File: afxwin2.inl
    Line: 669

    In the .inl file at Line 668/669 is:
    [668] _AFXWIN_INLINE int CListBox::AddString(LPCTSTR lpszItem)
    [669] { ASSERT(::IsWindow(m_hWnd)); return (int)::SendMessage(m_hWnd, LB_ADDSTRING, 0, (LPARAM)lpszItem); }

    As I wrote earlier, a statement which writes to an Edit Box on the Dialog form is successful, whereas a trying to AddString to the List Box at the same point in the function which instantiates the Dialog causes the Assertion failure. Looks to me like the CListBox::AddString command is expecting to find the Dialog in a standard place, rather than actually getting it from the instantiated Dlg. (Excuse my poor jargonese).

  4. #4
    Join Date
    Jun 2006
    Posts
    644

    Re: CDialog:ListBox in Doc/View

    May be you are missing DDX entry for the control or string. Please check if the variable name is present in your MESSAGE_MAP macro. Also, see to it that OnInitialUpdate() function calls the base class version in your view class.
    Regards,
    Bhushan

  5. #5
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,046

    Re: CDialog:ListBox in Doc/View

    That supports what I said in post #2. The Listbox window doesn't exist at the point you're trying to add strings to it.

  6. #6
    Join Date
    Mar 2006
    Posts
    63

    Re: CDialog:ListBox in Doc/View

    Thanks for reply, bhushan.
    The Dialog class has a DDX entry for the ListBox (c_list):
    void CDlg:oDataExchange(CDataExchange* pDX)
    {
    CDialog:oDataExchange(pDX);
    //{{AFX_DATA_MAP(CDlg)
    DDX_Control(pDX, IDC_LIST1, c_list);
    DDX_Text(pDX, IDC_EDIT1, m_edit1);
    //}}AFX_DATA_MAP
    }
    The MESSAGE_MAP for the entire Dialog class is empty. I would never guess in a million years what to put there, nor why.
    I also cannot guess what to put in View::OnInitialUpdate.
    This c**p drives me mad.

  7. #7
    Join Date
    Mar 2006
    Posts
    63

    Re: CDialog:ListBox in Doc/View

    I should add that I want to access the ListBox from the Doc: that's where the data is.
    I'll also repeat the point: I can write to the EditBox in the dialog from a Doc function, but attempting to access the CListBox of the Dialog causes an assertion error. It is clear that the Doc class doesn't have a clue about the CListBox, but how to get round this? Or any suggestions as to how to present the user with a list of runtime-generated items, from which they can select any or all? Where in any MS info is there any reference to the need to hand crank a CListBox into life (other than when it's embedded in a CDialog-based appplication)? Maybe I need to use the dreaded GetDlgItem(..) ?

  8. #8
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,010

    Re: CDialog:ListBox in Doc/View

    Quote Originally Posted by crasher View Post
    I should add that I want to access the ListBox from the Doc: that's where the data is.
    I'll also repeat the point: I can write to the EditBox in the dialog from a Doc function, but attempting to access the CListBox of the Dialog causes an assertion error. It is clear that the Doc class doesn't have a clue about the CListBox, but how to get round this?
    Your problem is in your design. You shouldn't access dialog controls from your doc, you should access data from your dialog. You can either pass the data from the doc to the dialog before you create it, or you can give the dialog a pointer to your doc and let the dialog ask for the information.
    Maybe I need to use the dreaded GetDlgItem(..) ?
    What's dreaded about GetDlgItem?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  9. #9
    Join Date
    Mar 2006
    Posts
    63

    Re: CDialog:ListBox in Doc/View

    D_Drmmr:
    You seem not to have read the posts.

    This is a doc/view app. The app reads in a few Mb from various data files (1 to many), and converts and displays the data. The user must be given the choice of which of the various data sets to display together. Therefore a dialog needs to be invoked, in order to present a listbox identifying the data sets which are in memory. All the data is at that point in the Doc. The ListBox has to present the choices, but obviously has to access the identities of the data sets. So I need to pass some info from the Doc to the Dialog. The data is not pre-existing in the dialog, and this is not a dialog app.
    You wrote:
    "You can ... pass the data from the doc to the dialog before you create it".
    That is what I am trying to do, and that is the problem!
    I can indeed write to an EditBox in the dialog which I instantiate in a Doc function, but when I try to get the Listbox to accept data (AddString(..)) in the same function, a Windows Assertion Failure is generated. Therefore the ClistBox appears not to have been initialised or its pointer is bent. So there is something tricky about a CListBox in a dialog which is not part of a Dialog-based application.

  10. #10
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,046

    Re: CDialog:ListBox in Doc/View

    I've already told you what you're doing wrong.

  11. #11
    Arjay's Avatar
    Arjay is online now Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,196

    Re: CDialog:ListBox in Doc/View

    Quote Originally Posted by crasher View Post
    D_Drmmr:
    You seem not to have read the posts.

    This is a doc/view app. The app reads in a few Mb from various data files (1 to many), and converts and displays the data. The user must be given the choice of which of the various data sets to display together. Therefore a dialog needs to be invoked, in order to present a listbox identifying the data sets which are in memory. All the data is at that point in the Doc. The ListBox has to present the choices, but obviously has to access the identities of the data sets. So I need to pass some info from the Doc to the Dialog. The data is not pre-existing in the dialog, and this is not a dialog app.
    You wrote:
    "You can ... pass the data from the doc to the dialog before you create it".
    That is what I am trying to do, and that is the problem!
    I can indeed write to an EditBox in the dialog which I instantiate in a Doc function, but when I try to get the Listbox to accept data (AddString(..)) in the same function, a Windows Assertion Failure is generated. Therefore the ClistBox appears not to have been initialised or its pointer is bent. So there is something tricky about a CListBox in a dialog which is not part of a Dialog-based application.
    This doesn't have anything to do with the architecture. Most likely you are trying to access the CListBox.Addstring before calling the base class O

    Code:
     
    BOOL CMyDlg::OnInitDialog()
    {
     
      // BUG: Don't make any calls to child controls here
     
      CDialog::OnInitDialog();
     
      // Child controls initialized, okay to make controls here.
     
      ...
    }
    By the way, passing the data to the dialog is fairly simple. I usually just pass in a pointer to the document in the dialog's constructor.

    Just add a parameter to the default dlg constructor that takes your specific app document pointer.

  12. #12
    Arjay's Avatar
    Arjay is online now Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,196

    Re: CDialog:ListBox in Doc/View

    Quote Originally Posted by D_Drmmr View Post
    What's dreaded about GetDlgItem?
    It's not that it's dreaded, it's just that using it results in extra code.

    IMO, most folks use GetDlgItem because it's a carry over from coding in Win32 or they don't know how to create a Control variable in MFC.

    The DDX mechanism hides the GetDlgItem implementation, when using data variables also handles the data transfer between the control and its associated variable.

    Rather than having ugly GetDlgItem calls with casting everywhere, you can just use the dialog control variable.

    Consider an edit box and say you want to hide it.

    Create a control variable, and then...

    Code:
    m_EditBox.ShowWindow( SW_HIDE );
    What about setting the edit box string?

    Create a value variable (like CString), and then...

    Code:
    m_sEdit = _T("some text");
    UpdateData( FALSE );
    Compare that with:

    Code:
     
    CEdit* pBoxOne = (CEdit*) GetDlgItem(IDC_EDIT1);
    pBoxOne->GetWindowText( _T("some text" );
    Sure, you can argue that they're both 2 lines. But consider that UpdateData( ) only needs to be called once after setting any values - even for multiple controls.

  13. #13
    Join Date
    Mar 2006
    Posts
    63

    Re: CDialog:ListBox in Doc/View

    GCDEF, yes , thanks for the reminder. And I did notice that nice row of medals you've got there. Now, what about a suggestion, or is putting a usable listbox in a dialog called from a menu entry in a doc/view app really complex? If I knew the solution, I wouldn't be posting here btw.

  14. #14
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Posts
    12,046

    Re: CDialog:ListBox in Doc/View

    Quote Originally Posted by crasher View Post
    GCDEF, yes , thanks for the reminder. And I did notice that nice row of medals you've got there. Now, what about a suggestion, or is putting a usable listbox in a dialog called from a menu entry in a doc/view app really complex? If I knew the solution, I wouldn't be posting here btw.
    The point is the listbox has to exist when you add strings to it. It exists after the call in OnInitDialog to CDialog::OnInitDialog, and before CDialog::EndDialog gets called, which usually happens when you press the okay or cancel buttons.

    Can you post a small snipped that shows how you're adding strings and from where.

  15. #15
    Arjay's Avatar
    Arjay is online now Moderator / MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    11,196

    Re: CDialog:ListBox in Doc/View

    This is pretty basic. I've created a VC++ 2005 project to show one approach. This sample opens a test dialog from the view and passes in the pointer to the document. However, the test dialog could be as easily invoked from the mainframe or document as well.

    I've added a m_sEdit variable to the document and a public GetEditString() public accessor method.

    Code:
    // Attributes
    private:
      CString m_sEdit;
    // Operations
    public:
      CString& GetEditString( ) { return m_sEdit; };
    
    When the OnViewTestdialog() menu handler in the view gets called, it creates a CTestDlg object and calls DoModal().

    Code:
    void CSdi2DlgView::OnViewTestdialog()
    {
      CTestDlg dlg( this, GetDocument( ) );
      dlg.DoModal( );
    }


    The changes for the TestDlg are simple.

    1) Pass in the CDocument ptr in the ctor

    Code:
     
    CTestDlg::CTestDlg(CWnd* pParent, CSdi2DlgDoc* pDocument)
      : CDialog(CTestDlg::IDD, pParent)
        , m_pDocument( pDocument )
        , m_sEdit(_T(""))
    {
    }
    2) Update the OnInitDialog() handler to initialize the local TestDlg
    m_sEdit variable with the data from the document

    Code:
    BOOL CTestDlg::OnInitDialog( )
    {
      m_sEdit = m_pDocument->GetEditString( );
     
      CDialog::OnInitDialog();
    
    
    
      return 0;
    }


    3) Finally, save the data back to the document when the Ok button is pressed.

    Code:
    void CTestDlg::OnBnClickedOk()
    {
    UpdateData( TRUE );
     
    m_pDocument->GetEditString( ) = m_sEdit;
     
      OnOK();
    }

    Attached Files Attached Files

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center