MFC 对话框控件自动布局

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

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

原理:

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

效果:

1、原始界面:

MFC 对话框控件自动布局

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

MFC 对话框控件自动布局

接口:

 /**
* @brief Init the rect and calc the ratio
*
* @param window_width the width of dialog
* @param window_height the height of dialog
* @return void
*/
void InitLayout(int window_width, int window_height); /**
* @brief Set the control change mode
*
* @param ctrl_id the id of control
* @param left_change_mode the mode how to change the left coord
* @param right_change_mode the mode how to change the right coord
* @param top_change_mode the mode how to change the top coord
* @param bottom_change_mode the mode how to change the bottom coord
* @return void
*/
void SetControlAutoChangeMode(int ctrl_id, int left_change_mode,
int right_change_mode, int top_change_mode, int bottom_change_mode); /**
* @brief Set dialog handle to this class to call some function
*
* @param wnd_dialog the handle of dialog which contains the control
* @return void
*/
void SetDialogHandle(CWnd *wnd_dialog); /**
* @brief Enable the layout function or not
*
* @param is_auto_layout indicate Enable layout or not
* @return void
*/
void SetAutoLayoutEnable(bool is_auto_layout); /**
* @brief Update the original rect of control.
* It will be use when you change the control original size
*
* @param control_item the handle of control
* @param rect new rect of control
* @return void
*/
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

 // Layout.h
// 控件
// LeftChangeMode : 0:与窗口客户区左边的距离不变; 1:按比例变化; 2:保持控件宽度不变;
// RightChangeMode : 0:与窗口客户区右边的距离不变; 1:按比例变化; 2:保持控件宽度不变;
// TopChangeMode : 0:与窗口客户区上边的距离不变; 1:按比例变化; 2:保持控件高度不变;
// BottomChangeMode : 0:与窗口客户区下边的距离不变; 1:按比例变化; 2:保持控件高度不变; // LeftChangeMode取值宏定义
#define LEFT_CHANGE_MODE_LEFTPADDING 0
#define LEFT_CHANGE_MODE_RATIO 1
#define LEFT_CHANGE_MODE_FIXED_WIDTH 2 // RightChangeMode取值宏定义
#define RIGHT_CHANGE_MODE_RIGHTPADDING 0
#define RIGHT_CHANGE_MODE_RATIO 1
#define RIGHT_CHANGE_MODE_FIXED_WIDTH 2 // TopChangeMode取值宏定义
#define TOP_CHANGE_MODE_TOPPADDING 0
#define TOP_CHANGE_MODE_RATIO 1
#define TOP_CHANGE_MODE_FIXED_HEIGHT 2 // BottomChangeMode取值宏定义
#define BOTTOM_CHANGE_MODE_BOTTOMPADDING 0
#define BOTTOM_CHANGE_MODE_RATIO 1
#define BOTTOM_CHANGE_MODE_FIXED_HEIGHT 2 //////////////////////////////////////////////////////////////////////////
//horizontal change mode
//////////////////////////////////////////////////////////////////////////
#define LEFT_PADDING_RIGHT_PADDING \
((LEFT_CHANGE_MODE_LEFTPADDING << ) + RIGHT_CHANGE_MODE_RIGHTPADDING)
#define LEFT_PADDING_RIGHT_RATIO \
((LEFT_CHANGE_MODE_LEFTPADDING << ) + RIGHT_CHANGE_MODE_RATIO)
#define LEFT_PADDING_RIGHT_FIXED_WIDTH \
((LEFT_CHANGE_MODE_LEFTPADDING << ) + RIGHT_CHANGE_MODE_FIXED_WIDTH) #define LEFT_RATIO_RIGHT_PADDING \
((LEFT_CHANGE_MODE_RATIO << ) + RIGHT_CHANGE_MODE_RIGHTPADDING)
#define LEFT_RATIO_RIGHT_RATIO \
((LEFT_CHANGE_MODE_RATIO << ) + RIGHT_CHANGE_MODE_RATIO)
#define LEFT_RATIO_RIGHT_FIXED_WIDTH \
((LEFT_CHANGE_MODE_RATIO << ) + RIGHT_CHANGE_MODE_FIXED_WIDTH) #define LEFT_FIXED_WIDTH_RIGHT_PADDING \
((LEFT_CHANGE_MODE_FIXED_WIDTH << ) + RIGHT_CHANGE_MODE_RIGHTPADDING)
#define LEFT_FIXED_WIDTH_RIGHT_RATIO \
((LEFT_CHANGE_MODE_FIXED_WIDTH << ) + RIGHT_CHANGE_MODE_RATIO)
#define LEFT_FIXED_WIDTH_RIGHT_FIXED_WIDTH \
((LEFT_CHANGE_MODE_FIXED_WIDTH << ) + RIGHT_CHANGE_MODE_FIXED_WIDTH) //////////////////////////////////////////////////////////////////////////
//vertical change mode
//////////////////////////////////////////////////////////////////////////
#define TOP_PADDING_BOTTOM_PADDING \
((TOP_CHANGE_MODE_TOPPADDING << ) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
#define TOP_PADDING_BOTTOM_RATIO \
((TOP_CHANGE_MODE_TOPPADDING << ) + BOTTOM_CHANGE_MODE_RATIO)
#define TOP_PADDING_BOTTOM_FIXED_HEIGHT \
((TOP_CHANGE_MODE_TOPPADDING << ) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT) #define TOP_RATIO_BOTTOM_PADDING \
((TOP_CHANGE_MODE_RATIO << ) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
#define TOP_RATIO_BOTTOM_RATIO \
((TOP_CHANGE_MODE_RATIO << ) + BOTTOM_CHANGE_MODE_RATIO)
#define TOP_RATIO_BOTTOM_FIXED_HEIGHT \
((TOP_CHANGE_MODE_RATIO << ) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT) #define TOP_FIXED_HEIGHT_BOTTOM_PADDING \
((TOP_CHANGE_MODE_FIXED_HEIGHT << ) + BOTTOM_CHANGE_MODE_BOTTOMPADDING)
#define TOP_FIXED_HEIGHT_BOTTOM_RATIO \
((TOP_CHANGE_MODE_FIXED_HEIGHT << ) + BOTTOM_CHANGE_MODE_RATIO)
#define TOP_FIXED_HEIGHT_BOTTOM_FIXED_HEIGHT \
((TOP_CHANGE_MODE_FIXED_HEIGHT << ) + BOTTOM_CHANGE_MODE_FIXED_HEIGHT) const double kdouble_precision = 1e-;
const int kcontrol_width_min = ;
const int kcontrol_height_min = ;

  ControlAutoLayout.h

 /**
* @file ControlAutoLayout.h
* @author Yongsheng Huang
* @date 8/9/2016
* @version 0.0.1
*
* @brief Layout control automatically in MFC dialog
*
* @section DESCRIPTION
*
* @how to
*
* 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);
*/ #pragma once
#include <cmath>
#include <map>
#include "Layout.h" class ControlAutoLayout
{
public:
ControlAutoLayout(void);
~ControlAutoLayout(void); public:
/**
* @brief Init the rect and calc the ratio
*
* @param window_width the width of dialog
* @param window_height the height of dialog
* @return void
*/
void InitLayout(int window_width, int window_height); /**
* @brief Set the control change mode
*
* @param ctrl_id the id of control
* @param left_change_mode the mode how to change the left coord
* @param right_change_mode the mode how to change the right coord
* @param top_change_mode the mode how to change the top coord
* @param bottom_change_mode the mode how to change the bottom coord
* @return void
*/
void SetControlAutoChangeMode(int ctrl_id, int left_change_mode,
int right_change_mode, int top_change_mode, int bottom_change_mode); /**
* @brief Set dialog handle to this class to call some function
*
* @param wnd_dialog the handle of dialog which contains the control
* @return void
*/
void SetDialogHandle(CWnd *wnd_dialog); /**
* @brief Enable the layout function or not
*
* @param is_auto_layout indicate Enable layout or not
* @return void
*/
void SetAutoLayoutEnable(bool is_auto_layout); /**
* @brief Update the original rect of control.
* It will be use when you change the control original size
*
* @param control_item the handle of control
* @param rect new rect of control
* @return void
*/
void UpateControlOriginalRect(CWnd* control_item, CRect rect); private:
void SetClientWindowRectOriginal(int window_width, int window_height); void SetClientWindowRectNow(int window_width, int window_height); void CalcHorizontalRatio(); void CalcVerticalRatio(); //
void CalcHorizontalCoord(int left_change_mode, int right_change_mode,
int &left_coord, int &right_coord); void CalcVerticalCoord(int top_change_mode, int bottom_change_mode,
int &top_coord, int &bottom_coord); //////////////////////////////////////////////////////////////////////////
void CalcLeftPadRightPad(int &left_coord, int &right_coord); void CalcLeftPadRightRatio(int &left_coord, int &right_coord); void CalcLeftRatioRightPad(int &left_coord, int &right_coord); void CalcLeftRatioRightRatio(int &left_coord, int &right_coord); void CalcLeftRatioRightFixedWidth(int &left_coord, int &right_coord); void CalcLeftFixedWidthRightPad(int &left_coord, int &right_coord); void CalcLeftFixedWidthRightRatio(int &left_coord, int &right_coord); //////////////////////////////////////////////////////////////////////////
void CalcTopPadBottomPad(int &top_coord, int &bottom_coord); void CalcTopPadBottomRatio(int &top_coord, int &bottom_coord); void CalcTopRatioBottomPad(int &top_coord, int &bottom_coord); void CalcTopRatioBottomRatio(int &top_coord, int &bottom_coord); void CalcTopRatioBottomFixedHeight(int &top_coord, int &bottom_coord); void CalcTopFixedHeightBottomPad(int &top_coord, int &bottom_coord); void CalcTopFixedHeightBottomRatio(int &top_coord, int &bottom_coord); //////////////////////////////////////////////////////////////////////////
void InitControlRectInMap(CWnd* control_item); CRect GetControlRect(CWnd* control_item); int GetHorizontalChangeMode(int left_change_mode, int right_change_mode); int GetVerticalChangeMode(int top_change_mode, int bottom_change_mode); void GetRectCoord(CRect rect, int &left_coord, int &right_coord,
int &top_coord, int &bottom_coord); void SetRectByCoord(CRect &rect, int left_coord, int right_coord,
int top_coord, int bottom_coord); bool IsExistControlRect(CWnd* control_item); bool IsEqual(double x, double y); private:
CWnd *wnd_dialog_; bool is_auto_layout_; CRect rect_client_window_original_;
CRect rect_client_window_now_; double horizontal_ratio_;
double vertical_ratio_;
std::map<CWnd*,CRect> map_control_original_rect_;
};

ControlAutoLayout.cpp

 #include "stdafx.h"
#include "ControlAutoLayout.h" ControlAutoLayout::ControlAutoLayout(void)
{
wnd_dialog_ = NULL; is_auto_layout_ = true; rect_client_window_original_ = CRect(,,,);
rect_client_window_now_ = CRect(,,,); horizontal_ratio_ = 0.0;
vertical_ratio_ = 0.0; map_control_original_rect_.clear();
} ControlAutoLayout::~ControlAutoLayout(void)
{ } void ControlAutoLayout::SetControlAutoChangeMode(int ctrl_id, int left_change_mode,
int right_change_mode, int top_change_mode, int bottom_change_mode)
{
if (!is_auto_layout_)
{
return;
} if (!wnd_dialog_)
{
return;
} CWnd* control_item = wnd_dialog_->GetDlgItem(ctrl_id);
if (!control_item)
{
return;
} int left_coord;
int right_coord;
int top_coord;
int bottom_coord; InitControlRectInMap(control_item);
CRect control_item_rect = GetControlRect(control_item); GetRectCoord(control_item_rect,
left_coord, right_coord, top_coord, bottom_coord); CalcHorizontalCoord(left_change_mode, right_change_mode,
left_coord, right_coord); CalcVerticalCoord(top_change_mode, bottom_change_mode,
top_coord, bottom_coord); SetRectByCoord(control_item_rect,
left_coord, right_coord, top_coord, bottom_coord); control_item->MoveWindow(control_item_rect);
} void ControlAutoLayout::SetDialogHandle(CWnd *wnd_dialog)
{
wnd_dialog_ = wnd_dialog;
} void ControlAutoLayout::SetAutoLayoutEnable(bool is_auto_layout)
{
is_auto_layout_ = is_auto_layout;
} void ControlAutoLayout::UpateControlOriginalRect(CWnd* control_item, CRect rect)
{
if (NULL == control_item)
{
return;
} map_control_original_rect_[control_item] = rect;
} void ControlAutoLayout::InitLayout(int window_width, int window_height)
{
//set the prev rect window first
SetClientWindowRectOriginal(window_width, window_height); SetClientWindowRectNow(window_width, window_height); CalcHorizontalRatio(); CalcVerticalRatio();
} void ControlAutoLayout::SetClientWindowRectOriginal(
int window_width, int window_height)
{
//the first time to call it, set the current window to original
if ( == rect_client_window_original_.right
&& == rect_client_window_original_.bottom)
{
rect_client_window_original_.left = ;
rect_client_window_original_.top = ;
rect_client_window_original_.right = window_width;
rect_client_window_original_.bottom = window_height;
}
} void ControlAutoLayout::SetClientWindowRectNow(
int window_width, int window_height)
{
rect_client_window_now_.left = ;
rect_client_window_now_.top = ;
rect_client_window_now_.right = window_width;
rect_client_window_now_.bottom = window_height;
} void ControlAutoLayout::CalcHorizontalRatio()
{
double width_now = (double)rect_client_window_now_.Width();
double width_prev = (double)rect_client_window_original_.Width();
if (IsEqual(width_prev, 0.0))
{
horizontal_ratio_ = 0.0;
return;
} horizontal_ratio_ = width_now/width_prev;
return;
} void ControlAutoLayout::CalcVerticalRatio()
{
double height_now = (double)rect_client_window_now_.Height();
double height_prev = (double)rect_client_window_original_.Height();
if (IsEqual(height_prev, 0.0))
{
vertical_ratio_ = 0.0;
return;
} vertical_ratio_ = height_now/height_prev;
return; } void ControlAutoLayout::CalcHorizontalCoord(int left_change_mode,
int right_change_mode, int &left_coord, int &right_coord)
{
int horizontal_change_mode =
GetHorizontalChangeMode(left_change_mode, right_change_mode); switch (horizontal_change_mode)
{
case LEFT_PADDING_RIGHT_PADDING:
CalcLeftPadRightPad(left_coord, right_coord);
break;
case LEFT_PADDING_RIGHT_RATIO:
CalcLeftPadRightRatio(left_coord, right_coord);
break;
case LEFT_PADDING_RIGHT_FIXED_WIDTH:
//do nothing
break;
case LEFT_RATIO_RIGHT_PADDING:
CalcLeftRatioRightPad(left_coord, right_coord);
break;
case LEFT_RATIO_RIGHT_RATIO:
CalcLeftRatioRightRatio(left_coord, right_coord);
break;
case LEFT_RATIO_RIGHT_FIXED_WIDTH:
CalcLeftRatioRightFixedWidth(left_coord, right_coord);
break;
case LEFT_FIXED_WIDTH_RIGHT_PADDING:
CalcLeftFixedWidthRightPad(left_coord, right_coord);
break;
case LEFT_FIXED_WIDTH_RIGHT_RATIO:
CalcLeftFixedWidthRightRatio(left_coord, right_coord);
break;
case LEFT_FIXED_WIDTH_RIGHT_FIXED_WIDTH:
//do nothing
break;
default:
break;
}
} void ControlAutoLayout::CalcVerticalCoord(int top_change_mode, int bottom_change_mode,
int &top_coord, int &bottom_coord)
{
int vertical_change_mode =
GetVerticalChangeMode(top_change_mode, bottom_change_mode); switch (vertical_change_mode)
{
case TOP_PADDING_BOTTOM_PADDING:
CalcTopPadBottomPad(top_coord, bottom_coord);
break;
case TOP_PADDING_BOTTOM_RATIO:
CalcTopPadBottomRatio(top_coord, bottom_coord);
break;
case TOP_PADDING_BOTTOM_FIXED_HEIGHT:
//do nothing
break;
case TOP_RATIO_BOTTOM_PADDING:
CalcTopRatioBottomPad(top_coord, bottom_coord);
break;
case TOP_RATIO_BOTTOM_RATIO:
CalcTopRatioBottomRatio(top_coord, bottom_coord);
break;
case TOP_RATIO_BOTTOM_FIXED_HEIGHT:
CalcTopRatioBottomFixedHeight(top_coord, bottom_coord);
break;
case TOP_FIXED_HEIGHT_BOTTOM_PADDING:
CalcTopFixedHeightBottomPad(top_coord, bottom_coord);
break;
case TOP_FIXED_HEIGHT_BOTTOM_RATIO:
CalcTopFixedHeightBottomRatio(top_coord, bottom_coord);
break;
case TOP_FIXED_HEIGHT_BOTTOM_FIXED_HEIGHT:
//do nothing
break;
default:
break;
} } //////////////////////////////////////////////////////////////////////////
void ControlAutoLayout::CalcLeftPadRightPad(int &left_coord, int &right_coord)
{
//left coordinate does not need change
//left_coord = left_coord; int right_pad_width_orginal = rect_client_window_original_.Width() - right_coord;
right_coord = rect_client_window_now_.Width() - right_pad_width_orginal;
} void ControlAutoLayout::CalcLeftPadRightRatio(int &left_coord, int &right_coord)
{
//left coordinate does not need change
//left_coord = left_coord; int right_pad_width_orignal = rect_client_window_original_.Width() - right_coord;
int right_pad_width_new = (int)(right_pad_width_orignal * horizontal_ratio_);
right_coord = rect_client_window_now_.Width() - right_pad_width_new;
} void ControlAutoLayout::CalcLeftRatioRightPad(int &left_coord, int &right_coord)
{
left_coord = (int)(left_coord * horizontal_ratio_); int right_pad_width_orginal = rect_client_window_original_.Width() - right_coord;
right_coord = rect_client_window_now_.Width() - right_pad_width_orginal;
} void ControlAutoLayout::CalcLeftRatioRightRatio(int &left_coord, int &right_coord)
{
left_coord = (int)(left_coord * horizontal_ratio_); int right_pad_width_orignal = rect_client_window_original_.Width() - right_coord;
int right_pad_width_new = (int)(right_pad_width_orignal * horizontal_ratio_);
right_coord = rect_client_window_now_.Width() - right_pad_width_new;
} void ControlAutoLayout::CalcLeftRatioRightFixedWidth(int &left_coord, int &right_coord)
{
int width_original = right_coord - left_coord; left_coord = (int)(left_coord * horizontal_ratio_); right_coord = left_coord + width_original;
} void ControlAutoLayout::CalcLeftFixedWidthRightPad(int &left_coord, int &right_coord)
{
int width_original = right_coord - left_coord;
int right_pad_width_original = rect_client_window_original_.Width() - right_coord; right_coord = rect_client_window_now_.Width() - right_pad_width_original; left_coord = right_coord - width_original;
} void ControlAutoLayout::CalcLeftFixedWidthRightRatio(int &left_coord, int &right_coord)
{
int width_original = right_coord - left_coord;
int right_pad_width_original = rect_client_window_original_.Width() - right_coord;
int right_pad_width_new = (int)(right_pad_width_original * horizontal_ratio_); right_coord = rect_client_window_now_.Width() - right_pad_width_new; left_coord = right_coord - width_original;
} ////////////////////////////////////////////////////////////////////////// void ControlAutoLayout::CalcTopPadBottomPad(int &top_coord, int &bottom_coord)
{
//
top_coord = top_coord; int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original;
} void ControlAutoLayout::CalcTopPadBottomRatio(int &top_coord, int &bottom_coord)
{
//
top_coord = top_coord; int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_); bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new;
} void ControlAutoLayout::CalcTopRatioBottomPad(int &top_coord, int &bottom_coord)
{
top_coord = (int)(top_coord * vertical_ratio_); int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original;
} void ControlAutoLayout::CalcTopRatioBottomRatio(int &top_coord, int &bottom_coord)
{
top_coord = (int)(top_coord * vertical_ratio_); int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_);
bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new;
} void ControlAutoLayout::CalcTopRatioBottomFixedHeight(int &top_coord, int &bottom_coord)
{
int height_original = rect_client_window_original_.Height() - top_coord; top_coord = (int)(top_coord * vertical_ratio_); bottom_coord = rect_client_window_now_.Height() - height_original;
} void ControlAutoLayout::CalcTopFixedHeightBottomPad(int &top_coord, int &bottom_coord)
{
int height_original = bottom_coord - top_coord;
int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord; bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_original; top_coord = bottom_coord - height_original;
} void ControlAutoLayout::CalcTopFixedHeightBottomRatio(int &top_coord, int &bottom_coord)
{
int height_original = bottom_coord - top_coord;
int bottom_pad_height_original = rect_client_window_original_.Height() - bottom_coord;
int bottom_pad_height_new = (int)(bottom_pad_height_original * vertical_ratio_); bottom_coord = rect_client_window_now_.Height() - bottom_pad_height_new; top_coord = bottom_coord - height_original;
} //////////////////////////////////////////////////////////////////////////
void ControlAutoLayout::InitControlRectInMap(CWnd* control_item)
{
CRect rect_control_item;
if (NULL == control_item || NULL == wnd_dialog_)
{
return;
} if (!IsExistControlRect(control_item))
{
control_item->GetWindowRect(&rect_control_item);
wnd_dialog_->ScreenToClient(&rect_control_item);
map_control_original_rect_[control_item] = rect_control_item;
}
} CRect ControlAutoLayout::GetControlRect(CWnd* control_item)
{
CRect rect_control_item;
if (NULL == control_item || NULL == wnd_dialog_)
{
return rect_control_item;
} if (IsExistControlRect(control_item))
{
rect_control_item = map_control_original_rect_[control_item];
}
else
{
control_item->GetWindowRect(&rect_control_item);
wnd_dialog_->ScreenToClient(&rect_control_item);
} return rect_control_item;
} int ControlAutoLayout::GetHorizontalChangeMode(
int left_change_mode, int right_change_mode)
{
//combine left mode and right mode
// top_change_mode = 0, bottom_change_mode = 1
// => vertical_change_mode = 0x0001
int horizontal_change_mode = (left_change_mode << ) + right_change_mode; return horizontal_change_mode;
} int ControlAutoLayout::GetVerticalChangeMode(int top_change_mode, int bottom_change_mode)
{
//combine top mode and bottom mode
// top_change_mode = 1, bottom_change_mode = 2
// => vertical_change_mode = 0x0102
int vertical_change_mode = (top_change_mode << ) + bottom_change_mode;
return vertical_change_mode;
} void ControlAutoLayout::GetRectCoord(CRect rect,
int &left_coord, int &right_coord, int &top_coord, int &bottom_coord)
{
left_coord = rect.left;
right_coord = rect.right;
top_coord = rect.top;
bottom_coord = rect.bottom;
} void ControlAutoLayout::SetRectByCoord(CRect &rect,
int left_coord, int right_coord, int top_coord, int bottom_coord)
{
rect.left = left_coord;
rect.top = top_coord; if (kcontrol_width_min > right_coord - left_coord)
{
rect.right = left_coord + kcontrol_width_min;
}
else
{
rect.right = right_coord;
} if (kcontrol_height_min > bottom_coord - top_coord)
{
rect.bottom = top_coord + kcontrol_height_min;
}
else
{
rect.bottom = bottom_coord;
}
} bool ControlAutoLayout::IsExistControlRect(CWnd* control_item)
{
std::map<CWnd*,CRect>::iterator itr;
itr = map_control_original_rect_.find(control_item);
if (itr != map_control_original_rect_.end())
{
return true;
} return false;
} bool ControlAutoLayout::IsEqual(double x, double y)
{
double differ = std::abs(x - y); if (kdouble_precision >= differ)
{
return true;
} return false;
}

源码下载:AutoLayout.7z

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

上一篇:Delphi的内存管理及内存泄露问题 FastMM4


下一篇:Access中的SELECT @@IDENTITY