让控件跟着窗体的大小变化其实是不难的,只需要在WM_SIZE消息的处理函数里做一些工作就好了。之所以提出来,是因为自己一开始在做的时候对一系列的坐标太不容易搞清楚,所以,总会带来每个控件不知道要按照哪个坐标信息做调整的困惑。写下WM_SIZE消息的处理过程,廖以告诉自己不要忘记~~
首先为窗体增加WM_SIZE的处理函数。这个简单,不在赘述。
OnSize函数的实现如下:
void CDisassembly::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
static RECT LastWindowRect = {0, 0, 0, 0};
CWnd *hWin;
int ux = cx - LastWindowRect.right;
int uy = cy - LastWindowRect.bottom;
if((hWin = GetDlgItem(IDC_DISASSEMBLY)) != NULL)
{
RECT rect;
hWin->GetWindowRect(&rect);
ScreenToClient(&rect);
rect.right += ux;
rect.bottom += uy;
hWin->MoveWindow(&rect);
}
LastWindowRect.right = cx;
LastWindowRect.bottom = cy;
}
OnSize函数的后两个参数表示了ReSize之后的窗体的大小。为了对控件进行调整,在OnSize函数中定义了一个static RECT LastWindowRet,以便记录上一次窗口的大小。并将本次大小与上一次做对比:
int ux = cx - LastWindowRect.right;
int uy = cy - LastWindowRect.bottom;
求得两次窗口的大小差异后,通过GetDlgItem()函数获取控件的指针(这里,只能手工遍历所有的控件,不晓得是否有比较智能的方法可以获取到对话框的所有子窗口的列表),然后使用MoveWindow函数对控件的大小进行调整。
在本例中,IDC_DISASSEMBLY是一个EditBox,我希望它随着对话框的大小变化而变化,所以,首先利用GetWindowRect获取EditBox的现在大小,然后利用ScrenToClient将获取到的区域信息转换成对话框内部的相对坐标,最后再根据之前计算出的ux和uy对EditBox的宽度和高度进行调整,最后使用MoveWindow修改大小。
上面就是利用OnSize来让控件跟着变的方法。如果控件的大小不希望改变,而只希望改变位置,那么可以将控件的RECT的left、right、top、bottom同步做调整即可~