【发布时间】:2018-06-19 10:01:08
【问题描述】:
我有很多CDialogEx 派生类在OnInitDialog 中执行类似的操作:
CMeetingScheduleAssistantApp::InitialiseResizeIcon(m_bmpResize, m_lblResize, this);
CMeetingScheduleAssistantApp::RestoreWindowPosition(_T("PublisherDB"), this, true);
然后,我在每个派生对话框类中添加了以下内容:
int CPublishersDatabaseDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
// Save Initial window size to m_rcInit
GetWindowRect(&m_rcInit);
return 0;
}
void CPublishersDatabaseDlg::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// Set the minimum window size to initial size.
lpMMI->ptMinTrackSize.x = m_rcInit.Width();
lpMMI->ptMinTrackSize.y = m_rcInit.Height();
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
void CPublishersDatabaseDlg::OnClose()
{
CMeetingScheduleAssistantApp::SaveWindowPosition(_T("PublisherDB"), this);
CDialogEx::OnClose();
}
每个对话框唯一不同的是用于保存窗口位置的短语。
我想要一个基于CDialogEx 的类,我可以从中继承它来执行上述操作。我看过 SO,似乎有一些问题,并创建了一个 CDialog 类并从另一个 CDialog 类继承。但是我想创建的这个类更通用。有效地用作基础而不是CDialogEx。
这可以吗?我是否过于复杂了?
问题
为什么我尝试创建一个新类,派生自CDialogEx:
我不知道是不是因为它需要一个 对话框 ID,如 here 所述。
CDialog、CFormView或CPropertyPage等类,需要对话框 ID。
所以我无法找到正确的方法来创建用于我所有其他对话框类的基本 CDialogEx 类。
更新
我创建了这段代码,它告诉我CResizingDialog 不是类或命名空间:
#include "ResizingDialog.h"
#include "resource.h"
#include "stdafx.h"
IMPLEMENT_DYNAMIC(CResizingDialog, CDialogEx)
CResizingDialog::CResizingDialog(const CString& strWindowID, UINT nIDTemplate, CWnd* pParent = nullptr)
: m_strWindowID(strWindowID), CDialogEx(nIDTemplate, pParent)
{
}
CResizingDialog::~CResizingDialog()
{
}
void CResizingDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CResizingDialog, CDialogEx)
ON_WM_CREATE()
ON_WM_GETMINMAXINFO()
ON_WM_CLOSE()
END_MESSAGE_MAP()
int CResizingDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
// Save Initial window size to m_rcInit
GetWindowRect(&m_rcInit);
return 0;
}
void CResizingDialog::OnGetMinMaxInfo(MINMAXINFO* lpMMI)
{
// Set the minimum window size to initial size.
lpMMI->ptMinTrackSize.x = m_rcInit.Width();
lpMMI->ptMinTrackSize.y = m_rcInit.Height();
CDialogEx::OnGetMinMaxInfo(lpMMI);
}
void CResizingDialog::OnClose()
{
SaveWindowPosition(m_strWindowID, this);
CDialogEx::OnClose();
}
【问题讨论】:
-
您想专门化您的对话框基类。 C++ 继承是该问题的标准解决方案。只需创建从
CDialogEx派生的对话框基类,提供与CDialogEx' 相同的参数的c'tor 加上您的字符串标识符。将const CString&成员添加到该基础,并从您的 c'tor 初始化列表中对其进行初始化,就像基础一样。本质上类似于CDialogBase::CDialogBase(const CString& phrase, UINT nIDTemplate, CWnd* pParent=NULL) : m_phrase(phrase), CDialogEx(nIDTemplate, pParent) {}。 -
只需从头开始创建您的
CDialogEx专业化,无需使用(经常损坏的)向导。无论如何,这对学习体验更好。 -
您需要在使用它的所有其他文件中
#include "ResizingDialog.h"! -
这就是预编译头文件的工作方式。
#include <stdafx.h>指令之前的所有内容都将被忽略,这就是您收到错误的原因,即符号不是类。如果您想防止此类错误,您可以使用/FI (Name Forced Include File) 编译器选项,而不再考虑您的预编译头文件。好吧,直到事情再次出错。 -
我不知道编译器选项的确切格式,但您可以使用 Visual Studio 的项目设置对话框(C/C++ -> 高级 -> 强制包含文件)来启用它(并检查命令行,以防您有兴趣)。我相信您可以启用每个项目以及每个编译单元的选项。无论如何,我几乎从不使用它。唯一的例外是当我必须编译无法修改但仍想继续使用预编译头文件的第 3 方代码时。
标签: c++ inheritance mfc cdialog