Detailed analysis of MFC Window Location Management and examples in the window client area of a program written in MFC, there may be several subwindows (Windows with wm_child style ). The top is the toolbar, the middle is the View window, and the bottom is the status bar. The three windows coexist in the customer area of the framework and do not overlap with each other. The size of the main frame window has changed. Other subwindows can adjust their size in time to keep their positions unchanged. For example, the status bar window can always be at the bottom of the main frame client area, and its width is always the same as that of the main frame customer zone. The toolbar window can always be docked on one side of the main frame, and its width or height can always be the same as the width or height of the main frame customer area. The View window can always fill the remaining space in the main frame customer area.
If we derive a window class from the cwnd class and generate a window, several subwindows will be generated in its customer area. We want to make these subwindows arranged in a regular and non-overlapping manner, when the size of the parent window changes, the size and position of each child window can be adjusted in a timely manner, so that the proportional relationship between the positions and sizes of each child window remains unchanged. When one or several subwindows are moved, other subwindows can give up their positions in time. Of course, we can use the Management window function in API functions to compile our own method for managing subwindows. However, if you have a toolbar, Status Bar, and other subwindows in the parent window, can the subwindows you added work well with the subwindows provided by the MFC? How do you ensure that your subwindow does not overwrite the toolbar that can be docked everywhere? How can you know when the toolbar and status bar disappear, so that you can adjust your size in time to overwrite the space occupied by the toolbar and status bar? There is also a view in the customer zone of the window based on the document view framework. Can the child windows that you add hard on your own compete with the View window?
Therefore, you must understand the methods for managing the customer zone of the MFC window. In fact, the method for managing the client zone of the MFC window is very simple: the parent window calls a function, and the subwindow responds to a message, so much.
Cwnd: repositionbars function and wm_sizeparent message
First, let's briefly describe the process of allocating the customer space for the Child window in the MFC window: this process is completed by the parent window and the Child Window. The parent window first provides a region in the customer zone, which is called the start zone. Then, call a function. In this function, the parent window submits this area to the first subwindow through a message. The subwindow determines the size of the subwindow that you want to occupy, then, you can drag out the occupied part in the available area so that the available area is split. The parent window then submits the remaining available areas to the second child window through the same message, and the second child window switches out one piece as needed. In this way, each sub-window is split into one that you need. The remaining zones are used in the last sub-window. It can be seen that, except for the last subwindow, all other subwindows have to have their own algorithms in the message response function to determine the size of each subwindow in the available area, this algorithm is not needed because the last sub-window has no choice.
Of course, the initial available area is a rectangle, and the remaining available area after each cut is still a rectangle, which cannot be in other shapes.
For example, in a typical single-document program, the parent window is the main frame window derived from cframewnd, And the last sub-window is the View window. If csplitterwnd is used to generate separation bars, the last sub-window is the window with separators. Other subwindows are toolbar windows, status bar windows, and other control windows.
In a typical multi-Document Interface Program, the parent window is the main frame window, And the last child window is the window that covers the main window client area. The background is black-gray and has the child frame window containing the document, this is a window with a predefined window class. Its window class name is "mdiclient ". If csplitterwnd is used to generate a separator, the last subwindow is the one with the separator. Other windows are toolbar windows, status bar windows, and other control windows.
The function and message are: cwnd: repositionbars () and wm_sizeparent. This message is customized by MFC, not by windows.
This function and message are briefly described.
1. Function cwnd: repositionbars ()
This function is not a virtual function, so you cannot compile your own version by overwriting In the derived class. You can only understand its functions for flexible use.
To put it simply, this function places the available customer zone information in the message parameters of the message wm_sizeparent, and then enumerate all the subwindows in this window, send this message to each subwindow (removing a specific subwindow is equivalent to the last subwindow mentioned above, each subwindow that responds to this message will split the available customer zones. At last, adjust the size and position of the specific sub-window to the available area at the end.
2. Message wm_sizeparent
Each subwindow to participate in the distribution of customer areas must respond to this message, unless this subwindow is the specific subwindow.
There are at least two things to do in the subwindow to respond to this message: 1. Switch the available parent window customer partition to the one occupied by the customer. 2. According to the Message Parameter instructions, adjust the size and position of the message to fit in the area occupied by the message or do not adjust it.
The following describes in detail the function cwnd: repositionbars () and message wm_sizeparent.
1. Function cwnd: repositionbars () void repositionbars (uint nidfirst, uint nidlast, uint second, uint nflag = cwnd: reposdefault, lprect second = NULL, lpcrect lprectclient = NULL, bool bstretch = true );
There are many parameters, but they are quite understandable.
(1) nidfirst and nidlast
The ID range of the subwindow that participates in allocating the parent window customer area.
Each wm_child window has an ID, which is specified during window creation. The sixth parameter of the function cwnd: Create () is the ID. The hmenu type parameter in the createwindow and createwindow Wex functions. When the window style contains wm_child, it is not the menu handle, but the ID of the window.
The nidfirst and nidlast parameters indicate that, if the id value of a subwindow is greater than or equal to nidfirst and less than or equal to nidlast, wm_sizeparent messages will be sent to this subwindow in this function, this subwindow can be used to allocate the customer area in the parent window.
(2) nidleftover
As mentioned above, there is a specific subwindow that does not respond to the wm_sizeparent message. Only when other sub-windows are allocated is used up will the remaining sub-windows in the parent window be retrieved. Nidleftover is the ID of this subwindow. It must be greater than or equal to nidfirst and less than or equal to nidlast.
(3) lprectclient
This is a pointer to the rect structure data. This rect structure stores the initial available areas of the parent window customer zone. As the function sends the wm_sizeparent message to each subwindow in sequence, each subwindow that responds to the message will remove the portion occupied by it. The last part is the area that the subwindow with ID nidleftover will occupy. This parameter can be null, and the initial zone is the entire parent window customer zone.
(4) nflag and lprectparam
It is better to put these two parameters together. Nflag is the Function Identifier of the function. It can have three values: reposdefault, reposquery, and reposextra.
When nflag is equal to reposdefault, The repositionbars function sends wm_sizeparent messages to subwindows whose IDs are between nidfirst and nidlast and are not equal to nidleftover, each subwindow that responds to the Message removes the part occupied by it from the structure indicated by lprectclient, and adjusts its size and position to the size of the region occupied by it, finally, the repositionbars function also adjusts the size and position of the subwindow whose ID is nidleftover to the available area left by other subwindows, so that the subwindow completely overwrites the last available area. In this case, lprectparam is not required. It can be null.
When nflag is equal to reposquery, The repositionbars function sends wm_sizeparent messages to subwindows whose IDs are between nidfirst and nidlast and are not equal to nidleftover, each subwindow that responds to this message is segmented from the structure indicated by lprectclient, but they do not adjust their size and position, finally, the repositionbars function does not adjust the size and position of the subwindow whose ID is nidleftover. Instead, it performs an action based on the bstretch value. If bstretch is true, the repositionbars function copies the last available regions to the rect structure pointed to by lprectparam. If bstretch is false, then the repositionbars function puts the height and width of the available areas occupied by all other sub-Windows (this value makes sense only when all sub-windows are tightly arranged to form a large rectangle) copy to the bottom of the rect structure pointed to by lprectparam
And right members, the top and left members are set to zero. The purpose of calling repositionbars with this nflag value is not to rearrange subwindows, but to see how many subwindows will occupy if subwindows are rearranged, the location of the last available area and so on.
When nflag is equal to reposextra, the function is similar to nflag when it is equal to reposdefault. In this case, lprectparam is used. As mentioned above, when nflag is equal to reposdefault, The repositionbars function will adjust the size and position of the subwindow with the ID of nidleftover to the available area left by other subwindows, make this sub-window completely overwrite the last available area. When nflag is equal to reposextra, before adjusting the size and position of the subwindow whose ID is nidleftover, repositionbars also uses lprectparam to correct the remaining available areas. If lprect points to the final zone, the correction is as follows:
Lprect-> top + = lprectparam-> top;
Lprect-> left + = lprectparam-> left;
Lprect-> right-= lprectparam-> right;
Lprect-> bottom-= lprectparam-> bottom;
With this correction, we can leave the remaining available areas empty for use instead of the sub-windows with the ID of nidleftover.
(5) bstretch
The role of this parameter has been mentioned above. It is mainly provided for subwindows that respond to wm_sizeparent messages. when determining the number of subwindows, such as the toolbar and status bar, you can determine how much space you want to move from the free space in the customer zone of the parent window, this parameter is also a basis for judgment. For details, see the onsizeparent function of the toolbar and status bar responding to wm_sizeparent ().