Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Strange behaviour very basic OpenGL app

  1. #1
    Junior Member Regular Contributor Heiko's Avatar
    Join Date
    Aug 2008
    Location
    the Netherlands
    Posts
    170

    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:

    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>(&amp;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(&amp;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?

  2. #2
    Junior Member Regular Contributor Heiko's Avatar
    Join Date
    Aug 2008
    Location
    the Netherlands
    Posts
    170

    Re: Strange behaviour very basic OpenGL app

    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •