在MFC开发窗口应用程序时,需要对窗体(如CFORMVIEW)中控件进行布局,如图1所示。特别在不同分辨率显示时,整个界面可能不尽人意,对所有控件位置调整过程领人烦恼。如图2为调整后的位置,看起来比图1布局美观。下面介绍控件位置布局实现原理,以及在MFC使用迭代函数处理过程。
图1
图2
解决方法:
图3
定义两个控件:一个作为左边坐标定位l(蓝颜色部分),另一个作为右边坐标定位r(黄颜色部分)。
定义:w为视图窗口宽度,m为调整适中的位置偏移,n为最左控件的与视图左边的偏移量,dx为对应所有窗口视图中控件所移动的偏移量。
m = (w – (r - l)) / 2;
l = n = m - dx;
实现代码:
void CXXXView::OnSize(UINT nType, int cx, int cy)
{
CFormView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
CWnd *pWndLeft = (CWnd *)GetDlgItem(IDC_LEFT);
CWnd *pWndRight = (CWnd *)GetDlgItem(IDC_RIGHT);
if (pWndLeft->GetSafeHwnd() && pWndRight->GetSafeHwnd())
{
AdaptScreen();
}
}
void CXXXView::AdaptScreen()
{
int nX = 0;
int nY = 0;
int nNewX, nNewY;
int nNewWidth, nNewHeight;
CRect rect, rectLeft, rectRight;
GetWindowRect(&rect);
ScreenToClient(&rect);
CWnd *pWndLeft = (CWnd *)GetDlgItem(IDC_LEFT);
CWnd *pWndRight = (CWnd *)GetDlgItem(IDC_RIGHT);
pWndLeft->GetWindowRect(rectLeft);
ScreenToClient(&rectLeft);
pWndRight->GetWindowRect(rectRight);
ScreenToClient(&rectRight);
int nRealWidth = rectRight.right - rectLeft.left;
nX = (rect.Width() - nRealWidth) / 2 - rectLeft.left;
if (nX < 0)
{
return;
}
CWnd *pWndChild = GetWindow(GW_CHILD);
while (pWndChild)
{
CRect rc;
pWndChild->GetWindowRect(&rc);
ScreenToClient(&rc);
nNewX = (int)(rc.left + nX);
nNewY = (int)(rc.top + nY);
nNewWidth = (int)rc.Width();
nNewHeight = (int)rc.Height();
pWndChild->MoveWindow(nNewX, nNewY, nNewWidth, nNewHeight);
pWndChild = pWndChild->GetNextWindow();
}
}
注:本文只对X轴方向位置适中调整,并且对分辨率低于当前视图窗口不作调整。