MFC小笔记:控件随窗口变化

一、需求

当窗口大小变化时,如最大化、最小化时,控件位置和大小并没有变化,本文实现此功能。

二、界面

主界面为对话框,有最小化、最大化、关闭等功能。

三、原理

当窗口变化时,响应 OnSize 函数,并计算各控件位置,按比例缩放。

四、编码

4.1 变量定义

在对话框类向导中添加 WM_SIZE 消息。其函数定义如下:

1
afx_msg void OnSize(UINT nType, int cx, int cy);

在对话框头文件声明变量:

1
CRect m_cRect;

用于保存位置信息。

4.2 初始化

在OnInitDialog函数中先获取位置信息并保存:

1
GetClientRect(&m_cRect);

4.3 实现缩放

同一文件,实现控件变化的计算,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CTestDlg::ChangeSize(int ctrID, int cx, int cy)
{
CWnd* pWnd = GetDlgItem(ctrID);
if (pWnd)
{
CRect rect; //获取控件变化前的大小
pWnd->GetWindowRect(&rect);
ScreenToClient(&rect);//将控件大小转换为在对话框中的区域坐标

// cx/m_cRect.Width()为对话框在横向的变化比例
rect.left = rect.left*cx / m_cRect.Width();//调整控件大小
rect.right = rect.right*cx / m_cRect.Width();
rect.top = rect.top*cy / m_cRect.Height();
rect.bottom = rect.bottom*cy / m_cRect.Height();
pWnd->MoveWindow(rect);//设置控件大小
}
}

先获取控件ID,得到控件大小,再根据当前的 x、y计算比例,再移动控件。

4.4 处理 OnSize 事件

在 OnSize 函数中调用 ChangeSize 函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CTestDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);

int CDlgItem[] = {
IDC_STC_1,
IDC_STC_2,
IDC_STC_3,
};

for (int i = 0; i < sizeof(CDlgItem) / sizeof(CDlgItem[0]); i++)
{
ChangeSize(CDlgItem[i], cx, cy);
}
GetClientRect(&m_cRect);// 将变化后的对话框大小设为旧大小
}

根据指定的控件ID进行缩放。注意,有些控件可以不进行缩放,比如,左上方的提示语相关控件,不需要移动。