MFC Dialog改变大小后,控件位置随之改变方法

在使用MFC写Dialog程序时,对话框大小调动后,控件的大小和位置没有变化,界面看起来会很不美观。上网也搜了一些方法,但要么编译有问题,要么运行结果不理想。使用了一下两种方法,经验证可用。

  一 手动写代码控制控件位置和大小的改变,控件是从CWnd派生的,但不能使用SetWindowPos()或OnSize()或OnSizing()来改变其大小,应在父窗口的WM_SIZE消息中使用MoveWindow()来进行调整。步骤如下:

1  在TestDlg类中添加变量m_rect,在Dialog的OnInitDialog()函数中获取对话框创建时的大小,添加GetClientRect(&m_rect)。

?
1
2
3
4
5
BOOL  CTestDlg::OnInitDialog()<br>{<br>    CDialog::OnInitDialog();<br>    ... 
     // TODO: Add extra initialization here
     GetClientRect(&m_rect); //添加代码
      return  TRUE;  // return TRUE  unless you set the focus to a control
}

2 给Dialog添加ReSize函数。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void  CTestDlg::ReSize( int  nID, int  cx, int  cy)
{
     CWnd *pWnd;
     pWnd = GetDlgItem(nID);     //获取控件句柄
     if (pWnd)  
     {
         CRect rect;   //获取控件变化前大小
          pWnd->GetWindowRect(&rect);
         ScreenToClient(&rect); //将控件大小转换为在对话框中的区域坐标
          rect.left=( int )(rect.left*(( float )cx/( float )m_rect.Width())); //调整控件大小
          rect.right=( int )(rect.right*(( float )cx/( float )m_rect.Width()));
         rect.top=( int )(rect.top*(( float )cy/( float )m_rect.Height()));
         rect.bottom = ( int )(rect.bottom*(( float )cy/( float )m_rect.Height()));
         pWnd->MoveWindow(rect); //设置控件位置
     }
}

3 添加WM_SIZE的响应函数OnSize()

?
1
2
3
4
5
6
7
8
9
10
void  CTestDlg::OnSize( UINT  nType, int  cx, int  cy)
{
     CDialog::OnSize(nType, cx, cy);
     // TODO: Add your message handler code here
     if (nType!=SIZE_MINIMIZED) //判断是否为最小化
     {
     ReSize(IDC_OK, cx, cy);
     GetClientRect(&m_rect);
     }
}

  在计算坐标位置的时候必须要强制转化成float去计算,否则误差会很大,这样做是将所有控件的大小和位置都按照Dialog的大小改变了,如果仅需改变位置,不改变大小,可以修改ReSize函数。

  二 除了上述方法以外,也可以是用easysize(easysize.h可以在codeproject下载)去改变控件位置和大小。使用方法如下:

1 把easysize放入CTestDlg项目文件夹中。同时在CTestDlg.h文件中加入#include "easysize.h"。

2 在CTestDlg类定义中加入DECLARE_EASYSIZE

?
1
2
3
4
5
6
class  CTestDlg : public  CDialog
{
      DECLARE_EASYSIZE  //没有分号
      // Construction
...
}

3 在CTestDlg类的OnInitDialog()函数的结尾处加入INIT_EASYSIZE

?
1
2
3
4
5
6
7
8
BOOL  CTestDlg::OnInitDialog()
{
         CDialog::OnInitDialog();
         ...
        //TODO: Add extra initialization here
        INIT_EASYSIZE;  //此处有分号
        return  TRUE;  // return TRUE  unless you set the focus to a control
}

4 增加WM_SIZE消息响应函数OnSize(),在函数中加入UPDATE_EASYSIZE

?
1
2
3
4
5
6
7
void  CTestDlg::OnSize( UINT  nType, int  cx, int  cy)
{
 
        CDialog::OnSize(nType, cx, cy);
        // TODO: Add your message handler code here
        UPDATE_EASYSIZE;  //此处有分号
}

5 在CTestDlg的cpp文件中添加EASYSIZE 的控件布局映射宏映射

?
1
2
3
BEGIN_EASYSIZE_MAP(CTestDlg)
EASYSIZE(nID,left,top,right,bottom,options) //此处根据自己需求
END_EASYSIZE_MAP

EASYSIZE(nID,left,top,right,bottom,options)

该宏表示对ID值为nID的控件实施缩放效果,缩放后的上下左右位置由control,left,top,right,bottom来确定,此处的方位是指的控件的上下左右,而不是Dialog的上下左右,left,top,right,bottom四个参数为控件位置的坐标,其值可为ES_BOARD,ES_KEEPSIZE, 控件ID值三者之一。Options可以为ES_HCENTER, ES_VCENTER,或两者的结合,也可以设置为0。

ES_BOARD表示控件与对话框边界(以下简称边界)的距离;

ES_KEEPSIZE表示控件水平/垂直方向上尺寸保持不变;

控件ID值表示当前控件与指定控件之间的距离;

ES_HCENTER表示缩放后控件在指定位置内水平居中;

ES_VCENTER表示缩放后控件在指定位置内垂直居中;

在使用EASYSIZE(nID,left,top,right,bottom,options)时,布局经常与理想布局出入较大,为了熟悉,可参考easysize的demo。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值