我怎样才能验证" CWnd *对象?

时间:2016-01-27 16:14:05

标签: c++ windows mfc

(有一个TL;最后一行的DR)

我实现了一个处理程序来关闭在软件应用程序中打开的选定窗口。这是一个粗略的代码:

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);
        }
    }
}

以下是上面显示的参数的一些声明:

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;
    ...
}

此外,可能有多个Window_Node具有不同pWnd参数的实例,源自单个CDocument类(即,存在不同类型的窗口以显示文档的不同显示)。

enter image description here

对于此软件,如果文档的第一个窗口(图中始终为&#34;绿色&#34;窗口类型)关闭,则与该文档关联的所有其他窗口将自动关闭。这就是问题发生的地方。

如果用户从同一文档中选择多个窗口(其中包含绿色窗口),则在完成第一次迭代时关闭所有窗口,并且所有pWnd指针现在指向一个现在未分配的窗口记忆。因此,当它尝试在下一次迭代时调用GetSafeHwnd()时,会提示存储器访问冲突错误:

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.

我知道简单的解决方法是在相反的方向上迭代向量。但是,我正在尝试将此方法集成到其他几个软件上,并且他们不一定以相同的方式组织他们的窗口。

因此,经过上述所有长期问题,这里有TL; DR:

有没有办法检查CWnd *的实例是否指向有效窗口?

1 个答案:

答案 0 :(得分:1)

一种可能性是从主窗口开始,如果找到有问题的HWND,则递归搜索子窗口。

获取CWnd::GetWindow(GW_CHILD)的第一个孩子以及CWnd::GetWindow(GW_HWNDNEXT)的下一个窗口。