Does anyone can help me with the MDI ?!

Pages: 12
May 15, 2020 at 3:56pm
Yes.. this excludes the area occupied by child windows when drawing..
Now it works I have to find out why when I press the first time Act 1 the window is created then if close the child window you can not create another one cause the menu is GRAYED ..
and If you have an advice how can I make to open for example Act 1 just once.. _ Cause if I press continuously Act 1 would create child window until I stop pressing it hahaha :)
May 15, 2020 at 4:08pm
Ok, I just tested the venerable Charles Petzold "Programming Windows, 5th Edition" code for creating MDI apps, using Visual Studio 2019, and it worked for 32-bit without a hitch*.

https://github.com/recombinant/petzold-pw5e/tree/master/Chapter%2019%20The%20Multiple-Document%20Interface/MDIDemo

*The <stdlib.h> header is missing for rand, MS apparently no longer implicitly includes it with <windows.h> in the Windows SDK.

64-bit compiled but silently crashed after opening a child window requiring a change to several casts: from (long) to (LONG_PTR) to stop pointer truncation, and adding a cast to (UINT) for a conversion from WPARAM.

Yes, this example creates just two distinct child windows that can be created multiple times, but it does work with Win 10, x86 & x64. It could be a good jumping off point for adding one or more different child windows for your code.
May 15, 2020 at 4:39pm
Now it works I have to find out why when I press the first time Act 1 the window is created then if close the child window you can not create another one cause the menu is GRAYED


You need to handle what happens to the menu when THE LAST child MDI window is destroyed.

Insert bellow code into your MDIChildWndProc to handle this case, see comments for more info:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	// This message is sent after MDI child window is destroyed
	case WM_NCDESTROY:
	{
		// get active child from client window
		HWND active_child = reinterpret_cast<HWND>(SendMessage(hMDIClientWindow, WM_MDIGETACTIVE, 0, 0));

		// This will be true if client window has no child MDI windows any more
		if (!IsWindow(active_child))
		{
			HMENU hMenu = GetMenu(hMainWindow);

                        // Since I'm last child and destroyed re-enable "Act" menu only
			EnableMenuItem(hMenu, 1, MF_BYPOSITION | MF_ENABLED);

			DrawMenuBar(hMainWindow);
		}

		break; // Let system finish destruction
	}


I would follow Furry Guy suggestion, petzholds book is great to learn about MDI ;)
Last edited on May 15, 2020 at 4:46pm
May 15, 2020 at 4:47pm
OU yes... first I just eliminated the WM_MDIACTIVATE to see if this is the problem .. and now i can destroy window and create from Act 1 again.

And yes.. your code is working.. just fine...
Now for each Act on the menu I have to create a different child window.. this will be a little work.. :)
May 15, 2020 at 5:10pm
Although it works for you, problem is that this is bad design.
The "Act" menu should have stay disabled.

"Act" menu purpose is to show menu items for each of existing MDI child windows.
Your job is to to create new MDI window with File -> New
then update "Act" menu for each new child MDI, to include sub menus for each one.
When one is destroyed you also need to update "Act" menu to show less items, that is only for existing MDI childs.

when all childs are gone the "Act" menu is disabled and you again need File -> New.
The "Act" menu purpose is to switch which MDI child is active, and bring it to foreground when user selects sub item.

The purpose of File -> New is to create new child, "Act" menu only selects which child is active.

You bring MDI child to foreground by sending a message to MDI client.

That's how it's supposed to work.
Last edited on May 15, 2020 at 5:13pm
May 15, 2020 at 6:07pm
The Petzold code shows how to activate/deactive child window menus on the fly, when a child window is active or not in the client area.
May 15, 2020 at 6:23pm
I'm looking at Petzold right now .. :)
I was trying to do a while loop from your code bellow .. but without success .. :\
May 15, 2020 at 6:44pm
What are you trying to accomplish with a while loop?

The layout of code is very different for an MDI application, versus an SDI app. Compile the code AS IS first, after making the changes I indicated earlier. See what that code does first. A while loop may not be needed.
Topic archived. No new replies allowed.
Pages: 12