Mfc 在CDDialog上创建多个CDockablePane
我试图做到与本文描述的完全相同: “” 我按照他的程序进行操作,现在可以卸下并移动CDockablePane,但当它重新停靠时,会发生同样的崩溃。在他自己的回答中,他说他自己创建了dummywnd,所以MFC跳过了创建和对GetToLevel Frame()的调用。这就是我困惑的地方,我该如何准确地创建dummywnd 我的第二个问题是如何在CMyFrame和CDialog之间交换数据 问了这个问题并回答了这个问题的人似乎多年来都不活跃,无法联系到他。谁能帮忙或有什么想法吗 谢谢Mfc 在CDDialog上创建多个CDockablePane,mfc,cdialog,dockable,Mfc,Cdialog,Dockable,我试图做到与本文描述的完全相同: “” 我按照他的程序进行操作,现在可以卸下并移动CDockablePane,但当它重新停靠时,会发生同样的崩溃。在他自己的回答中,他说他自己创建了dummywnd,所以MFC跳过了创建和对GetToLevel Frame()的调用。这就是我困惑的地方,我该如何准确地创建dummywnd 我的第二个问题是如何在CMyFrame和CDialog之间交换数据 问了这个问题并回答了这个问题的人似乎多年来都不活跃,无法联系到他。谁能帮忙或有什么想法吗 谢谢 编辑: 我破
编辑: 我破坏了程序,完全按照另一位作者的描述进行了追溯。上面提到的虚拟窗口实际上位于afxdragframeinpl.cpp中:
void cmfcdragframeinpl::MoveDragFrame(BOOL bForceMove)
它在何处创建:
m_pWndDummy=新的CDummyDockablePane代码>
并呼吁:
m_pWndDummy->CreateEx(0,_T(“”),afxGetToLevel框架(m_pDraggedWnd),正确(0,0,0,0),FALSE,AFX_DUMMY_WND_ID,WS_CHILD)代码>
是的,我试图在对话框中创建一个CFrameWndEx作为子窗口,然后在该CFrameWndEx中添加子CDockablePane
基本上,我有一个带有一些控件的MFC对话框a,在这个对话框a中,我需要一些撕下的tabsXYZ,我需要在每个撕下的tabsXYZ中添加一些控件。这意味着每个撕掉的tabsXYZ实际上是一个子dialogB。因此,我尝试在dialogA中使用CDockablePanes(实际上是CPanedDialog)
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();
...
}
我不推荐在对话框中放置框架窗口的上面的代码,因为CFrameWndEx
会做各种奇怪的事情,很容易破坏这段代码。令人惊讶的是,它在VS2015上运行良好,我无法复制任何崩溃。但窗户的行为仍然很奇怪
最好创建一个新的框架窗口,并在框架中放置一个子对话框。例如:
class CMyFrame : public CFrameWndEx
{
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
m_dialog.Create(IDD_CHILD1, this);
CRect rc;
m_dialog.GetClientRect(&rc);
m_dialog.SetWindowPos(NULL, 0, 0, rc.right, rc.bottom, SWP_SHOWWINDOW);
return 1;
}
DECLARE_MESSAGE_MAP()
};
class CMyFrame : public CFrameWndEx
{
CDockablePane m_DockWnd;
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
CDockingManager::SetDockingMode(DT_SMART);
EnableAutoHidePanes(CBRS_ALIGN_ANY);
m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, 0,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
CBRS_LEFT | CBRS_FLOAT_MULTI);
m_dialog.Create(IDD_PAGE1, &m_DockWnd);
CRect rdialog;
m_dialog.GetClientRect(&rdialog);
m_dialog.SetWindowPos(NULL, 0, 0, rdialog.Width(), rdialog.Height(), SWP_SHOWWINDOW);
m_DockWnd.SetMinSize(rdialog.Size());
m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_DockWnd);
return 0;
}
...
};
您可以按如下方式打开窗口:
void CMyMainFrame::OnButton()
{
CMyFrame *frame = new CMyFrame;
frame->LoadFrame(IDR_MAINFRAME,
WS_POPUPWINDOW | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU, this);
frame->SetMenu(0);
frame->ShowWindow(SW_SHOW);
}
您还可以创建一个子对话框并将其放入停靠窗格中。例如:
class CMyFrame : public CFrameWndEx
{
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
m_dialog.Create(IDD_CHILD1, this);
CRect rc;
m_dialog.GetClientRect(&rc);
m_dialog.SetWindowPos(NULL, 0, 0, rc.right, rc.bottom, SWP_SHOWWINDOW);
return 1;
}
DECLARE_MESSAGE_MAP()
};
class CMyFrame : public CFrameWndEx
{
CDockablePane m_DockWnd;
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
CDockingManager::SetDockingMode(DT_SMART);
EnableAutoHidePanes(CBRS_ALIGN_ANY);
m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, 0,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
CBRS_LEFT | CBRS_FLOAT_MULTI);
m_dialog.Create(IDD_PAGE1, &m_DockWnd);
CRect rdialog;
m_dialog.GetClientRect(&rdialog);
m_dialog.SetWindowPos(NULL, 0, 0, rdialog.Width(), rdialog.Height(), SWP_SHOWWINDOW);
m_DockWnd.SetMinSize(rdialog.Size());
m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_DockWnd);
return 0;
}
...
};
还要记住,如果主窗口也是CFrameWndEx
,则在InitInstance
中进行如下调用:
SetRegistryKey(_T("MyCompany\\MyApp"));
SetRegistryBase(_T("MainFrame"));
打开新的框架窗口时,必须使用
SetRegistryBase(_T("CMyFrame"));
然后在退出CMyFrame
我不推荐在对话框中放置框架窗口的上面的代码,因为CFrameWndEx
会做各种奇怪的事情,很容易破坏这段代码。令人惊讶的是,它在VS2015上运行良好,我无法复制任何崩溃。但窗户的行为仍然很奇怪
最好创建一个新的框架窗口,并在框架中放置一个子对话框。例如:
class CMyFrame : public CFrameWndEx
{
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
m_dialog.Create(IDD_CHILD1, this);
CRect rc;
m_dialog.GetClientRect(&rc);
m_dialog.SetWindowPos(NULL, 0, 0, rc.right, rc.bottom, SWP_SHOWWINDOW);
return 1;
}
DECLARE_MESSAGE_MAP()
};
class CMyFrame : public CFrameWndEx
{
CDockablePane m_DockWnd;
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
CDockingManager::SetDockingMode(DT_SMART);
EnableAutoHidePanes(CBRS_ALIGN_ANY);
m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, 0,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
CBRS_LEFT | CBRS_FLOAT_MULTI);
m_dialog.Create(IDD_PAGE1, &m_DockWnd);
CRect rdialog;
m_dialog.GetClientRect(&rdialog);
m_dialog.SetWindowPos(NULL, 0, 0, rdialog.Width(), rdialog.Height(), SWP_SHOWWINDOW);
m_DockWnd.SetMinSize(rdialog.Size());
m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_DockWnd);
return 0;
}
...
};
您可以按如下方式打开窗口:
void CMyMainFrame::OnButton()
{
CMyFrame *frame = new CMyFrame;
frame->LoadFrame(IDR_MAINFRAME,
WS_POPUPWINDOW | WS_THICKFRAME | WS_CAPTION | WS_SYSMENU, this);
frame->SetMenu(0);
frame->ShowWindow(SW_SHOW);
}
您还可以创建一个子对话框并将其放入停靠窗格中。例如:
class CMyFrame : public CFrameWndEx
{
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
m_dialog.Create(IDD_CHILD1, this);
CRect rc;
m_dialog.GetClientRect(&rc);
m_dialog.SetWindowPos(NULL, 0, 0, rc.right, rc.bottom, SWP_SHOWWINDOW);
return 1;
}
DECLARE_MESSAGE_MAP()
};
class CMyFrame : public CFrameWndEx
{
CDockablePane m_DockWnd;
CDialog m_dialog;
int OnCreate(LPCREATESTRUCT lpCreateStruct)
{
CFrameWndEx::OnCreate(lpCreateStruct);
CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
CDockingManager::SetDockingMode(DT_SMART);
EnableAutoHidePanes(CBRS_ALIGN_ANY);
m_DockWnd.Create(_T("Test"), this, CRect(0, 0, 200, 200), TRUE, 0,
WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
CBRS_LEFT | CBRS_FLOAT_MULTI);
m_dialog.Create(IDD_PAGE1, &m_DockWnd);
CRect rdialog;
m_dialog.GetClientRect(&rdialog);
m_dialog.SetWindowPos(NULL, 0, 0, rdialog.Width(), rdialog.Height(), SWP_SHOWWINDOW);
m_DockWnd.SetMinSize(rdialog.Size());
m_DockWnd.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockPane(&m_DockWnd);
return 0;
}
...
};
还要记住,如果主窗口也是CFrameWndEx
,则在InitInstance
中进行如下调用:
SetRegistryKey(_T("MyCompany\\MyApp"));
SetRegistryBase(_T("MainFrame"));
打开新的框架窗口时,必须使用
SetRegistryBase(_T("CMyFrame"));
然后在退出CMyFrame
时将其更改回SetRegistryBase(\u T(“大型机”)
,我对此没有太多经验,但您发布的链接看起来像是黑客。那里没有“虚拟窗口”。它似乎创建了一个CFrameWndEx
作为对话框的子窗口。我认为那不可取。您有基于对话框的应用程序吗?如果是,您是否正在尝试将窗格添加到主对话框中?注意,您只需创建一个CFrameWndEx
并将子对话框添加到其中,或者将子对话框添加到可文档窗格中。您可以跳过文档/视图部分。感谢您的回复。这不是黑客,我已经改变了链接的显示方式。并在“编辑”部分的顶部添加了更多详细信息。关于如何在对话框中使用儿童可拆卸/可固定对话框,您有什么建议吗?最好,你没有回答我的问题。没有理由将框架窗口创建为对话框的子窗口,没有任何好处CFrameWndEx
可以做任何事情CDialog
can等等。可以将子对话框添加到框架窗口。另一个链接中提到的方法对初学者来说可能更方便,但它需要可怕的黑客攻击,这会导致更多的问题。我有一个相对较大且复杂的应用程序,它基于CMDIFrameWnd。我正在处理的部分是CDialogEx(比如dialogA),我只能从与该dialogA关联的类中获取所需的数据。我需要在dialogA中创建子dialogXYZ来修改一些属性。我本可以使用一个选项卡控件,每个选项卡对应对话框X、Y和Z中的一个。但同时,我需要对话框X、Y和Z同时出现在屏幕上,所以我试图找到一个“撕下选项卡”的解决方案。我没有得到任何关于“撕下CDialogEx中的标签”的参考资料,所以它让我达到了现在的水平。我对此没有太多经验,但你发布的链接看起来像是黑客。那里没有“虚拟窗口”。它似乎创建了一个CFrameWndEx
作为对话框的子窗口。我认为那不可取。您有基于对话框的应用程序吗?如果是,您是否正在尝试将窗格添加到主对话框中?注意,您只需创建一个CFrameWndEx
并将子对话框添加到其中,或者将子对话框添加到可文档窗格中。您可以跳过文档/视图部分。感谢您的回复。这不是黑客,我已经改变了链接的显示方式。并在“编辑”部分的顶部添加了更多详细信息。关于如何在对话框中使用儿童可拆卸/可固定对话框,您有什么建议吗?最好,你没有回答我的问题。没有理由将框架窗口创建为对话框的子窗口,没有任何好处CFrameWndEx
可以做任何事情CDialog
c