繁体   English   中英

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

[英]how to inherit dialogs correctly in 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()
};

我想知道继承做错了什么。 有必要像我一样将父对象的指针发送到基本对话框吗? 上面的错误与它有关系吗?

这里的问题是enum符号IDD_CREATE_CUBE_DLG的范围。 当您继承一个类时,您不会继承它的“符号作用域”,而只继承了它的“成员名称空间”。 我确信某些语言律师会给出更准确的解释(技术上正确)。 但是,一个简单的解释是您不会继承符号(即枚举)定义。 即使它们处于受保护的范围内,您也应该能够访问它们。

因此,假设IDD_CREATE_CUBE_DLG在使用CreateCylinder类设置“的” IDD代替,那么,:

enum { IDD = IDD_CREATE_CUBE_DLG };

您应该写:

enum { IDD = CreateCylinder::IDD };

我认为正确的措词是说您需要此处的“完全限定”名称。

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

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

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

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

实际上将resource.h添加到我的基本对话框标题中可以解决此问题。 在添加继承的类之前,我只是无法理解它的完美工作方式。 在这两种情况下都没有包含此头文件,因此它是如何工作的?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM