【问题标题】:C++ MFC Feature Pack --> Create multiple CDockablePanes onto an CDialogC++ MFC Feature Pack --> 在 CDialog 上创建多个 CDockablePanes
【发布时间】:2011-06-20 22:36:05
【问题描述】:

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

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

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

这是因为可停靠窗格类尝试生成一个虚拟窗格来预览真实窗格的位置。它调用返回 NULL 的 GetTopLevelFrame()。这会在 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;
}

【问题讨论】:

  • 你应该发布一些代码来帮助描述你在做什么......你在使用停靠窗格管理器吗?另请注意,清理 CDockablePane 需要一些额外的钩子以避免内存泄漏。
  • 好的,我添加了一些代码。
  • DockablePanes 并非设计用于 CDialog。

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


【解决方案1】:

好的,我终于明白了。

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

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

【讨论】:

    【解决方案2】:

    另一个简单的方法是,如果你在一个实现对接框架的 Dlg 中,将你的对接模式设置为 DT_IMMEDIATE。称呼 CDockingManager::SetDockingMode(DT_IMMEDIATE);

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-06
      • 2010-09-09
      • 2011-03-02
      • 2020-11-20
      • 2011-03-20
      • 2014-03-14
      • 1970-01-01
      • 2010-09-13
      相关资源
      最近更新 更多