Как разделить диалог MFC с 3 видами? - PullRequest
0 голосов
/ 06 января 2019

Вопрос: Как разделить диалог MFC на 3 вида?
Среда: Win10 RS5 x64
Инструменты: Visual Studio 10.0 + Sp1

Когда я выполнил приложение, «Ошибка отладки!» произошла ошибка

Сообщение об ошибке:

Debug Assertion Failed!  
File: f:\dd\vctools\vc7libs\ship\atlmfc\include\afxwin2.inl  
Line: 82

Я хочу разделить диалог следующим образом:

enter image description here

Код реализации здесь:

// SampleDlg.h
class CSampleDlg : public CDialogEx
{
    //...
public:
    CSplitterWndEx m_wndSplitter;
};

// SampleDlg.cpp
BOOL CSampleDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();
    //...
    if (!m_wndSplitter.CreateStatic(this, 2, 1))
    {
        return FALSE;
    }
    if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CChild_NoteView), CSize(100, 100), 0) ||
        !m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CChild_LogView), CSize(100, 100), 0))
    {
        m_wndSplitter.DestroyWindow();
        return FALSE;
    }

    return TRUE;
}

// Child_NoteView.h
class CChild_NoteView : public CView
{
    DECLARE_DYNCREATE(CChild_NoteView)
    //...
public:
    CFont           m_note_font;
    CRichEditCtrl   m_note_edit;
}

// Child_NoteView.cpp
Message : WM_CREATE
int CChild_NoteView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if(CView::OnCreate(lpCreateStruct) == -1)
        return -1;

    CreateNoteEdit();

    return 0;
}
VOID CChild_NoteView::CreateNoteEdit()
{
    m_note_font.CreatePointFont(80, L"Consolas");
    m_note_edit.Create(ES_MULTILINE | WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | WS_HSCROLL, 
        CRect(10, 10, 100, 100), this, IDD_EDIT_NOTE);
    m_note_edit.SetReadOnly(TRUE);

    m_note_edit.SetFont(&m_note_font, 1);

    return VOID();
}

Я думал, что эта ошибка возникает при попытке создать пустое представление. Итак, я реализовал редактирование заметки, но все равно произошла ошибка.

1 Ответ

0 голосов
/ 06 января 2019

Когда вы получаете эти ошибки отладки, отладчик должен дать вам возможность просматривать исходный код (хотя старые версии Visual Studio могут доставить вам немало хлопот). Затем вы можете открыть «Стек вызовов» и отследить ошибку.

В этом случае отладчик, вероятно, сообщает вам, что CSplitterWndEx ищет CFrameWnd и не может его найти.

Вы можете получить свой собственный класс CMySplitterWndEx и изменить код так, чтобы он возвращал главное диалоговое окно вместо возврата CFrameWnd

В качестве альтернативы, вы можете добавить окно фальшивой рамки следующим образом:

BOOL CSampleDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    CRect rc;
    GetClientRect(&rc);

    CFrameWnd *frame = new CFrameWnd;
    CString framecls = AfxRegisterWndClass(0, NULL, NULL, NULL);
    frame->Create(framecls, L"", WS_VISIBLE | WS_CHILD, rc, this);

    m_wndSplitter.CreateStatic(frame, 2, 1);
    m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CChild_NoteView), CSize(100, 100), NULL);
    m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CChild_NoteView), CSize(100, 100), NULL);

    rc.MoveToXY(0, 0);
    m_wndSplitter.MoveWindow(rc);
    m_wndSplitter.ShowWindow(SW_SHOW);
    return TRUE;
}

Вы также можете добавить CCreateContext.

...