MFC 关于父对话框嵌入子对话框的方法可以参考这篇博客。这里不过多说明,其实也不难,都差不多。
一:一样,首先创建一个MFC对话框作为父对话框。在父对话框中加入一个picture控件,命名为 IDC_STATIC_RECT,作为要嵌入子对话框的位置。
二:创建两个子对话框,两个子对话框的 ID 分别为 IDD_CHILD1_DIALOG、IDD_CHILD2_DIALOG
三:在主父对话框的头文件添加变量
// CDlgParent.h
CRect Rect;
CDialog *m_SimpleConicDlg;//子对话框1
CDialog *m_ComplexConicDlg;//子对话框2
四:得到 picture 控件的坐标位置
// CDlgParent.cpp ——OnInitDialog()
//获取区域
GetDlgItem(IDC_STATIC_RECT)->GetWindowRect(&Rect);
ScreenToClient(&Rect);
五:
// CDlgParent.cpp ——OnInitDialog()
//创建非模态对话框
m_SimpleConicDlg = new CDialog();
m_ComplexConicDlg = new CDialog();
m_SimpleConicDlg->Create(IDD_CHILD1_DIALOG, this);
m_ComplexConicDlg->Create(IDD_CHILD2_DIALOG, this);
//将对话框移动到该区域并显示出来
m_SimpleConicDlg->MoveWindow(Rect.left, Rect.top, Rect.Width(), Rect.Height());
m_SimpleConicDlg->ShowWindow(SW_SHOW);
六:创建两个button按钮控件:
void CxxDlg::OnBnClickedButton1()
{
//方法一
m_SimpleConicDlg->ShowWindow(SW_HIDE);
m_ComplexConicDlg->MoveWindow(Rect.left, Rect.top, Rect.Width(), Rect.Height());
m_ComplexConicDlg->ShowWindow(SW_SHOW);
//方法二
//m_SimpleConicDlg.SetWindowPos(NULL, Rect.left, Rect.top, Rect.Width(), Rect.Height(), SWP_HIDEWINDOW);
//m_ComplexConicDlg.SetWindowPos(NULL, Rect.left, Rect.top, Rect.Width(), Rect.Height(), SWP_SHOWWINDOW);
}
void CxxDlg::OnBnClickedButton2()
{
m_ComplexConicDlg->ShowWindow(SW_HIDE);
m_SimpleConicDlg->MoveWindow(Rect.left, Rect.top, Rect.Width(), Rect.Height());
m_SimpleConicDlg->ShowWindow(SW_SHOW);
}
这里主要是利用了 ShowWindow 和 MoveWindow 这两个函数实现对话框的隐藏和显示。
ShowWindow
函数功能:该函数设置指定窗口的显示状态。
函数原型:BOOL ShowWindow(HWND hWnd, int nCmdShow);
hWnd:指窗口句柄。
nCmdShow:指定窗口如何显示。如果发送应用程序的程序提供了STARTUPINFO结构,则应用程序第一次调用ShowWindow时该参数被忽略。
否则,在第一次调用ShowWindow函数时,该值应为在函数WinMain中nCmdShow参数。在随后的调用中,该参数可以为下列值之一:
SW_FORCEMINIMIZE:在WindowNT5.0中最小化窗口,即使拥有窗口的线程被挂起也会最小化。在从其他线程最小化窗口时才使用这个参数。nCmdShow=11。
SW_HIDE:隐藏窗口并激活其他窗口。nCmdShow=0。
SW_MAXIMIZE:最大化指定的窗口。nCmdShow=3。
SW_MINIMIZE:最小化指定的窗口并且激活在Z序中的下一个顶层窗口。nCmdShow=6。
SW_RESTORE:激活并显示窗口。如果窗口最小化或最大化,则系统将窗口恢复到原来的尺寸和位置。在恢复最小化窗口时,应用程序应该指定这个标志。nCmdShow=9。
SW_SHOW:在窗口原来的位置以原来的尺寸激活和显示窗口。nCmdShow=5。
SW_SHOWDEFAULT:依据在STARTUPINFO结构中指定的SW_FLAG标志设定显示状态,STARTUPINFO 结构是由启动应用程序的程序传递给CreateProcess函数的。nCmdShow=10。
SW_SHOWMAXIMIZED:激活窗口并将其最大化。nCmdShow=3。
SW_SHOWMINIMIZED:激活窗口并将其最小化。nCmdShow=2。
SW_SHOWMINNOACTIVE:窗口最小化,激活窗口仍然维持激活状态。nCmdShow=7。
SW_SHOWNA:以窗口原来的状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=8。
SW_SHOWNOACTIVATE:以窗口最近一次的大小和状态显示窗口。激活窗口仍然维持激活状态。nCmdShow=4。
SW_SHOWNORMAL:激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。nCmdShow=1。
返回值:如果窗口之前可见,则返回值为非零。如果窗口之前被隐藏,则返回值为零。
MoveWindow
功能是改变指定窗口的位置和大小。对子窗口来说,位置和大小取决于父窗口客户区的左上角;对于Owned窗口,位置和大小取决于屏幕左上角。
函数原型:BOOL MoveWindow( HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint );
参数:
hWnd指定了窗口的句柄
x指定了CWnd的左边的新位置。
y指定了CWnd的顶部的新位置。
nWidth指定了CWnd的新宽度。
nHeight指定了CWnd的新高度。
bRepaint指定了是否要重画CWnd。如果为TRUE,则CWnd象通常那样在OnPaint消息处理函数中接收到一条WM_PAINT消息。如果这个参数为FALSE,则不会发生任何类型的重画操作。这应用于客户区、非客户区(包括标题条和滚动条)和由于CWnd移动而露出的父窗口的任何部分。当这个参数为FALSE的时候,应用程序必须明确地使CWnd和父窗口中必须重画的部分无效或重画。
在这里说明一个问题:按照我上面的创建出来的子窗口里面是无法响应函数的,接下来进行下面的修改就能使子窗口 “盘活”。
其实很简单!
一:给两个子对话框都创建一个类,我这里为CChildDialog1 和CChildDialog2。
二:父对话框的头文件包含两个子对话框的头文件,然后将之前的定义改成:
CRect Rect;
CDialog *m_pInnerDlg;
CChildDialog1 m_SimpleConicDlg;
CChildDialog2 m_ComplexConicDlg;
//CDialog *m_SimpleConicDlg; //子对话框1
//CDialog *m_ComplexConicDlg; //子对话框2
三:回到父窗口函数:
// CDlgParent.cpp ——OnInitDialog()
将这里注释掉。
//创建非模态对话框
//m_SimpleConicDlg = new CDialog(); //注释掉
//m_ComplexConicDlg = new CDialog();
m_SimpleConicDlg.Create(IDD_CHILD1_DIALOG, this);
m_ComplexConicDlg.Create(IDD_CHILD2_DIALOG, this);
然后将所有的 关于错误位置的 - > 改成 . 即可。
//将对话框移动到该区域并显示出来
m_SimpleConicDlg.MoveWindow(Rect.left, Rect.top, Rect.Width(), Rect.Height());
m_SimpleConicDlg.ShowWindow(SW_SHOW);
如何父对话框和子对话框(非模态对话框)之间互传参数?
原理:在子对话框里定义一个父对话框的指针,利用指针互相传参。
但这里会走入一个误区,如果在子对话框的。h文件中包含父对话框的头文件的话会报错:
未知重写说明符
这是因为父对话框的。h文件和子对话框的。h文件互相包含了。
这里正确的方法是,在子对话框的。cpp文件中添加父对话框的头文件。h,然后在函数中加入:
//CMFC_TabControlDlgDlg *parent = (CMFC_TabControlDlgDlg*)GetParent();
CMFC_TabControlDlgDlg *parent = (CMFC_TabControlDlgDlg*)this->GetParent();
//然后这里的parent指针就能和父窗口互相传递参数了 :parent-> 参数or函数;