// 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
Window creation problem
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.
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?
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?
chad_420: The if-statement is perfectly valid.
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.
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.
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.
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.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement