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);
用法:
- 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 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
原标题:MFC 对话框控件自动布局
关键词: