C++ MFC Feature Pack -> Создание нескольких CDockablePanes на CDialog

Я пытаюсь создать область на CDialog, где я могу вставить несколько CDockablePanes. Они должны быть идеально пристыкованы к фиксированному содержимому диалога.

Образец диалоговых окон Codejock - это именно то, что мне нужно, но реализовано с помощью классов пакетов возможностей MFC: http://codejock.com/downloads/samples/dockingpane.asp

На данный момент я получил класс, унаследованный от CFrameWndEx, который встроен в CDialog. У меня также есть рабочий CDockablePane. Я могу отсоединить его и переместить, но когда я хочу установить его, программа вылетает.

Это связано с тем, что класс закрепляемой панели пытается создать фиктивную панель для предварительного просмотра, куда пойдет настоящая панель. Он вызывает GetTopLevelFrame(), который возвращает NULL. Это приводит к сбою в afxpane.cpp @CreateEx().

Есть ли у кого-нибудь помощь или идеи для меня?:(

поздравил,


Редактировать:
Хорошо, немного кода:
Я написал небольшой класс, унаследованный от CFrameWndEx (потому что его конструктор защищен):

class CMyFrame: public CFrameWndEx  
{  
    public:  
    DECLARE_MESSAGE_MAP()  
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);  
    CDockablePane m_DockWnd; // Will use an own class inherited from CDockablePane later on
};

Теперь я встроил этот класс в свой CDialog и изменил его размер на размер диалогов:

BOOL CMyDlg::OnInitDialog()  
{      
    CRect wndRect;  
    GetWindowRect(wndRect);    
    m_pFrame = new CMyFrame();  
    m_pFrame->Create(NULL, NULL, WS_CHILD | WS_VISIBLE | WS_BORDER, wndRect, this);  
    m_pFrame->MoveWindow(wndRect);

    CDialog::OnInitDialog();
    ...
}

В OnCreate() класса CMyFrame я установил CDockablePane и закрепил его:

int CMyFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
        return -1;

    CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

    EnableDocking(CBRS_ALIGN_ANY);
    // DT_SMART creates dummy dockable panes for previewing the possible position of  
    // the currently floating pane, this leads to a crash at call to GetTopLevelFrame()
    CDockingManager::SetDockingMode(DT_SMART);
    EnableAutoHidePanes(CBRS_ALIGN_ANY);

    // m_DockWnd is a CDockablePane
    if (!m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, IDC_DOCK_WND, 
        WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | CBRS_LEFT | CBRS_FLOAT_MULTI))
    {
    TRACE0("Failed to create Properties window\n");
    return 1; // failed to create
    }

    m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
    DockPane(&m_DockWnd);

    return 0;
}

2 ответа

Решение

Хорошо, я наконец-то понял.

Вместо того чтобы позволить MFC создать dummywnd, я создал его сам. Таким образом, MFC пропускает создание и вызов GetTopLevelFrame().

Теперь проблема была в том, что переменная-член dummywnd была защищена и не имела открытого метода set. Таким образом, я унаследовал класс и создал себе публичный метод set.

Другой простой способ - установить режим стыковки в DT_IMMEDIATE, если вы находитесь в Dlg, реализующем стыковочные рамки. Вызов CDockingManager::SetDockingMode(DT_IMMEDIATE);

в вашем объекте CFrameWndEx OnCreate (или где-то уместно).

Другие вопросы по тегам