我尝试在 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;
}