如何在MFC中正确继承对话框

时间:2016-07-18 15:36:47

标签: c++ opengl mfc

我正在使用OpenGL和MFC在C ++中构建一个3d画家。 我创建了用于创建我拥有的每个形状的对话框:如立方体,圆柱等...... 我的立方体类继承了圆柱类,只有堆栈和切片的数量不同。 因此,CreateCylinder对话框应与CreateCube对话框相同。 我能够很好地继承它,但我有一个错误说:

Error   6   error C2065: 'IDD_BASEWIN_DIALOG' : undeclared identifier   c:\users\l122\desktop\opengl\opengl\basewindlg.h    19  1   OpenGL

在一些次要代码更改后,每次新编译都会发生这种情况。

要解决此问题,我会对此行发表评论:

enum { IDD = IDD_BASEWIN_DIALOG };

然后编译并取消注释相同的行,这有助于下一次编译工作正常。

我在CreateCube对话框类中继承了CreateCylinder对话框的方式:

IMPLEMENT_DYNAMIC(CreateCube, CreateCylinder)

CreateCube::CreateCube()
: CreateCylinder(this->GetSafeOwner())
{

}

CreateCube::~CreateCube()
{
}


void CreateCube::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    CreateCylinder::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CreateCube, CreateCylinder)
END_MESSAGE_MAP()

我还在CreateCylinder构造函数中编辑了这一行:

CreateCylinder::CreateCylinder(CWnd* pParent /*=NULL*/)
: CDialogEx(CreateCylinder::IDD, this->GetSafeOwner())

标题文件:

#pragma once
#include "CreateCylinder.h"

// CreateCube dialog

class CreateCube : public CreateCylinder
{
    DECLARE_DYNAMIC(CreateCube)

public:
    CreateCube();   // standard constructor
    virtual ~CreateCube();

// Dialog Data
    enum { IDD = IDD_CREATE_CUBE_DLG };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

    DECLARE_MESSAGE_MAP()
};

我想知道我对继承做错了什么。是否有必要像我一样将父指针发送到基本对话框? 以上错误是否必须对它做任何事情?

2 个答案:

答案 0 :(得分:0)

此处的问题是enum符号IDD_CREATE_CUBE_DLG的范围。当你继承一个类时,你不会继承它的符号范围",你只需继承它的" members namespace"。我确信某位语言律师可以提供更准确(技术上正确)的解释。但是,一个简单的解释是你不会继承符号 - 因此枚举 - 定义。但是,即使它们处于受保护的范围内,您也应该能够访问它们。

因此,假设在IDD_CREATE_CUBE_DLG类中使用CreateCylinder来设置"它的" IDD,然后,而不是:

enum { IDD = IDD_CREATE_CUBE_DLG };

你应该写:

enum { IDD = CreateCylinder::IDD };

我认为正确的措辞是说你需要完全合格的"在这里命名。

这实际上是一件好事,一些类库使用它来表示技巧,比如枚举类支持的消息等等 - 例如,参见FOX(widget)工具包库。

更新: 如果您更改此处更新的声明,从而避免使用IDD_CREATE_CUBE_DLG,则您很可能再次遇到IDD_CREATE_CUBE_DLG问题。但是,如果您仍然这样做,问题将是IDD_CREATE_CUBE_DLG,因为它在Resource.h中声明,然后,在它被使用时(这是错误的行)报告),Resource.h没有(正确)包括在内。因此,请检查报告错误时编译的.cpp文件是什么。然后检查该文件中的包含。你应该清理它们,但是,对于初学者,你可能只是"只是" #include "Resource.h"位于.h文件的顶部。

对于CDialogEx的构造函数,只需传递参数,如下所示:

CreateCylinder::CreateCylinder(CWnd* pParent)
: CDialogEx(CreateCylinder::IDD, pParent)

答案 1 :(得分:0)

实际上将resource.h添加到我的基本对话框标题中解决了这个问题。在添加继承的类之前,我无法理解它是如何完美运行的。在这两种情况下,这个头文件都没有包含在内,那么它是如何在第一时间起作用的呢?