CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking A tricky problem : Dynamic pointers to hold dynamic dialogs

    Now, in my case, I've a need to create n-th number of modeless dialogs at runtime and access them from other parts of the program.

    Of course, I can easily achieve this by creating them locally, as in something like :
    Code:
    for(int i = 0; i < 10; i++)
    {
        CMyModelessDialog* pDlg = new CMyModelessDialog();
        pDlg->Create(IDD_DIALOG1,this);
        pDlg->ShowWindow(SW_SHOW);
    }
    This works, but the problem with this approach is that if I wanna access these dialogs from other classes or other parts of the same classes(other function etc.), it's totally impossible, cos' these dialog pointers are local.

    The member/global dialog pointer approach whereby you create member/global pointers to hold the dialogs doesn't work too, cos' in my case, you dunno how many member/global dialog pointers to create to hold the n-th number of modeless dialog, because it can be any number at run-time.

    Another probable way is to use a single member/global dialog pointer with the new and delete operator to create dialogs. But this is impossible when u try it out, and even if it's possible, there's no way to access a desired dialog, cos' this pointer will always be set to the latest dialog you created.

    So, my question is :

    Is it possible to create n-th number of modeless dialogs at run-time and STILL have valid pointers to access them from other parts of the program at any time?

    Please and thanks a lot! Thanks!
    Xeon.
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  2. #2
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking Solved! But need an explanation!

    Let's face it : sometimes, I really feel as though the minds and powers of those famous industry experts lies in me, such as Jeff Prosise, Dino Esposito, Jeffrey Richter, and John Robbins.
    In short : I am the man.

    Now, I managed to solve this problem with a solution : create local pointers to achieve the creation of n-th number of modeless dialogs at run-time, and storing these pointers in a CArray template class so that I can access them later.

    The code snippet is as follows :
    Code:
    //called when a push-button is clicked
    void CManyDlgsDlg::OnCreatedlgs() 
    {
    	for(int i = 0; i < 10; i++)
    	{
    		CMyDialog* pDlg = new CMyDialog(this);
    		m_arDlgs.Add(pDlg);
    	}
    }
    
    //called when another push button is clicked.......basically, this part changes the window text of the first modeless dialog
    void CManyDlgsDlg::OnChangetext() 
    {
    	m_arDlgs.GetAt(0)->SetWindowText("Hugo!");
    }
    m_arDlgs is declared as :
    Code:
    CArray<CMyDialog*, CMyDialog*> m_arDlgs;
    where CMyDialog is my modeless dialog class.


    When I run the program and click the buttons and such, I was expecting to get an Access Violation error, cos' u see, the local dialog pointers(pDlg) SHOULD ALL BE OUTTA SCOPE and be DESTROYED when the OnCreatedlgs() function ends, and when I try to access them in the OnChangeText() function, an Access Violation error should occur, cos' I'm trying to access something that's already invalid; gone outta scope; destroyed.

    But INSTEAD........(I dunno why)........everything works as though they're in God's garden! Isn't this crazy! This is even more mysterious than the Bermuda Triangle! Crazy!

    I would really appreciate it if anyone can gimme an explanation of why success occurs instead of failure.

    Please and thanks a lot!
    Xeon.
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  3. #3
    Join Date
    Feb 2000
    Location
    Greensboro NC
    Posts
    123

    Re: Solved! But need an explanation!

    Originally posted by Xeon

    Let's face it : sometimes, I really feel as though the minds and powers of those famous industry experts lies in me, such as Jeff Prosise, Dino Esposito, Jeffrey Richter, and John Robbins.
    In short : I am the man.
    you're kidding us right? either i am misunderstanding the question or you dont understand the 'new' keyword.

    Originally posted by Xeon

    Now, I managed to solve this problem with a solution : create local pointers to achieve the creation of n-th number of modeless dialogs at run-time, and storing these pointers in a CArray template class so that I can access them later.
    yes this is a solution and i realize to you it is eye opening and wonderful but it certainly doesnt put you in a league with above mentioned experts by any means

    Originally posted by Xeon

    When I run the program and click the buttons and such, I was expecting to get an Access Violation error, cos' u see, the local dialog pointers(pDlg) SHOULD ALL BE OUTTA SCOPE and be DESTROYED when the OnCreatedlgs() function ends, and when I try to access them in the OnChangeText() function, an Access Violation error should occur, cos' I'm trying to access something that's already invalid; gone outta scope; destroyed.

    But INSTEAD........(I dunno why)........everything works as though they're in God's garden! Isn't this crazy! This is even more mysterious than the Bermuda Triangle! Crazy!
    when you use the keyword 'new' that allocates memory which does not go out of scope when the function ends it is really just that simple. the list of pointers you make is valid after the function ends, as a matter of fact you must free this memory before your program ends or the memory you new'ed will be leaked.

  4. #4
    Join Date
    Sep 2002
    Posts
    77
    If you are using new to create an object the memory for this object is allocated on the heap and stays valid until you free this memory block.

    So you code is:
    Code:
    ...
    for(int i = 0; i < 10; i++)
    {
      CMyDialog* pDlg = new CMyDialog(this);
      m_arDlgs.Add(pDlg);
    }
    ...
    The only thing which is going out of scopy is the pointer variable pDlg which holds an address to the CMyDialog object on the heap.
    After the closing bracket pDlg is invalid / not accessable but your object is still there.

    It is you who has to clean up the memory when its no longer needed. In your case you would do this by calling delete in a loop:
    Code:
    for (int i=0; i<=m_arDlgs.GetSize(); i++)
    {
       CMyDialog* pDlg = m_arrDlgs.GetAt(i);
       delete pDlg;
    }

  5. #5
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Thanks a lot, Alpha and Itachna!

    Well, because these are modeless dialogs, I coded something like :
    Code:
    delete this;
    inside the virtual funtion PostNcDestroy() windows message handler.

    Is this enough? Or do I need to delete them inside a loop which u mention, Alpha? Thanks a lot!

    Also, Itachna.......of course I'm kidding, k? I'm one of those folks who behave as though I'm the Lord, even though I know darn well I'm not. This is what is termed by, "Behaving like a big-headed guy when u're really humble inside, to amuse folks".

    That's the morale of the story. Need I say more?
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  6. #6
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Now, folks.......I've attached my sample program, totally focused on this dialog/pointers issue.

    I hope you can help me to see if there's any memory leak etc.
    Please and thanks a lot!

    (the pointer deletion code is in CMyDialog::OnPostNcDestroy())

    Please and thanks a lot!
    Attached Files Attached Files
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  7. #7
    Join Date
    Sep 2002
    Posts
    77
    ...I'm one of those folks who behave as though I'm the Lord...
    Well, there are a lot of those folks out there.
    ...even though I know darn well I'm not...
    This reduces the number of the first group to only a few, ok?

    But now to your problem:
    "delete this" in PostNcDestroy is absolutely perfect! There is a very good technical article about this topic in MSDN - every serious windows programmer should know.
    See "TN017: Destroying Window Objects".

  8. #8
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Hi there Alpha! Thank you so much!
    But previously, u mention on this thread that I should code:
    Code:
    for(int i = 0; i < 10; i++)
    {
        for (int i=0; i<=m_arDlgs.GetSize(); i++)
       {
           CMyDialog* pDlg = m_arrDlgs.GetAt(i);
           delete pDlg;
       }
    }
    Is this needed anymore in my case? Or is it darn sufficient to call "delete this"? Thanks!

    ...I'm one of those folks who behave as though I'm the Lord...
    --------------------------------------------------------------------------------
    Well, there are a lot of those folks out there.
    quote:
    --------------------------------------------------------------------------------
    ...even though I know darn well I'm not...
    --------------------------------------------------------------------------------
    This reduces the number of the first group to only a few, ok?
    Darn it! Look here, Alpha : One of these fine days, u're really gonna get it from me, k???!!!! Yes! Chicken chop!!!!!
    Last edited by Xeon; October 20th, 2002 at 05:54 AM.
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  9. #9
    Join Date
    Sep 2002
    Posts
    77
    To my opinion it is sufficient to have the "delete this" on PostNcDestroy.

    Your modeless dialogs will once be destroyed - either by explicitly calling DestroyWindow or when your main application window is destroyed (for the later it is important that you have specified a parent window in pDlg->Create rather then using the desktop window).
    And when the dialog is destroyed the virtual PostNcDestroy is called and your C++ object of the dialog will be cleaned up.

    So coding the "delete this" is a very beautifull solution because the clean up is encapsulated inside the dialog class.

  10. #10
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Hoo! Thanks a lot, Alpha! U're the.....ummm......errr.......ummm.....(run outta words to say).....errr.........One! Yes! U're the One!
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  11. #11
    Join Date
    Jul 2002
    Location
    Connecticut, U.S.
    Posts
    275
    Xeon,

    Looking at your code, you might want to change:
    Code:
    void CMyDialog::PostNcDestroy() 
    {	
    	CDialog::PostNcDestroy();
    
    	CManyDlgsDlg* pDlg = (CManyDlgsDlg*)AfxGetMainWnd();
    	CMyDialog* pDlg2 = pDlg->m_arDlgs.GetAt(m_nIndex);
    
    	delete pDlg2;
    }
    to
    Code:
    void CMyDialog::PostNcDestroy() 
    {	
    	CDialog::PostNcDestroy();
    
    	CManyDlgsDlg* pDlg = (CManyDlgsDlg*)AfxGetMainWnd();
    	CMyDialog* pDlg2 = pDlg->m_arDlgs.GetAt(m_nIndex);
    
    	delete pDlg2;
    	pDlg->m_arDlgs.SetAt(m_nIndex, NULL);
    }
    Regards,
    John Flegert

  12. #12
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Thanks a lot, Jonh!
    But just wanna know : what if I don't change it? Will it have any memory leaks etc.?

    Thanks!
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

  13. #13
    Join Date
    Jul 2002
    Location
    Connecticut, U.S.
    Posts
    275
    But just wanna know : what if I don't change it? Will it have any memory leaks etc.?
    I don't know. I was more concerned with your following statement:
    Now, in my case, I've a need to create n-th number of modeless dialogs at runtime and access them from other parts of the program.
    If the window has been destroyed, and you try to access it in other parts of the program, you will have problems.


    Regards,
    John Flegert

  14. #14
    Join Date
    Sep 2002
    Posts
    77
    I haven't downloaded the source code before so now I'm a little bit puzzeled about the implementation of PostNcDestroy.

    You needn't to find the dialog (which is finding "this"!) - you can optimize it to the following code:

    Code:
    void CMyDialog::PostNcDestroy()
    {
       delete this;
    }

  15. #15
    Xeon's Avatar
    Xeon is offline Want me to ban you?! Power Poster
    Join Date
    Jul 2000
    Location
    Singapore
    Posts
    4,195

    Talking

    Thanks a lot, John and Alpha! Cool!
    "Hell is calling for you!" - Rufus, from Valkyrie Profile 2 : Silmeria

    "I'm getting tired of you devils.....finishing strike......Final Blast!" - Arngrim, from Valkyrie Profile 2 : Silmeria

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured