本文主要针对MFC的dialog,实现控件随窗口大小变化。

原理:首先获取dialog的初始大小,当窗口发送变动时,调用OnSize事件和方法,计算缩放比例,然后对界面中的所有控件进行缩放和布局。

实现:

创建一个CMFCDemoDlg的dialog对话框;

// CMFCDemoDlg 对话框
class CMFCDemoDlg : public CDialogEx
{
// 构造
public:
CMFCDemoDlg(CWnd* pParent = NULL); // 标准构造函数 // 对话框数据
enum { IDD = IDD_MFCDEMO_DIALOG }; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 protected:
CRect m_rect;
void ChangeSize(UINT nID,int x,int y);
void ReSize(void);
POINT old;
protected:
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSize(UINT nType, int cx, int cy);
DECLARE_MESSAGE_MAP()
};

在OnInitDialog方法中获取dialog的初始大小,记录到old变量中;

注册OnSize事件处理方法(ON_WM_SIZE(), OnSize()函数),设置控件大小

CMFCDemoDlg::CMFCDemoDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFCDemoDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} void CMFCDemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
} BEGIN_MESSAGE_MAP(CMFCDemoDlg, CDialogEx)
ON_WM_SIZE()
END_MESSAGE_MAP() // CMFCDemoDlg 消息处理程序 BOOL CMFCDemoDlg::OnInitDialog()
{
CDialogEx::OnInitDialog(); // 获取对话框初始大小
GetClientRect(&m_rect); //获取对话框的大小
old.x=m_rect.right-m_rect.left;
old.y=m_rect.bottom-m_rect.top; return TRUE;
} void CMFCDemoDlg::ReSize(void)
{
float fsp[];
POINT Newp; //获取现在对话框的大小
CRect recta;
GetClientRect(&recta); //取客户区大小
Newp.x=recta.right-recta.left;
Newp.y=recta.bottom-recta.top;
fsp[]=(float)Newp.x/old.x;
fsp[]=(float)Newp.y/old.y;
CRect Rect;
int woc;
CPoint OldTLPoint,TLPoint; //左上角
CPoint OldBRPoint,BRPoint; //右下角
HWND hwndChild=::GetWindow(m_hWnd,GW_CHILD); //列出所有控件
while(hwndChild){
woc=::GetDlgCtrlID(hwndChild);//取得ID
GetDlgItem(woc)->GetWindowRect(Rect);
ScreenToClient(Rect);
OldTLPoint = Rect.TopLeft();
TLPoint.x = long(OldTLPoint.x*fsp[]);
TLPoint.y = long(OldTLPoint.y*fsp[]);
OldBRPoint = Rect.BottomRight();
BRPoint.x = long(OldBRPoint.x *fsp[]);
BRPoint.y = long(OldBRPoint.y *fsp[]);
Rect.SetRect(TLPoint,BRPoint);
GetDlgItem(woc)->MoveWindow(Rect,TRUE);
hwndChild=::GetWindow(hwndChild, GW_HWNDNEXT);
}
old=Newp;
} void CMFCDemoDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType,cx,cy);
if(nType!=SIZE_MINIMIZED ) //判断窗口是不是最小化了,因为窗口最小化之后 ,窗口的长和宽会变成0,当前一次变化的时就会出现除以0的错误操作
{
ReSize();
}
}

通过hwndChild=::GetWindow(m_hWnd,GW_CHILD);和::GetWindow(hwndChild, GW_HWNDNEXT); 列出所有控件

也可针对特定控件设置其大小,如:

//change control size
void CMFCDemoDlg::ChangeSize(UINT nID,int x,int y)
{
CWnd *pWnd = GetDlgItem(nID);
if(pWnd!=NULL)
{
CRect rec;
pWnd->GetWindowRect(&rec);//获取控件变化前的大小
ScreenToClient(rec); //将控件大小装换位在对话框中的区域坐标
// x / m_rect.Width(); 伸缩rate
rec.left = rec.left * x / m_rect.Width();
rec.top = rec.top * y / m_rect.Height();
rec.bottom = rec.bottom * y / m_rect.Height();
rec.right = rec.right * x / m_rect.Width();
pWnd->MoveWindow(rec);//伸缩控件
}
}

参考:http://blog.csdn.net/lujianfeiccie2009/article/details/5485602

MFC控件随窗口大小变化原理及实现的更多相关文章

  1. C# Winform 界面中各控件随着窗口大小变化

    在做一项工程中,由于不确定目标平台的分辨率,而正常使用要求铺满整个屏幕,所以界面中的各个控件必须能够适应窗口的变化. 首先想到的就是控件的百分比布局,但是再尝试写了几个控件的Location和Size ...

  2. 【MFC】mfc控件位置调整和坐标确定 .

    摘自DoubleLi:   http://www.cnblogs.com/lidabo/archive/2012/08/24/2654678.html mfc控件位置调整和坐标确定 http://my ...

  3. MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.

    MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...

  4. MFC控件编程之鼠标跟键盘消息

    MFC控件编程之鼠标跟键盘消息 在MFC中鼠标消息.键盘消息我们很常用.所以说一下. 鼠标消息分为客户区消息.跟非客户区消息. 一丶客户区消息 我们可以处理消息.来进行我们相应的函数即可. MFC添加 ...

  5. MFC控件的SubclassDlgItem

    MFC控件的SubclassDlgItem 要在程序中创建新设计的控件,显然不能用自动创建的办法,因为对话框模板对新控件的特性一无所知.程序可以用手工方法创建控件,在调用派生类的Create函数时,派 ...

  6. [MFC] 梳理一个简单的图片处理桌面软件中用到的MFC控件技巧

     前言 前些天应好友之拖,帮忙设计一个简单的图像处理的小软件.朋友把核心算法封装好了,但是是用openCV类似于console的编程环境,要我在此基础上改成MFC桌面程序.下图是做成之后的效果: 我是 ...

  7. paip.gui控件form窗体的原理实现以及easyui的新建以及编辑实现

    paip.gui控件form窗体的原理实现以及easyui的新建以及编辑实现 //////新建 与编辑  var  EditForm=new Form_easyui();    if(row)     ...

  8. Android控件TextView的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/8636153 在前面一个系列的文章中,我们以窗口 ...

  9. MFC控件编程进度条编写

    MFC控件编程进度条编写 一丶进度条编程需要用到的方法 进度条MFC已经帮我们封装好类了. 叫做 CProgressCtrl  进度条编程也很简单. 封装的方法也就那个那几个. GetPos()  获 ...

随机推荐

  1. C#中String和string有什么区别

    在C#中,string 是 System.String 的别名,所以基本上在使用时是没有差别的. 习惯上,我们把字符串当作对象时(有值的对象实体),我们用string.而我们把它当类时(需要字符串类中 ...

  2. js中获取函数的参数

    刘海波 2015/2/11 9:11:43 tmp = tmp.replace(/\{(\d+)\}/g, function($1, $2) {return addrow.arguments[pars ...

  3. tachyon 配置项

    Tachyon 配置参数分为4类:Master,Worker, Common (Master and Worker), and User configurations. 环境变量配置文件在$TACHY ...

  4. C# 代码生成工具 Millennials

    Millennials 是一个可定制的 C# 代码生成工具,支持 MVC 和三层架构.ADO.NET.Nhibernate 和 LINQ. 项目主页:http://www.open-open.com/ ...

  5. 1.4.7 Schema API

    Schema API Schema API允许使用REST API每个集合(collection)(或者单机solr的核(core)).包含了定义字段类型,字段,动态字段,复制字段等.在solr4.2 ...

  6. 程序员怎样在复杂代码中找 bug?(简单)

    分享下我的debug的经验 1. 优先解决那些可重现的,可重现的bug特别好找,反复调试测试就好了,先把好解决的干掉,这样最节约时间. 2. 对于某些bug没有头绪或者现象古怪不知道从哪里下手,找有经 ...

  7. .NET强制进行即时垃圾回收

    大家知道,.NET控制系统垃圾回收(一种自动回收未使用内存的服务)是自动的. 可有时候需要手动强制进行即时垃圾回收. 代码如下: GC.Collect();

  8. 一道简单的动态规划题目——House Robber

    一.题目 House Robber(一道Leetcode上的关于动态规划的简单题目)具体描述如下: There is a professional robber planning to rob hou ...

  9. Shell学习笔记 - 正则表达式

    一.正则表达式是什么? 正则表达式是用于描述字符排列和匹配模式的一种语法规则.它主要用于字符串的模式分割.匹配.查找及替换操作. 二.正则表达式与通配符 1. 正则表达式 用来在文件中匹配符合条件的字 ...

  10. Linux 网卡设备驱动程序设计(3)

    三.网络子系统深度分析 用户程序通过网络发送这个网络数据包 通过 SCI 协议无关接口 协议栈 <   UDP的实现  会选择路由 <    IP的实现  会建立这个邻居子系统,建立邻居信 ...