MFC 对话框控件自动布局
MFC 设计界面程序总是不够智能,没有这样,没有那样。
今天为了加强mfc功能,设计了一个自动布局的类,使用非常简单。
原理:
每个控件都有一个矩形区域,矩形区域就是控件在对话框中的显示位置和大小,
通过矩形的四个顶点,控制控件的布局,
在mfc中OnSize()函数在对话框大小变化时被调用,所有每次对话框大小变化时,
我们重新计算对控件的矩形坐标,然后移动到新的坐标,实现控件自动布局。
效果:
1、原始界面:

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

接口:
/**
* @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);
用法:
- 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 ControlAutoLayoutOn 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 对话框控件自动布局的更多相关文章
- 回调函数中使用MFC类的成员或对话框控件的简单方法
在MFC的很多程序中,常常需要在回调函数中调用MFC类的类成员变量.类成员函数,亦或者对话框控件的句柄.由于回调函数是基于C编程的Windows SDK的技术,而类成员又有this指针客观条件限制.. ...
- MFC中 自定义类访问主对话框控件的方法
之前一直在找有木有好点的方法.现在终于被我找到,收藏之~~~~~~ 在使用mfc的时候经常遇到自定义类访问主对话框控件的问题,例如自定义类中的方法要输出一段字符串到主对话框的EDIT控件.控制对话框的 ...
- MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为"计算"按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但 ...
- VS2010/MFC设置对话框控件的Tab顺序
设置对话框控件的Tab顺序 前面几节为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法 ...
- VS2010/MFC编程入门之十(对话框:设置对话框控件的Tab顺序)
前面几节鸡啄米为大家演示了加法计算器程序完整的编写过程,本节主要讲对话框上控件的Tab顺序如何调整. 上一讲为“计算”按钮添加了消息处理函数后,加法计算器已经能够进行浮点数的加法运算.但是还有个遗留的 ...
- 发布MFC ActiveX控件并实现自动更新
一. 引言 上一篇我们讲了如何使用 VC 2005来开发 MFC ActiveX控件,我们开发 ActiveX控件最终目的是将 ActiveX控件发布出来并嵌入在 Web网页中,随着控件 ...
- MFC TabCtrl 控件修改标签尺寸
注意:无论那种方法,都要先设置Tab控件的Style属性为fixed width. 第一种方法 MFC,tabcontrol控件改变标签大小 - CSDN博客 https://blog.csdn.ne ...
- vs2010开发activex(MFC)控件/ie插件(一)
原文:http://blog.csdn.net/yhhyhhyhhyhh/article/details/50782904 vs2010开发activex(MFC)控件: 第一步:生成ac ...
- 开发ActiveX控件调用另一个ActiveX系列1——开发一个MFC ActiveX控件
ActiveX开发的教程有很多,我也从中受益匪浅,例如以下这几篇: 基本教程:http://www.cnblogs.com/guenli/articles/1629915.html 注意事项:http ...
随机推荐
- 调用微信JsAPI端获取位置
public partial class test : BasePage { protected test() { AccessPage = PageWebType.WX; } protected s ...
- Css 备忘知识点
1.Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示,可通过加入 CSS 属性 -webkit-text-size-adjust: none; 2.HTML5的form如 ...
- [地图SkyLine二次开发]关于IE内存限制问题(1G)
相信很多人也遇到过同样的问题,地图加载中,IE占用的内存一直增加,到了1G多一些的时候,IE就崩溃了. 在网上查阅了一番,有很多结果,下面归纳一下: a).64bit的IE最多可达到4G的内存,但Sk ...
- OO的五大原则是指SRP、OCP、LSP、DIP、ISP。
OO的高层原则,面向对象设计的基本原则 设计模式之六大原则--开闭原则(OCP) 设计模式之六大原则--迪米特法则(LoD,LKP) 设计模式之六大原则--接口隔离原则(ISP) 设计模式之六大原则- ...
- asp TreeView控件的使用
相对于之前发过一个TreeView控件的使用方法 本次利用js操作,页面无刷新,性能提高 Css编码可能时我的模板页样式被继承下来,导致页面变乱,不需要的可以去掉 前台 <style> . ...
- asp 使用TreeView控件
这段代码为了使用 TreeNodeCheckChanged 事件,会有回刷新的效果: 不喜欢的可查看改进版,利用js控制选择操作,无界面刷新, “http://www.cnblogs.com/GoCi ...
- 在linux上配置并创建JavaFX项目
本环境为linux配置,因为这里的JavaFX项目是为定制Oracle监控工具而写的.现Oracle已收购Java好几年,用它自己的产生监控自己的东西还是很兼容的.此处Eclipse 为4.5版本. ...
- 电子爱好者DIY篇
2016/7/15 电子爱好者DIY篇 一年和之前就想到了一些感悟,现在有些模糊的清晰起来了,但还是不够清晰,故写下来做个日志. 结论 首先把结论放在前面.目前随着电子集成电路的发展,电子DIY越来越 ...
- java数据库连接池技术原理(浅析)
在执行数据库SQL语句时,我们先要进行数据连接:而每次创建新的数据库的连接要消耗大量的资源,这样,大家就想出了数据库连接池技术.它的原理是,在运行过程中,同时打开着一定数量的数据库连接,形成数据连接池 ...
- leetcode刷题全纪录(持续更新)
2.Add Two Numbers 原题链接https://leetcode.com/problems/add-two-numbers/ AC解: public ListNode addTwoNumb ...