zoukankan      html  css  js  c++  java
  • mfc控件位置随对话框窗口移动

    ControlPos.h代码

    //------------------------------------------------------------------------------
    // ControlPos.h
    // 
    //    CControlPos 
    //    Position controls on a form's resize 
    // 
    //        Copyright (c) 2000 Paul Wendt
    // 
    //        VERSION#    DATE            NAME    DESCRIPTION OF CHANGE
    //        --------    ----------    ----    ---------------------
    //        1.01      07/11/2000    PRW    Original creation.
    // 
    #ifndef CONTROLPOS_H_
    #define CONTROLPOS_H_
    
    //----------------------------------------------
    // these #define's specify HOW the control
    // will move. they can be combined with the
    // bitwise or operator
    //
    #define CP_MOVE_HORIZONTAL                    1
    #define CP_MOVE_VERTICAL                    2
    #define CP_RESIZE_HORIZONTAL                4
    #define CP_RESIZE_VERTICAL                    8
    #define CP_MOVE_HORIZONTAL_CENTER           16
    #define CP_MOVE_VERTICAL_CENTER                32
    class CControlPos
    {
    public:
        CControlPos(CWnd* pParent = NULL);
        virtual ~CControlPos();
    
    public:
        void SetParent(CWnd* pParent);
    
        BOOL AddControl(CWnd* pControl, const DWORD& dwStyle = CP_MOVE_HORIZONTAL);
        BOOL AddControl(const UINT& unId, const DWORD& dwStyle = CP_MOVE_HORIZONTAL);
        BOOL RemoveControl(CWnd* pControl);
        BOOL RemoveControl(const UINT& unId);
        void ResetControls(void);
        virtual void MoveControls(void);
    
        //---------------------------------------------------
        // most of the time, you don't want to move controls
        // if the user reduces window size [controls can
        // overlap and cause "issues"]
        // negative moves won't move controls when the parent
        // window is getting smaller than its original size
        //
        void SetNegativeMoves(const BOOL& fNegativeMoves = TRUE);
        BOOL GetNegativeMoves(void) const;
    
    protected:
        virtual void UpdateParentSize(void);
    
    private:
        CWnd*  m_pParent;        
        int    m_nOldParentWidth;            
        int    m_nOldParentHeight;
        int    m_nOriginalParentWidth;
        int    m_nOriginalParentHeight;
        BOOL   m_fNegativeMoves;
    
        CObArray m_awndControls;
    };
    
    //----------------------------------------------------
    // internal structure used to hold all information
    // about a CWnd* control
    //
    typedef struct tagCONTROLDATA
    {
        HWND  hControl;    // HWND's never change; some MFC functions return temporary CWnd *'s
        DWORD dwStyle;        // check the #define's above
    } CONTROLDATA, *LPCONTROLDATA;
    
    #endif

    ControlPos.cpp

    //------------------------------------------------------------------------------
    // ControlPos.cpp
    // 
    //    CControlPos 
    //    Position controls on a form's resize 
    // 
    //        Copyright (c) 2000 Paul Wendt
    // 
    //        VERSION#    DATE            NAME    DESCRIPTION OF CHANGE
    //        --------    ----------    ----    ---------------------
    //        1.01      07/11/2000    PRW    Original creation.
    // 
    #include "StdAfx.h"
    #include "ControlPos.h"
    
    //------------------------------------------------------------------------------
    // CControlPos::CControlPos
    // 
    //    default constructor 
    // 
    //    Access: public
    // 
    //    Args:
    //        CWnd* pParent                =    pointer to parent window
    // 
    //    Return:
    //        none
    // 
    CControlPos::CControlPos(CWnd* pParent /* = NULL */)
    {
        m_pParent = pParent;
        UpdateParentSize();
    
        m_nOldParentHeight = 0;
        m_nOldParentWidth = 0;
        
        SetNegativeMoves(FALSE);
    
        ResetControls();
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::~CControlPos
    // 
    //    default destructor -- It deletes all controls. 
    // 
    //    Access: public
    // 
    //    Args:
    //        none
    // 
    //    Return:
    //        none
    // 
    CControlPos::~CControlPos()
    {
        ResetControls();
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::SetParent
    // 
    //    This sets the parent window. It should be called from a CWnd's 
    //    post-constructor function, like OnInitdialog or InitialUpdate. 
    // 
    //    Access: public
    // 
    //    Args:
    //        CWnd* pParent    =    parent window
    // 
    //    Return:
    //        none
    // 
    void CControlPos::SetParent(CWnd* pParent)
    {
        CRect rcParentOriginalSize;
    
        m_pParent = pParent;
    
        m_pParent->GetClientRect(rcParentOriginalSize);
        m_nOriginalParentWidth = rcParentOriginalSize.right;
        m_nOriginalParentHeight = rcParentOriginalSize.bottom;
    
        UpdateParentSize();
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::AddControl
    // 
    //    This adds a control to the internal list of controls in CControlPos.  
    // 
    //    Access: public
    // 
    //    Args:
    //        CWnd* pControl                =    pointer to the control to be added
    //        const DWORD& dwStyle        =  how the window should be moved -- see #define's
    //                               in the header file
    // 
    //    Return:
    //        BOOL     =    TRUE if the control was added successfully, FALSE otherwise
    // 
    BOOL CControlPos::AddControl(CWnd* pControl, const DWORD& dwStyle /* = CP_MOVE_HORIZONTAL */)
    {
        BOOL fReturnValue = TRUE;
    
        if (pControl && m_pParent)
        {
            LPCONTROLDATA pstControl = new CONTROLDATA;
            pstControl->hControl = pControl->GetSafeHwnd();
            pstControl->dwStyle = dwStyle;
            m_awndControls.Add(((CObject*)pstControl));
        }
        else
        {
            fReturnValue = FALSE;
        }
    
        return (fReturnValue);
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::AddControl
    // 
    //    This adds a control the internal list of controls in CControlPos. 
    // 
    //    Access: public
    // 
    //    Args:
    //        const UINT& unId            =    ID of the control to add
    //        const DWORD& dwStyle        =    how the window should be moved -- see #define's
    //                               in the header file
    // 
    //    Return:
    //        BOOL     =    TRUE if the control was added successfully, FALSE otherwise
    // 
    BOOL CControlPos::AddControl(const UINT& unId, const DWORD& dwStyle /* = CP_MOVE_HORIZONTAL */)
    {
        CWnd* pControl;
    
        if (m_pParent)
        {
            pControl = m_pParent->GetDlgItem(unId);
            return (AddControl(pControl, dwStyle));
        }
        else
        {
            return (FALSE);
        }
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::RemoveControl
    // 
    //    If a client ever wants to remove a control programmatically, this 
    //    function will do it. 
    // 
    //    Access: public
    // 
    //    Args:
    //        CWnd* pControl    =    pointer of the window who should be removed from 
    //                                the internal control list [ie: will not be repositioned]
    // 
    //    Return:
    //        BOOL     =    TRUE if the control was found [and deleted], FALSE otherwise
    // 
    BOOL CControlPos::RemoveControl(CWnd* pControl)
    {
        BOOL fReturnValue = FALSE;
    
        for (int i = 0; i < m_awndControls.GetSize(); i++)
        {
            LPCONTROLDATA pstControl = ((LPCONTROLDATA)m_awndControls.GetAt(i));
            
            if (pstControl->hControl == pControl->GetSafeHwnd())
            {
                m_awndControls.RemoveAt(i);
                delete pstControl;
                fReturnValue = TRUE;
                break;
            }
        }
    
        return (fReturnValue);
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::RemoveControl
    // 
    //    If a client ever wants to remove a control programmatically, this 
    //    function will do it. 
    // 
    //    Access: public
    // 
    //    Args:
    //        const UINT& unId  =  ID of the control that should be removed from the
    //                         internal control list [ie: will not be repositioned]
    // 
    //    Return:
    //        BOOL     =    TRUE if the control was found [and deleted], FALSE otherwise
    // 
    BOOL CControlPos::RemoveControl(const UINT& unId)
    {
        CWnd* pControl;
    
        if (m_pParent)
        {
            pControl = m_pParent->GetDlgItem(unId);
            return (RemoveControl(pControl));
        }
        else
        {
            return (FALSE);
        }
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::ResetControls
    // 
    //    This function removes all controls from the CControlPos object 
    // 
    //    Access: public
    // 
    //    Args:
    //        none
    // 
    //    Return:
    //        none
    // 
    void CControlPos::ResetControls(void)
    {
        while (m_awndControls.GetSize() > 0)
        {
            int   nHighIdx = m_awndControls.GetUpperBound();
            LPCONTROLDATA pstControl = ((LPCONTROLDATA)m_awndControls.GetAt(nHighIdx));
            if (pstControl)
            {
                m_awndControls.RemoveAt(nHighIdx);
                delete pstControl;
            }
        }
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::MoveControls
    // 
    //    This function takes care of moving all controls that have been added to 
    //    the object [see AddControl].  This function should be called from the 
    //    WM_SIZE handler-function [typically OnSize]. 
    // 
    //    Access: public
    // 
    //    Args:
    //        none
    // 
    //    Return:
    //        none
    // 
    void CControlPos::MoveControls(void)
    {
        if (m_pParent)
        {
            //--------------------------------------------------------------------
            // for each control that has been added to our object, we want to
            // check its style and move it based off of the parent control's
            // movements.
            // the thing to keep in mind is that when you resize a window, you
            // can resize by more than one pixel at a time. this is important
            // when, for example, you start with a width smaller than the
            // original width and you finish with a width larger than the
            // original width. you know that you want to move the control, but
            // by how much? that is why so many if's and calculations are made
            //
            for (int i = 0; i < m_awndControls.GetSize(); i++)
            {
                LPCONTROLDATA pstControl = ((LPCONTROLDATA)m_awndControls.GetAt(i));
                CRect rcParentBounds;
                CRect rcBounds;
                CWnd* pControl = m_pParent->FromHandle(pstControl->hControl);
    
                pControl->GetWindowRect(rcBounds);
                m_pParent->GetClientRect(rcParentBounds);
    
                if ((pstControl->dwStyle & (CP_RESIZE_VERTICAL)) == (CP_RESIZE_VERTICAL))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.bottom > m_nOriginalParentHeight)
                        {
                            if (m_nOriginalParentHeight <= m_nOldParentHeight)
                            {
                                rcBounds.bottom += rcParentBounds.bottom - m_nOldParentHeight;
                            }
                            else
                            {
                                rcBounds.bottom += rcParentBounds.bottom - m_nOriginalParentHeight;
                            }
                        }
                        else
                        {
                            if (m_nOldParentHeight > m_nOriginalParentHeight)
                            {
                                rcBounds.bottom += m_nOriginalParentHeight - m_nOldParentHeight;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.bottom += rcParentBounds.bottom - m_nOldParentHeight;
                    }
                }
    
                if ((pstControl->dwStyle & (CP_RESIZE_HORIZONTAL)) == (CP_RESIZE_HORIZONTAL))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.right > m_nOriginalParentWidth)
                        {
                            if (m_nOriginalParentWidth <= m_nOldParentWidth)
                            {
                                rcBounds.right += rcParentBounds.right - m_nOldParentWidth;
                            }
                            else
                            {
                                rcBounds.right += rcParentBounds.right - m_nOriginalParentWidth;
                            }
                        }
                        else
                        {
                            if (m_nOldParentWidth > m_nOriginalParentWidth)
                            {
                                rcBounds.right += m_nOriginalParentWidth - m_nOldParentWidth;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.right += rcParentBounds.right - m_nOldParentWidth;
                    }
                }
    
                if ((pstControl->dwStyle & (CP_MOVE_VERTICAL)) == (CP_MOVE_VERTICAL))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.bottom > m_nOriginalParentHeight)
                        {
                            if (m_nOriginalParentHeight <= m_nOldParentHeight)
                            {
                                rcBounds.bottom += rcParentBounds.bottom - m_nOldParentHeight;
                                rcBounds.top += rcParentBounds.bottom - m_nOldParentHeight;
                            }
                            else
                            {
                                rcBounds.bottom += rcParentBounds.bottom - m_nOriginalParentHeight;
                                rcBounds.top += rcParentBounds.bottom - m_nOriginalParentHeight;
                            }
                        }
                        else
                        {
                            if (m_nOldParentHeight > m_nOriginalParentHeight)
                            {
                                rcBounds.bottom += m_nOriginalParentHeight - m_nOldParentHeight;
                                rcBounds.top += m_nOriginalParentHeight - m_nOldParentHeight;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.bottom += rcParentBounds.bottom - m_nOldParentHeight;
                        rcBounds.top += rcParentBounds.bottom - m_nOldParentHeight;
                    }
                }
    
                if ((pstControl->dwStyle & (CP_MOVE_HORIZONTAL)) == (CP_MOVE_HORIZONTAL))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.right > m_nOriginalParentWidth)
                        {
                            if (m_nOriginalParentWidth <= m_nOldParentWidth)
                            {
                                rcBounds.right += rcParentBounds.right - m_nOldParentWidth;
                                rcBounds.left += rcParentBounds.right - m_nOldParentWidth;
                            }
                            else
                            {
                                rcBounds.right += rcParentBounds.right - m_nOriginalParentWidth;
                                rcBounds.left += rcParentBounds.right - m_nOriginalParentWidth;
                            }
                        }
                        else
                        {
                            if (m_nOldParentWidth > m_nOriginalParentWidth)
                            {
                                rcBounds.right += m_nOriginalParentWidth - m_nOldParentWidth;
                                rcBounds.left += m_nOriginalParentWidth - m_nOldParentWidth;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.right += rcParentBounds.right - m_nOldParentWidth;
                        rcBounds.left += rcParentBounds.right - m_nOldParentWidth;
                    }
                }
    
                if ((pstControl->dwStyle & (CP_MOVE_HORIZONTAL_CENTER)) == (CP_MOVE_HORIZONTAL_CENTER))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.right > m_nOriginalParentWidth)
                        {
                            if (m_nOriginalParentWidth <= m_nOldParentWidth)
                            {
                                rcBounds.right += (rcParentBounds.right - m_nOldParentWidth)/2;
                                rcBounds.left += (rcParentBounds.right - m_nOldParentWidth)/2;
                            }
                            else
                            {
                                rcBounds.right += rcParentBounds.right - m_nOriginalParentWidth;
                                rcBounds.left += rcParentBounds.right - m_nOriginalParentWidth;
                            }
                        }
                        else
                        {
                            if (m_nOldParentWidth > m_nOriginalParentWidth)
                            {
                                rcBounds.right += m_nOriginalParentWidth - m_nOldParentWidth;
                                rcBounds.left += m_nOriginalParentWidth - m_nOldParentWidth;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.right += rcParentBounds.right - m_nOldParentWidth;
                        rcBounds.left += rcParentBounds.right - m_nOldParentWidth;
                    }
                }
    
                if ((pstControl->dwStyle & (CP_MOVE_VERTICAL_CENTER)) == (CP_MOVE_VERTICAL_CENTER))
                {
                    if (!m_fNegativeMoves)
                    {
                        if (rcParentBounds.bottom > m_nOriginalParentHeight)
                        {
                            if (m_nOriginalParentHeight <= m_nOldParentHeight)
                            {
                                rcBounds.bottom += (rcParentBounds.bottom - m_nOldParentHeight)/2;
                                rcBounds.top += (rcParentBounds.bottom - m_nOldParentHeight)/2;
                            }
                            else
                            {
                                rcBounds.bottom += rcParentBounds.bottom - m_nOriginalParentHeight;
                                rcBounds.top += rcParentBounds.bottom - m_nOriginalParentHeight;
                            }
                        }
                        else
                        {
                            if (m_nOldParentHeight > m_nOriginalParentHeight)
                            {
                                rcBounds.bottom += m_nOriginalParentHeight - m_nOldParentHeight;
                                rcBounds.top += m_nOriginalParentHeight - m_nOldParentHeight;
                            }
                        }
                    }
                    else
                    {
                        rcBounds.bottom += rcParentBounds.bottom - m_nOldParentHeight;
                        rcBounds.top += rcParentBounds.bottom - m_nOldParentHeight;
                    }
                }
    
                m_pParent->ScreenToClient(rcBounds);
                pControl->MoveWindow(rcBounds);
            }
    
            UpdateParentSize();
        }
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::SetNegativeMoves
    // 
    //    This sets the NegativeMoves boolean parameter of the object. When the 
    //    parent window becomes smaller than it started, setting this to FALSE 
    //    will not allow controls to be moved; the parent size may change, but 
    //    it'll just force the controls to go off of the 
    //    This parameter defaults to FALSE on object creation.
    // 
    //    Access: public
    // 
    //    Args:
    //        const BOOL& fNegativeMoves /* = TRUE */    =    value to set
    // 
    //    Return:
    //        none
    // 
    void CControlPos::SetNegativeMoves(const BOOL& fNegativeMoves /* = TRUE */)
    {
        m_fNegativeMoves = fNegativeMoves;
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::GetNegativeMoves
    // 
    //    This function returns whether or not negative moves are enabled. 
    // 
    //    Access: public
    // 
    //    Args:
    //        none
    // 
    //    Return:
    //        BOOL     =    TRUE if negative moves are enabled, FALSE otherwise
    // 
    BOOL CControlPos::GetNegativeMoves(void) const
    {
        return (m_fNegativeMoves);
    }
    
    //------------------------------------------------------------------------------
    // CControlPos::UpdateParentSize
    // 
    //    Since CControlPos keeps track of the parent's size, it gets updated 
    //    every time it tells us to size the controls. We keep track so we know 
    //    how much it changed from the last WM_SIZE message. 
    // 
    //    Access: protected
    // 
    //    Args:
    //        none
    // 
    //    Return:
    //        none
    // 
    void CControlPos::UpdateParentSize(void)
    {
        if (m_pParent)
        {
            CRect rcBounds;
            m_pParent->GetClientRect(rcBounds);
    
            m_nOldParentWidth = rcBounds.Width();
            m_nOldParentHeight = rcBounds.Height();
        }
    }

    调用方法:

    .h文件中添加
    CControlPos m_ControlPos;

    .cpp文件中添加
    //OnCreate或OnInitDialog中添加
    m_ControlPos.SetParent(this);
    m_ControlPos.AddControl(GetDlgItem(控件ID), CP_MOVE_HORIZONTAL | CP_MOVE_VERTICAL); //随窗口变化移动

    /* 参数例表
    CP_MOVE_HORIZONTAL //随窗口水平移动
    CP_MOVE_VERTICAL //随窗口垂直移动
    CP_RESIZE_HORIZONTAL //随窗口水平变化而变化
    CP_RESIZE_VERTICAL //随窗口垂直变化而变化
    CP_MOVE_HORIZONTAL_CENTER //随窗口水平变化始终保存着居中比例
    CP_MOVE_VERTICAL_CENTER //随窗口垂直变化始终保存着居中比例
    */

    //添加WM_SIZE消息 OnSize中添加
    m_ControlPos.MoveControls();

  • 相关阅读:
    tty 与 多任务的解释备忘
    Oracle 安装时候的fs.filemax参数
    100多个Web2.0在线生成器
    精心整理的微软原版光盘
    WEB3.0开启商务魔法时代
    VBO与Displaylists的进一步讨论 (转)
    基于UML和ASP.NET实现三层B/S结构系统开发(转)
    BYTE* To Float*
    COM高手总结的八个经验和教训(转)
    OpenGL: 3D坐标到屏幕坐标的转换逻辑(gluProject的实现)(转)
  • 原文地址:https://www.cnblogs.com/begoogatprogram/p/5952605.html
Copyright © 2011-2022 走看看