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);
用法:
- 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