Windows SDK Notes (7): Create an MDI window

zhaozj2021-02-17  69

1. Overview The MDI window contains a frame window and a number of sub-windows. In fact, the frame window itself is an ordinary main window, but its customers are covered by a special window. This special window is a system-predefined "window class", class name: "mdiclient". It is responsible for the management of individual MDI sub-windows.

Second, the window is established 1. Register an MDI frame window class, provide the MDI Frame Wall Wall Processing Function MDI Framework window message processing function, the unprocessed message is handled by DEFFRAMEPROC

// MDI Frame Wall Message Processing Function

Lresult Callback MDIFrameWndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)

{

// ...

/ / Other messages handle the default frame processing function provided by the system DEFFRAMEPROC

// where the second parameter is the client area window handle

Return :: DefframeProc (HWND, HWndClient, Message, WPARAM, LPARAM);

} 2. Register multiple MDI sub-window classes, corresponding to the message processing function of each MDI sub-window

In the sub-window message processing function, the unopened message is handled by MDIDEFMDICHILDPROC.

// MDI sub-window message processing function

LResult Callback MdichildWndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM)

{

// ...

// ...

// Other messages handle the default MDI sub-window processing function provided by the system

Return :: DefmdichildProc (HWND, Message, WPARAM, LPARAM);

}

3. Establish the MDI management sub-window in the client area of ​​the frame window

The management of the MDI sub-window is actually done by the "MDILIENT" window of the frame window client area.

This is a system predefined window.

After receiving the WM_CREATE message at the main window:

Case WM_CREATE:

{

Hinst = ((lpcreateStruct) LParam -> Hinstance;

// Fill the ClientCreatestruct structure

ClientCreatestruct ClientCreate;

ClientCreate.hwindowMenu = HMENUINITWINDOW; / / Menu handle for adding a window list

ClientCreate.idfirstchild = 50000; // Start ID

HWndClient = CREATEWINDOWEX (0,

"Mdiclient", // class name is "mdiclient"

NULL,

WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE,

0,

0,

0,

0,

HWnd,

(HMENU) 1, // ID

Hinst, // Example handle

& clientcreate); // parameter

}

Return 0; the size of the window does not matter, the default frame window message handler is to overwrite the entire client area.

After the MDI client area window is established, the establishment, destruction, arrangement, etc. of the message management sub-window is sent to it.

4. The establishment of MDI sub-window can be added to the menu to create a sub-window. After the message processing function of the frame window receives the command, send a command to the MDI Customer Window.

Case ID_new:

{

Mdicreatestruct Mdicreate;

Mdicreate.szclass = szmdichildname; // MDI sub-window class name

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 Customer Area Handle

Wm_mdicreate, // Create a MDI sub-window

0,

(LpMdicreateStruct) & mdicreate // Create parameters

);

}

Break;

Third, the message loop is handled for the MDI hotkey

In the message loop, use TranslateMdisysAccel to process hot keys for MDI.

While (GetMessage (& MSG, NULL, 0, 0))

{

IF (! TranslateMdisysaccel (HWndClient, & MSG) &&&

TranslateAccelerator (HWndFrame, Haccel, & MSG))

{

TranslateMessage (& MSG);

DispatchMessage (& MSG);

}

}

Fourth, the flow of orders

After receiving the WM_COMMAND, the frame window should provide the currently activated MDI window to process the process.

Case WM_COMMAND:

Switch (loword (wparam))

{

// command to the framework

Case id_one:

// ...

Return 0;

/ / Direct to MDI sub-window management

Case idm_window_tile:

SendMessage (hwndclient, wm_mditile, 0, 0);

Return 0;

/ / Deal with the sub-window for the sub-window

DEFAULT:

HWNDCHILD = (hwnd) SendMessage (HWndClient,

WM_MDIGETACTIVE, 0, 0);

IF (Iswindow (HWNDPHILD))

SendMessage (HWndchild, WM_Command, WPARAM, LPARAM);

Break; //..and the to defframeproc

}

Break; // Jump out of the CASE branch for WM_Command, and defframePROC handles the remaining command

5. Management of sub-windows

1 Overview

Control the message to the MDI client area window

Such as:

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 up of the current sub-window

When you turn off the current activation window, first send query messages to this window: WM_QueryEndSession.

The message processing loop of the sub-window responds to this message, and some processing before turning off, if it is turned off, return true

Otherwise it will return.

In the frame window, according to this return value, decide if the window is turned off.

If the user directly presses the off button of the sub-window, the WM_CLOSE message sends directly to the sub-window message processing function.

For example: Frame window command processing:

Case IDM_FILE_CLOSE: // Get the current activation window

HWNDCHILD = (hwnd) SendMessage (HWndClient, WM_MDiGetActive, 0, 0);

// After the inspection, destroy the window

IF (SendMessage (HWndchild, WM_QueryEndSession, 0, 0))

SendMessage (HWndClient, WM_MDIDESTROY, (WPARAM) HWNDCHILD, 0);

Return 0; the message processing function of the sub-window:

LResult Callback HellownProc (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 sub-windows

When you use a command mode to close all sub-windows, you need to enumerate all sub-windows to close.

example:

Frame window Response command:

Case idm_window_closeall:

// Perform CloseenumProc for all subsets

EnumchildWindows (HWndClient, CloseenumProc, 0);

Return 0; enumeration function:

Bool Callback CloseenumProc (HWND HWND, LPARAM LPARAM)

{

IF (getWindow (hwndow (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;

}

Six, menu control

In the MDI program, the menu of the frame window can be switched depending on the activated sub-window.

Also, you can add a window list to the menu. The added menu item command is completed by the default message processing function corresponding to the frame.

1. Prepare a set of menu resources for each window class

2. Load menu to get a menu handle

3. When the framework is established, use the handle of the frame menu as the parameter.

4. When the child window is activated, load your own menu to the frame window.

Restore the frame menu when you lose the focus.

Use the WM_MDisetMenu or WM_MDisetMenu message to the MDI client area window.

WPARAM is a menu handle, LParam For the child handle to add a window list

Case WM_MDIACTIVATE:

/ / When activated, set the frame menu

IF (lparam == (lparam) hWnd)

SendMessage (HWndClient, WM_MDisetMenu,

(Wparam) HMenuhello, (lParam) hmenuhellowindow);

// When you lose the focus, restore the frame menu

IF (lParam! = (lparam) hWnd) SendMessage (HWndClient, WM_MDisetMenu, (WPARAM) HMenuinit,

(LParam) HMenuinitWindow;

Drawmenubar (HWNDFrame);

// Note: How to get hwndframe:

// hWndClient = getParent (hwnd);

// hwndframe = getParent (hwndclient);

Return 0; (full text)

转载请注明原文地址:https://www.9cbs.com/read-31179.html

New Post(0)