Hi guys
I'm trying to use WndProc as a member function, but no matter what I do, I always get a null handle. One thing I'm uncertain of is that when my StaticWndProc is called, the p_hWnd is null. Is that correct? Once it leaves the function it remains null and is never populated, I'd have thought this is what SetWindowLongPtr was supposed to do in the WM_NCCREATE or WM_CREATE message using the instance passed through in lParams. I've had a look here and on the rest of the web and none of the other examples I've seen have worked for me, so I figured the next logical step would be to get someone with a little more expertise to review what I've got and tell me where I'm going wrong. I've checked GetLastError after both CreateWindowEx and SetWindowLongPtr, both are 0.
Here's what I have so far, minus a bunch of superfluous stuff:
GLWindow.h
#pragma once
#ifndef __GLWindow_H
#define __GLWindow_H
#include <windows.h>
#include <GLU.H> // Header File For The GLu32 Library
#include "SOIL.h"
#include <glut.h>
class GLWindow
{
protected:
HDC g_hDC; // Private GDI Device Context
HGLRC g_hRC; // Permanent Rendering Context
HINSTANCE g_hInstance; // Holds The Instance Of The Application
UINT g_uMsg;
bool g_active; // Window Active Flag Set To TRUE By Default
bool g_fullscreen; // Fullscreen Flag Set To Fullscreen Mode By Default
bool g_keys[256];
public:
HWND g_hWnd; // Holds Our Window Handle
GLWindow();
GLWindow(const GLWindow& p_glWindow);
~GLWindow();
GLWindow& operator=(const GLWindow& p_glWindow);
void SetHWND(HWND p_hWnd);
HWND& GetHWND();
HDC GetHDC();
BOOL GetActive();
void SetActive(BOOL p_active);
BOOL GetFullScreen();
void SetFullScreen(BOOL p_fullscreen);
void SetMsg(UINT p_msg);
UINT GetMsg();
bool* GetKeys();
GLvoid ReSizeGLScene(GLsizei p_width, GLsizei p_height);
GLvoid KillGLWindow(GLvoid);
LPCSTR ClassName() const { return (LPCSTR)"Sample Window Class"; }
LRESULT HandleMessage(UINT p_uMsg, WPARAM p_wParam, LPARAM p_lParam);
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CreateGLWindow(
PCWSTR p_lpWindowName,
DWORD p_dwStyle,
DWORD p_dwExStyle = 0,
int p_x = CW_USEDEFAULT,
int p_y = CW_USEDEFAULT,
int p_width = 800,
int p_height = 600,
HWND p_hWndParent = 0,
HMENU p_hMenu = 0
)
{
WNDCLASSEX m_wc;
m_wc.cbSize = sizeof(WNDCLASSEX);
m_wc.style = 0;
m_wc.lpfnWndProc = (WNDPROC)GLWindow::StaticWndProc;
m_wc.cbClsExtra = 0;
m_wc.cbWndExtra = 0;
m_wc.hInstance = GetModuleHandle(NULL);
m_wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
m_wc.hCursor = LoadCursor(NULL, IDC_ARROW);
m_wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
m_wc.lpszMenuName = NULL;
m_wc.lpszClassName = ClassName();
m_wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
DWORD m_dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
DWORD m_dwStyle=WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
if(!RegisterClassEx(&m_wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
g_hInstance = m_wc.hInstance;
g_hWnd = CreateWindowEx(m_dwExStyle, ClassName(), (LPCSTR)"mbees", m_dwStyle, 0, 0, p_width, p_height, NULL, NULL, m_wc.hInstance, (void*)this); // Dont Pass Anything To WM_CREATE
if(g_hWnd == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
SetWindowLongPtr(g_hWnd, GWLP_USERDATA, (LONG_PTR)this);
return (g_hWnd ? TRUE : FALSE);
}
static LRESULT CALLBACK StaticWndProc(HWND p_hWnd, UINT p_uMsg, WPARAM p_wParam, LPARAM p_lParam)
{
GLWindow* m_this = (GLWindow*)GetWindowLongPtr(p_hWnd, GWL_USERDATA);
switch (p_uMsg)
{
case WM_NCCREATE:
{
CREATESTRUCT* pCreate = (CREATESTRUCT*)p_lParam;
m_this = (GLWindow*)pCreate->lpCreateParams;
SetWindowLongPtr(p_hWnd, GWL_USERDATA, (long)m_this);
m_this->g_hWnd = p_hWnd;
return m_this->WndProc(p_hWnd, p_uMsg, p_wParam, p_lParam);
}
}
return DefWindowProc(p_hWnd, p_uMsg, p_wParam, p_lParam);
}
BOOL InitGLWindow();
};
#endif
GlWindow.cpp
#include "GLWindow.h"
GLWindow::GLWindow()
{
g_hDC = NULL;
g_hRC = NULL;
g_hWnd = NULL;
g_hInstance = NULL;
g_fullscreen = TRUE;
}
GLWindow::GLWindow(const GLWindow& p_glWindow)
{
g_hDC = p_glWindow.g_hDC;
g_hRC = p_glWindow.g_hRC;
g_hWnd = p_glWindow.g_hWnd;
g_hInstance = p_glWindow.g_hInstance;
g_fullscreen = p_glWindow.g_fullscreen;
}
GLWindow& GLWindow::operator=(const GLWindow& p_glWindow)
{
if(this != &p_glWindow)
{
g_hDC = p_glWindow.g_hDC;
g_hRC = p_glWindow.g_hRC;
g_hWnd = p_glWindow.g_hWnd;
g_hInstance = p_glWindow.g_hInstance;
g_fullscreen = p_glWindow.g_fullscreen;
}
return *this;
}
GLWindow::~GLWindow()
{
}
void GLWindow::SetHWND(HWND p_hWnd)
{
g_hWnd = p_hWnd;
}
HWND& GLWindow::GetHWND()
{
return g_hWnd;
}
HDC GLWindow::GetHDC()
{
return g_hDC;
}
BOOL GLWindow::GetActive()
{
return g_active;
}
void GLWindow::SetActive(BOOL p_active)
{
g_active = p_active;
return;
}
BOOL GLWindow::GetFullScreen()
{
return g_fullscreen;
}
void GLWindow::SetFullScreen(BOOL p_fullscreen)
{
g_fullscreen = p_fullscreen;
}
void GLWindow::SetMsg(UINT p_uMsg)
{
g_uMsg = p_uMsg;
}
UINT GLWindow::GetMsg()
{
return g_uMsg;
}
bool* GLWindow::GetKeys()
{
return g_keys;
}
GLvoid GLWindow::ReSizeGLScene(GLsizei p_width, GLsizei p_height) // Resize And Initialise The GL Window
{
if (p_height==0) // Prevent A Divide By Zero By
{
p_height=1; // Making Height Equal One
}
glViewport(0, 0, p_width, p_height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f, (GLfloat)p_width / (GLfloat)p_height, 0.001f, 100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
GLvoid GLWindow::KillGLWindow(GLvoid) // Properly Kill The Window
{
if (g_hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(g_hRC)) // Are We Able To Delete The RC?
{
MessageBox(NULL, "Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
g_hRC=NULL; // Set RC To NULL
}
if (g_hDC && !ReleaseDC(g_hWnd, g_hDC)) // Are We Able To Release The DC
{
MessageBox(NULL, "Release Device Context Failed.","SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_hDC=NULL; // Set DC To NULL
}
if (g_hWnd && !DestroyWindow(g_hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_hWnd=NULL; // Set hWnd To NULL
}
if (g_fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (!UnregisterClass("OpenGL", g_hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL, "Could Not Unregister Class.","SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
g_hInstance = NULL; // Set hInstance To NULL
}
}
LRESULT CALLBACK GLWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(uMsg)
{
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
default:
{
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
}
return 0;
}
WinMain function
int WINAPI WinMain( HINSTANCE p_hInstance, // Instance
HINSTANCE p_hPrevInstance, // Previous Instance
LPSTR p_lpCmdLine, // Command Line Parameters
int p_nCmdShow) // Window Show State
{
MSG m_mMsg; // Windows Message Structure
BOOL m_bDone = FALSE; // Bool Variable To Exit Loop
BOOL m_msgResult = FALSE; //Bool variable to capture return value for PeekMessage
g_glWindow = new GLWindow();
UINT m_wndCount = 1;
HWND m_hWnd;
Controller m_controller;
//m_wndProc = &WndProc;
// Ask The User Which Screen Mode They Prefer
if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
{
g_glWindow->SetFullScreen(FALSE);//g_fullscreen = FALSE; // Windowed Mode
}
// Create Our OpenGL Window
if (!g_glWindow->CreateGLWindow((PCWSTR)"mBees", 800, 600, 32, g_glWindow->GetFullScreen()))//g_fullscreen))
{
return 0; // Quit If Window Was Not Created
}
if (!InitGL()) // Initialise Our Newly Created GL Window
{
g_glWindow->KillGLWindow(); // Reset The Display
MessageBox(NULL,"Initialisation Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
g_scale.x = g_scale.y = g_scale.z = (9*(5.0f)); //Set an initial size for the global scale
g_map = new Map();
while(!m_bDone) // Loop That Runs While done=FALSE
{
m_hWnd = g_glWindow->GetHWND();
m_msgResult = PeekMessage(&m_mMsg,m_hWnd,0,0,PM_REMOVE); //Get the message for this window
if(m_msgResult == TRUE)
{
if (m_mMsg.message==WM_QUIT) // Have We Received A Quit Message?
{
m_bDone=TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&m_mMsg); // Translate The Message
DispatchMessage(&m_mMsg); // Dispatch The Message
}
}
else // If There Are No Messages
{
if (!g_glWindow->GetActive() && g_keys[VK_ESCAPE]) // Active? Was There A Quit Received?
{
m_bDone=TRUE; // ESC or DrawGLScene Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
DrawGLScene(); // Draw GL Scene
g_keys = g_glWindow->GetKeys();
ProcessKeyboard();
}
}
}
// Shutdown
g_glWindow->KillGLWindow(); // Kill The Window
CleanUp();
return (m_mMsg.wParam); // Exit The Program
}
Any help would be much appreciated!