Creating a child window?

Started by
17 comments, last by MatsVed 14 years, 1 month ago
I'm creating an installer in C++ (or at least I'm trying to...) I messed around a bit to get the standard Win32 application to display a bitmap on the main window. Now I'd like a child window on top of the main window that is borderless! I couldn't actually find any examples of this on Google Image Search, so I made a mockup: ; This is what my InitInstance() function looks like:
//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
   HWND ChildWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   ChildWnd = CreateWindow(szChldWndClass, szTitle, WS_OVERLAPPEDWINDOW,
	   CW_USEDEFAULT, WS_VISIBLE | WS_CHILD | BS_VCENTER | BS_CENTER, 
	   500, 100, NULL, NULL, hInst, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   ShowWindow(ChildWnd, nCmdShow);
   UpdateWindow(hWnd);
   UpdateWindow(ChildWnd);

   return TRUE;
}


The child window still doesn't display! Why is this?
Advertisement
You need to define the parent in CreateWindowEx if you want to make it a real child window

   ChildWnd = CreateWindow(szChldWndClass, szTitle, WS_OVERLAPPEDWINDOW,	   CW_USEDEFAULT, WS_VISIBLE | WS_CHILD | BS_VCENTER | BS_CENTER, 	   500, 100, hWnd /* Parent Parameter */, NULL, hInst, NULL);

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Thanks! :)

The window still doesn't display though :(
You have
ChildWnd = CreateWindow(szChldWndClass, szTitle, WS_OVERLAPPEDWINDOW,	   CW_USEDEFAULT, WS_VISIBLE | WS_CHILD | BS_VCENTER | BS_CENTER, 	   500, 100, NULL, NULL, hInst, NULL);
You want
ChildWnd = CreateWindow(szChldWndClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CHILD | BS_VCENTER | BS_CENTER,	   CW_USEDEFAULT, CW_USEDEFAULT, 	   500, 100, NULL, NULL, hInst, NULL);
I question the BS_VCENTER and BS_CENTER styles though...
[edit] Plus you want to include the parent hWnd as Rattrap specified of course
[edit again] Plus WS_OVERLAPPEDWINDOW will give you a border ... but get the thing to display first and then mess with the styles I'd say.
Thanks again!
Still doesn't display...

Should I call BeginPaint() on the childwindow? And where should I call it?
Also, when you create your main window:
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

In order you have
CW_USEDEFAULT, // x pos
0, // y pos
CW_USEDEFAULT, // width
0, // height
So you create your parent window with a height of 0. Nothing will display, and your button/editbox/whatever child window you are making of course won't display because there is no parent window to display.
try CW_USEDEFAULT, CW_USEDEFAULT, 600, 200
or something since your child window is 500x100 and needs to fit inside it.

Note that CW_USEDEFAULT will pretty much plop the window anywhere, and the child. If you know where you want them, specify.
You might want to use CreateWindowEx instead of the CreateWindow macro, so that you can specify WS_EX_TRANSPARENT, which might be necessary to achieve the effect shown in your mock up.

Also, and probably more importantly, you need to specify an identifier for the window in the hMenu parameter.

Quote:
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.


Identifiers are usually #define[d] in the resource header.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
I am not sure exactly what you are trying to achieve.
You want a see through Box where you can display Text. Is that it?
WS_EX_TRANSPARENT should do the Trick.
The only Alternative, which requires a bit of Work, is creating a normal Child Window and then during WM_PAINT, send a Message to the Parent to request it to paint itself in the Child's Device Context, then the Child paints on top of that. This second Option would give you also the possibility of Alphablending.
Which is a very nice Effect.
You're probably drawing over the top of your child window. Try adding WS_CLIPCHILDREN to the parent. In addition to what popsoftheyear and rattrap said.
-Mike
I don't want my child window to be transparent!
I just want it to be like a normal window, but without a border!

I already created an ID... I had to, to be able to call LoadString() in the beginning;

	// 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);


I added the ID to the hMenu param, and used WS_CLIPCHILDREN on the parent:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){   HWND hWnd;   HWND ChildWnd;   hInst = hInstance; // Store instance handle in our global variable   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   ChildWnd = CreateWindow(szChldWndClass, szTitle, WS_OVERLAPPEDWINDOW | WS_VISIBLE | 	   WS_CHILD | BS_VCENTER | BS_CENTER, CW_USEDEFAULT, CW_USEDEFAULT, 	   500, 100, hWnd, (HMENU)IDC_INSTALLER_CHLD, hInst, NULL);   if (!hWnd)   {      return FALSE;   }   ShowWindow(hWnd, nCmdShow);   ShowWindow(ChildWnd, nCmdShow);   UpdateWindow(hWnd);   UpdateWindow(ChildWnd);   return TRUE;}


The child window still isn't displaying!

Edit:

This is how I'd like the child window to be, without the image and the border:

This topic is closed to new replies.

Advertisement