I am posting the answer to the question as suggested by a comment :
The answer is that for the window creation to complete, the pWndProc passed to RegisterClass WINAPI has to process default messages (in particular OS messages).
During the execution of CreateWindow(after the call has started and before it has returned), the pWndProc function already receives messages that it has to process, in my case it didn't process them.
This is a standard pWndProc function:
LRESULT CALLBACK pWndProc(HWND hwnd, // Handle to our main window
UINT Msg, // Our message that needs to be processed
WPARAM wParam, // Extra values of message
LPARAM lParam) // Extra values of message
{
switch (Msg)
{
case WM_DESTROY:
...
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
}
source :
A window procedure does not usually ignore a message. If it does not process a message, it must send the message back to the system for default processing. The window procedure does this by calling the DefWindowProc function, which performs a default action and returns a message result. The window procedure must then return this value as its own message result. Most window procedures process just a few messages and pass the others on to the system by calling DefWindowProc.