1、效果
在Qt中可使用QStackedWidget控件直接拖动布置即可实现,但在MFC中并未提供类似的控件,因此需要自己简单实现。
2、实现原理
实现原理比较简单,父级对话框在显示的区域部分,通过切换子对话框即可实现。子对话框去掉边框后移动到父级对话框的显示区域即可。需要注意的是子对话框需要用非模态方式创建,同时记得在父级对话框销毁指针。
3、源码
// SwitchChildrenDlgDlg.h: 头文件
#pragma once
#include "CChild1Dlg.h"
#include "CChild2Dlg.h"
// CSwitchChildrenDlgDlg 对话框
class CSwitchChildrenDlg : public CDialogEx
{
// 构造
public:
CSwitchChildrenDlg(CWnd* pParent = nullptr); // 标准构造函数
virtual ~CSwitchChildrenDlg();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_SWITCHCHILDRENDLG_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
//afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnBnClickedOk();
afx_msg void OnBnClickedCancel();
afx_msg void OnCbnSelchangeComboType();
private:
CChild1Dlg* m_Child1Dlg;
CChild2Dlg* m_Child2Dlg;
CComboBox m_cmbType;
};
CSwitchChildrenDlg::CSwitchChildrenDlg(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_SWITCHCHILDRENDLG_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
CSwitchChildrenDlg::~CSwitchChildrenDlg()
{
if (m_Child1Dlg)
{
delete m_Child1Dlg;
m_Child1Dlg = nullptr;
}
if (m_Child2Dlg)
{
delete m_Child2Dlg;
m_Child2Dlg = nullptr;
}
}
BOOL CSwitchChildrenDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != nullptr)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
if (!m_Child1Dlg)
{
m_Child1Dlg = new CChild1Dlg(this);
m_Child1Dlg->Create(IDD_CHILD1_DLG, this);
}
if (!m_Child2Dlg)
{
m_Child2Dlg = new CChild2Dlg(this);
m_Child2Dlg->Create(IDD_CHILD2_DLG, this);
}
m_cmbType.AddString(_T("地域"));
m_cmbType.AddString(_T("范围"));
m_cmbType.SetCurSel(0);
OnCbnSelchangeComboType();
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CSwitchChildrenDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
if (m_cmbType.GetCurSel() == 0)
{
m_Child1Dlg->OnBnClickedOk();
}
else if (m_cmbType.GetCurSel() == 1)
{
m_Child2Dlg->OnBnClickedOk();
}
CDialogEx::OnOK();
}
void CSwitchChildrenDlg::OnCbnSelchangeComboType()
{
// TODO: 在此添加控件通知处理程序代码
CRect cltrect;
GetClientRect(cltrect);//获取当前主对话框的坐标
if (m_cmbType.GetCurSel() == 0)
{
m_Child1Dlg->ShowWindow(SW_SHOW);
m_Child2Dlg->ShowWindow(SW_HIDE);
//设置动态对话框的位置
m_Child1Dlg->SetWindowPos(&wndTop, cltrect.left + 10, cltrect.top + 30, cltrect.Width(), cltrect.Height() - 100, SWP_NOACTIVATE);
}
else if (m_cmbType.GetCurSel() == 1)
{
if (!m_Child2Dlg)
{
m_Child2Dlg = new CChild2Dlg(this);
m_Child2Dlg->Create(IDD_CHILD2_DLG, this);
}
m_Child2Dlg->ShowWindow(SW_SHOW);
m_Child1Dlg->ShowWindow(SW_HIDE);
//设置动态对话框的位置
m_Child2Dlg->SetWindowPos(&wndTop, cltrect.left + 10, cltrect.top + 30, cltrect.Width(), cltrect.Height() - 100, SWP_NOACTIVATE);
}
}