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_TIMEenum { IDD = IDD_SWITCHCHILDRENDLG_DIALOG };
#endifprotected: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);}
}