Relationship between the main frame window, customer window, subwindow, and view of multiple documents, as shown in a diagram

Source: Internet
Author: User

Area redrawing of Multi-document programs and windowsSelected from:

      MDIApplications are another important type of document-based structured programs. It features that users can open multiple documents at a time, and each document corresponds to a different window; the menu of the main window will automatically change with the change of the subwindow of the current activity; sub-windows can be stacked, tiled, and other operations. Sub-windows can be located, changed, maximized, and minimized in the MDI Main Window area. When the sub-window is maximized, it will be filled with MDI
All customer zones in the main window. MDI can not only open multiple documents at the same time, but also open multiple views for the same document. Select New under the Windows menu to open a new subwindow for the current active document.

From the programmer's point of view, each MDI application must have an instance of cmdiframewnd or its derived class. This window is called
Framework Window. Cmdiframewnd is a derived class of cframewnd. It not only has all the features of the cframewnd framework window class, but also has the following MDI-related features:

Unlike SDI, the main framework window is not directly associated with a document and view. The MDI frame window has mdiclient (MDI
Customer window). When the control bar (including toolbar, Status Bar, and dialog bar) is displayed or hidden, you can reposition the sub-window.

The MDI customer window is the direct parent window of the MDI child window. It manages the customer area of the main frame window and creates a child window. Each MDI main frame window has only one MDI
Customer window.

Shows the relationship between the MDI main frame window, customer window, and child window:


The MDI sub-window is an instance of cmdichildwnd or its derived class, And cmdichildwnd is a derived class of cframewnd, used to hold views and documents, which is equivalent to SDI
Main Frame window. Each time a document is opened, the Framework automatically creates an MDI subwindow for the document. An MDI Application dynamically creates and deletes an MDI subwindow. At any time, only one subwindow is active (
The color of the window title bar is highlighted ). The MDI frame window is always associated with the current active child window. Command messages are distributed to the active child window before being passed to the MDI frame window.

When there is no active MDI child window, the MDI frame window can have its own default menu. When an active subwindow exists, the menu bar of the MDI frame window is replaced by the menu bar of the quilt window. The framework automatically monitors the subwindow type of the current activity and changes the menu of the Main Window accordingly. For example
In studio, When you select the dialog box resource editing window or source program window, the menu will be different. However, for programmers, they only need to specify the menus used by each type of subwindows (strictly speaking, documents) when registering a document in initinstance, instead of explicitly calling a function to change the menu of the main framework window, because the framework automatically completes this task.

The MDI frame window provides default menu responses for some standard window operations, such as cascade, tile, arrange subwindows, and create subwindows. In response to the new subwindow command, the Framework calls cdoctemplate: createnewframe () to create a subwindow for the current active document. Createnewframe ()
Not only create a subwindow, but also create a view corresponding to the document.

Next, we will introduce the multi-document interface technology using a drawing program example. Before that, we should first introduce how to plot in windows and Windows Graphics Device Interface (GDI ).




Redraw the window area

When the Windows Notification window needs to re-paint the user area, not all user areas need to be re-painted. The areas to be re-painted are called "invalid rectangle area ". An invalid rectangle appears in the user area, prompting windows to place the wm_paint message in the application queue. Because wm_paint has the lowest priority, you can use updatewindows to send the wm_paint message to the window immediately and re-paint it immediately. Invalid rectangle area restriction program can only draw in this area, cross-border drawing will be cropped out. The following three functions are related to invalid rectangles:

LInvalidaterect generates an invalid rectangle and generates the wm_paint message.

LValidaterect makes the invalid rectangle valid

LGetupdaterect get invalid rectangle coordinate (logic)

Windows retains a paintstruct structure for each window, which contains the coordinate values of the invalid rectangular area.

To efficiently draw and only draw invalid rectangles in your own program, you must first reload the onupdate member function of the view.

Virtual void cview: onupdate (cview * psender, lparam lhint, cobject * phint );

When you call updateallviews of a document, the Framework automatically calls the onupdate function or directly calls the function in the View class. The onupdate function is generally used to access a document, read the data of the document, and update the data members or controls of the view to reflect the changes to the document. You can use the onupdate function to invalidate a part of the view to trigger the ondraw of the view and redraw the window using the document data. The default onupdate will invalidate the entire client area of the window. When re-designing the window, use the prompt information lhint and phint to define a small invalid rectangle. The modified onupdate member functions are as follows:

Void cdrawview: onupdate (cview * psender, lparam lhint, cobject * phint)


If (phint! = NULL)


If (phint-> iskindof (runtime_class (cstroke )))


Cstroke * pstroke = (cstroke *) phint;

Cclientdc DC (this );

Onpreparedc (& DC );

Crect rectinvalid = pstroke-> getboundingrect ();

DC. lptodp (& rectinvalid );

Invalidaterect (& rectinvalid );




Invalidate (true );



Here, the content passed to the phint pointer is the pointer to the stroke object to be drawn. Use forced type conversion to convert it to a stroke pointer, and then obtain the smallest rectangle surrounded by the stroke. Onpreparedc is used to adjust the coordinate origin of a view. Because invalidaterect requires device coordinates, call lptodp (& rectinvalid) to convert logical coordinates to device coordinates. Finally, calling invalidaterect is "invalid" in some window areas, that is, the view needs to re-paint this area after receiving the wm_paint message.

The invalidaterect function is prototype:

Void invalidaterect (lpcrect lprect, bool berase = true );

The first parameter is the pointer to the rectangle to be repainted, and the second parameter tells the view whether to delete the background in the area.

In this way, when you need to re-draw a stroke, you only need to re-draw the smallest rectangle part of the stroke, and the other part will not be re-painted. This is why the smallest rectangle information is provided in the stroke object.

If phint is empty, it indicates normal re-painting. At this time, the entire customer zone needs to be re-painted.

Now, in ondraw, draw an image based on the invalid rectangle instead of re-painting all strokes, as shown below

Void cdrawview: ondraw (CDC * PDC)


Cdrawdoc * pdoc = getdocument ();

Assert_valid (pdoc );


Crect rectclip;

Crect rectstroke;

PDC-> getclipbox (& rectclip );

PDC-> lptodp (& rectclip );

Rectclip. inflaterect (1, 1); // avoid rounding to nothing

Ctypedptrlist <coblist, cstroke *> & strokelist = pdoc-> m_strokelist;

Position Pos = strokelist. getheadposition ();

While (Pos! = NULL)


Cstroke * pstroke = strokelist. getnext (POS );

Rectstroke = pstroke-> getboundingrect ();

PDC-> lptodp (& rectstroke );

Rectstroke. inflaterect (1, 1); // avoid rounding to nothing

If (! Rectstroke. intersectrect (& rectstroke, & rectclip ))


Pstroke-> drawstroke (PDC );



Ondraw first calls getclipbox to obtain the currently cropped area (invalid rectangle area). It copies the rectangle to the rectclip parameter of getclipbox. Then, convert the coordinates of rectclip from the logical coordinate transformation to the device coordinate. To prevent the rectangle from being too small to enclose other content, the upper and lower sides are enlarged by one unit. Ondraw then traverses all the strokes in the stroke linked list and obtains their smallest rectangle. Use intersectrect to check whether it is intersecting with the invalid rectangle. If the intersection exists, it means that part of the stroke falls into the invalid rectangle. At this time, the drawstroke method of the stroke is called to draw the stroke.

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