有时候,多个对话框有许多共同的控件并执行的操作类似。这里可以提取这些共同控件,生成一个基础对话框以及对应的基础类。后面其他的对话框都可以从这个基础对话框继承控件以及对控件的操作,从而实现代码复用。一下为操作流程示例。
新建的一个基于对话框的工程。到底是基于对话框还是view不重要。这里使用对话框仅仅给操作提供一个展示平台。
在对话框上添加两个按钮 并添加其响应函数,用于后面的测试。
运行时的界面如下:
设计基础类
设计自己的对话框,该对话框就是上文提到的具有共同控件并将作为父类被继承的对话框。
这里设计如下
输入框ID为 IDC_EDIT_NUMA 和 IDC_EDIT_NUMB
绑定的整形变量为m_numberA 和 m_numberB
测试按钮 ID IDC_BUTTEN_DO 响应函数为OnClickedButtonDo()
建立Base对话框的类CMyBase
为了让子类可以完成具体的具有差异的功能,
在CMyBase中定义一个虚函数。由虚函数的性质知道,如果子类中也定了该函数,父类中的方法调用的函数应该是子类中的函数。
这里定义一个void DoWhat()如图
DoWhat()显示一个消息框作为测试
void CMyBase::DoWhat(void)
{
MessageBox(_TEXT("Base"));
}
在按钮start的响应函数中,简单的调用一下虚函数 作为测试。
void CMyBase::OnClickedButtonDo()
{
// TODO: 在此添加控件通知处理程序代码
DoWhat();
}
在按钮测试1和 测试2的响应函数中显示一下上面的BASE对话框
void CMyDialogTestDlg::OnClickedButtonAdd()
{
// TODO: 在此添加控件通知处理程序代码
CMyBase dlg;
dlg.DoModal();
}
void CMyDialogTestDlg::OnClickedButtonProg()
{
// TODO: 在此添加控件通知处理程序代码
CMyBase dlg;
dlg.DoModal();
}
注意需要包含CMyBase类的头文件。
完成以上工作后运行显示如下
源码
改造:
首先 修改CMyBase类 使其可以作为父对话框被继承
修改如下内容
在CMyBase的头文件中作如下修改
1. 修改CMyBase类的构造函数CMyBase(CWnd* pParent = NULL); // 标准构造函数
为 CMyBase(UINT nIDTemplate, CWnd *pParent = NULL);
2.注释掉enum { IDD = IDD_DIALOG_BASE };
因为该类要作为父类了 现在不应该和任何对话框绑定起来
在CMyBase的CPP文件中我们只需修改CMyBase的构造函数
其实仅修改一下函数头,然后把CDialogEx的CMyBase::IDD用nIDTemplate代替
CMyBase::CMyBase(CWnd* pParent /*=NULL*/) : CDialogEx(CMyBase::IDD, pParent) { m_dNumberA = 0; m_dNumberB = 0; }
CMyBase::CMyBase(UINT nIDTemplate, CWnd *pParent) : CDialogEx(nIDTemplate, pParent) { m_dNumberA = 0; m_dNumberB = 0; }
基类改造完成
继承:
新建对一个话框 并且添加它的类 文中添加的是CChildOne, 文中将改造CChildOne使其重CMyBase继承
IDE会为我们生成ChildOne.h
#pragma once // CChildOne 对话框 class CChildOne : public CDialogEx { DECLARE_DYNAMIC(CChildOne) public: CChildOne(CWnd* pParent = NULL); // 标准构造函数 virtual ~CChildOne(); // 对话框数据 enum { IDD = IDD_DIALOG_ADD }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP() };
和ChildOne.cpp
// ChildOne.cpp : 实现文件 // #include "stdafx.h" #include "MyDialogTest.h" #include "ChildOne.h" #include "afxdialogex.h" // CChildOne 对话框 IMPLEMENT_DYNAMIC(CChildOne, CDialogEx) CChildOne::CChildOne(CWnd* pParent /*=NULL*/) : CDialogEx(CChildOne::IDD, pParent) { } CChildOne::~CChildOne() { } void CChildOne::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CChildOne, CDialogEx) END_MESSAGE_MAP() // CChildOne 消息处理程序
改造CChildOne使其从父类CMyBase继承
现在只要把CChildOne从CDialogEx继承改为从CMyBase继承。
1.在ChildOne.h中添加对父类头文件的引用(#include "MyBase.h")
2.用CMyBase替换CChildOne类中所有的CDialogEx出现
在ChildOne.cpp中一样 用CMyBase替换所有的CDialogEx
类改造完成
改造对话框
把之前CMyBase对应的IDD_DIALOG_BASE对话框复制到ChildOne对应的IDD_DIALOG_ADD对话框
复制CMyBase对应的IDD_DIALOG_BASE对话框
删除ChildOne对应的IDD_DIALOG_ADD对话框
修改 “复制CMyBase对应的IDD_DIALOG_BASE对话框”id为IDD_DIALOG_ADD
操作完成。
现在做一下测试
修改
void CMyDialogTestDlg::OnClickedButtonAdd() { // TODO: 在此添加控件通知处理程序代码 //CMyBase dlg; CChildOne dlg; dlg.DoModal(); } void CMyDialogTestDlg::OnClickedButtonProg() { // TODO: 在此添加控件通知处理程序代码 //CMyBase dlg; CChildOne dlg; dlg.DoModal(); }
最后一步
继承CMyBase的虚函数DoWhat完成子类的具体功能
这里,仅简单的取得出入筐的值 求和 输出
在void CChildOne::DoWhat(void) { UpdateData(TRUE); int sum = m_dNumberA + m_dNumberB; CString msg; msg.Format(_TEXT("%d+%d = %d"),m_dNumberA, m_dNumberB, sum); MessageBox(msg); }
到这里,从自定义类继承对话框的步骤完成。
下面是另一个从CMyDialog继承的对话框,在对话框中 添加了一个进度条的控件。
源码