Инициализация данных членов для производного класса CFormView в MFC - PullRequest
0 голосов
/ 04 июня 2019

Я использую классы MFC, но нестандартным способом (т.е. вообще не использую производный класс CDocument).

Как бы то ни было, у меня есть несколько представлений, полученных из CFormView, и есть переменные-члены класса.

У меня есть код, который использует производный класс от CMiniFrameWnd, и это похоже на

CCreateContext context;
context.m_pNewViewClass = RUNTIME_CLASS(CImageView);
context.m_pCurrentDoc = NULL;
CView* pNewView = STATIC_DOWNCAST(CView, CreateView(&context));
if (pNewView != NULL)
{  
    pNewView->ShowWindow(SW_SHOW);
    pNewView->OnInitialUpdate();
    SetActiveView(pNewView);
}
// save view

Но загвоздка в том, что CreateView () вызывает конструктор CImageView по умолчанию, а OnInitialUpdate (), являющийся виртуальным переопределением, должен совпадать с сигнатурой CView ().

Так как мне инициализировать данные члена, принадлежащие CImageView? CreateView () и OnInitialUpdate () мешают (если я что-то упускаю). Кажется, что производные классы от CView или CFormView не легко инициализируются в архитектуре MFC.

Спасибо

1 Ответ

0 голосов
/ 04 июня 2019

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

BOOL CCommunityTalksDoc::SwitchToView(CRuntimeClass* pNewViewClass)
{
    POSITION        rPos;
    CView           *pOldActiveView;
    CFrameWnd       *pChild;
    CCreateContext  context;
    BOOL            bAutoDelete;

    rPos = GetFirstViewPosition();
    pOldActiveView = GetNextView(rPos);
    pChild = pOldActiveView->GetParentFrame();

    // If we're already displaying this kind of view, no need to go further.
    if (pOldActiveView->IsKindOf(pNewViewClass))
        return TRUE;

    // Set flag so that document will not be deleted when view is destroyed.
    bAutoDelete = m_bAutoDelete;
    m_bAutoDelete = FALSE;
    // Delete existing view
    pOldActiveView->DestroyWindow();
    // restore flag
    m_bAutoDelete = bAutoDelete;

    // Create new view.
    m_pScriptView = (CScriptParseView*)pNewViewClass->CreateObject();
    if (m_pScriptView == nullptr)
    {
        TRACE1("Warning: Dynamic create of view type %s failed\n", pNewViewClass->m_lpszClassName);
        return FALSE;
    }

    // we must ensure the popup dialogues don't display
    m_pScriptView->SetBuildMode(FALSE);

    // Draw new view.
    context.m_pNewViewClass = pNewViewClass;
    context.m_pCurrentDoc = this;
    context.m_pNewDocTemplate = nullptr;
    context.m_pLastView = nullptr;
    context.m_pCurrentFrame = pChild;
    if (!m_pScriptView->Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW, CRect(0, 0, 0, 0), 
                pChild, AFX_IDW_PANE_FIRST, &context))
    {
        TRACE0("Warning: couldn't create view for frame\n");
        delete m_pScriptView;
        m_pScriptView = nullptr;
        return FALSE; 
    }

    m_pScriptView->SendMessage(WM_INITIALUPDATE, 0, 0);  // WM_INITIALUPDATE is defined in afxpriv.h
    pChild->RecalcLayout();
    m_pScriptView->UpdateWindow();
    pChild->SetActiveView(m_pScriptView);
    return TRUE;
}

Телефонный код:

// we must set our view correctly
// note, I am not convinced we are doing this in the right place
// what happens if user makes a second view?
// and what about when RebuildReport is called ?
if(m_pScriptView == nullptr)
{
    //bNewReport = true;
    // we must create view
    pNewViewClass = RUNTIME_CLASS(CScriptParseView);
    if (!SwitchToView(pNewViewClass))
    {
        // fail, don't know why it would fail
        ASSERT(FALSE);
    }
    else
    {
        // we set the variables map only once
        m_pScriptView->SetVarValuesMap(psData->pMapSSVarsValues);
        m_pScriptView->SetVarOptionsMap(psData->pMapSSVarsOptions); // AJT v10.6.0
    }
}

Надеюсь, это поможет.

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