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

我尝试在 CDialog 上创建一个区域,我可以在其中放置一些 CDockablePanes.这些应该可以完美地停靠到固定的对话框内容.

I try to create an area onto a CDialog, where I can put some CDockablePanes in. Those shall be perfectly dockable to a fixed dialog content.

Codejock 对话框窗格示例正是我想要的,但通过 MFC 功能包类实现:http://codejock.com/downloads/samples/dockingpane.asp

The Codejock Dialog Panes Sample is exactly what I want, but realized with the MFC feature pack classes: http://codejock.com/downloads/samples/dockingpane.asp

目前我有一个继承自 CFrameWndEx 的类,它嵌入在 CDialog 中.我还有一个工作 CDockablePane 在里面.我可以取消停靠并移动它,但是当我想停靠它时,程序会崩溃.

At the moment I got a class inherited from CFrameWndEx, which is embedded in the CDialog. I also got a working CDockablePane in it. I can undock it and move it, but when I want to dock it the program crashes.

这是因为可停靠窗格类尝试生成一个虚拟窗格来预览真实窗格的位置.它调用返回 NULL 的 GetTopLevelFrame().这会在 afxpane.cpp @CreateEx() 中产生崩溃.

This is because the dockable pane class tries to generate a dummy pane for previewing where the real pane would go. It calls GetTopLevelFrame() which returns NULL. This produces the crash in afxpane.cpp @CreateEx().

有人对我有什么帮助或想法吗?:(

Does someone has any help or ideas for me? :(

你好,


好的,一些代码:
我写了一个继承自 CFrameWndEx 的小类(因为它的构造函数是受保护的):


Okay, some code:
I wrote a little class inherited from CFrameWndEx (because its constructor is protected):

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 中,并将其大小更改为对话框大小:

Now I embedded this class in my CDialog and change its size to the dialogs size:

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 并将其停靠:

In the OnCreate() of the CMyFrame class I set up the CDockablePane and dock it:

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
");
    return 1; // failed to create
    }

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

    return 0;
}

推荐答案

好吧,我终于明白了.

我没有让 MFC 创建 dummywnd,而是自己创建了它.所以 MFC 跳过了创建和调用 GetTopLevelFrame().

Instead of letting the MFC create the dummywnd, I created it by myself. So the MFC skips the creation and the call to GetTopLevelFrame().

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

Now the problem was, that the dummywnd member variable was protected and had no public set method. So I inherited a class and built myself a public set method.

相关文章