所以我认为这很简单,但我忘记了它是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
派生窗口发送消息,那么它也可以...
答案 0 :(得分:0)
这是我不想做的明显的解决方法,但是经过数小时的调试并且没有响应,我想这是一个可行的答案:
我向std::vector<CDockPane*> 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
。