MFC 对话框控件自动布局

时间:2022-09-20 19:58:15

  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

MFC 对话框控件自动布局的更多相关文章

  1. 回调函数中使用MFC类的成员或对话框控件的简单方法

    在MFC的很多程序中,常常需要在回调函数中调用MFC类的类成员变量.类成员函数,亦或者对话框控件的句柄.由于回调函数是基于C编程的Windows SDK的技术,而类成员又有this指针客观条件限制.. ...

  2. MFC中 自定义类访问主对话框控件的方法

    之前一直在找有木有好点的方法.现在终于被我找到,收藏之~~~~~~ 在使用mfc的时候经常遇到自定义类访问主对话框控件的问题,例如自定义类中的方法要输出一段字符串到主对话框的EDIT控件.控制对话框的 ...

  3. MFC编程入门之十(对话框:设置对话框控件的Tab顺序)

    前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为"计算"按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但 ...

  4. VS2010&sol;MFC设置对话框控件的Tab顺序

    设置对话框控件的Tab顺序 前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法 ...

  5. VS2010&sol;MFC编程入门之十(对话框:设置对话框控件的Tab顺序)

    前面几节鸡啄米为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但是还有个遗留的 ...

  6. 发布MFC ActiveX控件并实现自动更新

    一.        引言 上一篇我们讲了如何使用 VC 2005来开发 MFC ActiveX控件,我们开发 ActiveX控件最终目的是将 ActiveX控件发布出来并嵌入在 Web网页中,随着控件 ...

  7. MFC TabCtrl 控件修改标签尺寸

    注意:无论那种方法,都要先设置Tab控件的Style属性为fixed width. 第一种方法 MFC,tabcontrol控件改变标签大小 - CSDN博客 https://blog.csdn.ne ...

  8. vs2010开发activex(MFC)控件&sol;ie插件&lpar;一&rpar;

    原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/50782904  vs2010开发activex(MFC)控件:      第一步:生成ac ...

  9. 开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件

    ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇: 基本教程:http://www.cnblogs.com/guenli/articles/1629915.html 注意事项:http ...

随机推荐

  1. 实现List按与一个字符串的相似度和字母顺序排序(适用于模糊查询后的排序)

    因公司业务需要,自己写了一个,保存起来以后可能还会用到.如果还有更好的方法或者算法,希望大家提出来. 1.简单的相似度算法(自己想到的)      因为List中每个String都会包含一个标准的字符 ...

  2. &lbrack;原创&rsqb;java WEB学习笔记64:Struts2学习之路--主题

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. CodeForces 149D Coloring Brackets 区间DP

    http://codeforces.com/problemset/problem/149/D 题意: 给一个给定括号序列,给该括号上色,上色有三个要求 1.只有三种上色方案,不上色,上红色,上蓝色 2 ...

  4. 转&colon;关于数据库压缩技术的Survey

    原文来自于:http://outofmemory.cn/mysql/database-compression-tech 昨天给团队内的小伙伴做了一个关于数据库压缩技术的Survey,现将其中可以公开的 ...

  5. &lbrack;转&rsqb;简述volatile

    volatile int i=10; int j = i; ... int k = i; volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执 ...

  6. java 线程中断机制

    上一篇文章我们了解过了java有关线程的基本概念,有线程的属性,线程可能处于的状态,还有线程的两种创建的方式,最后还说了一个关键字synchronized,解决了高并发导致数据内容不一致问题,本篇文章 ...

  7. Python连接MySQL数据库之pymysql模块使用

    安装PyMySQL pip install pymysql PyMySQL介绍 PyMySQL是在python3.x版本中用于连接MySQL服务器的一个库,2中则使用mysqldb. Django中也 ...

  8. 浅析 JavaScript 链式调用

    对$函数你已经很熟悉了.它通常返回一个html元素或一个html元素的集合,如下: function$(){ var elements = []; for(vari=0,len=arguments.l ...

  9. LPC1800 and LPC4300 Boot&sol;ISP&sol;CRP

    MCU的启动方式有很多种:UART接口,扩展的静态存储单元(NOR Flash), SPI Flash,quad SPI Flash,高速USB0和USB1.另外可以通过对OTP存储单元的编程. 首先 ...

  10. 9-python 的ProxyHandler处理器(代理设置)

    ProxyHandler处理器(代理设置) 使用代理IP,这是爬虫/反爬虫的第二大招,通常也是最好用的. 很多网站会检测某一段时间某个IP的访问次数(通过流量统计,系统日志等),如果访问次数多的不像正 ...