2011-02-03 3 views
0

Я пытаюсь создать область на CDialog, где я могу поместить некоторые CDockablePanes. Они должны быть идеально закреплены за фиксированным диалоговым контентом.C++ MFC Feature Pack -> Создать несколько CDockablePanes на CDialog

Выборка Codejock Диалог Panes именно то, что я хочу, но понял, что с классами MFC Feature Pack: http://codejock.com/downloads/samples/dockingpane.asp

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

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

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

здоровается,


Edit:
Хорошо, некоторый код:
я написал небольшой класс, унаследованный от 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; 
} 
+0

Вы должны опубликовать код, который поможет описать, что вы делаете ... используете ли вы диспетчер панели управления? Также обратите внимание, что очистка CDockablePane требует дополнительных крючков, чтобы избежать утечек памяти. – AJG85

+0

Хорошо, я добавил код. – slaindevil

+1

DockablePanes не предназначены для использования на CDialog. – sergiol

ответ

2

Хорошо, я, наконец, получил его.

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

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

0

Еще один простой способ - установить режим стыковки в DT_IMMEDIATE, если вы используете DLC-фреймы. Вызов CDockingManager :: SetDockingMode (DT_IMMEDIATE);

В вашем окне объекта CFrameWndEx OnCreate (или в каком-то подходящем месте).