C ++ MFC功能包 - >在CDialog上创建多个CDockablePanes

时间:2011-02-03 20:13:05

标签: visual-c++ mfc mfc-feature-pack dockable panes

我尝试在CDialog上创建一个区域,在那里我可以放入一些CDockablePanes。这些区域可以完美地停靠在固定的对话框内容中。

Codejock Dialog Panes Sample正是我想要的,但是通过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();
    ...
}

在CMyFrame类的OnCreate()中,我设置了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 个答案:

答案 0 :(得分:2)

好的,我终于明白了。

我没有让MFC创建虚拟符号,而是由我自己创建。因此,MFC会跳过创建和调用GetTopLevelFrame()。

现在的问题是,dummywnd成员变量受到保护并且没有公共set方法。所以我继承了一个类,并为自己建立了一个公共集合方法。

答案 1 :(得分:0)

另一种简单的方法是,如果您在实现停靠帧的Dlg中,则将停靠模式设置为DT_IMMEDIATE。呼叫     CDockingManager :: SetDockingMode(DT_IMMEDIATE);

在您的CFrameWndEx对象的OnCreate(或适当的地方)。