欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MFC 对话框控件自动布局

程序员文章站 2022-07-04 21:56:32
MFC 设计界面程序总是不够智能,没有这样,没有那样。 今天为了加强mfc功能,设计了一个自动布局的类,使用非常简单。 原理: 每个控件都有一个矩形区域,矩形区域就是控件在对话框中的显示位置和大小, 通过矩形的四个顶点,控制控件的布局, 在mfc中OnSize()函数在对话框大小变化时被调用,所有每 ......

  MFC 设计界面程序总是不够智能,没有这样,没有那样。

  今天为了加强mfc功能,设计了一个自动布局的类,使用非常简单。

原理:

  每个控件都有一个矩形区域,矩形区域就是控件在对话框中的显示位置和大小,
通过矩形的四个顶点,控制控件的布局,
  在mfc中OnSize()函数在对话框大小变化时被调用,所有每次对话框大小变化时,
我们重新计算对控件的矩形坐标,然后移动到新的坐标,实现控件自动布局。

 

效果:

1、原始界面:

MFC 对话框控件自动布局

2、改变对话框大小后界面:

MFC 对话框控件自动布局

接口:
 1 /** 
 2 *   @brief  Init the rect and calc the ratio   
 3 *  
 4 *   @param  window_width    the width of dialog
 5 *   @param  window_height   the height of dialog
 6 *   @return void
 7 */
 8 void InitLayout(int window_width, int window_height);
 9 
10 /** 
11 *   @brief  Set the control change mode   
12 *  
13 *   @param  ctrl_id             the id of control
14 *   @param  left_change_mode    the mode how to change the left coord
15 *   @param  right_change_mode   the mode how to change the right coord
16 *   @param  top_change_mode     the mode how to change the top coord
17 *   @param  bottom_change_mode  the mode how to change the bottom coord
18 *   @return void
19 */
20 void SetControlAutoChangeMode(int ctrl_id, int left_change_mode, 
21     int right_change_mode, int top_change_mode, int bottom_change_mode);
22 
23 /** 
24 *   @brief  Set dialog handle to this class to call some function    
25 *  
26 *   @param  wnd_dialog    the handle of dialog which contains the control
27 *   @return void
28 */
29 void SetDialogHandle(CWnd *wnd_dialog);
30 
31 /** 
32 *   @brief  Enable the layout function or not    
33 *  
34 *   @param  is_auto_layout    indicate Enable layout or not
35 *   @return void
36 */
37 void SetAutoLayoutEnable(bool is_auto_layout);
38 
39 /** 
40 *   @brief  Update the original rect of control.
41 *           It will be use when you change the control original size 
42 *  
43 *   @param  control_item    the handle of control
44 *   @param  rect            new rect of control
45 *   @return void
46 */
47 void UpateControlOriginalRect(CWnd* control_item, CRect rect);

 

用法: Copy ControlAutoLayout.h, ControlAutoLayout.cpp, Layout.h too you project Include ControlAutoLayout.h in the dialog class file Add a member variable of ControlAutoLayout in dialog class,such as: ControlAutoLayout control_auto_layout_;

On the OnInitDialog() function of dialog class,
use "control_auto_layout_.SetDialogHandle(this);" to
set the dialog handle to ControlAutoLayout

On the OnSize() function of dialog class,
use "control_auto_layout_.InitLayout(int window_width, int window_height);"
to init ControlAutoLayout and then, set each control's change mode:
control_auto_layout_.SetControlAutoChangeMode(int ctrl_id, int left_change_mode,
int right_change_mode, int top_change_mode, int bottom_change_mode);

 

源码:   Layout.h
 1 // Layout.h
 2 // 控件
 3 // LeftChangeMode   : 0:与窗口客户区左边的距离不变; 1:按比例变化; 2:保持控件宽度不变;  
 4 // RightChangeMode  : 0:与窗口客户区右边的距离不变; 1:按比例变化; 2:保持控件宽度不变;  
 5 // TopChangeMode    : 0:与窗口客户区上边的距离不变; 1:按比例变化; 2:保持控件高度不变;  
 6 // BottomChangeMode : 0:与窗口客户区下边的距离不变; 1:按比例变化; 2:保持控件高度不变;  
 7   
 8 // LeftChangeMode取值宏定义  
 9 #define LEFT_CHANGE_MODE_LEFTPADDING            0  
10 #define LEFT_CHANGE_MODE_RATIO                  1  
11 #define LEFT_CHANGE_MODE_FIXED_WIDTH            2  
12   
13 // RightChangeMode取值宏定义  
14 #define RIGHT_CHANGE_MODE_RIGHTPADDING          0  
15 #define RIGHT_CHANGE_MODE_RATIO                 1  
16 #define RIGHT_CHANGE_MODE_FIXED_WIDTH           2  
17   
18 // TopChangeMode取值宏定义  
19 #define TOP_CHANGE_MODE_TOPPADDING              0  
20 #define TOP_CHANGE_MODE_RATIO                   1  
21 #define TOP_CHANGE_MODE_FIXED_HEIGHT            2  
22   
23 // BottomChangeMode取值宏定义  
24 #define BOTTOM_CHANGE_MODE_BOTTOMPADDING        0  
25 #define BOTTOM_CHANGE_MODE_RATIO                1  
26 #define BOTTOM_CHANGE_MODE_FIXED_HEIGHT         2
27 
28 
29 //////////////////////////////////////////////////////////////////////////
30 //horizontal change mode
31 //////////////////////////////////////////////////////////////////////////
32 #define LEFT_PADDING_RIGHT_PADDING \
33     ((LEFT_CHANGE_MODE_LEFTPADDING << 8) + RIGHT_CHANGE_MODE_RIGHTPADDING)
34 #define LEFT_PADDING_RIGHT_RATIO \
35     ((LEFT_CHANGE_MODE_LEFTPADDING << 8) + RIGHT_CHANGE_MODE_RATIO)
36 #define LEFT_PADDING_RIGHT_FIXED_WIDTH \
37     ((LEFT_CHANGE_MODE_LEFTPADDING << 8) + RIGHT_CHANGE_MODE_FIXED_WIDTH)
38 
39 #define LEFT_RATIO_RIGHT_PADDING \
40     ((LEFT_CHANGE_MODE_RATIO << 8) + RIGHT_CHANGE_MODE_RIGHTPADDING)
41 #define LEFT_RATIO_RIGHT_RATIO \
42     ((LEFT_CHANGE_MODE_RATIO << 8) + RIGHT_CHANGE_MODE_RATIO)
43 #define LEFT_RATIO_RIGHT_FIXED_WIDTH \
44     ((LEFT_CHANGE_MODE_RATIO << 8) + RIGHT_CHANGE_MODE_FIXED_WIDTH)
45 
46 #define LEFT_FIXED_WIDTH_RIGHT_PADDING \
47     ((LEFT_CHANGE_MODE_FIXED_WIDTH << 8) + RIGHT_CHANGE_MODE_RIGHTPADDING)
48 #define LEFT_FIXED_WIDTH_RIGHT_RATIO \
49     ((LEFT_CHANGE_MODE_FIXED_WIDTH << 8) + RIGHT_CHANGE_MODE_RATIO)
50 #define LEFT_FIXED_WIDTH_RIGHT_FIXED_WIDTH \
51     ((LEFT_CHANGE_MODE_FIXED_WIDTH << 8) + RIGHT_CHANGE_MODE_FIXED_WIDTH)
52 
53 //////////////////////////////////////////////////////////////////////////
54 //vertical change mode
55 //////////////////////////////////////////////////////////////////////////
56 #define TOP_PADDING_BOTTOM_PADDING \
57     ((TOP_CHANGE_MODE_TOPPADDING << 8) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
58 #define TOP_PADDING_BOTTOM_RATIO \
59     ((TOP_CHANGE_MODE_TOPPADDING << 8) + BOTTOM_CHANGE_MODE_RATIO)
60 #define TOP_PADDING_BOTTOM_FIXED_HEIGHT \
61     ((TOP_CHANGE_MODE_TOPPADDING << 8) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT)
62 
63 #define TOP_RATIO_BOTTOM_PADDING \
64     ((TOP_CHANGE_MODE_RATIO << 8) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
65 #define TOP_RATIO_BOTTOM_RATIO \
66     ((TOP_CHANGE_MODE_RATIO << 8) + BOTTOM_CHANGE_MODE_RATIO)
67 #define TOP_RATIO_BOTTOM_FIXED_HEIGHT \
68     ((TOP_CHANGE_MODE_RATIO << 8) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT)
69 
70 #define TOP_FIXED_HEIGHT_BOTTOM_PADDING \
71     ((TOP_CHANGE_MODE_FIXED_HEIGHT << 8) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
72 #define TOP_FIXED_HEIGHT_BOTTOM_RATIO \
73     ((TOP_CHANGE_MODE_FIXED_HEIGHT << 8) + BOTTOM_CHANGE_MODE_RATIO)
74 #define TOP_FIXED_HEIGHT_BOTTOM_FIXED_HEIGHT \
75     ((TOP_CHANGE_MODE_FIXED_HEIGHT << 8) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT)
76 
77 
78   
79 const double kdouble_precision = 1e-015;
80 const int kcontrol_width_min = 50;
81 const int kcontrol_height_min = 25;

 

  ControlAutoLayout.h
  1 /** 
  2  *  @file    ControlAutoLayout.h
  3  *  @author  Yongsheng Huang
  4  *  @date    8/9/2016  
  5  *  @version 0.0.1
  6  *  
  7  *  @brief Layout control automatically in MFC dialog
  8  *
  9  *  @section DESCRIPTION  
 10  *  
 11  *  @how to
 12  *
 13  *  1、Copy ControlAutoLayout.h, ControlAutoLayout.cpp, Layout.h too you project
 14  *  2、Include ControlAutoLayout.h in the dialog class file
 15  *  3、Add a member variable of ControlAutoLayout in dialog class,
 16  *      such as: ControlAutoLayout control_auto_layout_;
 17  *  4、On the OnInitDialog() function of dialog class, 
 18  *      use "control_auto_layout_.SetDialogHandle(this);"  to 
 19  *      set the dialog handle to ControlAutoLayout
 20  *  5、On the OnSize() function of dialog class,
 21  *      use "control_auto_layout_.InitLayout(int window_width, int window_height);" 
 22  *      to init ControlAutoLayout and then, set each control's change mode:
 23  *      control_auto_layout_.SetControlAutoChangeMode(int ctrl_id, int left_change_mode, 
 24  *      int right_change_mode, int top_change_mode, int bottom_change_mode);
 25  */
 26 
 27 #pragma once
 28 #include <cmath>
 29 #include <map>
 30 #include "Layout.h"
 31 
 32 class ControlAutoLayout
 33 {
 34 public:
 35     ControlAutoLayout(void);
 36     ~ControlAutoLayout(void);
 37 
 38 
 39 public:
 40     /** 
 41     *   @brief  Init the rect and calc the ratio   
 42     *  
 43     *   @param  window_width    the width of dialog
 44     *   @param  window_height   the height of dialog
 45     *   @return void
 46     */
 47     void InitLayout(int window_width, int window_height);
 48 
 49     /** 
 50     *   @brief  Set the control change mode   
 51     *  
 52     *   @param  ctrl_id             the id of control
 53     *   @param  left_change_mode    the mode how to change the left coord
 54     *   @param  right_change_mode   the mode how to change the right coord
 55     *   @param  top_change_mode     the mode how to change the top coord
 56     *   @param  bottom_change_mode  the mode how to change the bottom coord
 57     *   @return void
 58     */
 59     void SetControlAutoChangeMode(int ctrl_id, int left_change_mode, 
 60         int right_change_mode, int top_change_mode, int bottom_change_mode);
 61 
 62     /** 
 63     *   @brief  Set dialog handle to this class to call some function    
 64     *  
 65     *   @param  wnd_dialog    the handle of dialog which contains the control
 66     *   @return void
 67     */
 68     void SetDialogHandle(CWnd *wnd_dialog);
 69 
 70     /** 
 71     *   @brief  Enable the layout function or not    
 72     *  
 73     *   @param  is_auto_layout    indicate Enable layout or not
 74     *   @return void
 75     */
 76     void SetAutoLayoutEnable(bool is_auto_layout);
 77 
 78     /** 
 79     *   @brief  Update the original rect of control.
 80     *           It will be use when you change the control original size 
 81     *  
 82     *   @param  control_item    the handle of control
 83     *   @param  rect            new rect of control
 84     *   @return void
 85     */
 86     void UpateControlOriginalRect(CWnd* control_item, CRect rect);
 87 
 88 
 89 private:
 90     void SetClientWindowRectOriginal(int window_width, int window_height);
 91 
 92     void SetClientWindowRectNow(int window_width, int window_height);
 93 
 94     void CalcHorizontalRatio();
 95 
 96     void CalcVerticalRatio();
 97 
 98     //
 99     void CalcHorizontalCoord(int left_change_mode, int right_change_mode,
100         int &left_coord, int &right_coord);
101 
102     void CalcVerticalCoord(int top_change_mode, int bottom_change_mode,
103         int &top_coord, int &bottom_coord);
104 
105 
106     //////////////////////////////////////////////////////////////////////////
107     void CalcLeftPadRightPad(int &left_coord, int &right_coord);
108 
109     void CalcLeftPadRightRatio(int &left_coord, int &right_coord);
110 
111     void CalcLeftRatioRightPad(int &left_coord, int &right_coord);
112 
113     void CalcLeftRatioRightRatio(int &left_coord, int &right_coord);
114 
115     void CalcLeftRatioRightFixedWidth(int &left_coord, int &right_coord);
116 
117     void CalcLeftFixedWidthRightPad(int &left_coord, int &right_coord);
118 
119     void CalcLeftFixedWidthRightRatio(int &left_coord, int &right_coord);
120 
121     //////////////////////////////////////////////////////////////////////////
122     void CalcTopPadBottomPad(int &top_coord, int &bottom_coord);
123 
124     void CalcTopPadBottomRatio(int &top_coord, int &bottom_coord);
125 
126     void CalcTopRatioBottomPad(int &top_coord, int &bottom_coord);
127 
128     void CalcTopRatioBottomRatio(int &top_coord, int &bottom_coord);
129 
130     void CalcTopRatioBottomFixedHeight(int &top_coord, int &bottom_coord);
131 
132     void CalcTopFixedHeightBottomPad(int &top_coord, int &bottom_coord);
133 
134     void CalcTopFixedHeightBottomRatio(int &top_coord, int &bottom_coord);
135 
136     //////////////////////////////////////////////////////////////////////////
137     void InitControlRectInMap(CWnd* control_item);
138 
139     CRect GetControlRect(CWnd* control_item);
140 
141     int GetHorizontalChangeMode(int left_change_mode, int right_change_mode);
142 
143     int GetVerticalChangeMode(int top_change_mode, int bottom_change_mode);
144 
145     void GetRectCoord(CRect rect, int &left_coord, int &right_coord,
146         int &top_coord, int &bottom_coord);
147 
148     void SetRectByCoord(CRect &rect, int left_coord, int right_coord,
149         int top_coord, int bottom_coord);
150 
151     bool IsExistControlRect(CWnd* control_item);
152 
153     bool IsEqual(double x, double y);
154 
155 private:
156     CWnd *wnd_dialog_;
157 
158     bool is_auto_layout_;
159 
160     CRect rect_client_window_original_;
161     CRect rect_client_window_now_;
162 
163     double horizontal_ratio_;
164     double vertical_ratio_;
165     std::map<CWnd*,CRect> map_control_original_rect_;
166 };

 

ControlAutoLayout.cpp
  1 #include "stdafx.h"
  2 #include "ControlAutoLayout.h"
  3 
  4 
  5 ControlAutoLayout::ControlAutoLayout(void)
  6 {
  7     wnd_dialog_ = NULL;
  8 
  9     is_auto_layout_ = true;
 10 
 11     rect_client_window_original_ = CRect(0,0,0,0);
 12     rect_client_window_now_ = CRect(0,0,0,0);
 13 
 14     horizontal_ratio_ = 0.0;
 15     vertical_ratio_ = 0.0;
 16 
 17     map_control_original_rect_.clear();
 18 }
 19 
 20 
 21 ControlAutoLayout::~ControlAutoLayout(void)
 22 {
 23 
 24 }
 25 
 26 
 27 
 28 void ControlAutoLayout::SetControlAutoChangeMode(int ctrl_id, int left_change_mode, 
 29         int right_change_mode, int top_change_mode, int bottom_change_mode) 
 30 {
 31     if (!is_auto_layout_)
 32     {
 33         return;
 34     }
 35 
 36     if (!wnd_dialog_)
 37     {
 38         return;
 39     }
 40 
 41     CWnd* control_item = wnd_dialog_->GetDlgItem(ctrl_id);
 42     if (!control_item)
 43     {
 44         return;
 45     }
 46 
 47     int left_coord;
 48     int right_coord;
 49     int top_coord;
 50     int bottom_coord;
 51 
 52     InitControlRectInMap(control_item);
 53     CRect control_item_rect = GetControlRect(control_item);
 54 
 55     GetRectCoord(control_item_rect, 
 56         left_coord, right_coord, top_coord, bottom_coord);
 57 
 58     CalcHorizontalCoord(left_change_mode, right_change_mode, 
 59         left_coord, right_coord);
 60 
 61     CalcVerticalCoord(top_change_mode, bottom_change_mode,
 62         top_coord, bottom_coord);
 63 
 64 
 65     SetRectByCoord(control_item_rect, 
 66         left_coord, right_coord, top_coord, bottom_coord);
 67 
 68     control_item->MoveWindow(control_item_rect);
 69 }  
 70 
 71 
 72 void ControlAutoLayout::SetDialogHandle(CWnd *wnd_dialog)
 73 {
 74     wnd_dialog_ = wnd_dialog;
 75 }
 76 
 77 void ControlAutoLayout::SetAutoLayoutEnable(bool is_auto_layout)
 78 {
 79     is_auto_layout_ = is_auto_layout;
 80 }
 81 
 82 void ControlAutoLayout::UpateControlOriginalRect(CWnd* control_item, CRect rect)
 83 {
 84     if (NULL == control_item)
 85     {
 86         return;
 87     }
 88 
 89     map_control_original_rect_[control_item] = rect;
 90 }
 91 
 92 
 93 void ControlAutoLayout::InitLayout(int window_width, int window_height)
 94 {
 95     //set the prev rect window first
 96     SetClientWindowRectOriginal(window_width, window_height);
 97 
 98     SetClientWindowRectNow(window_width, window_height);
 99 
100     CalcHorizontalRatio();
101 
102     CalcVerticalRatio();
103 }
104 
105 
106 void ControlAutoLayout::SetClientWindowRectOriginal(
107     int window_width, int window_height)
108 {
109     //the first time to call it, set the current window to original
110     if (0 == rect_client_window_original_.right
111         && 0 == rect_client_window_original_.bottom)
112     {
113         rect_client_window_original_.left = 0;
114         rect_client_window_original_.top = 0;
115         rect_client_window_original_.right = window_width;
116         rect_client_window_original_.bottom = window_height;
117     }
118 }
119 
120 
121 void ControlAutoLayout::SetClientWindowRectNow(
122     int window_width, int window_height)
123 {
124     rect_client_window_now_.left = 0;
125     rect_client_window_now_.top = 0;
126     rect_client_window_now_.right = window_width;
127     rect_client_window_now_.bottom = window_height;
128 }
129 
130 
131 void ControlAutoLayout::CalcHorizontalRatio()
132 {
133     double width_now = (double)rect_client_window_now_.Width();
134     double width_prev = (double)rect_client_window_original_.Width();
135     if (IsEqual(width_prev, 0.0))
136     {
137         horizontal_ratio_ = 0.0;
138         return;
139     }
140 
141     horizontal_ratio_ = width_now/width_prev;
142     return; 
143 }
144 
145 void ControlAutoLayout::CalcVerticalRatio()
146 {
147     double height_now = (double)rect_client_window_now_.Height();
148     double height_prev = (double)rect_client_window_original_.Height();
149     if (IsEqual(height_prev, 0.0))
150     {
151         vertical_ratio_ = 0.0;
152         return;
153     }
154 
155     vertical_ratio_ = height_now/height_prev;
156     return; 
157 
158 }
159 
160 
161 void ControlAutoLayout::CalcHorizontalCoord(int left_change_mode, 
162                                          int right_change_mode, int &left_coord, int &right_coord)
163 {
164     int horizontal_change_mode = 
165         GetHorizontalChangeMode(left_change_mode, right_change_mode);
166 
167     switch (horizontal_change_mode)
168     {
169     case LEFT_PADDING_RIGHT_PADDING:
170         CalcLeftPadRightPad(left_coord, right_coord);
171         break;
172     case LEFT_PADDING_RIGHT_RATIO:
173         CalcLeftPadRightRatio(left_coord, right_coord);
174         break;
175     case LEFT_PADDING_RIGHT_FIXED_WIDTH:
176         //do nothing
177         break;
178     case LEFT_RATIO_RIGHT_PADDING:
179         CalcLeftRatioRightPad(left_coord, right_coord);
180         break;
181     case LEFT_RATIO_RIGHT_RATIO:
182         CalcLeftRatioRightRatio(left_coord, right_coord);
183         break;
184     case LEFT_RATIO_RIGHT_FIXED_WIDTH:
185         CalcLeftRatioRightFixedWidth(left_coord, right_coord);
186         break;
187     case LEFT_FIXED_WIDTH_RIGHT_PADDING:
188         CalcLeftFixedWidthRightPad(left_coord, right_coord);
189         break;
190     case LEFT_FIXED_WIDTH_RIGHT_RATIO:
191         CalcLeftFixedWidthRightRatio(left_coord, right_coord);
192         break;
193     case LEFT_FIXED_WIDTH_RIGHT_FIXED_WIDTH:
194         //do nothing
195         break;
196     default:
197         break;
198     }
199 }
200 
201 void ControlAutoLayout::CalcVerticalCoord(int top_change_mode, int bottom_change_mode,
202                                        int &top_coord, int &bottom_coord)
203 {
204     int vertical_change_mode = 
205         GetVerticalChangeMode(top_change_mode, bottom_change_mode);
206 
207     switch (vertical_change_mode)
208     {
209     case TOP_PADDING_BOTTOM_PADDING:
210         CalcTopPadBottomPad(top_coord, bottom_coord);
211         break;
212     case TOP_PADDING_BOTTOM_RATIO:
213         CalcTopPadBottomRatio(top_coord, bottom_coord);
214         break;
215     case TOP_PADDING_BOTTOM_FIXED_HEIGHT:
216         //do nothing
217         break;
218     case TOP_RATIO_BOTTOM_PADDING:
219         CalcTopRatioBottomPad(top_coord, bottom_coord);
220         break;
221     case TOP_RATIO_BOTTOM_RATIO:
222         CalcTopRatioBottomRatio(top_coord, bottom_coord);
223         break;
224     case TOP_RATIO_BOTTOM_FIXED_HEIGHT:
225         CalcTopRatioBottomFixedHeight(top_coord, bottom_coord);
226         break;
227     case TOP_FIXED_HEIGHT_BOTTOM_PADDING:
228         CalcTopFixedHeightBottomPad(top_coord, bottom_coord);
229         break;
230     case TOP_FIXED_HEIGHT_BOTTOM_RATIO:
231         CalcTopFixedHeightBottomRatio(top_coord, bottom_coord);
232         break;
233     case TOP_FIXED_HEIGHT_BOTTOM_FIXED_HEIGHT:
234         //do nothing
235         break;
236     default:
237         break;
238     }
239 
240 }
241 
242 
243 //////////////////////////////////////////////////////////////////////////
244 void ControlAutoLayout::CalcLeftPadRightPad(int &left_coord, int &right_coord)
245 {
246     //left coordinate does not need change
247     //left_coord = left_coord;
248 
249     int right_pad_width_orginal = rect_client_window_original_.Width() - right_coord;
250     right_coord = rect_client_window_now_.Width() - right_pad_width_orginal;
251 }
252 
253 void ControlAutoLayout::CalcLeftPadRightRatio(int &left_coord, int &right_coord)
254 {
255     //left coordinate does not need change
256     //left_coord = left_coord;
257 
258     int right_pad_width_orignal = rect_client_window_original_.Width() - right_coord;
259     int right_pad_width_new = (int)(right_pad_width_orignal * horizontal_ratio_);
260     right_coord = rect_client_window_now_.Width() - right_pad_width_new;
261 }
262 
263 void ControlAutoLayout::CalcLeftRatioRightPad(int &left_coord, int &right_coord)
264 {
265     left_coord = (int)(left_coord * horizontal_ratio_);
266 
267     int right_pad_width_orginal = rect_client_window_original_.Width() - right_coord;
268     right_coord = rect_client_window_now_.Width() - right_pad_width_orginal;
269 }
270 
271 void ControlAutoLayout::CalcLeftRatioRightRatio(int &left_coord, int &right_coord)
272 {
273     left_coord = (int)(left_coord * horizontal_ratio_);
274 
275     int right_pad_width_orignal = rect_client_window_original_.Width() - right_coord;
276     int right_pad_width_new = (int)(right_pad_width_orignal * horizontal_ratio_);
277     right_coord = rect_client_window_now_.Width() - right_pad_width_new;
278 }
279 
280 
281 void ControlAutoLayout::CalcLeftRatioRightFixedWidth(int &left_coord, int &right_coord)
282 {
283     int width_original = right_coord - left_coord;
284 
285     left_coord = (int)(left_coord * horizontal_ratio_);
286 
287     right_coord = left_coord + width_original;
288 }
289 
290 
291 void ControlAutoLayout::CalcLeftFixedWidthRightPad(int &left_coord, int &right_coord)
292 {
293     int width_original = right_coord - left_coord;
294     int right_pad_width_original = rect_client_window_original_.Width() - right_coord;
295 
296     right_coord = rect_client_window_now_.Width() - right_pad_width_original;
297 
298     left_coord = right_coord - width_original;
299 }
300 
301 
302 void ControlAutoLayout::CalcLeftFixedWidthRightRatio(int &left_coord, int &right_coord)
303 {
304     int width_original = right_coord - left_coord;
305     int right_pad_width_original = rect_client_window_original_.Width() - right_coord;
306     int right_pad_width_new = (int)(right_pad_width_original * horizontal_ratio_);
307 
308     right_coord = rect_client_window_now_.Width() - right_pad_width_new;
309 
310     left_coord = right_coord - width_original;
311 }
312 
313 //////////////////////////////////////////////////////////////////////////
314 
315 void ControlAutoLayout::CalcTopPadBottomPad(int &top_coord, int &bottom_coord)
316 {
317     //
318     top_coord = top_coord;
319 
320     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
321     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original;
322 }
323 
324 
325 void ControlAutoLayout::CalcTopPadBottomRatio(int &top_coord, int &bottom_coord)
326 {
327     //
328     top_coord = top_coord;
329 
330     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
331     int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_);
332 
333     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new;
334 }
335 
336 
337 void ControlAutoLayout::CalcTopRatioBottomPad(int &top_coord, int &bottom_coord)
338 {
339     top_coord = (int)(top_coord * vertical_ratio_);
340 
341     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
342     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original;
343 }
344 
345 
346 void ControlAutoLayout::CalcTopRatioBottomRatio(int &top_coord, int &bottom_coord)
347 {
348     top_coord = (int)(top_coord * vertical_ratio_);
349 
350     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
351     int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_);
352     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new;
353 }
354 
355 void ControlAutoLayout::CalcTopRatioBottomFixedHeight(int &top_coord, int &bottom_coord)
356 {
357     int height_original = rect_client_window_original_.Height() - top_coord;
358 
359     top_coord = (int)(top_coord * vertical_ratio_);
360 
361     bottom_coord = rect_client_window_now_.Height() - height_original;
362 }
363 
364 
365 void ControlAutoLayout::CalcTopFixedHeightBottomPad(int &top_coord, int &bottom_coord)
366 {
367     int height_original = bottom_coord - top_coord;
368     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
369 
370     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original;
371 
372     top_coord = bottom_coord - height_original;
373 }
374 
375 
376 void ControlAutoLayout::CalcTopFixedHeightBottomRatio(int &top_coord, int &bottom_coord)
377 {
378     int height_original = bottom_coord - top_coord;
379     int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
380     int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_);
381 
382     bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new;
383 
384     top_coord = bottom_coord - height_original;
385 }
386 
387 
388 //////////////////////////////////////////////////////////////////////////
389 void ControlAutoLayout::InitControlRectInMap(CWnd* control_item)
390 {
391     CRect rect_control_item;
392     if (NULL == control_item || NULL == wnd_dialog_)
393     {
394         return;
395     }
396 
397     if (!IsExistControlRect(control_item))
398     {
399         control_item->GetWindowRect(&rect_control_item);
400         wnd_dialog_->ScreenToClient(&rect_control_item);
401         map_control_original_rect_[control_item] = rect_control_item;
402     }
403 }
404 
405 CRect ControlAutoLayout::GetControlRect(CWnd* control_item)
406 {
407     CRect rect_control_item;
408     if (NULL == control_item || NULL == wnd_dialog_)
409     {
410         return rect_control_item;
411     }
412 
413     if (IsExistControlRect(control_item))
414     {
415         rect_control_item = map_control_original_rect_[control_item];
416     }
417     else
418     {
419         control_item->GetWindowRect(&rect_control_item);
420         wnd_dialog_->ScreenToClient(&rect_control_item);
421     }
422 
423     return rect_control_item;
424 }
425 
426 
427 int ControlAutoLayout::GetHorizontalChangeMode(
428     int left_change_mode, int right_change_mode)
429 {
430     //combine left mode and right mode
431     // top_change_mode = 0, bottom_change_mode = 1
432     //  =>   vertical_change_mode = 0x0001
433     int horizontal_change_mode = (left_change_mode << 8) + right_change_mode;
434 
435     return horizontal_change_mode;
436 }
437 
438 
439 int ControlAutoLayout::GetVerticalChangeMode(int top_change_mode, int bottom_change_mode)
440 {
441     //combine top mode and bottom mode
442     // top_change_mode = 1, bottom_change_mode = 2 
443     //  =>   vertical_change_mode = 0x0102
444     int vertical_change_mode = (top_change_mode << 8) + bottom_change_mode;
445     return vertical_change_mode;
446 }
447 
448 
449 void ControlAutoLayout::GetRectCoord(CRect rect, 
450                                   int &left_coord, int &right_coord, int &top_coord, int &bottom_coord)
451 {
452     left_coord = rect.left;
453     right_coord = rect.right;
454     top_coord = rect.top;
455     bottom_coord = rect.bottom;
456 }
457 
458 void ControlAutoLayout::SetRectByCoord(CRect &rect, 
459                                     int left_coord, int right_coord, int top_coord, int bottom_coord)
460 {
461     rect.left = left_coord;
462     rect.top = top_coord;
463 
464 
465     if (kcontrol_width_min > right_coord - left_coord)
466     {
467         rect.right = left_coord + kcontrol_width_min;
468     }
469     else
470     {
471         rect.right = right_coord;
472     }
473 
474 
475     if (kcontrol_height_min > bottom_coord - top_coord)
476     {
477         rect.bottom = top_coord + kcontrol_height_min;
478     }
479     else
480     {
481         rect.bottom = bottom_coord; 
482     }
483 }
484 
485 
486 bool ControlAutoLayout::IsExistControlRect(CWnd* control_item)
487 {
488     std::map<CWnd*,CRect>::iterator itr;
489     itr = map_control_original_rect_.find(control_item);
490     if (itr != map_control_original_rect_.end())
491     {
492         return true;
493     }
494 
495     return false;
496 }
497 
498 
499 bool ControlAutoLayout::IsEqual(double x, double y)
500 {
501     double differ = std::abs(x - y);
502 
503     if (kdouble_precision >= differ)
504     {
505         return true;
506     }
507 
508     return false;
509 }

 

源码下载:AutoLayout.7z

reference:http://blog.csdn.net/beanjoy/article/details/9146375