Перед тем, как перейти к рассмотрению дочерних окон документов, разберемся с обработкой сообщений в FrameWndProc. При выборе в меню File опции Close программа MDIDEMO закрывает активное дочернее окно. Описатель активного дочернего окна она получает, посылая окну - сообщение WM_MDIGETACTIVE. Если дочернее окно отвечает утвердительно на сообщение WM_QUERYENDSESSION, то программа MDIDEMO для закрытия дочернего окна посылает окну - сообщение WM_MDIDESTROY.
Для обработки опции Exit меню File необходимо только, чтобы оконная процедура главного окна послала себе сообщение WM_CLOSE.
Обработать опции Tile, Cascade и Arrange Icons из подменю Window проще простого, нужно только послать окну - сообщения WM_MDITILE, WM_MDICASCADE и WM_MDIICONARRANGE.
Обработка опции Close All несколько сложнее. FrameWndProc вызывает функцию EnumChildWindows, передавая указатель на функцию CloseEnumProc. Эта функция посылает сообщение WM_MDIRESTORE каждому дочернему окну, затем сообщение WM_QUERYENDSESSION и сообщение WM_MDIDESTROY. Этого не делается для окна заголовка значка, определяемого, если возвращаемое значение функции GetWindow c параметром GW_OWNER не равно NULL.
Все сообщения , которые оконная процедура главного окна не обрабатывает , должны передаваться в DefFrameProc. Эта функция заменяет в оконной процедуре главного окна функцию DefWindowProc. Даже если оконная процедура главного окна и перехватывает сообщения WM_MENUCHAR, WM_SETFOCUS или WM_SIZE, все равно они должны передаваться в DefFrameProc.
Необрабатываемые сообщения WM_COMMAND также должны передаваться в DefFrameProc. В частности, FrameWndProc не обрабатывает сообщений WM_COMMAND, появившихся в результате того, что пользователь выбирает один из документов из списка в подменю Window. ( параметра wParam для этих опций начинается с IDM_FIRSTCHILD.) Эти сообщения передаются в DefFrameProc и обрабатываются там. Обратите внимание , что главному окну не нужно поддерживать список описателей окон всех созданных документов . При необходимости (, при обработке опции Close All из меню ), эти описатели можно получить , вызывая функцию EnumChildWindows.