CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Mar 2001
    Posts
    2,529

    Mystery of the Modeless Dialog

    I am looking at some code similar to this. I have theories as to
    why the destructor is never called. In my opinion, the dialog does go
    out of scope...the manager object should automatically delete it.
    Code:
    void ShowSearchDialog(void)
    {
      uniqe_ptr<CModeLess> m_pmodeless(new CModeLess(this)); 
      m_pmodeless->Create(CModeLess::IDD);
      m_pmodeless->ShowWindow(SW_SHOW);	
    }
    In the dialog, based on some query results certain controls are disabled.

    The next time the function is called the same controls are disabled even
    if the query did not return the state that causes the controls to be disabled
    again.

    #1 Why doesn't the destructor get called?
    #2 Why is the object hanging around?
    #3 Why does the same object appear to be
    reconnecting to the pointer on subsequent calls?
    Last edited by ahoodin; April 10th, 2016 at 08:37 PM.
    ahoodin
    To keep the plot moving, that's why.

  2. #2
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Mystery of the Modeless Dialog

    Out of curiosity, why do you name your local variable m_pmodeless?

    The 'm_p' prefix implies a class member field that is a pointer.

    Is this code within a class that contains a m_pmodeless field? If so, is the value getting stored in a class field?

    Some folks get a little upset when naming conventions are mentioned, but following them often prevents these types of issues.

  3. #3
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: Mystery of the Modeless Dialog

    It has no much sense to create a modeless dialog either using a locally defined smart pointer or instantiate a local object. In both cases it will be destroyed when goes out of function scope. Moreover you'll get (at least in the last MFC versions) a warning from the CDialog's destructor:
    Code:
    ... \dlgcore.cpp(136) : AppMsg - Warning: calling DestroyWindow in CDialog::~CDialog
    ... \dlgcore.cpp(137) : AppMsg - OnDestroy or PostNcDestroy in derived class will not be called.
    That's to avoid wondering/having headaches if somehow handle WM_DESTROY and/or override PostNcDestroy in the CDialog-derived class, write some cool code in there and nothing happens.

    Just put a member of child dialog type in its parent class then create it first time it's necessary to be shown.
    Something like in the next example:
    Code:
    class CParentDialog : public CDialog
    {
        CChildDialog m_dlgChild;
        // ...
    };
    Code:
    void CParentDialog::ShowModelessDialog()
    {
        if (! ::IsWindow(m_dlgChild.GetSafeHwnd()))
            m_dlgChild.Create(CMyDialog::IDD, this);
    
        m_dlgChild.ShowWindow(SW_SHOW);
    }
    
    void CParentDialog::HideModelessDialog()
    {
        if (::IsWindow(m_dlgChild.GetSafeHwnd()))
            m_dlgChild.ShowWindow(SW_HIDE);
    }
    Nothing more. Further, the parent will take care to cleanly destroy its children when it's being destroyed itself.

    An aditional note, completing Arjay's post: a smart pointer defined as above is in fact an object so, to increase the code readability and avoid any confusion, you can prefix it with "sp" (if it's locally defined), or with "m_sp" (if it's a class member).
    Last edited by ovidiucucu; May 31st, 2016 at 10:54 AM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

Tags for this Thread

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