Thread: Child window inside child window

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Child window inside child window

    I'm having problems using child windows inside child windows. Thre creation works, but the window doesn't respond to any interaction. What I'm trying to do is a main window which has several child windows (like files, kinda) which have 1 text edit child window each. If I create the text edit as a normal window, or as a child to the main window it works fine, but when I create it as a child to a child window it doesn't work at all. Is this not even possible to do?
    Code:
    //Sets the text window styles
    	Style = WS_BORDER | WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_VISIBLE;
    	Style |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    	Style |= WS_CHILD | WS_CLIPSIBLINGS;
    
    	//Sets the starting location
    	StartWidth = 300;
    	StartHeight = 200;
    	StartX = 10;
    	StartY = 10;
    
    	//Creates the text window
    	TempWindow = CreateWindowEx(0, TextWindowClassName, "Unnamed", Style,
    								StartX, StartY, StartWidth, StartHeight,
    								MainWindow, NULL, GetModuleHandle(NULL), NULL);
    
    	//Aborts on creation failure
    	if(TempWindow == NULL)
    	{
    		Magos::Error.SetMessage("Unable to create text window!");
    		return FALSE;
    	}
    
    	//Sets the text edit styles
    	Style = ES_MULTILINE | ES_WANTRETURN | ES_LEFT | WS_VISIBLE;
    	Style |= WS_CHILD | WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
    
    	//Creates the text edit
    	TempTextWindow.TextEdit = CreateWindowEx(0, "EDIT", "Testing...", Style, 0, 0,
    											 StartWidth, StartHeight, TempWindow,
    											 reinterpret_cast<HMENU>(TextEditId),
    											 GetModuleHandle(NULL), NULL);
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Perhaps your TextEditId is causing a problem?
    hMenu
    [in] Handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.
    [EDIT]
    but you didn't say you have multiple edit's with the same parent....
    I'm not aware of any "child-of-a-child" limitation on an edit control.
    [/EDIT]

    gg
    Last edited by Codeplug; 04-19-2004 at 10:34 AM.

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Is DefWindowProc() being bypassed somewhere?

    gg

  4. #4
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    There is only 1 text edit per window, so it *shouldn't* be any problems. Even with 1 window it doesn't work, so I doubt that is the (primary) problem.

    I'm returning DefWindowProc in all cases where I don't handle the message myself, and 0 when I do. I dunno what more info I can give. I could post the message handler if you want.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  5. #5
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Or just write a very simple app that creates an edit box as a child-of-a-child so we can have something to run and see how it isn't behaving right.

    gg

  6. #6
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Even simple apps in winprog takes tons of code ^^. Anyway, here's a nerfed version of my app. The text edit inside the child window is non-responding.
    Code:
    #include <windows.h>
    
    HWND MainWindow = NULL;
    HWND ChildWindow = NULL;
    HWND ChildChildWindow = NULL;
    
    //+-----------------------------------------------------------------------------
    
    LRESULT MainMessageHandler(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch(Message)
    	{
    		case WM_CLOSE:
    		{
    			PostQuitMessage(0);
    			return 0;
    		}
    
    		case WM_DESTROY:
    		{
    			return 0;
    		}
    	}
    	return DefWindowProc(Window, Message, wParam, lParam);
    }
    
    //+-----------------------------------------------------------------------------
    
    BOOL Setup()
    {
    	DWORD Style;
    	WNDCLASSEX ClassInfo;
    
    	ClassInfo.cbSize = sizeof(WNDCLASSEX);
    	ClassInfo.style = CS_HREDRAW | CS_VREDRAW;
    	ClassInfo.cbClsExtra = 0;
    	ClassInfo.cbWndExtra = 0;
    	ClassInfo.hInstance = GetModuleHandle(NULL);
    	ClassInfo.hCursor = LoadCursor(NULL, IDC_ARROW);
    	ClassInfo.hIconSm = NULL;
    	ClassInfo.lpfnWndProc = reinterpret_cast<WNDPROC>(MainMessageHandler);
    	ClassInfo.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	ClassInfo.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_APPWORKSPACE + 1);
    	ClassInfo.lpszMenuName = NULL;
    	ClassInfo.lpszClassName = "MainClass";
    
    	if(!RegisterClassEx(&ClassInfo)) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = WS_BORDER | WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_VISIBLE;
    	Style |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    	Style |= WS_CLIPCHILDREN;
    
    	MainWindow = CreateWindowEx(0, "MainClass", "Main Window", Style,
    								100, 100, 500, 400,
    								NULL, NULL, GetModuleHandle(NULL), NULL);
    
    	if(MainWindow == NULL) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = WS_BORDER | WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_VISIBLE;
    	Style |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    	Style |= WS_CHILD | WS_CLIPSIBLINGS;
    
    	ChildWindow = CreateWindowEx(0, "MainClass", "Child Window", Style,
    								 50, 50, 200, 200,
    								 MainWindow, NULL, GetModuleHandle(NULL), NULL);
    
    	if(ChildWindow == NULL) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = ES_MULTILINE | ES_WANTRETURN | ES_LEFT | WS_VISIBLE;
    	Style |= WS_CHILD | WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
    
    	ChildChildWindow = CreateWindowEx(0, "EDIT", "Child Child Window", Style,
    									  0, 0, 192, 166,
    									  ChildWindow, reinterpret_cast<HMENU>(1337),
    									  GetModuleHandle(NULL), NULL);
    
    	if(ChildChildWindow == NULL) return FALSE;
    
    	return TRUE;
    }
    
    //+-----------------------------------------------------------------------------
    
    VOID Shutdown()
    {
    	if(ChildChildWindow != NULL) DestroyWindow(ChildChildWindow);
    	if(ChildWindow != NULL) DestroyWindow(ChildWindow);
    	if(MainWindow != NULL) DestroyWindow(MainWindow);
    }
    
    //+-----------------------------------------------------------------------------
    
    INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
    {
    	MSG Message;
    
    	if(!Setup())
    	{
    		Shutdown();
    		return 0;
    	}
    
    	while(GetMessage(&Message, NULL, 0, 0))
    	{
    		TranslateMessage(&Message);
    		DispatchMessage(&Message);
    	}
    
    	Shutdown();
    	return 0;
    }
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Remove the WS_CAPTION style from child window (the parent of the edit) control and you can access/use the edit control but obviously lose the other style capabilities.

    By the look of your layout I think a multiple document interface may be a better approach...
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  8. #8
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    But removing WS_CAPTION removes the window looks of it, making it a stiff but resizeable frame. Also, WHY does it not work with WS_CAPTION?

    I'll take a look at MDI...
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  9. #9
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Ken is right.
    You will need MDI to achieve what you want.
    It looks like the problem is that the main window doesn't want to give up being active (notice that the child window is always grayed) and the main window never gives up keyboard focus so the edit control looks stagnant.

    gg

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    You can use SetParent to achieve what you want.
    Also, WndProc uses the CALLBACK calling convention and you do not need to cast it unless you have done something wrong.
    Corrected sample:
    Code:
    #include <windows.h>
    
    HWND MainWindow = NULL;
    HWND ChildWindow = NULL;
    HWND ChildChildWindow = NULL;
    
    //+-----------------------------------------------------------------------------
    
    LRESULT CALLBACK MainMessageHandler(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch(Message)
    	{
    		case WM_CLOSE:
    		{
    			PostQuitMessage(0);
    			return 0;
    		}
    
    		case WM_DESTROY:
    		{
    			return 0;
    		}
    	}
    	return DefWindowProc(Window, Message, wParam, lParam);
    }
    
    //+-----------------------------------------------------------------------------
    
    BOOL Setup()
    {
    	DWORD Style;
    	WNDCLASSEX ClassInfo;
    
    	ClassInfo.cbSize = sizeof(WNDCLASSEX);
    	ClassInfo.style = CS_HREDRAW | CS_VREDRAW;
    	ClassInfo.cbClsExtra = 0;
    	ClassInfo.cbWndExtra = 0;
    	ClassInfo.hInstance = GetModuleHandle(NULL);
    	ClassInfo.hCursor = LoadCursor(NULL, IDC_ARROW);
    	ClassInfo.hIconSm = NULL;
    	ClassInfo.lpfnWndProc = MainMessageHandler;
    	ClassInfo.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    	ClassInfo.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_APPWORKSPACE + 1);
    	ClassInfo.lpszMenuName = NULL;
    	ClassInfo.lpszClassName = "MainClass";
    
    	if(!RegisterClassEx(&ClassInfo)) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = WS_BORDER | WS_CAPTION | WS_SIZEBOX | WS_SYSMENU | WS_VISIBLE;
    	Style |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    	Style |= WS_CLIPCHILDREN;
    
    	MainWindow = CreateWindowEx(0, "MainClass", "Main Window", Style,
    								100, 100, 500, 400,
    								NULL, NULL, GetModuleHandle(NULL), NULL);
    
    	if(MainWindow == NULL) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = WS_BORDER | WS_CAPTION  | WS_SIZEBOX | WS_SYSMENU | 0;
    	Style |= WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
    	Style |= 0 | WS_CLIPSIBLINGS | WS_SYSMENU;
    
    	ChildWindow = CreateWindowEx(0, "MainClass", "Child Window", Style,
    								 50, 50, 200, 200,
    								 MainWindow, NULL, GetModuleHandle(NULL), NULL);
    	SetParent(ChildWindow, MainWindow);
    	ShowWindow(ChildWindow, SW_SHOW);
    
    
    	if(ChildWindow == NULL) return FALSE;
    
    	//+---------------------------------------------
    
    	Style = ES_MULTILINE | ES_WANTRETURN | ES_LEFT | WS_VISIBLE;
    	Style |= WS_CHILD | WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
    
    	ChildChildWindow = CreateWindowEx(0, "EDIT", "Child Child Window", Style,
    									  0, 0, 192, 166,
    									  ChildWindow, reinterpret_cast<HMENU>(1337),
    									  GetModuleHandle(NULL), NULL);
    
    
    	if(ChildChildWindow == NULL) return FALSE;
    
    	return TRUE;
    }
    
    //+-----------------------------------------------------------------------------
    
    VOID Shutdown()
    {
    	if(ChildChildWindow != NULL) DestroyWindow(ChildChildWindow);
    	if(ChildWindow != NULL) DestroyWindow(ChildWindow);
    	if(MainWindow != NULL) DestroyWindow(MainWindow);
    }
    
    //+-----------------------------------------------------------------------------
    
    INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
    {
    	MSG Message;
    
    	if(!Setup())
    	{
    		Shutdown();
    		return 0;
    	}
    
    	while(GetMessage(&Message, NULL, 0, 0))
    	{
    		TranslateMessage(&Message);
    		DispatchMessage(&Message);
    	}
    
    	Shutdown();
    	return 0;
    }
    http://groups.google.com/groups?thre...defix.eunet.fi

  11. #11
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Thank you very much. Apart from the text edit bug, that solved 2 other things I've had problems with too.

    *leaps away singing*

    EDIT: Correction. 3 (!) other things, namely child window overlaps, active child windows (they were always grayed) and a slight rendering problem (bottom right wasn't re-rendered).
    Last edited by Magos; 04-20-2004 at 05:05 AM.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  12. #12
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    It's amaizing how something like that can escape you for years......thanks MFC!

    gg

  13. #13
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    On a related note, is it possible to have a child window non-grayed when you select the main window (so both the main and the child stays non-grayed)?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  14. #14
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Just eat the WM_NCACTIVATE message when appropriate:
    Code:
    LRESULT CALLBACK MainMessageHandler(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam)
    {
    	switch(Message)
    	{
    		case WM_CLOSE:
    		{
    			PostQuitMessage(0);
    			return 0;
    		}
    
    		case WM_DESTROY:
    		{
    			return 0;
    		}
    
    		case WM_NCACTIVATE:
    			if (Window == ChildWindow && wParam == FALSE) return TRUE;
    	}
    	return DefWindowProc(Window, Message, wParam, lParam);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. Linking OpenGL in Dev-C++
    By linkofazeroth in forum Game Programming
    Replies: 4
    Last Post: 09-13-2005, 10:17 AM
  3. input/output
    By dogbert234 in forum Windows Programming
    Replies: 11
    Last Post: 01-26-2005, 06:57 AM
  4. Adding colour & bmps to a Win 32 Window??
    By carey_sizer in forum Windows Programming
    Replies: 4
    Last Post: 09-04-2004, 05:55 PM
  5. problem with open gl engine.
    By gell10 in forum Game Programming
    Replies: 1
    Last Post: 08-21-2003, 04:10 AM