Window creation called from constructor not working

Started by
2 comments, last by Geoffrey 10 years, 1 month ago

Hi there,

i am trying to implement a little wrapper class for the win32 window api. It works quite nicely, but one problem i cannot seem to solve remains, and it is a quite peculiar one.
This is the code in the class (only the relevant parts):


LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    // sort through and find what code to run for the message given
    switch (message)
    {
        // this message is read when the window is closed
        case WM_DESTROY:
        {
            // close the application entirely
            PostQuitMessage(0);
            return 0;
        }break;
     }


    // Handle any messages the switch statement didn't
    return DefWindowProc(hWnd, message, wParam, lParam);
}

Window::Window(HINSTANCE thisInstance, DirectX::XMINT2 size, wstring title, bool enableFullscreen) :
appInstance(thisInstance),
position(0, 0),
size(size),
#ifdef UNICODE
title(title),
#else
title(string(title.begin(), title.end())),
#endif
fullscreen(false)
{
    this->buildWindow();
    if (fullscreen)
        setFullscreenWindowed(true);
}


Window::~Window()
{
    DestroyWindow(windowHandle);


    UnregisterClass(CLASSNAME, appInstance);
}


void Window::buildWindow()
{
    WNDCLASSEX wClass; //window class structur
    wClass.hInstance = this->appInstance;
    wClass.lpszClassName = "Classname";
    wClass.lpfnWndProc = WindowProc;
    wClass.style = CS_HREDRAW | CS_VREDRAW;
    wClass.cbSize = sizeof(WNDCLASSEX);
    wClass.hIcon = NULL;
    wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    wClass.lpszMenuName = NULL;
    wClass.hbrBackground = NULL;
    wClass.cbClsExtra = 0;
    wClass.cbWndExtra = 0;
    if (!RegisterClassEx(&wClass))
    {
          Debug::getInstance().log("Faild to create Window Class", EDEBUG_LEVEL::E_ERROR);
          //throw some errors
          return;
    }

    this->windowHandle = CreateWindowEx(
         NULL,
        "Classname",
        "Dies ist ein Titel", //real window title
        WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
        0, 0,
        800, 600,
        NULL,
        NULL,
        this->appInstance,
        NULL
        );
    if (this->windowHandle == NULL)
    {
         Debug::getInstance().log("CreateWindow failed.", EDEBUG_LEVEL::E_ERROR);
    }
}

void Window::show()
{
    ShowWindow(windowHandle, SW_SHOW);
    UpdateWindow(windowHandle);
    SetFocus(windowHandle);
}

And this is my main loop (in main.cpp)


int WINAPI WinMain(HINSTANCE instance, HINSTANCE prevInstance, PSTR sCmdLine, int cmdShow)
{
    Window mainWindow = Window(instance, { 800, 600 }, std::wstring(L"Hier steht ein netter Titel"), false);
    mainWindow.show();

    MSG msg;

    while (TRUE) {
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        if (msg.message == WM_QUIT) {
            break;
        }
    }

    return msg.wParam;
}

Now the problem is: The window does not appear. In fact it gets destroyed immediately after its creation. The reason for this seems to be that i call the


buildWindow()

method from the constructor of the Window class. If i call the method like a member function directly from the main-loop like


mainWindow.buildWindow()

right before


mainWindow.show()

it works as expected. What is wrong here?

Thanks in advance

Advertisement
Rule of Three violation.

You're constructing a window, then copying it using the (default) copy constructor and the original window is destroyed.

Change your declaration to this.

Window mainWindow(instance, { 800, 600 }, std::wstring(L"Hier steht ein netter Titel"), false);

and read up on the Rule of Three.

Stephen M. Webb
Professional Free Software Developer

Rule of Three violation.

You're constructing a window, then copying it using the (default) copy constructor and the original window is destroyed.

Change your declaration to this.


Window mainWindow(instance, { 800, 600 }, std::wstring(L"Hier steht ein netter Titel"), false);

and read up on the Rule of Three.

Oh i did not know that. Nice read. Thank you a lot!

Also msg isn't initialized, and it isn't guaranteed to be set by PeekMessage, so it could happen that msg.message == WM_QUIT by coincidence (in practice you will almost certainly have a WM_CREATE message or some such on the first loop iteration which renders this bug somewhat theoretical).

The Trouble With Robots - www.digitalchestnut.com/trouble

This topic is closed to new replies.

Advertisement