Win32 API logic error: Code compiles fine but the main window doesn't show up

时间:2015-05-24 20:32:32

标签: c++ winapi

I'm rewriting a software I wrote, because of program size and performance problems; The code compiles fine but the window doesn't show up.

I've looked into other questions about this but none solved my problem, that's why I'm asking a new question, for sake of completeness, please explain what is wrong with the code and how to solve the problem.

I'm using Visual Studio 2013. Here's the code:

WFrame.h

#pragma once

#include <Windows.h>
#include <tchar.h>
#include <wchar.h>

class WFrame
{
public:
    WFrame();
    WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle = WS_EX_OVERLAPPEDWINDOW);
    ~WFrame();

    void show();

    static LRESULT CALLBACK staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
    virtual LRESULT CALLBACK WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam);
protected:

private:
    HWND hWnd;
    int cmdShow;
};

WFrame.cpp

#include "WFrame.h"


WFrame::WFrame()
{

}

WFrame::WFrame(LPCWSTR szClassName, LPCWSTR szWindowTitle, HINSTANCE hInstance, int nCmdShow, int nX, int nY, int nWidth, int nHeight, DWORD dwStyle)
{
    WNDCLASSEX wClass;
    ZeroMemory(&wClass, sizeof(WNDCLASSEX));
    wClass.cbClsExtra = NULL;
    wClass.cbSize = sizeof(WNDCLASSEX);
    wClass.cbWndExtra = NULL;
    wClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wClass.hIcon = NULL;
    wClass.hIconSm = NULL;
    wClass.hInstance = hInstance;
    wClass.lpfnWndProc = (WNDPROC) WFrame::staticWindowProcedure;
    wClass.lpszClassName = szClassName;
    wClass.lpszMenuName = NULL;
    wClass.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&wClass))
    {
        int nResult = GetLastError();
        MessageBox(NULL,
            L"Window class creation failed",
            L"Window Class Failed",
            MB_ICONERROR);
    }

    this->hWnd = CreateWindow(
        szClassName,
        szWindowTitle,
        dwStyle,
        nX,
        nY,
        nWidth,
        nHeight,
        NULL,
        NULL,
        hInstance,
        NULL);

    if (!hWnd)
    {
        int nResult = GetLastError();

        MessageBox(NULL,
            L"Window creation failed",
            L"Window Creation Failed",
            MB_ICONERROR);
    }

}

WFrame::~WFrame()
{
    delete this;
}

void WFrame::show()
{
    ShowWindow(this->hWnd, this->cmdShow);
    UpdateWindow(this->hWnd);
}

LRESULT CALLBACK WFrame::staticWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    WFrame* winptr = (WFrame*)GetWindowLongPtr(hWnd, GWLP_USERDATA);

    if (winptr == NULL) {
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    else {
        return winptr->WindowProcedure(uMsg, wParam, lParam);
    }
}

LRESULT CALLBACK WFrame::WindowProcedure(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        case WM_CLOSE:
            DestroyWindow(this->hWnd);
            break;
        case WM_DESTROY:
            if (!GetParent(this->hWnd))
                PostQuitMessage(0);
            break;
    }

    return DefWindowProc(this->hWnd, uMsg, wParam, lParam);
}

Main.cpp

#include <Windows.h>

#include "WFrame.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WFrame * frame = new WFrame(L"Window", L"Window", hInstance, nCmdShow, 0, 0, 1024, 700);
    frame->show();

    MSG msg;
    ZeroMemory(&msg, sizeof(MSG));

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

Thanks to further answers.

2 个答案:

答案 0 :(得分:3)

I didn't see you assign a value to member variable cmdShow, so its default value is 0, which is SW_HIDE, so you should try the code below, see if the window can show up or assign cmdShow in WFrame initializer.

void WFrame::show()
{
    ShowWindow(this->hWnd, SW_SHOW);
    UpdateWindow(this->hWnd);
}

答案 1 :(得分:2)

You are using WS_EX_OVERLAPPEDWINDOW for the dwStyle param of CreateWindow. This flag should actually be used for the dwExStyle param of CreateWindowEx. Use WS_OVERLAPPEDWINDOW instead.

Don't forget to delete frame; when you're done. You actually don't even need a pointer here. Just instantiate frame on the stack.

Also, you should return 0; for the window messages that you handled, instead of calling DefWindowProc.