[C++] 선행 선언에 대한 질문입니다.
KLDP에는 초행인데 질문부터 올려서 참 죄송합니다만......
프레임이라는 클래스와 챠일드라는 클래스들이 서로를 참조해야 하기 때문에 프레임 클래스를 선행 선언하고 챠일드 클래스들을 작성한 뒤 프레임 클래스를 작성했습니다.
그런데 선행 선언을 한 뒤에 자꾸 오류가 발생해 버립니다.
#include "resource.h"
#include "wap.h"
using namespace wap;
class oFrame;
class oChildEdit : public oMDIChild {
public:
oEdit myEdit;
oMenu myMenu;
oMenu myMenuSub;
BeginMsgProc()
CreateMsg()
MDIActivateMsg()
SizeMsg()
SetFocusMsg()
DestroyMsg()
EndMsgProcOnMDIChild()
LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU3))) return -1;
myMenuSub = myMenu.GetSub(1);
if(!myMenuSub.Is()) return -1;
if(!myEdit.Create(0, WS_VISIBLE | ES_AUTOHSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | WS_HSCROLL | WS_VSCROLL, 0, 0, 0, 0, this, 100)) return -1;
return 0;
}
LRESULT OnSize(unsigned int nFlags, int nWidth, int nHeight)
{
MoveWindow(0, 0, nWidth, nHeight, true);
return 0;
}
LRESULT OnSetFocus(oHWND *poHWND)
{
myEdit.SetFocus();
return 0;
}
LRESULT OnDestroy(void)
{
delete this;
return 0;
}
LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();
if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 부분에서 오류가 발생합니다.
// error C2027 정의되지 않은 형식 'oFrame'을(를) 사용했습니다. 라는 오류와 함께 밑에
// (6)(선행선언이 된 라인) : 'oFrame' 선언을 참조하십시오. 라는 문구가 뜹니다.
poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.
return 0;
}
};
class oChildDraw : public oMDIChild {
public:
oMenu myMenu;
oMenu myMenuSub;
oDC myDC;
int x;
int y;
bool bDrawNow;
BeginMsgProc()
CreateMsg()
MDIActivateMsg()
LButtonDownMsg()
LButtonUpMsg()
LButtonDblClkMsg()
MouseMoveMsg()
EndMsgProcOnMDIChild()
LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU2))) return -1;
myMenuSub = myMenu.GetSub(1);
if(!myMenuSub.Is()) return -1;
bDrawNow = false;
return 0;
}
LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();
if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 라인에서도 같은 문제가 발생해 버립니다.
poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.
return 0;
}
LRESULT OnLButtonDown(unsigned int nFlags, int x, int y)
{
this->x = x;
this->y = y;
bDrawNow = true;
return 0;
}
LRESULT OnLButtonUp(unsigned int nFlags, int x, int y)
{
bDrawNow = false;
return 0;
}
LRESULT OnLButtonDblClk(unsigned int nFlags, int x, int y)
{
InvalidateRect(NULL, true);
return 0;
}
LRESULT OnMouseMove(unsigned int nFlags, int x, int y)
{
if(bDrawNow) {
myDC = GetDC();
myDC.MoveToEx(this->x, this->y, NULL);
this->x = x;
this->y = y;
myDC.LineTo(this->x, this->y);
ReleaseDC(&myDC);
}
return 0;
}
};
class oFrame : public oWnd {
public:
oMDIClient myMDIClient;
oMenu myMenu;
oMenu myMenuSub;
BeginMsgProc()
CreateMsg()
CommandMsg()
DestroyMsg()
EndMsgProcOnMDIClient(&myMDIClient);
LRESULT OnCreate(CREATESTRUCT *pcs)
{
if(!myMenu.Load(MAKEINTRESOURCE(IDR_MENU1))) return -1;
myMenuSub = myMenu.GetSub(0);
if(!myMenuSub.Is()) return -1;
if(!SetMenu(&myMenu)) return -1;
if(!myMDIClient.Create(0, WS_VSCROLL | WS_HSCROLL | WS_CLIPCHILDREN, this, 30000, &myMenuSub, 40000)) return -1;
myMDIClient.Show(SW_SHOW);
return 0;
}
LRESULT OnCommand(unsigned int nID, unsigned int nNtfMsg, oHWND *pohWnd)
{
BeginIDMap()
When(ID_FILE_NEWEDIT) myMDIClient.CreateMDIWindow(TEXT("myChild"), TEXT("Edit"), MDIS_ALLCHILDSTYLES); break;
When(ID_FILE_NEWDRAW) myMDIClient.CreateMDIWindowW(TEXT("myChild"), TEXT("Draw"), MDIS_ALLCHILDSTYLES); break;
When(ID_WIN_TILE) myMDIClient.MDITile(MDITILE_HORIZONTAL); break;
When(ID_WIN_CASCADE) myMDIClient.MDICascade(MDITILE_SKIPDISABLED); break;
When(ID_WIN_ARRANGE) myMDIClient.MDIIconArrange(); break;
EndIDMap()
}
LRESULT OnDestroy(void)
{
::PostQuitMessage(0);
return 0;
}
oMenu GetFrameMenu(void)
{
return myMenu;
}
oMenu GetFrameMenuSub(void)
{
return myMenuSub;
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
oFrame myFrame;
oWCX myWCX;
oMsg myMsg;
myWCX.SetBackground((HBRUSH)COLOR_APPWORKSPACE + 1);
myWCX.SetStyle(0);
myWCX.Register(TEXT("myFrame"));
myWCX.SetBackground((HBRUSH)::GetStockObject(WHITE_BRUSH));
myWCX.SetIcon(::LoadIcon(NULL, IDI_ASTERISK));
myWCX.Register(TEXT("myChildEdit"));
myWCX.SetStyle(CS_DBLCLKS);
myWCX.SetIcon(::LoadIcon(NULL, IDI_ERROR));
myWCX.Register(TEXT("myChildDraw"));
myFrame.Create(0, TEXT("myFrame"), TEXT("wapTest"), WS_OVERLAPPEDWINDOW);
myFrame.Show(nCmdShow);
return myMsg.Run();
}
분명히 선행선언을 해 주었는 것 같은데도 이러는 이유가 뭔지 궁금합니다. 혹시나 하여 인클루드 했던 헤더파일을 첨부합니다.
첨부 | 파일 크기 |
---|---|
wap.txt | 28.09 KB |
컴파일러가 oFrame에 대한 정보가 없기 때문입니다.
LRESULT OnMDIActivate(oHWND *poHWND)
{
oMDIClient myMDIClient = GetParent();
oFrame *poFrame = myMDIClient.GetParentImplemented();
if(poHWND == this) myMDIClient.MDISetMenu(&myMenu, &myMenuSub);
else myMDIClient.MDISetMenu(&(poFrame->GetFrameMenu()), &(poFrame->GetFrameMenuSub())); // 이 부분에서 오류가 발생합니다.
// error C2027 정의되지 않은 형식 'oFrame'을(를) 사용했습니다. 라는 오류와 함께 밑에
// (6)(선행선언이 된 라인) : 'oFrame' 선언을 참조하십시오. 라는 문구가 뜹니다.
poFrame->DrawMenuBar(); // 이 라인에서도 같은 문제가 발생해 버립니다.
return 0;
}
컴파일러가 이 함수를 컴파일 할 때 알고 있는 것은 class oFrame ; , 그냥 oFrame이란 class가 있구나
라는 것 밖에 없습니다. 실제 oFrame은 한참 아래에 정의되어 있죠.
member function 정의를 class 내부에서 하지 마시고 아래처럼 바깥으로 꺼내 주시면 해결 될 겁니다.
// class 선언
class oChildEdit : public oMDIChild {
public:
oEdit myEdit;
oMenu myMenu;
oMenu myMenuSub;
BeginMsgProc()
CreateMsg()
MDIActivateMsg()
SizeMsg()
SetFocusMsg()
DestroyMsg()
EndMsgProcOnMDIChild()
} ;
class oFrame
{
// 생략
} ;
// 멤버함수 정의
LRESULT oChildEdit::OnMDIActivate(oHWND *poHWND)
{
// 생략
}
// ... 생략
그럼 이만...
댓글 달기