1

I am trying to create an OpenGL window inside of already existing parent window using win32 api. However, when creating a child, the function CreateWindowEx returns NULL with an error 1407 ERROR_CANNOT_FIND_WND_CLASS. The window must be a child so there is a space left for other controls such as buttons and checkboxes...

Part of code that creates the parent window:

WNDCLASSEX wincl;
wincl.style = 0;
wincl.lpszMenuName = NULL;
wincl.lpszClassName = L"WindowClass";
wincl.lpfnWndProc = WndProc;
wincl.hInstance = hInstance;
wincl.hIconSm = LoadIcon(NULL, IDC_ICON);
wincl.hIcon = LoadIcon(NULL, IDC_ICON);
wincl.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wincl.cbWndExtra = 0;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.cbClsExtra = 0;

if(!RegisterClassEx(&wincl)){
    std::cout << "Window failed to register!" << std::endl;
    return false;
}

DWORD style = WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU | WS_SIZEBOX;

parentHwnd = CreateWindowEx(WS_EX_CLIENTEDGE,
                      L"WindowClass",
                      L"Title",
                      style,
                      CW_USEDEFAULT, // X
                      CW_USEDEFAULT, // Y
                      800, // Width
                      600, // Height
                      NULL,
                      NULL,
                      hInstance,
                      0);

if (parentHwnd == NULL){
    std::cout << "Window failed to create!" << std::endl;
    return false;
}

ShowWindow(parentHwnd, SW_SHOWNORMAL);
UpdateWindow(parentHwnd);

Inside the message loop, I am creating the child window:

LRESULT WndProc(HWND hwnd, UINT Msg, WPARAM wParam , LPARAM lParam){
    switch (Msg){
        case WM_CREATE:{
            // Create child OpenGL window
            childHwnd = CreateWindowEx(0,
                                   L"OpenGL",
                                   NULL,
                                   WS_CLIPCHILDREN | WS_VISIBLE,
                                   100, // X
                                   100, // Y
                                   400, // Width
                                   300, // Height
                                   hwnd, // Parent
                                   0, // ID
                                   NULL,
                                   NULL);
            // Prints 1407 ERROR_CANNOT_FIND_WND_CLASS
            std::cout << "Last error: " << GetLastError() << std::endl;
        }
        default:{
            return DefWindowProc(hwnd, Msg, wParam, lParam);
        }
    }
    return 0;
}

I have looked into several tutorials (NeHe, cs.rit.edu, and many other but I can't post more than 2 links) and all of them used L"OpenGL" as class name for the second argument in the function CreateWindowEx().

What am I doing wrong? Is "OpenGL" a valid class name such as "Edit" / "Static" / "Button" ? Can I replace it with something else? I tried "Static" but it did not rendered anything.

I know there are many libraries (GLFW, SDL, ...) that handle window creation, but I need to use pure win32 API.

UPDATE:

RegisterClass() solved the problem. Here is the code that works for me:

WNDCLASS wc      = {0}; 
wc.lpfnWndProc   = WndProc;
wc.hInstance     = hInstance; // Same hinstance used by parent
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"OpenGL";
wc.style = CS_OWNDC;

if(!RegisterClass(&wc)){
    std::cout << "Failed to register window!" << std::endl;
    return false;
}

childHwnd = CreateWindowEx(0, // Must be zero
                           L"OpenGL",
                           NULL,
                           WS_VISIBLE | WS_CHILD,
                           100, // X
                           100, // Y
                           400, // Width
                           300, // Height
                           parentHwnd, // Parent HWND
                           0, // ID
                           hInstance, // Same hinstance used by parent
                           NULL);
  • 3
    The error code `ERROR_CANNOT_FIND_WND_CLASS` is fairly descriptive: You didn't register a window class named `"OpenGL"`. This is specifically spelled out in the documentation for [CreateWindowEx](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632680.aspx): *"lpClassName: A **null**-terminated string or a class atom created by a previous call to the [**RegisterClass**](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633586.aspx) or [**RegisterClassEx**](https://msdn.microsoft.com/en-us/library/windows/desktop/ms633587.aspx) function."* – IInspectable Aug 15 '15 at 21:28
  • Also, a child window needs to specify the `WS_CHILD` [window style](https://msdn.microsoft.com/en-us/library/windows/desktop/ms632600.aspx). `WS_CLIPCHILDREN`, on the other hand, is not needed for a window, that doesn't have child windows itself. – IInspectable Aug 15 '15 at 22:25
  • 1
    No, there is no built-in `OpenGL` window class. The NeHe tutorial creates the `OpenGL` window class itself. In your link, look near "In the next section of code, we grab an instance for our Window, then we declare the Window Class.". The other one does so too, but more subtly: it creates the `"OpenGL"` string as a global variable and uses `...` to omit the `WNDCLASS` lines, hoping you would fill in the blanks mentally. – andlabs Aug 15 '15 at 23:12
  • 1
    RegisterWindow solved it. I thought that it is needed only to register the parent, not child windows. I was wrong. – Matus Novak Aug 16 '15 at 06:50

0 Answers0