红尘多梦

导航

MFC 对话框控件自动布局

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

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

原理:

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

 

效果:

1、原始界面:

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

接口:

 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);

 

用法:

  1. Copy ControlAutoLayout.h, ControlAutoLayout.cpp, Layout.h too you project
  2. Include ControlAutoLayout.h in the dialog class file
  3. Add a member variable of ControlAutoLayout in dialog class,such as: ControlAutoLayout control_auto_layout_;
  4. On the OnInitDialog() function of dialog class,
    use "control_auto_layout_.SetDialogHandle(this);" to
    set the dialog handle to ControlAutoLayout

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

 

posted on 2016-08-09 11:46  红尘多梦  阅读(6697)  评论(4编辑  收藏  举报