2016-07-18 1 views
0

Я создаю 3d-художника на C++ с OpenGL и MFC. Я создал диалоговые окна для создания каждой фигуры, которая у меня есть: как куб, цилиндр и т. Д. Мой класс куба наследует класс цилиндров с разницей в количестве стека и фрагментов. Следовательно, диалог CreateCylinder должен выглядеть так же, как диалог CreateCube. я смог унаследовать его хорошо, но у меня есть ошибка, которая говорит:Как правильно наследовать диалоги в MFC

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 }; 

затем компилировать и раскомментируйте ту же линию, что помогает в следующей компиляции работать нормально.

То, как я унаследовал класс диалогового окна CreateCylinder в моем классе диалога CreateCube:

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() 
}; 

Я хочу знать, что я сделал неправильно с наследованием. необходимо ли отправить указатель родителя в базовый диалог, как я? И ошибка выше должна что-нибудь с этим делать?

+0

Не могли бы вы также поделиться заголовком (декларация класса)? Также является 'CreateCylinder' ваш класс или часть некоторой библиотеки? Он не похож на часть MFC, так как классы MFC имеют префикс 'C', поэтому он должен быть' CCreateCylinder'. –

+0

Я добавил код заголовка в свой пост. И да, CreateCylinder - это класс, это была моя ошибка, чтобы не называть его правильным (CCreateCylinderDlg). Можно ли поменять его имя с помощью мастера (в Visual Studio), не беспокоясь о тоннах ошибок, которые будут связаны с этим изменением? – serg90

+0

Если вы не испортили «метку мастера» в своем коде, вы должны иметь возможность изменить имя класса с помощью мастера. –

ответ

0

Проблема здесь в области enum символ IDD_CREATE_CUBE_DLG. Когда вы наследуете класс, вы не наследуете его «область символов», вы просто наследуете его «пространство имен членов». Я уверен, что какой-то адвокат языка может дать более точное (технически правильное) объяснение. Но простое объяснение состоит в том, что вы не наследуете символ - таким образом, перечисляете - определения. Однако вы должны иметь доступ к ним, даже если они находятся в защищенной области.

Таким образом, если предположить, что IDD_CREATE_CUBE_DLG используется в CreateCylinder классе, чтобы установить "его" IDD, то, вместо того, чтобы:

enum { IDD = IDD_CREATE_CUBE_DLG }; 

вы должны написать:

enum { IDD = CreateCylinder::IDD }; 

Я считаю, что правильная формулировка было бы сказать, что вам нужно «полное квалифицированное» имя здесь.

Это действительно хорошо, и некоторые библиотеки классов используют его для воспроизведения трюков, таких как перечисление сообщений, поддерживаемых классом, и т. Д. - см., Например, библиотеку инструментов FOX (widget).

UPDATE: Если вы измените свое заявление, как обновляется здесь, таким образом, избегая использования 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) 
+0

Символ IDD_CREATE_CUBE_DLG фактически объявлен в файле Resource.h, а не в классе CreateCylinder, поэтому я не могу использовать его, как вы сказали. И как-то компилятор дает мне ошибку о символе BaseWinDlg, который является моим главным диалогом, откуда я могу открыть другие диалоги. Кроме того, отправляется «this-> GetSafeOwner()» в конструктор базового класса, необходимо для унаследованных диалогов или это неправильно? я понятия не имею, когда и если я должен что-либо сделать с аргументами родителей. – serg90

+0

Я изменил '#include ' на '#include" Resource.h "и' .cpp' на '.h' – sergiol

0

На самом деле добавление resource.h мой диалоговой базы заголовка решить эту проблему. Я просто не понимаю, как это работает безупречно, прежде чем я добавлю унаследованные классы. В обоих случаях этот заголовочный файл не был включен, и как он работал в первую очередь?

+0

Может быть,« Resource.h »был включен косвенно? – sergiol

+0

Посмотрите, содержит ли ваша Resource.h строку VS '// {{NO_DEPENDENCIES}}', которая НЕ приведет к повторной компиляции, когда она изменится из-за обновленных идентификаторов (например). Это так, что ВСЕМ не перекомпилируется из-за зависимости от одной настройки ресурса. Обычно вы можете просто принудительно перекомпилировать модуль ONE, который будет зависеть от настройки ONE ресурса. – franji1