窗口的继承,子类窗口可以拥有父类窗口的一些属性、风格和方法等,将极大的简化代码量,本例将完成一个mfc窗口继承的实例:
1.新建一个基于对话框的dialog,作为父类窗口,本例名称TemplateDlg
TemplateDlg.h:
-
// TemplateDlg.h : 头文件
-
//
-
-
#pragma once
-
-
// CTemplateDlg 对话框
-
class CTemplateDlg :
public CDialog
-
{
-
// 构造
-
public:
-
//CTemplateDlg(CWnd* pParent = NULL); // 标准构造函数
-
CTemplateDlg(UINT nIDTemplate,CWnd* pParent =
NULL);
-
//enum { IDD = IDD_TEMPLATE_DIALOG };
-
-
protected:
-
virtual void DoDataExchange(CDataExchange* pDX);
// DDX/DDV 支持
-
// 生成的消息映射函数
-
DECLARE_MESSAGE_MAP()
-
public:
-
//afx_msg void OnPaint(); //原版OnPaint
-
virtual afx_msg void OnPaint();
//virtual虚方法,留待method dialog重写
-
void HelloWorld();
-
-
};
TemplateDlg.cpp:
-
// TemplateDlg.cpp : 实现文件
-
//
-
-
#include "stdafx.h"
-
#include "Template.h"
-
#include "TemplateDlg.h"
-
-
#ifdef _DEBUG
-
#define new DEBUG_NEW
-
#endif
-
-
// CTemplateDlg 对话框
-
-
/*
-
标准构造函数
-
IDD_TEMPLATE_DIALOG:template dialog的控件资源id
-
*/
-
//CTemplateDlg::CTemplateDlg(CWnd* pParent /*=NULL*/)
-
// : CDialog(IDD_TEMPLATE_DIALOG,pParent)
-
//{
-
//
-
//}
-
/*
-
方便继承的构造函数
-
nIDTemplate:子窗口的控件资源id
-
*/
-
CTemplateDlg::CTemplateDlg(UINT nIDTemplate,CWnd* pParent
/*=NULL*/)
-
: CDialog(nIDTemplate,pParent)
-
{
-
-
}
-
-
void CTemplateDlg::DoDataExchange(CDataExchange* pDX)
-
{
-
CDialog::DoDataExchange(pDX);
-
}
-
-
BEGIN_MESSAGE_MAP(CTemplateDlg, CDialog)
-
//}}AFX_MSG_MAP
-
ON_WM_PAINT()
-
END_MESSAGE_MAP()
-
-
-
// CTemplateDlg 消息处理程序
-
-
void CTemplateDlg::OnPaint()
-
{
-
CRect rect;
-
CPaintDC dc(this);
-
GetClientRect(rect);
-
dc.FillSolidRect(rect,RGB(
0,
255,
0));
//设置为绿色背景
-
CDialog::OnPaint();
-
}
-
-
void CTemplateDlg::HelloWorld()
-
{
-
AfxMessageBox(
L"Hello world!");
-
}
2.新建一个基于TemplateDlg的对话框,名称MethodDlg:
MethodDlg.h:
-
#pragma once
-
#include "TemplateDlg.h" //引用模板窗口
-
-
// CMethodDlg 对话框
-
-
//class CMethodDlg : public CDialog
-
class CMethodDlg :
public CTemplateDlg
//继承template
-
{
-
DECLARE_DYNAMIC(CMethodDlg)
-
-
public:
-
CMethodDlg(CWnd* pParent =
NULL);
// 标准构造函数
-
-
// 对话框数据
-
enum { IDD = IDD_METHODDLG };
-
-
protected:
-
virtual void DoDataExchange(CDataExchange* pDX);
// DDX/DDV 支持
-
-
DECLARE_MESSAGE_MAP()
-
-
public:
-
//没有在method dialog的消息映射中出现,但是可以重写template dialog的消息处理
-
afx_msg void OnPaint();
-
-
//添加一个属于method dialog自己的消息处理
-
afx_msg void OnBnClickedButton1();
-
};
MethodDlg.cpp:
-
// MethodDlg.cpp : 实现文件
-
//
-
-
#include "stdafx.h"
-
#include "Template.h"
-
#include "MethodDlg.h"
-
-
-
// CMethodDlg 对话框
-
-
IMPLEMENT_DYNAMIC(
CMethodDlg, CDialog)
-
-
//: CDialog(CMethodDlg::IDD, pParent)
-
CMethodDlg::
CMethodDlg(CWnd* pParent
/*=NULL*/)
-
:
CTemplateDlg(
CMethodDlg::IDD,pParent)
//继承template
-
{
-
-
}
-
-
void
CMethodDlg::DoDataExchange(CDataExchange* pDX)
-
{
-
//CDialog::DoDataExchange(pDX); //原继承CDialog
-
CTemplateDlg::DoDataExchange(pDX);
//继承template
-
}
-
-
//BEGIN_MESSAGE_MAP(CMethodDlg, CDialog) //原只处理method自己的消息映射
-
BEGIN_MESSAGE_MAP(
CMethodDlg,
CTemplateDlg)
//继承template dialog的所有消息映射
-
ON_BN_CLICKED(IDC_BUTTON1, &
CMethodDlg::OnBnClickedButton1)
//method dialog自己的消息映射处理
-
END_MESSAGE_MAP()
-
-
// CMethodDlg 消息处理程序
-
void
CMethodDlg::OnPaint()
-
{
-
CRect rect;
-
CPaintDC dc(
this);
-
GetClientRect(rect);
-
dc.FillSolidRect(rect,RGB(
0,
0,
255));
//设置为蓝色背景
-
CDialog::OnPaint();
-
}
-
-
void
CMethodDlg::OnBnClickedButton1()
-
{
-
//调用父窗口中的方法
-
CTemplateDlg::HelloWorld();
//this->HelloWorld();
-
}
3.修改一下Template.cpp(本例项目名Template)
修改为启动我们的子类窗口MethodDlg:
-
BOOL
CTemplateApp::InitInstance()
-
{
-
// 如果一个运行在 Windows XP 上的应用程序清单指定要
-
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
-
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
-
INITCOMMONCONTROLSEX InitCtrls;
-
InitCtrls.dwSize =
sizeof(InitCtrls);
-
// 将它设置为包括所有要在应用程序中使用的
-
// 公共控件类。
-
InitCtrls.dwICC = ICC_WIN95_CLASSES;
-
InitCommonControlsEx(&InitCtrls);
-
-
CWinApp::InitInstance();
-
-
AfxEnableControlContainer();
-
-
// 标准初始化
-
// 如果未使用这些功能并希望减小
-
// 最终可执行文件的大小,则应移除下列
-
// 不需要的特定初始化例程
-
// 更改用于存储设置的注册表项
-
// TODO: 应适当修改该字符串,
-
// 例如修改为公司或组织名
-
SetRegistryKey(_T(
"应用程序向导生成的本地应用程序"));
-
-
//CTemplateDlg dlg;
-
CMethodDlg dlg;
//启动method dialog
-
m_pMainWnd = &dlg;
-
INT_PTR nResponse = dlg.DoModal();
-
if (nResponse == IDOK)
-
{
-
// TODO: 在此放置处理何时用
-
// “确定”来关闭对话框的代码
-
}
-
else
if (nResponse == IDCANCEL)
-
{
-
// TODO: 在此放置处理何时用
-
// “取消”来关闭对话框的代码
-
}
-
-
// 由于对话框已关闭,所以将返回 FALSE 以便退出应用程序,
-
// 而不是启动应用程序的消息泵。
-
return
FALSE;
-
}
4.编译运行,效果如下:
本例启动的是子类窗口MethodDlg,但是他具有父类窗口TemplateDlg的风格(蓝色底色,无控件),因为加载自己的控件资源,所有显示了属于自己的控件(Button1),点击Button1,调用了属于父类窗口的方法。