Strange behaviour very basic OpenGL app

I’m fairly new to Microsoft Windows programming, but I’m trying to create a portable (Linux and Windows) window class. To create an OpenGL window in Windows I started out from the example in the OpenGL Superbible and that worked. But now I wanted to put the window creation code in a class and things started to get ugly. Everything worked until I started changing class member variables from the message handling switch… below is the relevant code:


/*************************************************************
 * A static member function of the class Window that
 * creates and returns a new window.
 * This function is called from WinMain.
 ************************************************************/
Window &Window::createWindow(HINSTANCE hInstance)
{
  WNDCLASS wc;
	
  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

  // use a static member function for WNDPROC
  wc.lpfnWndProc = reinterpret_cast<WNDPROC>(&Window::staticWndProc);
  wc.cbClsExtra = 0;

  // reserve extra room for a pointer to a Window instance
  wc.cbWndExtra = sizeof(Window *);
  wc.hInstance = hInstance;
  wc.hIcon = NULL;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	
  wc.hbrBackground = NULL;
  wc.lpszMenuName = NULL;
  wc.lpszClassName = "myApp";
	
  if (RegisterClass(&wc) == 0)
    throw std::string("error");
		
  HWND hWnd = CreateWindow(
    "myApp",
    "myApp",
    WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
    100, 100,
    250, 250,
    NULL,
    NULL,
    hInstance,
    NULL);
		
  if (hWnd == NULL)
    throw std::string("error");
		
  Window *win = new Window;
	
  // store a pointer to the Window instance in DWLP_USER
  SetWindowLongPtr(hWnd, DWLP_USER, reinterpret_cast<long>(win));
		
  ShowWindow(hWnd, SW_SHOW);
  UpdateWindow(hWnd);
	
  return *win;
}


/*************************************************************
 * The static wndProc member function of the class Window.
 * Handles all messages for the window.
 * It just gets the stored pointer to the Window instance and
 * passes the message to the instance.
 ************************************************************/
LRESULT CALLBACK Window::staticWndProc(
  HWND hWnd,
  UINT message,
  WPARAM wParam,
  LPARAM lParam)
{
  // get the pointer that was stored in DWLP_USER
  Window *wnd = reinterpret_cast<Window *>(GetWindowLongPtr(hWnd, DWLP_USER));

  // pass the message along to the Window instance
  return wnd->wndProc(hWnd, message, wParam, lParam);
}


/*************************************************************
 * A (non-static) member function of class Window.
 * Gets the message to be handled from the static wndproc
 * member function.
 *
 * If a member variable of the class Window is changed within
 * this code, things start going wrong.
 ************************************************************/
LRESULT CALLBACK Window::wndProc(
  HWND hWnd,
  UINT message,
  WPARAM wParam,
  LPARAM lParam)
{
  switch (message)
  {
    case WM_CREATE:
    {
      HDC hDC = GetDC(hWnd);
      setDCPixelFormat(hDC);
			
      HGLRC hRC = wglCreateContext(hDC);
      wglMakeCurrent(hDC, hRC);
			
      SetTimer(hWnd, 33, 1, NULL);
      break;
    }
    case WM_DESTROY:
    {
      KillTimer(hWnd, 101);
			
      HDC hDC = GetDC(hWnd);
      wglMakeCurrent(hDC, NULL);
			
      HGLRC hRC = wglGetCurrentContext();
      wglDeleteContext(hRC);
			
      PostQuitMessage(0);
      break;
    }
    case WM_SIZE:
    {
      //ChangeSize(LOWORD(lParam), HIWORD(lParam));
      break;
    }
    case WM_TIMER:
    {
      //IdleFunction();


      // this line causes a `test.exe has stopped working'
      ++d_count;


			
      InvalidateRect(hWnd, NULL, false);
      break;
    }
    case WM_PAINT:
    {
      //RenderScene();


      // this line causes the Window not to be updated
      // (contents of the desktop can be seen through the window)
      ++d_count; 

      HDC hDC = GetDC(hWnd);
      SwapBuffers(hDC);
		

      // if I put the statement overhere, everything seems ok...
      ++d_count;

      ValidateRect(hWnd, NULL);
      break;
    }
    default:
      return (DefWindowProc(hWnd, message, wParam, lParam));
  }
	
  return (0L);
}

In the final function you can see various `++d_count’ statements that cause problems. The variable d_count is a size_t member variable of the class Window that is properly initialized to 0 when the constructor of the class is called.

Does anybody have a clue why this is causing problems?

It looks like I have it working. I’m using GWLP_USERDATA now instead of DWLP_USER to store the pointer to the instance. So far no strange behaviour.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.