How can I "validate" CWnd* object?

1

(There's a TL;DR on the last line)

I'm implementing a handler to close selected windows open in a software application. Here's a rough code:

void CDlg_Dummy_Dialog::OnCloseWindows()
{
    for (int i = 0; i < m_WindowsInfo.size(); i++) {
        Window_Node *pWN = &m_WindowsInfo.at(i);
        if (pWN->checked && IsWindow(pWN->pWnd->GetSafeHwnd())) {
            pWN->pWnd->GetParentFrame()->SendMessage(WM_CLOSE);
        }
    }
}

Here are some declarations of the parameters shown above:

struct Window_Node {
    CString name;
    CString path;
    CWnd *pWnd;
    BOOL checked;
    HICON icon;
    ....
};

class CDlg_Dummy_Dialog : public CDialog {
    ...
protected:
    std::vector<struct Window_Node> m_WindowsInfo;
    ...
}

Also, there can be multiple instances of Window_Node with different pWnd parameter, originating from a single CDocument class (ie. different types of windows exist to show different displays for the document).

enter image description here

For this software, if the first window of the document (which is always the "green" Window type in the diagram) is closed, all other windows associated with that document will automatically be closed with them. This is where the problem happens.

If the user selects multiple windows from the same document (with the green window among them), it closes all windows by the time it finishes the first iteration, and all pWnd pointers are now pointing to a now unassigned memory. Therefore, when it tries to call GetSafeHwnd() on the next iteration, it prompts a memorry access violation error:

First-chance exception at 0x00000000521B4AD0 (mfc100d.dll) in Settle3D.exe: 0xC0000005: Access violation reading location 0x00000000136943E0.
Unhandled exception at 0x00000000521B4AD0 (mfc100d.dll) in Settle3D.exe: 0xC000041D: An unhandled exception was encountered during a user callback.

I'm aware that the easy fix would be to iterate through the vector in the opposite direction. However, I am trying to integrate this method on several other software as well, and they don't necessarily organize their windows in the same manner.

So, after all the long question above, here's TL;DR:

Is there any way to check if an instance of CWnd* is pointing to a valid window?

c++
windows
mfc
asked on Stack Overflow Jan 27, 2016 by Caladbolgll • edited Jan 27, 2016 by Jabberwocky

1 Answer

1

One possibility would be to start with your main window, and recursively search through the child windows if you find the HWND in question.

Get the first child with CWnd::GetWindow(GW_CHILD) and the next windows with CWnd::GetWindow(GW_HWNDNEXT).

answered on Stack Overflow Jan 27, 2016 by dwo

User contributions licensed under CC BY-SA 3.0