Windows SDK programming-create an MDI window

Source: Internet
Author: User

I. Overview
The MDI window contains a frame window and a dry window.
In fact, the Framework Window itself is a common main window, but its customers are overwritten by a special window.
This special window is a pre-defined window class named "MDICLIENT ". It manages the child windows of MDI.

Ii. Window Creation
1. register an MDI framework window class and provide message processing functions for the MDI Framework Window.
In the message processing function of the MDI Framework Window, unprocessed messages are handed over to DefFrameProc for processing.

// Message processing function lresult callback MDIFrameWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ){//... // other messages are sent to the DefFrameProc, the default framework processing function provided by the system. // The second parameter is the client zone window handle return: DefFrameProc (hwnd, hwndClient, message, wParam, lParam );}

2. register multiple MDI subwindow classes and provide message processing functions for each MDI subwindow
In the subwindow message processing function, unprocessed messages are sent to MDIDefMDIChildProc for processing.

// Message processing function lresult callback MDIChildWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam ){//... //... // return: DefMDIChildProc (hwnd, message, wParam, lParam );}

3. Create an MDI management subwindow in the customer area of the Framework Window.
The management of the MDI subwindow is actually completed by the "MDILIENT" window in the customer area of the Framework Window.
This is a pre-defined window of the system.

After receiving the WM_CREATE message in the main window:

Case WM_CREATE: {hinst = (LPCREATESTRUCT) lParam)-> hInstance; // fill in CLIENTCREATESTRUCT structure CLIENTCREATESTRUCT clientcreate; clientcreate. hWindowMenu = hMenuInitWindow; // The menu handle used to add the window list clientcreate. idFirstChild = 50000; // start ID hwndClient = createjavaswex (0, "MDICLIENT", // The class name is "MDICLIENT" NULL, WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) 1, // ID hinst, // instance handle & clientcreate); // parameter} return 0;

The window size does not matter. The default Framework Window message processing function overwrites the entire customer zone.
After the MDI customer window is created, the establishment, destruction, and arrangement of the Message Management subwindow are sent to it.

4. Create an MDI subwindow
You can add command items in the menu to create a subwindow.
After receiving the command, the message processing function in the Framework Window sends the creation command to the MDI client window.

Case ID_NEW: {MDICREATESTRUCT mdicreate; mdicreate. szClass = szMDIChildName; // The Class Name of the MDI child window mdicreate. szTitle = TEXT ("Hello"); mdicreate. hOwner = hinst; mdicreate. x = CW_USEDEFAULT; mdicreate. y = CW_USEDEFAULT; mdicreate. cx = CW_USEDEFAULT; mdicreate. cy = CW_USEDEFAULT; mdicreate. style = 0; mdicreate. lParam = 0; SendMessage (hwndClient, // MDI client window handle WM_MDICREATE, // create MDI child window 0, (LPARAM) (LPMDICREATESTRUCT) & mdicreate // create parameters );} break;

3. process the MDI-specific hotkeys in a message loop
In a message loop, use TranslateMDISysAccel to process the hot key for MDI.

while (GetMessage (&msg, NULL, 0, 0)){       if (!TranslateMDISysAccel (hwndClient, &msg) &&           !TranslateAccelerator (hwndFrame, hAccel, &msg))       {            TranslateMessage (&msg) ;            DispatchMessage (&msg) ;       }}

Iv. Command Flow
After receiving notifications such as WM_COMMAND, the Framework Window should provide a processing opportunity for the currently activated MDI window.

Case WM_COMMAND: switch (LOWORD (wParam) {// Command case ID_ONE for the framework ://... return 0; // Command case IDM_WINDOW_TILE for MDI subwindow management: SendMessage (hwndClient, WM_MDITILE, 0, 0); return 0; // The Sub-window commands are used to process the default: hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0); if (IsWindow (hwndChild )) sendMessage (hwndChild, WM_COMMAND, wParam, lParam); break ;//.. and then to DefFrameProc} break; // jump out of the case Branch for WM_COMMAND and DefFrameProc process the remaining commands

5. subwindow Management
1. Overview
Send control messages to the MDI customer zone window.
For example:

case WM_COMMAND:switch (LOWORD (wParam)){ case IDM_WINDOW_TILE:   SendMessage (hwndClient, WM_MDITILE, 0, 0) ;   return 0 ;                  case IDM_WINDOW_CASCADE:   SendMessage (hwndClient, WM_MDICASCADE, 0, 0) ;   return 0 ;                  case IDM_WINDOW_ARRANGE:   SendMessage (hwndClient, WM_MDIICONARRANGE, 0, 0) ;       return 0;                           //...          //...}break;

2. Close the current subwindow
When the current activation window is closed, a query message WM_QUERYENDSESSION is sent to the window.
The subwindow responds to the message in the message processing cycle for some processing before it is closed. If it can be closed, the returned result is true.
Otherwise, false is returned.
In the Framework Window, the root determines whether to close the window based on the returned value.

If you directly press the close button of the subwindow, The WM_CLOSE message is directly sent to the subwindow message processing function.

For example:
The Framework Window command is being processed:

Case IDM_FILE_CLOSE: // obtain the currently activated window hwndChild = (HWND) SendMessage (hwndClient, WM_MDIGETACTIVE, 0, 0); // destroy the window if (SendMessage (hwndChild, WM_QUERYENDSESSION, 0, 0) SendMessage (hwndClient, WM_MDIDESTROY, (WPARAM) hwndChild, 0); return 0;

In the message processing function of the subwindow:

LRESULT CALLBACK HelloWndProc (HWND hwnd, UINT message,                                  WPARAM wParam, LPARAM lParam){       switch (message)       { //... //...       case WM_QUERYENDSESSION:       case WM_CLOSE:            if (IDOK != MessageBox (hwnd, TEXT ("OK to close window?"),                                    TEXT ("Hello"),                                     MB_ICONQUESTION | MB_OKCANCEL))                 return 0 ;                             break ;     // i.e., call DefMDIChildProc       }       return DefMDIChildProc (hwnd, message, wParam, lParam) ;}

3. Close all subwindows
When you close all subwindows by using commands, You need to enumerate all subwindows to close them.
Example:
Framework Window response command:

Case IDM_WINDOW_CLOSEALL: // execute CloseEnumProc EnumChildWindows (hwndClient, CloseEnumProc, 0) for all subwindows; return 0;

Enumeration functions:

BOOL CALLBACK CloseEnumProc (HWND hwnd, LPARAM lParam){       if (GetWindow (hwnd, GW_OWNER))           // Check for icon title            return TRUE ;              SendMessage (GetParent (hwnd), WM_MDIRESTORE, (WPARAM) hwnd, 0) ;              if (!SendMessage (hwnd, WM_QUERYENDSESSION, 0, 0))            return TRUE ;              SendMessage (GetParent (hwnd), WM_MDIDESTROY, (WPARAM) hwnd, 0) ;       return TRUE ;}

Vi. Menu Control
In the MDI program, you can switch the menu of the Framework Window Based on the activated Child Window.
In addition, you can add the window list to the menu. The added menu item command is completed by the default message processing function corresponding to the framework.
1. Prepare a set of menu resources for each window class
2. Load the menu and get the menu handle.
3. When the framework is created, use the framework menu handle as the parameter.
4. When the sub-window is activated, load the menu to the frame window.
Restore the framework menu when the focus is lost.
Send the message WM_MDISETMENU or WM_MDISETMENU to the MDI client window.
WParam is the menu handle, and lParam is the sub-menu handle of the window list to be added

Case WM_MDIACTIVATE: // when activating, set the framework menu if (lParam = (LPARAM) hwnd) SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuHello, (LPARAM) hMenuHelloWindow ); // restore the framework menu if (lParam! = (LPARAM) hwnd) SendMessage (hwndClient, WM_MDISETMENU, (WPARAM) hMenuInit, (LPARAM) hMenuInitWindow); DrawMenuBar (hwndFrame); // Note: how to obtain hwndFrame: // hwndClient = GetParent (hwnd); // hwndFrame = GetParent (hwndClient); return 0;
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.