Creating a child window?

Started by
17 comments, last by MatsVed 14 years, 1 month ago
Your main window is being created with a height of 0, thus it doesn't really exist, so there is no where for the child window to go since it's parent isn't even there. Read my most recent post that explains why and what to do. Then, check all your parameters for CreateWindow and figure out if you did everything you meant to.

My recommendation? Comment out code for the child control, and get your parent window to display first. No sense in trying to get the child control to display if you can't get the parent first.
Advertisement
Uhm, what?
The parent window is in the first post! It's been displayed all along!

Edit: Don't ask me how it's displayed with a height of 0, but it's there!
Your (revised) code works for me.

You aren't checking for errors in the second CreateWindow call. I suspect CreateWindow is failing and you're getting back NULL for ChildWnd. If that's true then 99% of the time it's failing because you've screwed up your WndProc, does the WndProc for the child window ever get called?

It could also be something like you forgot to register your szChldWndClass or for some reason RegisterClass[Ex] is failing. Just for testing purposes I would recommend you try one of the built-in window classes (e.g. "EDIT" rather than szChldWndClass) and see if that works.

Some more nitpicking for whenever you get it figured out:

You say you want the child to be borderless but you're specifying WS_OVERLAPPEDWINDOW.

BS_* styles apply to the built-in BUTTON window class yet it looks very much like you're using a custom window class for your child.

Calling ShowWindow on the child window with nCmdShow is just plain wierd.

Calling UpdateWindow is (very likely) completely unnecessary.

You really need to read the docs about for CreateWindow, the large number of minor errors you're making make me suspect you're just cut&pasting code.
-Mike
I did read the docs about CreateWindow(), but it doesn't seem to explain anything about creating child windows?
I've been Googling around for tutorials on this topic, but there really isn't much information available, so I've had to guesstimate which functions to call and where.

How do I call RegisterClassEx() for the child window?!
The only time it's being called at present is after initializing the global strings;

	// Initialize global strings	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);	LoadString(hInstance, IDC_INSTALLER, szWindowClass, MAX_LOADSTRING);	LoadString(hInstance, IDC_INSTALLER_CHLD, szChldWndClass, MAX_LOADSTRING);	MyRegisterClass(hInstance);


This is what MyRegisterClass looks like:

////  FUNCTION: MyRegisterClass()////  PURPOSE: Registers the window class.////  COMMENTS:////    This function and its usage are only necessary if you want this code//    to be compatible with Win32 systems prior to the 'RegisterClassEx'//    function that was added to Windows 95. It is important to call this function//    so that the application will get 'well formed' small icons associated//    with it.//ATOM MyRegisterClass(HINSTANCE hInstance){	WNDCLASSEX wcex;	wcex.cbSize = sizeof(WNDCLASSEX);	wcex.style			= CS_HREDRAW | CS_VREDRAW;	wcex.lpfnWndProc	= WndProc;	wcex.cbClsExtra		= 0;	wcex.cbWndExtra		= 0;	wcex.hInstance		= hInstance;	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_INSTALLER));	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_INSTALLER);	wcex.lpszClassName	= szWindowClass;	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));	return RegisterClassEx(&wcex);}


Anyways, I added a function called EnumChildProc() that is supposed to (I think) redraw any child windows when the parent window has changed size. I found it in this article.

BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam) {     LPRECT rcParent;     int i, idChild;      // Retrieve the child-window identifier. Use it to set the     // position of the child window.      idChild = GetWindowLong(hwndChild, GWL_ID);      if (idChild == IDC_INSTALLER_CHLD)         i = 0;     else         i = 2;      // Size and position the child window.       rcParent = (LPRECT) lParam;     MoveWindow(hwndChild,                (rcParent->right / 3) * i,                0,                rcParent->right / 3,                rcParent->bottom,                TRUE);      // Make sure the child window is visible.      ShowWindow(hwndChild, SW_SHOW);      return TRUE;}


I'm calling it from my WndProc() like so:

	case WM_SIZE: //main window changed size 		// Get the dimensions of the main window's client         // area, and enumerate the child windows. Pass the         // dimensions to the child windows during enumeration.         GetClientRect(hWnd, &rcClient);         EnumChildWindows(hWnd, EnumChildProc, (LPARAM) &rcClient);         return 0; 


It doesn't seem to have helped anything though...

I am at a loss as to what to do at this point! :(
Focus on getting the window up and running before worrying about the style or about repainting it after the parent window has been resized.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
You aren't registering a class for your child window.
-Mike
The question is;

How do I do it? :\
The following are instructions for creating a custom child window that I posted in an old thread. I'm calling it "FrameWindow" because the OP in that thread wanted to use it as a Win32 parent for other child controls, but call it whatever you want.
Quote:
1.) Register your custom frame class. Write something like the following and then call it when your app starts up:
void RegisterMyFrameClass(HINSTANCE app_instance) {    WNDCLASSEX  wndclass;    ZeroMemory(&wndclass, sizeof (wndclass));    wndclass.cbSize        = sizeof (wndclass) ;    wndclass.style         = CS_HREDRAW | CS_VREDRAW;    wndclass.lpfnWndProc   =  MyFrameWindowProc;    wndclass.cbWndExtra    = 0 ;    wndclass.hInstance     = app_instance;    wndclass.lpszMenuName  = NULL ;    wndclass.lpszClassName = "MyFrameClass";    wndclass.hbrBackground = GetSysColorBrush(COLOR_WINDOW);    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);    RegisterClassEx(&wndclass);}

2.) Write a barebones window procedure like the following. You could actually just use DefWindowProc in the wndclass above, but you may find that you want the frame to do something and you'll have to add this later anyway.
LRESULT MyFrameWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)    return DefWindowProc(hwnd, msg, wparam, lparam);}

3.) Create a frame by calling a function like this:
HWND CreateFrameWindow(HWND parent, int id, HINSTANCE app_inst,                        int x, int y, int wd, int hgt) {    return CreateWindowEx(0, "MyFrameClass", "", WS_CHILD|WS_VISIBLE,                       x, y, wd, hgt, parent, (HMENU)id, app_inst, NULL);}

4.) When you create your controls use the hwnd of your frame as their parent.

Just do this in your program, put a break point in the MyFrameWindowProc, and if execution hits the break point you've created a child window.
Got it working!

Thanks! :D

This topic is closed to new replies.

Advertisement