valid window handle

Hi,

In my MDI app, I'm keeping a vector of dialog handles so I can reference these windows later on, something like:

void OnBnCreateDialogWindow()
{
    CMyDialog *pNewDlg = new CMyDlg();
    pNewDlg->Create(...);
    theApp.m_vDialogHandles.push_back(pNewDlg->m_hWnd);
}

Anytime I close one of these dialogs, then do a count of valid hwnds in the vector, the count never seems to decrease:

void OnBnCountValidHwnds()
{
    int n = 0;
    for (int i = 0; i < theApp.m_vDialogHandles.size(); i++)  {
        if (::IsWindow(theApp.m_vDialogHandles[i])) {
            n++;
        }
    }

    CString str;
    str.Format("there are [%i] valid handles.", n);
    AfxMessageBox(str);
}

Now if I opened a few dialogs, close them all, then run the count function, it thinks each of the window handles are still valid. Any ideas? Any better ways to do this?

Thank you

LVL 7
minnirokAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AndyAinscowFreelance programmer / ConsultantCommented:
All you have posted here is how you add handles to the collection.  How do you remove them from the collection?


There is a virtual function PostNcDestroy - that is a place often used for tidying up.  Do you remove the handle from the collection there for instance?
0
AndyAinscowFreelance programmer / ConsultantCommented:
The dialogs are modeless - how do you destroy them is also relevant  (Hopefully NOT with CDialog::OnOK or CDialog::OnCancel).
0
minnirokAuthor Commented:
Ah ok, I guess since I am allocating a new dialog object with 'new', 'delete' is never being called on it, even though the WM_CLOSE message is getting called, I guess the memory for it is still valid even though you can't 'see' the dialog anymore. Is it ok to then do something like:

void CMyDialog::OnClose()
{
    CDialog::OnDestroy();
    delete this;
}

then the hwnd will not be valid anymore?

Thanks
0
Cloud Class® Course: CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

minnirokAuthor Commented:
Hi Andy,

Sorry didn't see your posts before my last one - yes I am not deleting the dialogs anyplace. So should I call:

    delete this

in that PostNcDestroy() message handler? Will it be called even when the user clicks the close icon on the titlebar?

Thanks
0
mahesh1402Commented:
You may try using IsWindowVisible() API function OR you may manually assign NULL to window handle in list after closing window.

MAHESH
0
AndyAinscowFreelance programmer / ConsultantCommented:
I use code like this for 'disposable' windows to remove memory allocated with new.

void CXYZDlg::PostNcDestroy()
{
      CDialog::PostNcDestroy();
      delete this;
}
0
AndyAinscowFreelance programmer / ConsultantCommented:
void CMyDialog::OnClose()
{
HWND hWnd = GetSafeHwnd();    //Get the window handle, now remove from the collection
    CDialog::OnDestroy();
}
0
AndyAinscowFreelance programmer / ConsultantCommented:
ps.
I had a quick look at PostNcDestroy - at that point the window has been destroyed so no valid handle at that point, the OnClose should be better for tidying up the HANDLE in the collection, use the PostNcDestroy for the memory.
0
minnirokAuthor Commented:
Hi Andy,

How is your PostNcDestroy handler getting called? Right now I have:

void CMyDialog::OnClose()
{
     OnClose();
     delete this;
}

void CMyDialog::PostNcDestroy()
{
    AfxMessageBox("Post Destroy");
    CDialog::PostNcDestroy();
}

My message is never getting called in PostNcDestroy(), not when I close the dialog, nor when I exit the application. I added it through the vc 2003 wizard,

Thanks
   
0
AndyAinscowFreelance programmer / ConsultantCommented:
void CMyDialog::OnClose()
{
     OnClose();
     delete this;
}

At this point you have deleted the 'this' - so PostNcDestroy isn't being called.

void CMyDialog::PostNcDestroy()
{
    AfxMessageBox("Post Destroy");
    CDialog::PostNcDestroy();
}


do this
void CMyDialog::OnClose()
{
//remove handle from collection
     DestroyWindow();
}

void CMyDialog::PostNcDestroy()
{
    AfxMessageBox("Post Destroy");
    CDialog::PostNcDestroy();
delete this;
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mahesh1402Commented:
In some cases PostNcDestroy does not get called automatically, so we have to call it ourselves.

e.g
void CMyDialog::OnDestroy()
{
    CDialog::OnDestroy();    
    ....
    PostNcDestroy ();        
}

MAHESH
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.