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,如:

image

2.添加控件到表格中,跟MFC中的消息映射表是同样的道理:

image

3.初始化相关数据,可以在InitDialog中进行:

image

4.把这个类加入到对话框的消息处理序列中:

image

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;
    }
};
原文地址:https://www.cnblogs.com/aishangxue/p/3492959.html