Chicktopus 0 Newbie Poster

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!