Hello again everyone,
How are you all doing? I am an fairly familiar with C/C++. I have five books on my shelf about programming in C/C++ but none could provide me with a satisfactory solution to this one problem. I would like to graduate from the Hello World project in Window application and move on to a more intermediate level. For a while I have steered away from class creations because I don't quite have a full grasp on the concept. However, I would have to face them eventually so I took the liberty to go at it. Below are the code of my entire Hello World Advance project, My Project 5.
Under the
void c_AppSys::CreateMyWindow()
method definition
cm_wcx.lpfnWndProc = WinProc;
.
When I compile the code I get an undeclared error.
49 MyProject5\project5main.cpp 'WinProc' undeclared (first use this function)
These code are my own but I based the class off of the sample given in one of my books SAMS Teach yourself GAME PROGRAMMING in 24 hours by Michael Morrison. I don't understand how the class would work for him. I even copy his code exactly onto My Project 3 but it also showed me the same error. I'm only assuming that the code somehow works for him. And thats what I want to know, how does he solve this error to get the class to recognise his WndProc from outside the class? Thanks in advance everyone. Oh and there are some opengl codes in there I figured I'd kill two birds with one stone and incorporate some gl in the mix.
These are his:
BOOL GameEngine::Initialize(int iCmdShow)
{
WNDCLASSEX wndclass;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbWndExtra = 0;
wndclass.cbClsExtra = 0;
wndclass.hInstance = m_hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
wndclass.lpszClassName = m_szWindowClass;
wndclass.lpszMenuName = NULL;
m_hWindow = CreateWindow(m_szWindowClass,m_szTitle,WS_POPUPWINDOW|WS_CAPTION|WS_MINIMIZEBOX, 0,0,640,480,NULL,NULL,m_hInstance,NULL);
His WinProc is
LRESULT CALLBACK WndProc(HWND hWindow,UINT msg,WPARAM wParam,LPARAM lParam)
{
return GameEngine::GetEngine()->HandleEvent(hWindow,msg,wParam,lParam);
}
And here are my codes:
#include <windows.h>
#include <windowsx.h>
#include <glut.h>
//my very own class used to handle the application system
class c_AppSys
{private://private members
bool cm_bRun;//flags to die or live
HINSTANCE cm_hInstance;//application instance
HWND cm_hWnd;//application window handle
int cm_iwidth;//window width
int cm_iheight;//window height
WNDCLASSEX cm_wcx;//application class
public:
c_AppSys();//the constructor automatically executes the instant this class's
//object is declared
~c_AppSys();//the destructor automatically executes the instance this class's
//object is destroyed
//some of the methods - functions that has access to the private data
bool CreateMyWindow();
bool LeakFlag(){return cm_bRun;}
HWND LeakhWnd(){return cm_hWnd;}
LRESULT CALLBACK MyWinProc(HWND,UINT,WPARAM,LPARAM);
void ClearOut();//use this to clear out any allocated memory
void IDoKeys();//handles any keys as they are pressed
void InitSys();//i will use this to initiate glut api
void MyResizing(int,int);//in event the window is changed in dimension
};
//the definitions of all of my methods
c_AppSys::c_AppSys()//the constructor
{
cm_bRun = TRUE;//initiated to be set as true
cm_iwidth = 640;//default width of my window
cm_iheight = 480;//default height of my window
}
c_AppSys::~c_AppSys()//the destructor
{
}
bool c_AppSys::CreateMyWindow()
{
HINSTANCE hInstance;
HWND hWnd;
cm_wcx.style = CS_HREDRAW|CS_VREDRAW;
cm_wcx.cbSize = sizeof(WNDCLASSEX);
cm_wcx.lpfnWndProc = WinProc;
cm_wcx.cbClsExtra = 0;
cm_wcx.cbWndExtra = 0;
cm_wcx.hIcon = LoadIcon(NULL,IDI_APPLICATION);
cm_wcx.hIconSm = NULL;
cm_wcx.hCursor = LoadCursor(NULL,IDC_ARROW);
cm_wcx.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
cm_wcx.lpszClassName = "MYPROJECT5";
cm_wcx.lpszMenuName = NULL;
if(!(RegisterClassEx(&cm_wcx)))
{return FALSE;}
if(!(hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,"MYPROJECT5",
"My Project 5",WS_CLIPSIBLINGS|WS_CLIPCHILDREN,
60,60,cm_iwidth,cm_iheight,NULL,NULL,hInstance,NULL)))
{return FALSE;}
cm_hWnd = hWnd;//store the handle in the class member
cm_hInstance = hInstance;//store the instance in the class member
ShowWindow(cm_hWnd,SW_SHOW);
UpdateWindow(cm_hWnd);
return TRUE;
}
LRESULT CALLBACK c_AppSys::MyWinProc(HWND hWnd,UINT umsg,WPARAM wParam,LPARAM lParam)
{
switch(umsg)
{
case WM_DESTROY:
ClearOut();
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,umsg,wParam,lParam);
}
//this is where i initialize any glut api
void c_AppSys::InitSys()
{
int* argc;
char** argv;
glInit(&argc,argv);
glInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
//Undo comments to have glut handle window creation
//glutInitWindowSize(640,480);
//glutCreateWindow("MYPROJECTX");
glutKeyboardFunc(IDoKeys);//i will handle the keys not glut
glutReshapeFunc(MyResizing);//i will handle the resizing not glut
}
void c_AppSys::IDoKeys()
{
}
void c_AppSys::ClearOut()
{
//this is probably the wrong way to clear allocated space
UnregisterClass("MYPROJECT5",cm_hInstance);
cm_bRun = FALSE;//flag set to kill
cm_hInstance = NULL;
cm_hWnd = NULL;
}
void c_AppSys::MyResizing(int iwidth,int iheight)
{
glViewPort(0,0,iwidth,iheight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,(double)iwidth/(double)iheight,1.0,200.0);
}
//a redering class system
class c_RenderSys
{public:
void IDoDraw();
void InitRenderSys();
void InitRenderAccel();
};
void c_RenderSys::IDoDraw()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrxMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f,0.0f,0.0f);
glVertex3f(0.0f,-1.0f,0.0f);
glVertex3f(1.0f,0.0f,0.0f);
glEnd();
glutSwapBuffers();
}
void c_RenderSys::InitRenderSys()
{
glutDisplayFunc(IDoDraw);
}
void c_RenderSys::InitRenderAccel()
{
glEnable(GL_DEPTH_TEST);
}
//i declare my application object
c_AppSys MyApp;
c_RenderSys MyRender;
LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);//the real winproc
int TheLoop()//handles the eternal loop here
{
HWND hWnd;
MSG msg;
hWnd = pMyApp.LeakhWnd();
do
{
if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
//MyApp.ClearOut();
PostQuitMessage(0);
break;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
MyRender.IDoDraw();
MyApp.IDoKeys();
}
while(MyApp.LeakFlag() != FALSE);
pMyApp.ClearOut();
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,LPSTR lpszCmdLine,int iCmdShow)
{
MyApp.CreateMyWindow();
MyApp.InitSys();
MyRender.InitRenderSys();
TheLoop();
return 0;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT umsg,WPARAM wParam,LPARAM lParam)
{
return pMyApp.MyWinProc(hWnd,umsg,wParam,lParam);
}