CDockingManager GetPaneList () вызывает ошибку подтверждения в wincore.cpp? - PullRequest
0 голосов
/ 26 февраля 2011

Так что я подумал, что это будет довольно просто, но я забыл, что это MFC. Вместо регистрации получателя уведомлений об изменениях модели данных, которые, возможно, потребуют обновления графического интерфейса для каждого отдельного элемента управления, я думаю, почему бы не зарегистрировать его один раз, а затем отправить сообщение всем панелям открытых док-станций и позволить им при необходимости обновить свои элементы управления собственные условия эффективности.

Моя функция обратного вызова для обработки уведомлений с сервера выглядит примерно так:

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

Ошибка, которую я получаю, - ошибка подтверждения в строке 926 файла wincore.cpp

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

Ниже этого комментария говорится, что это может произойти, если вы передаете управление между потоками, однако это однопоточное приложение MFC, и все это делается из основного фрейма.

Кто-нибудь знает, что еще может вызвать это?

Если есть другой способ отправки сообщения всем открытым CDockablePane производным окнам в MFC, который также работает ...

1 Ответ

0 голосов
/ 01 марта 2011

Вот очевидный обходной путь, который я не хотел делать, но после часов отладки и отсутствия ответа, я думаю, что это жизнеспособный ответ:

Я добавил 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 для каждого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...