Thread: Can't create child windows

  1. #1
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555

    Can't create child windows

    I am trying to make one main window and inside that one I want to have one window that renders OpenGL stuff and another one that is an edit control. So I made this:
    Code:
    const char wndclass[] = "OpenGL Program";
    const char oglclass[] = "OpenGL Renderer";
    WNDPROC oldconproc;
    HWND window;
    
    int WINAPI WinMain (HINSTANCE inst, HINSTANCE pinst, char* args, int show)
    {
    	WNDCLASSEX wc;
    	WNDCLASSEX oc;
    	MSG msg;
    
    	ZeroMemory(&wc, sizeof(wc));
    	wc.cbSize        = sizeof(wc);
    	wc.lpfnWndProc   = wndproc;
    	wc.hInstance     = inst;
    	wc.hbrBackground = COLOR_WINDOW;
    	wc.lpszClassName = wndclass;
    
    	ZeroMemory(&oc, sizeof(oc));
    	oc.cbSize        = sizeof(oc);
    	oc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    	oc.lpfnWndProc   = oglproc;
    	oc.hInstance     = inst;
    	oc.hbrBackground = COLOR_WINDOW;
    	oc.lpszClassName = oglclass;
    
    	if (!RegisterClassEx(&wc) || !RegisterClassEx(&oc)) {
    		Error();
    		return 1;
    	}
    	window = CreateWindowEx(WS_EX_CLIENTEDGE, wndclass, "OpenGL", WS_OVERLAPPEDWINDOW,
    	                        CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, inst, NULL);
    	if (window == NULL) {
    		Error();
    		return 1;
    	}
    	ShowWindow(window, show);
    	UpdateWindow(window);
    
    	while (GetMessage(&msg, NULL, 0, 0) > 0) {
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    
    	return msg.wParam;
    }
    This part of the code runs fine, but when it gets to WM_CREATE for the window I just made it throws me an error because it couldn't create neither of the two child windows with the error message "Cannot create a top-level child window.".

    The wndproc function, cut off to show the important parts:
    Code:
    LRESULT CALLBACK wndproc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
    {
    	static HWND ogl;
    	static HWND con;
    	static int fonth;
    
    	switch (msg) {
    		case WM_CREATE:
    		{
    			HFONT font, oldfont;
    			HDC condc;
    			TEXTMETRIC tm;
    
    			font = CreateFont(-MulDiv(12, GetDeviceCaps(GetDC(hwnd), LOGPIXELSY), 72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Shell Dlg"));
    			/*Here comes the trouble makers*/
    			ogl = CreateWindowEx(0, oglclass, TEXT(""), WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 0, 0, window, NULL, GetModuleHandle(NULL), NULL);
    			con = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("EDIT"), TEXT(""), WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 0, 0, 0, 0, window, NULL, GetModuleHandle(NULL), NULL);
    			if (font == NULL || ogl == NULL || con == NULL) { /*End of the line*/
    				Error();
    				PostQuitMessage(1);
    				break;
    			}
    			oldconproc = SetWindowLongPtr(con, GWLP_WNDPROC, (LONG_PTR) conproc);
    			SendMessage(con, WM_SETFONT, (WPARAM) font, MAKELPARAM(FALSE, 0));
    			condc = GetDC(con);
    			oldfont = SelectObject(condc, font);
    			GetTextMetrics(condc, &tm);
    			SelectObject(condc, oldfont);
    			ReleaseDC(con, condc);
    			fonth = tm.tmHeight;
    			break;
    		}
    'ogl' is the child window that is to draw the OpenGL stuff and 'con', for console, is the edit control.
    Looking up the error message doesn't help me solve my problem, "As part of its user interface, an application has tried to create a child window at an inappropriate level.", what are these "levels" to begin with?

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    The variable window isn't a valid window handle until CreateWindowEx returns (recall that a WM_CREATE message is issued during system processing of that api function) so the child windows essentially have a NULL handle as a parent. A top-level window is a non-child window, like your main window.

    Just use the HWND parameter passed to the window procedure in the WM_CREATE handler as the parent handle when creating the child windows .
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    You're right, I had forgotten about that, even though I copypasted stuff from another program which used hwnd instead. :|
    Now it works fine, except that the OpenGL window isn't showing anything. EDIT: Forgot WS_VISIBLE. Now everything's like it should.
    Last edited by OnionKnight; 11-30-2006 at 08:15 PM.

  4. #4
    Registered User
    Join Date
    Apr 2011
    Posts
    1

    Opengl multiiwindow ...

    Hey OnionKnight,

    I am kinda stuck in the sam eproblem as yours. Since you were able to reneder to opengl, I thought you may be able to help me. I tired modifying my code according to yours but was not successful when it came to graphics. Can you have a looka t my code and see where am I wrong? My code compiles uccesfully but I do not see anything on the ogl window.

    Thank you in anticipation.
    Vijay

    Code:
    #include "windows.h"
    #include "commctrl.h"
    #include "resource.h"
    #include "gl/gl.h"
    #include "gl/glu.h"
    #include "rates.h"
    
    HWND    hWnd, hStatusBar, hRunTimeInfo, ogl;
    HDC     hDC, hOGLDC, runHDC;
    HGLRC   hRC, hOGLRC;
    RECT rcStatusBar, rcMain;
    const LPCWSTR appname = TEXT("OpenGL Sample");
    const LPCWSTR oglname = TEXT("OpenGLName");
    
    double  r, b, g;
    
    
    void DrawGraphics()
    {
    	//wglMakeCurrent(hOGLDC, hOGLRC);
      	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glTranslated(0, 0, -10);
    	
    	double x = -3, y =-0.25;
    	double w = 0.5 , h = 0.005;
        // Draw a square
    	for (x=-3;x<=3;x+=h)
    	{
    r  = 255; b = 0, g = 0;
    	glBegin(GL_QUADS);
      	glColor3d(r/255,g/255,b/255);
        glVertex3d(y,x, 0);
        glVertex3d(y+w, x, 0);
        glVertex3d(y+w, x+h,  0);
        glVertex3d(y, x+h, 0);
        glEnd();
    	}
        SwapBuffers(hDC);
    }
    
    // Set up pixel format for graphics initialization
    void SetupPixelFormat()
    {
        PIXELFORMATDESCRIPTOR pfd, *ppfd;
        int pixelformat;
        ppfd = &pfd;
        ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
        ppfd->nVersion = 1;
        ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        ppfd->dwLayerMask = PFD_MAIN_PLANE;
        ppfd->iPixelType = PFD_TYPE_COLORINDEX;
        ppfd->cColorBits = 16;
        ppfd->cDepthBits = 16;
        ppfd->cAccumBits = 0;
        ppfd->cStencilBits = 0;
        pixelformat = ChoosePixelFormat(hDC, ppfd);
        SetPixelFormat(hDC, pixelformat, ppfd);
    }
    
    
    // Initialize OpenGL graphics
    void InitGraphics()
    {
        hDC = GetDC(hWnd);
        SetupPixelFormat();
        hRC = wglCreateContext(hDC);
        wglMakeCurrent(hDC, hRC);
        glClearColor(0, 0, 0, 0.5);
        glClearDepth(1.0);
        glEnable(GL_DEPTH_TEST);
    }
    
    
    // Resize graphics to fit window
    
    // Handle window events and messages
    LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM  wParam, LPARAM  lParam)
    {
    	const LPCWSTR file = TEXT("File");
    	const LPCWSTR save = TEXT("Save");
    	const LPCWSTR saveas = TEXT("Save As");
    	const LPCWSTR exit = TEXT("Exit");
        switch (uMsg)
        {
    	case WM_CREATE:
        {
    		ogl = CreateWindowEx(0, oglname, TEXT(""), WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE, 225 , 0, rcMain.top - 225, rcMain.bottom-rcStatusBar.bottom, hWnd, NULL, GetModuleHandle(NULL), NULL);
    		InitGraphicsOGL();
    	}
        case WM_SIZE:
           
            break;
    
        case WM_CLOSE: 
            DestroyWindow(hWnd);
            break;
     
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
     
        // Default event handler
        default: 
            return DefWindowProc (hWnd, uMsg, wParam, lParam); 
            break; 
        } 
     
        return 1; 
    }
    
    int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
    {
        WNDCLASS wndclass;
        MSG      msg;
    	
        // Define the window class
        wndclass.style         = 0;
        wndclass.lpfnWndProc   = (WNDPROC)MainWndProc;
        wndclass.cbClsExtra    = 0;
        wndclass.cbWndExtra    = 0;
        wndclass.hInstance     = hInstance;
        wndclass.hIcon         = LoadIcon(hInstance, appname);
        wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT);
        wndclass.lpszMenuName  = NULL;
        wndclass.lpszClassName = appname;
    
    
    	WNDCLASS oc;
    	WNDPROC oglproc;
        // Define the window class
    	oc.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    	oc.lpfnWndProc   = (WNDPROC)MainWndProc;
    	oc.hInstance     = hInstance;
    	oc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    	oc.lpszClassName = oglname;
    
        RegisterClass(&wndclass);
    	RegisterClass(&oc);
        hWnd = CreateWindow(appname, appname, WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL);
        InitGraphics();
        ShowWindow(hWnd, nCmdShow);
        UpdateWindow(hWnd);
    	InitCommonControls();
    	hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD|WS_VISIBLE|SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, NULL, hInstance,NULL); 
    	GetClientRect(hWnd, &rcMain);
    	GetClientRect(hStatusBar, &rcStatusBar);
    	hRunTimeInfo = CreateWindowEx(0, TEXT("STATIC"), NULL, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE , 0, 0, 225, rcMain.bottom-rcStatusBar.bottom, hWnd, NULL, hInstance, 0); //rcMain.bottom-rcStatusBar.bottom
    	
    		// Event loop
        while (1)
        {
            if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
            {
                if (!GetMessage(&msg, NULL, 0, 0)) return TRUE;
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
            DrawGraphics();
        }
        wglDeleteContext(hRC);
        ReleaseDC(hWnd, hDC);
    }
    EDIT: Code tags added by moderator.
    Last edited by VirtualAce; 04-10-2011 at 04:15 PM.

  5. #5
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    @dotrana:
    Do not hijack threads to get help on your own code. Create a new thread. Also read the rules and please use code tags when posting code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 10-15-2008, 09:24 AM
  2. Removing/Hiding Child Windows
    By Hysteresis in forum Windows Programming
    Replies: 4
    Last Post: 07-14-2006, 11:50 AM
  3. Child window inside child window
    By Magos in forum Windows Programming
    Replies: 13
    Last Post: 04-20-2004, 06:51 AM
  4. child windows
    By face_master in forum Windows Programming
    Replies: 14
    Last Post: 03-01-2002, 07:08 AM