CreateWindowEx возвращает NULL

Ниже приведена часть моего кода. Каждый раз, когда я запускаю программу, CreateWindowEx из SPanel возвращает NULL, вызывая ошибку. Может ли кто-нибудь увидеть, что не так с этим фрагментом кода?

SPanelProc и MainWndProc уже объявлены и имеют прототип LRESULT CALLBACK SPanelProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);.

Среда, в которой я программирую, — Visual C++ 2010.

Почему CreateWindowEx всегда возвращает NULL?

#include <Windows.h>
#include <WindowsX.h>

LRESULT CALLBACK SPanelProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_MOUSEMOVE:

        break;
    }

    return 0;
}

void Init ()
{
    HWND child;
    HINSTANCE hInstance = (HINSTANCE)(GetWindowLongPtr (parent, GWLP_HINSTANCE));
    WNDCLASSEX wc;
    const char PanelClassName[] = "SPanel"; //ClassName of the panel. Do not reuse on another window

    //Create the window, initialize GWLP_USERDATA, check for errors, register the window class, and hide the window


    //Create the windowclass for the button
    wc.cbSize        = sizeof (WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = SPanelProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = hInstance;
    wc.hIcon         = LoadIcon (hInstance, IDI_APPLICATION);
    wc.hCursor       = LoadCursor (hInstance, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = PanelClassName;
    wc.hIconSm       = LoadIcon (hInstance, IDI_APPLICATION);

    //If could not register window class
    if(!RegisterClassEx (&wc))
    {
        MessageBox (NULL, "Panel registration failed!", "Error!", MB_OK);
        PostQuitMessage (0);
        return;
    }

    //Create window
    child = CreateWindowEx (WS_EX_NOPARENTNOTIFY, PanelClassName, "TITLE_TEXT", WS_CHILD, 0, 0, 400, 200, parent, NULL, hInstance, NULL);

    //Check for error in window creation
    if (child == NULL)
    {
        MessageBox (NULL, "Panel creation failed!", "Error!", MB_OK);
        PostQuitMessage (0);
        return;
    }

    return;
}


int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASSEX wc;
    HWND hWnd;
    MSG Msg;
    int length, width;

    //Register the window, create the window, and check for errors
    {
        //Window class
        wc.cbSize        = sizeof (WNDCLASSEX);
        wc.style         = 0;
        wc.lpfnWndProc   = MainWndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance     = hInstance; //Instance used to create the window
        wc.hIcon         = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_CODERICON)); //Change here to change large application icon
        wc.hCursor       = LoadCursor (hInstance, IDC_ARROW); //Change here to change application cursor
        wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); //Change here to change starting background color (white)
        wc.lpszMenuName  = NULL;
        wc.lpszClassName = Coder::Constants::MAINWNDCLASSNAME;
        wc.hIconSm       = (HICON)LoadImage (hInstance, MAKEINTRESOURCE (IDI_CODERICON), IMAGE_ICON, GetSystemMetrcs (SM_CXSMICON), GetSystemMetrics (SM_CYSMICON), 0); //Change here to change application icon (small, as in taskbar)

        //Register the window class so that the ClassName can be used to create the window and then check for error
        if (!RegisterClassEx (&wc))
        {
            MessageBox (NULL, "Main window registration failed!", "Error!", MB_OK);
            return 0;
        }

        //Get screen dimensions
        length = GetSystemMetrics (SM_CXSCREEN);
        width = GetSystemMetrics (SM_CYSCREEN);

        //Create window
        hWnd = CreateWindowEx (WS_EX_CLIENTEDGE, /*Border*/
            Coder::Constants::MAINWNDCLASSNAME,
            Coder::Constants::MAINWNDTITLETEXT, /*Title of window*/
            WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_THICKFRAME | WS_CLIPCHILDREN, /*Window style*/
            (length - Coder::Constants::XDEFAULT - Coder::Constants::XSHIFT) / 2, (width - Coder::Constants::YDEFAULT - Coder::Constants::YSHIFT) / 2, /*Top-left x and y coordinates*/
            Coder::Constants::XDEFAULT + Coder::Constants::XSHIFT, Coder::Constants::YDEFAULT + Coder::Constants::YSHIFT, /*Lengths and widths of window*/
            NULL, NULL, 
            hInstance, NULL);

        //Check for error in window creation
        if (hWnd == NULL)
        {
            MessageBox (NULL, "Main window creation failed!", "Error!", MB_OK);
            return 0;
        }
    }

    //Call function
            Init (hWnd);

    //Show and redraw the window
    ShowWindow (hWnd, nCmdShow);
    UpdateWindow (hWnd);

    //Put window in message loop
    while (GetMessage (&Msg, NULL, 0, 0) > 0) //While not terminated
    {
        TranslateMessage (&Msg);
        DispatchMessage (&Msg);
    }

    //Return
    return static_cast<int>(Msg.wParam);
}

person GILGAMESH    schedule 19.06.2012    source источник
comment
Как SPanelProc() справляется с WM_NCCREATE и WM_CREATE? Возвращает ли он TRUE при обработке WM_NCCREATE и 0 при обработке WM_CREATE?   -  person Frédéric Hamidi    schedule 19.06.2012
comment
Откуда берется parent? Он принадлежит другому процессу? Это невозможно.   -  person Hans Passant    schedule 19.06.2012
comment
Можете ли вы включить вывод GetLastError? Возможно, вы сможете использовать его для диагностики вашей проблемы. msdn.microsoft.com/en -нас/библиотека/окна/рабочий стол/   -  person Wug    schedule 19.06.2012
comment
Попробуйте GetLastError и FormatMessage, чтобы потенциально получить некоторую информацию о том, почему это не удается. Обычно это связано с тем, что у вас есть недопустимый параметр, например конфликтующие стили и т. д.   -  person AJG85    schedule 19.06.2012
comment
Я подозреваю ошибку в вашем wnd proc. Можете ли вы опубликовать этот код?   -  person i_am_jorf    schedule 19.06.2012
comment
SPanelProc() не обрабатывает упомянутые сообщения. GetLastError() вернул DWORD со значением 0. Я обновил код, чтобы он был более полным. Спасибо за помощь и просмотр этого сложного кода.   -  person GILGAMESH    schedule 19.06.2012


Ответы (1)


Каждая оконная процедура ДОЛЖНА возвращать DefWindowProc(hwnd,msg,wparam,lparam) для каждого сообщения, за исключением таких сообщений, как WM_ERASEBKGND и WM_PAINT, когда вы используете собственную процедуру рисования (вы должны вернуть 0, чтобы ОС не перерисовывала окно с помощью процедуры по умолчанию)

person lazy_banana    schedule 19.06.2012
comment
Да, это была причина. Я думал, что смогу доработать создание и потом разобраться с WndProc, но похоже, что это не так. Спасибо вам всем! Я проголосовал за всех и отметил вас как ответ. - person GILGAMESH; 19.06.2012