你的位置:首页 > ASP.net教程

[ASP.net教程]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 control14 *  @param left_change_mode  the mode how to change the left coord15 *  @param right_change_mode  the mode how to change the right coord16 *  @param top_change_mode   the mode how to change the top coord17 *  @param bottom_change_mode the mode how to change the bottom coord18 *  @return void19 */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 control27 *  @return void28 */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 not35 *  @return void36 */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 control44 *  @param rect      new rect of control45 *  @return void46 */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     227 28 29 //////////////////////////////////////////////////////////////////////////30 //horizontal change mode31 //////////////////////////////////////////////////////////////////////////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 mode55 //////////////////////////////////////////////////////////////////////////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 original110   if (0 == rect_client_window_original_.right111     && 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 nothing177     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 nothing195     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 nothing217     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 nothing235     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 change247   //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 change256   //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   else418   {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 mode431   // top_change_mode = 0, bottom_change_mode = 1432   // =>  vertical_change_mode = 0x0001433   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 mode442   // top_change_mode = 1, bottom_change_mode = 2 443   // =>  vertical_change_mode = 0x0102444   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   else470   {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   else480   {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