WTL布局对话框 CDialogResize
WTL提供了一个很棒的对话框扩充类CDialogResize,可以使对话框控件随对话框大小改变而改变(包括大小和位置,只能选一个)。
该类定义在:atlframe.h
一个很棒的教程:Using WTL's Built-in Dialog Resizing Class
还有一个可以在MFC中实现同样效果:Using WTL's Built-in Dialog Resizing Class for MFC
步骤如下:
1.继承列表加入CDialogResize,如:
2.添加控件到表格中,跟MFC中的消息映射表是同样的道理:
3.初始化相关数据,可以在InitDialog中进行:
4.把这个类加入到对话框的消息处理序列中:
this’s it!
另外,我对里面的Group概念不是很清楚,干脆改掉原来的逻辑。我的目的是:将一个Group看做一个整体,就像一个独立的控件,和独立控件的动作应该是一致的。
下面贴出修改的代码:
bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGroup, _AtlDlgResizeData& data, bool bGroup, _AtlDlgResizeData* pDataPrev = NULL) { T* pT = static_cast<T*>(this); ATLASSERT(::IsWindow(pT->m_hWnd)); ATL::CWindow ctl; RECT rectCtl = { 0 }; ctl = pT->GetDlgItem(data.m_nCtlID); if(!ctl.GetWindowRect(&rectCtl)) return false; ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); if(bGroup) { //add the constant by shang const int cxGroup = rectGroup.right-rectGroup.left; const int cyGroup = rectGroup.bottom - rectGroup.top; const int cxCtrl = data.m_rect.right-data.m_rect.left; const int cyCtrl = data.m_rect.bottom - data.m_rect.top; const int cxCtrlLeftMargin = data.m_rect.left-rectGroup.left; const int cyCtrlTopMargin = data.m_rect.top-rectGroup.top; if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) { // int cxRight = rectGroup.right + cxWidth - m_sizeDialog.cx; // int cxCtl = data.m_rect.right - data.m_rect.left; // rectCtl.left = rectGroup.left + (cxRight - rectGroup.left - cxCtl) / 2; // rectCtl.right = rectCtl.left + cxCtl; ////////////////////////////////////////////////////////////////////////// //modify by shang rectCtl.left = cxCtrlLeftMargin + (cxWidth-(cxGroup))/2; rectCtl.right = rectCtl.left + cxCtrl; } else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) { // rectCtl.left = rectGroup.left + ::MulDiv(data.m_rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); // // if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0) // { // rectCtl.right = rectGroup.left + ::MulDiv(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_sizeDialog.cx), rectGroup.right - rectGroup.left); // // if(pDataPrev != NULL) // { // ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); // RECT rcPrev = { 0 }; // ctlPrev.GetWindowRect(&rcPrev); // ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); // int dxAdjust = (rectCtl.left - rcPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right); // rcPrev.right += dxAdjust; // ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); // } // } // else // { // rectCtl.right = rectCtl.left + (data.m_rect.right - data.m_rect.left); // } ////////////////////////////////////////////////////////////////////////// //modify by shang if(data.m_dwResizeFlags & DLSZ_SIZE_X){ rectCtl.left = data.m_rect.left+::MulDiv(cxWidth-m_sizeDialog.cx,cxCtrlLeftMargin,cxGroup); rectCtl.right = data.m_rect.right+::MulDiv(cxWidth-m_sizeDialog.cx,cxCtrl+cxCtrlLeftMargin,cxGroup); } else{ //DLSZ_MOVE_X rectCtl.left = data.m_rect.left+(cxWidth-m_sizeDialog.cx); rectCtl.right = rectCtl.left+cxCtrl; } } if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) { // int cyBottom = rectGroup.bottom + cyHeight - m_sizeDialog.cy; // int cyCtl = data.m_rect.bottom - data.m_rect.top; // rectCtl.top = rectGroup.top + (cyBottom - rectGroup.top - cyCtl) / 2; // rectCtl.bottom = rectCtl.top + cyCtl; ////////////////////////////////////////////////////////////////////////// //modify by shang rectCtl.top = cyCtrlTopMargin + (cyHeight-cyGroup)/2; rectCtl.bottom = rectCtl.top + cyCtrl; } else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) { // rectCtl.top = rectGroup.top + ::MulDiv(data.m_rect.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); // // if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0) // { // rectCtl.bottom = rectGroup.top + ::MulDiv(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); // // if(pDataPrev != NULL) // { // ATL::CWindow ctlPrev = pT->GetDlgItem(pDataPrev->m_nCtlID); // RECT rcPrev = { 0 }; // ctlPrev.GetWindowRect(&rcPrev); // ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rcPrev, 2); // int dxAdjust = (rectCtl.top - rcPrev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom); // rcPrev.bottom += dxAdjust; // ctlPrev.SetWindowPos(NULL, &rcPrev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); // } // } // else // { // rectCtl.bottom = rectCtl.top + (data.m_rect.bottom - data.m_rect.top); // } ////////////////////////////////////////////////////////////////////////// //modify by shang if(data.m_dwResizeFlags & DLSZ_SIZE_Y){ rectCtl.top = data.m_rect.top+::MulDiv(cyHeight-m_sizeDialog.cy,cyCtrlTopMargin,cyGroup); rectCtl.bottom = data.m_rect.bottom+::MulDiv(cyHeight-m_sizeDialog.cy,cyCtrl+cyCtrlTopMargin,cyGroup); } else{ //DLSZ_MOVE_Y rectCtl.top = data.m_rect.top+(cyHeight-m_sizeDialog.cy); rectCtl.bottom = rectCtl.top+cyCtrl; } } } else // no group { if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) { int cxCtl = data.m_rect.right - data.m_rect.left; rectCtl.left = (cxWidth - cxCtl) / 2; rectCtl.right = rectCtl.left + cxCtl; } else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE_X)) != 0) { rectCtl.right = data.m_rect.right + (cxWidth - m_sizeDialog.cx); if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0) rectCtl.left = rectCtl.right - (data.m_rect.right - data.m_rect.left); } if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) { int cyCtl = data.m_rect.bottom - data.m_rect.top; rectCtl.top = (cyHeight - cyCtl) / 2; rectCtl.bottom = rectCtl.top + cyCtl; } else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE_Y)) != 0) { rectCtl.bottom = data.m_rect.bottom + (cyHeight - m_sizeDialog.cy); if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0) rectCtl.top = rectCtl.bottom - (data.m_rect.bottom - data.m_rect.top); } } if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0) ctl.Invalidate(); if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0) ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOACTIVATE); return true; } };