Sign in to follow this  
Clueless

Window creation problem

Recommended Posts

Ouch ... a lot of code ... sorry about that. But maybe you'll know where to look ... The main problem is that there are no errors reported in the logfile. Instead the program crashes because of a read operation. This happens when ShowWindow is called. What I tried was changing the nehe code so that I have an object oriented approach and a software renderer instead of OpenGL.
// Header Include
#include <render/ddwinwindow.h>

// Includes
#include <ddfw.h>

#ifdef DD_WIN

// Api

namespace ddfw
{

namespace ddrender
{

     //! Variable: appInstance
     HINSTANCE                 appInstance;

     //! Variable: windowHandle
     HWND                      windowHandle;

     //! Variable: deviceContext
     HDC                       deviceContext;

     //! Pixelformat Descriptor
     PIXELFORMATDESCRIPTOR     pixelFD;

     //! Function: WndProc(HWND, UINT, WPARAM, LPARAM)
     LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
                              WPARAM wParam, LPARAM lParam)
     {
         LRESULT lResult = DefWindowProc(hWnd,uMsg,wParam,lParam);

         switch (uMsg)
                {
                    case WM_ACTIVATE:
                    {
                        if (!HIWORD(wParam))
                           {
                               get_pRenderer()->get_pWindow()->enter();
                           }
                        else
                           {
                               get_pRenderer()->get_pWindow()->leave();
                           }
                        // end if
                        lResult = 0;
                    }

                    case WM_SYSCOMMAND:
                    {
                        switch (wParam)
                               {
                                   case SC_SCREENSAVE:
                                   case SC_MONITORPOWER:
                                   lResult = 0;
                               }
                        // end switch
			        }

                    case WM_CLOSE:
                    {
                        PostQuitMessage(0);
                        lResult = 0;
                    }

                    case WM_KEYDOWN:
                    {
                        lResult = 0;
                    }

                    case WM_KEYUP:
                    {
                        lResult = 0;
                    }

                    case WM_LBUTTONDOWN:
                    {
                        lResult = 0;
                    }

                    case WM_RBUTTONDOWN:
                    {
                        lResult = 0;
                    }

                    case WM_MBUTTONDOWN:
                    {
                        lResult = 0;
                    }

                    case WM_LBUTTONUP:
                    {
                        lResult = 0;
                    }

                    case WM_RBUTTONUP:
                    {
                        lResult = 0;
                    }

                    case WM_MBUTTONUP:
                    {
                        lResult = 0;
                    }

                    case WM_SIZE:
                    {
                        lResult = 0;
                    }
                }
         // end switch

         return lResult;
     }

     CWinWindow::CWinWindow()
     {
         appInstance = GetModuleHandle(NULL);

         pixelFD.nSize       = sizeof(PIXELFORMATDESCRIPTOR);
         pixelFD.nVersion    = 1;
         pixelFD.dwFlags     = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
         pixelFD.iPixelType  = PFD_TYPE_RGBA;
         pixelFD.cColorBits  = m_pWndSettings->redBits +
                               m_pWndSettings->greenBits +
                               m_pWndSettings->blueBits +
                               m_pWndSettings->alphaBits;
         pixelFD.cRedBits    = m_pWndSettings->redBits;
         pixelFD.cRedShift   = 0;
         pixelFD.cGreenBits  = m_pWndSettings->greenBits;
         pixelFD.cGreenShift = 0;
         pixelFD.cBlueBits   = m_pWndSettings->blueBits;
         pixelFD.cBlueShift  = 0;
         pixelFD.cAlphaBits  = m_pWndSettings->alphaBits;
         pixelFD.cAlphaShift = 0;
         pixelFD.cAccumBits  = 0;
         pixelFD.cAccumRedBits   = 0;
         pixelFD.cAccumGreenBits = 0;
         pixelFD.cAccumBlueBits  = 0;
         pixelFD.cAccumAlphaBits = 0;
         pixelFD.cDepthBits   = 8;
         pixelFD.cStencilBits = 0;
         pixelFD.cAuxBuffers  = 0;
         pixelFD.iLayerType = PFD_MAIN_PLANE;
         pixelFD.bReserved  = 0;
         pixelFD.dwLayerMask   = 0;
         pixelFD.dwVisibleMask = 0;
         pixelFD.dwDamageMask = 0;
     }

     CWinWindow::~CWinWindow()
     {
     }

     void CWinWindow::initialize()
     {
         bool     success = true;

         DEVMODE  wnd_screenSettings;
         UINT     wnd_pixelFormat;
         WNDCLASS wnd_class;
         DWORD    wnd_style;
         DWORD    wnd_extStyle;
         RECT     wnd_rect;
         UINT     wnd_bits;

         wnd_bits = m_pWndSettings->redBits +
                    m_pWndSettings->greenBits +
                    m_pWndSettings->blueBits +
                    m_pWndSettings->alphaBits;

         #ifndef DARE_NO_DEBUGGING
         dddebugging::CLogfile* pLogfile = get_pGlobalLog();
         (*pLogfile) << "-- Initializing Window<br />" << ENDL;
         (*pLogfile) << "-- Settings ... width: " << m_pWndSettings->width
                     << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... height: " << m_pWndSettings->height
                     << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... red bits: " 
                     << m_pWndSettings->redBits << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... green bits: "
                     << m_pWndSettings->greenBits << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... blue bits: "
                     << m_pWndSettings->blueBits << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... alpha bits: "
                     << m_pWndSettings->alphaBits << "<br />" << ENDL;
         (*pLogfile) << "-- Settings ... color bits: " << wnd_bits
                     << "<br />" << ENDL;
         if (m_pWndSettings->fullscreen)
            {
                (*pLogfile) << "-- Fullscreen Mode <br />" << ENDL;
            }
         else
            {
                (*pLogfile) << "-- Windowed Mode <br />" << ENDL;
            }
         // end if
         (*pLogfile) << "-- Title: " << m_pWndSettings->caption << "<br />"
                     << ENDL;
         (*pLogfile) << "--- Setting pixel format<br />" << ENDL;
         #endif

         wnd_rect.left   = 0;
         wnd_rect.right  = (long)m_pWndSettings->width;
         wnd_rect.top    = 0;
         wnd_rect.bottom = (long)m_pWndSettings->height;

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Get application instance handle<br />" << ENDL;
         #endif

         if (!appInstance)
            {
                MessageBox(NULL,"Noooo! No application instance!",
                           "ERROR",MB_OK|MB_ICONSTOP);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Defining class settings<br />" << ENDL;
         #endif

         wnd_class.style         = CS_HREDRAW | CS_VREDRAW;
         wnd_class.lpfnWndProc   = WndProc;
         wnd_class.cbClsExtra    = 0;
         wnd_class.cbWndExtra    = 0;
         wnd_class.hInstance     = appInstance;
         wnd_class.hIcon         = LoadIcon(NULL, IDI_WINLOGO);
         wnd_class.hCursor       = LoadCursor(NULL, IDC_ARROW);
         wnd_class.hbrBackground = NULL;
         wnd_class.lpszMenuName  = NULL;
         wnd_class.lpszClassName = "Software";		

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Trying to register class<br />" << ENDL;
         #endif

         if (!RegisterClass(&wnd_class))
            {
                MessageBox(NULL,"Failed To Register The Window Class.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Attempting fullscreen mode if requested!<br />"
                     << ENDL;
         #endif

         if (m_pWndSettings->fullscreen)
            {
                memset(&wnd_screenSettings,0,sizeof(wnd_screenSettings));
                wnd_screenSettings.dmSize=sizeof(wnd_screenSettings);
                wnd_screenSettings.dmPelsWidth  =
                    (long)m_pWndSettings->width;
                wnd_screenSettings.dmPelsHeight =
                    (long)m_pWndSettings->height;
                wnd_screenSettings.dmBitsPerPel = wnd_bits;
                wnd_screenSettings.dmFields = DM_BITSPERPEL |
                                              DM_PELSWIDTH  |
                                              DM_PELSHEIGHT;
                if (ChangeDisplaySettings(&wnd_screenSettings,CDS_FULLSCREEN)
                    !=DISP_CHANGE_SUCCESSFUL)
                   {
                       if (MessageBox(NULL,
                       "No fullscreen possible. Windowed mode instead?",
                       "NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
                          {
                              m_pWndSettings->fullscreen = false;
                          }
                       else
                          {
                              MessageBox(NULL,"Program Will Now Close.",
                                         "ERROR",MB_OK|MB_ICONSTOP);
                              success = false;
                          }
                       // end if
                   }
                // end if
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Setting style stuff!<br />"
                     << ENDL;
         #endif

         if (m_pWndSettings->fullscreen)
            {
                wnd_extStyle = WS_EX_APPWINDOW;
                wnd_style    = WS_POPUP;
                ShowCursor(FALSE);
            }
         else
            {
                wnd_extStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
                wnd_style    = WS_OVERLAPPEDWINDOW;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Adjust rectangle!<br />"
                     << ENDL;
         #endif

         if (!(AdjustWindowRectEx(&wnd_rect,wnd_style,FALSE,wnd_extStyle)))
            {
                MessageBox(NULL,"Adjust window rect ex error.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Create window, get handle!<br />"
                     << ENDL;
         #endif

         if (!(windowHandle=CreateWindowEx(
             wnd_extStyle,
             "Software",
             m_pWndSettings->caption,
             WS_CLIPSIBLINGS | WS_CLIPCHILDREN | wnd_style,
             0, 0,
             wnd_rect.right-wnd_rect.left,
             wnd_rect.bottom-wnd_rect.top,
             NULL,
             NULL,
             appInstance,
             NULL)))
            {
                uninitialize();
                MessageBox(NULL,"CreateWindowEx Error.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Get device context!<br />"
                     << ENDL;
         #endif

         if (!(deviceContext=GetDC(windowHandle)))
            {
		        uninitialize();
                MessageBox(NULL,"Can't create a device context.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Choose actual pixel format!<br />"
                     << ENDL;
         #endif

         if (!(wnd_pixelFormat=ChoosePixelFormat(deviceContext,&pixelFD)))
            {
                uninitialize();
                MessageBox(NULL,"Can't Find A Suitable PixelFormat.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Set actual pixel format!<br />"
                     << ENDL;
         #endif

         if (!SetPixelFormat(deviceContext,wnd_pixelFormat,&pixelFD))
            {
                uninitialize();
                MessageBox(NULL,"Can't Set The PixelFormat.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- Show window and set keyboard focus!<br />"
                     << ENDL;
         #endif
         pLogfile->flush("Initializing Window");

         if (!ShowWindow(windowHandle,SW_SHOW))
            {
                uninitialize();
                MessageBox(NULL,"Can't show the window for some reason.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         pLogfile->flush("Initializing Window");

         if (!SetForegroundWindow(windowHandle))
            {
                uninitialize();
                MessageBox(NULL,"Can't set as foreground window!",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         if (!SetFocus(windowHandle))
            {
                uninitialize();
                MessageBox(NULL,"Can't set keyboard focus!",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
                success = false;
            }
         // end if

         if (!success)
            {
                MessageBox(NULL,"Something went wrong.",
                           "ERROR",MB_OK|MB_ICONEXCLAMATION);
            }
         // end if

         #ifndef DARE_NO_DEBUGGING
         (*pLogfile) << "--- We are done here! Leaving<br />"
                     << ENDL;
         pLogfile->flush("Initializing Window");
         #endif
     }

     void CWinWindow::uninitialize()
     {
         if (m_pWndSettings->fullscreen)
            {
                ChangeDisplaySettings(NULL,0);
                ShowCursor(TRUE);
            }
         // end if

         if (deviceContext && !ReleaseDC(windowHandle,deviceContext))
            {
                MessageBox(NULL,"Release Device Context Failed.",
                           "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
                deviceContext = NULL;
            }
         // end if

         if (windowHandle && !DestroyWindow(windowHandle))
            {
                MessageBox(NULL,"Could Not Release hWnd.",
                           "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
                windowHandle = NULL;
            }
         // end if

         if (!UnregisterClass("Software", appInstance))
            {
                MessageBox(NULL,"Could Not Unregister Class.",
                           "SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
                appInstance = NULL;
            }
         // end if
     }

     void CWinWindow::enter()
     {
     }

     void CWinWindow::leave()
     {
     }

     void CWinWindow::run_frameBegin()
     {
     }

     void CWinWindow::run_frameIdle()
     {
     }

     void CWinWindow::run_frameEnd()
     {
     }

     void CWinWindow::swap_buffers()
     {
     }

};
// end namespace ddrender

};
// end namespace ddfw

#endif
// end ifdef DD_WIN

Share this post


Link to post
Share on other sites
if (deviceContext && !ReleaseDC(windowHandle,deviceContext))


What do you expect that to do? even if !deviceContext, ReleaseDC still get called, is that what you intend?

have you tried stepping through your code with a debugger?

Share this post


Link to post
Share on other sites
chad_420: The if-statement is perfectly valid.
if (deviceContext && !ReleaseDC(windowHandle,deviceContext))

ReleaseDC will only be called if deviceContext is not NULL. If deviceContext is false, the whole statement must be false, so ReleaseDC is never evaluated.

Clueless: The call to ShowWindow is strange. According to the documentation for ShowWindow, it returns false if the windows was previously hidden. However, your code treats this like an error condition and displays an error message. I suggest you remove the error checking from ShowWindow, because it can never return an error.

Share this post


Link to post
Share on other sites
chad_420:
The code you quoted is taken pretty much directly from the nehe code. I simply changed the variable names.
I`ll take a closer look at it later. Thanks for pointing that out.

Is it possible to use the debugger if the code is in a static library?

Not sure how it might help ... I can log the content of all the interesting variables.
I know it crashes when it tries to run ShowWindow ... would the debugger find out more?

EliasAE:
Sure about the if statement? I think in Java it would try ReleaseDC in any case.
Is that different in C++?

About the error checking ... yeah I did put that in.
Should have looked closer at the return type in the documentation.
I just made sure it returns false in some case and assumed it is in the case of an error.
But it doesn't make a difference. SetWindow never gets to return anything.
I just put that in when I realized that the error occurs in that line.

Share this post


Link to post
Share on other sites
About the evaluation of if-statements: it is the same in both Java and C++. As soon as the value of the condition is determined, no more part of it is evaluated. This means that DoThings() will never be called in:
if(false && DoThings())
and DoThings() will never be called in:
if(true || DoThings())

You say that ShowWindow never returns. Then the problem is perhaps in your message handler. I see two lines there, that could be problematic:
get_pRenderer()->get_pWindow()->enter();
and
get_pRenderer()->get_pWindow()->leave();

Are you sure that the return values from get_pRenderer and get_pWindow is valid pointers? Try to check the return values or temporarily remove those lines.

And yes, most debuggers can debug inside a statis library. Debuggers may even pause your program on the line it is crashing on. At least you could place break points at interesting places in your code.

Good luck finding your bug.

Share this post


Link to post
Share on other sites
You rock!!!

Thanks. Of course ... enter() and leave() are called before the window in the renderer exists.
Quoting out the lines fixes the error.
Guess it should be possible to not call those procedures until the window exists.

:)

Thanks again!! And again ... and again ... and so on!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this