【问题标题】:CDockingManager GetPaneList() causes assertion failure in wincore.cpp?CDockingManager GetPaneList() 导致 wincore.cpp 中的断言失败?
【发布时间】:2011-02-25 22:59:21
【问题描述】:

所以我以为这会很简单,但我忘了它是 MFC。而不是为可能需要对每个单独控件进行 GUI 更新的数据模型更改注册通知侦听器,我想为什么不注册一次,然后向所有打开的停靠窗格发送消息,并允许他们根据需要更新他们的控件自己的效率条款。

用于处理来自服务器的通知的回调函数如下所示:

void CMainFrame::ChangeCallback(uint32_t nNewVersion, const std::vector<uint32_t>& anChangedObjectTypes)
{
    CObList panes;
    GetDockingManager()->GetPaneList(panes); // assert failure

    if (!panes.IsEmpty())
    {
        POSITION pos = panes.GetHeadPosition();
        while (pos)
        {
            CDockablePane* pPane = dynamic_cast<CDockablePane*>(panes.GetNext(pos));
            if (pPane)
                pPane->PostMessage(DM_REFRESH, nNewVersion);
        }
    }
}

我得到的错误是 wincore.cpp 第 926 行的断言失败

CHandleMap* pMap = afxMapHWND();
ASSERT(pMap != NULL); // right here

下面有一条评论说如果您跨线程传递控件可能会发生这种情况,但这是一个单线程 MFC 应用程序,这一切都是从主框架完成的。

有谁知道还有什么可能导致这种情况?

如果有另一种方法可以向 MFC 中所有打开的 CDockablePane 派生窗口发送消息也可以...

【问题讨论】:

    标签: c++ user-interface mfc


    【解决方案1】:

    这是我不想做的明显解决方法,但经过数小时的调试并且这里没有响应,我想这是一个可行的答案:

    我将std::vector&lt;CDockPane*&gt; m_dockList;添加到CMainFrame的成员中

    现在,在可以创建和打开新停靠窗格的各个地方每次调用 AddPane 之后,我都会对 push_back 进行后续调用,然后像这样覆盖 CDockablePane::OnClose

    CMainFrame* pMainFrame = reinterpret_cast<CMainFrame*>(AfxGetMainWnd());
    if (pMainFrame)
    {
        std::vector<CDockPane*>::const_iterator found(
            std::find(pMainFrame->DockList()->begin(), pMainFrame->DockList()->end(), this));
        if (found != pMainFrame->DockList()->end())
            pMainFrame->DockList()->erase(found);
    }
    CDockablePane::OnClose();
    

    现在这个列表将只包含指向打开停靠窗格的指针,它允许我在回调中处理事件通知,并且只需执行一个 for 循环和 PostMessage 到每个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-30
      • 2013-08-17
      • 2020-10-19
      • 2023-03-29
      • 2018-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多