控件的大小和位置按照我们的要求随对话框变化而变化

下面两个文件是一个派生自 CDialog 的对话框类,能够非常好的实现控件的大小和位置按照我们的要求随对话框变化而变化的功能。

将这两个文件加入你的工程中,并将你的对话框修改成继承 ClxDialog,通过设置各个控件的iFlag值,实现位置和大小的改变。

头文件:

///

//      自动改变控件位置和大小的对话框类

//      文件名:lxDialog.h

//      作者:StarLee(coolstarlee@sohu.com)

//



class ClxDialog : public CDialog

{

public:

    ClxDialog(UINT nID, CWnd* pParent = NULL);



    typedef struct _dlgControlTag 

    {

        int iId;

        int iFlag;

        int iPercent;

    } DLGCTLINFO, *PDLGCTLINFO;



    enum

    {

        MOVEX = 0,

        MOVEY,

        MOVEXY,

        ELASTICX,

        ELASTICY,

        ELASTICXY

    };



    //  设置控件信息

    BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);



    //  是否在对话框右下角显示表示可改变大小的图标

    void ShowSizeIcon(BOOL bShow = TRUE);



protected:

    virtual BOOL OnInitDialog();

    afx_msg void OnSize(UINT nType, int cx, int cy);

    afx_msg void OnSizing(UINT nSide, LPRECT lpRect);

    DECLARE_MESSAGE_MAP()



private:

    int m_iClientWidth;  //  对话框client区域的宽度

    int m_iClientHeight;  //  对话框client区域的高度

    int m_iMinWidth;  //  对话框的最小宽度

    int m_iMinHeight;  //  对话框的最小高度

    PDLGCTLINFO m_pControlArray;  //  控件信息数组指针

    int m_iControlNumber;  //  设置控件信息的控件个数

    BOOL m_bShowSizeIcon;  //  是否显示表示可改变大小的图标

    CStatic m_wndSizeIcon;  //  放图标的静态控件

    //  保存图标的bitmap

    CBitmap m_bmpSizeIcon; 

    BITMAP m_bitmap; 

};

源文件:

///

//      自动改变控件位置和大小的对话框类

//      文件名:lxDialog.cpp

//      作者:StarLee(coolstarlee@sohu.com)

//



#include "stdafx.h"

#include "lxDialog.h"



//  表示可改变大小的图标ID

#ifndef OBM_SIZE

#define OBM_SIZE 32766

#endif



ClxDialog::ClxDialog(UINT nID, CWnd* pParent /*=NULL*/)

    : CDialog(nID, pParent)

    , m_iClientWidth(0)

    , m_iClientHeight(0)

    , m_iMinWidth(0)

    , m_iMinHeight(0)

    , m_pControlArray(NULL)

    , m_iControlNumber(0)

    , m_bShowSizeIcon(TRUE)

{}



BEGIN_MESSAGE_MAP(ClxDialog, CDialog)

    ON_WM_SIZE()

    ON_WM_SIZING()

END_MESSAGE_MAP()



BOOL ClxDialog::OnInitDialog()

{

    CDialog::OnInitDialog();



    //  设置对话框为可变大小的

    ModifyStyle(0, WS_SIZEBOX);



    //  以对话框的初始大小作为对话框的宽度和高度的最小值

    CRect rectDlg;

    GetWindowRect(rectDlg);

    m_iMinWidth = rectDlg.Width();

    m_iMinHeight = rectDlg.Height();



    //  得到对话框client区域的大小

    CRect rectClient;

    GetClientRect(rectClient);

    m_iClientWidth = rectClient.Width();

    m_iClientHeight = rectClient.Height();



    //  Load图标

    m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE);

    m_bmpSizeIcon.GetBitmap(&m_bitmap);



    //  创建显示图标的静态控件并放在对话框右下角

    m_wndSizeIcon.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0);

    m_wndSizeIcon.SetBitmap(m_bmpSizeIcon);

    m_wndSizeIcon.MoveWindow(m_iClientWidth - m_bitmap.bmWidth, m_iClientHeight - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);



    //  显示图标

    m_wndSizeIcon.ShowWindow(m_bShowSizeIcon);



    return TRUE;

}



void ClxDialog::OnSize(UINT nType, int cx, int cy) 

{

    CDialog::OnSize(nType, cx, cy);

 

    //  对话框宽度和高度的增量 

    int iIncrementX = cx - m_iClientWidth;

    int iIncrementY = cy - m_iClientHeight;



    //  最小化时增量为0

    if (nType == SIZE_MINIMIZED)

    {

        iIncrementX = iIncrementY = 0;

    }



    for (int i = 0; i < m_iControlNumber; i++)

    {

        CWnd *pWndCtrl = NULL;



        int iId = m_pControlArray[i].iId;

        int iFlag = m_pControlArray[i].iFlag;

        int iPercent = m_pControlArray[i].iPercent;



        //  无效值

        if ((iPercent < 0) || (iPercent > 100))

            continue;



        //  得到控件指针

        pWndCtrl = GetDlgItem(iId);

        if ((NULL != pWndCtrl) && IsWindow(pWndCtrl->GetSafeHwnd()))

        {

            CRect rectCtrl;

            pWndCtrl->GetWindowRect(rectCtrl);



            ScreenToClient(rectCtrl);



            int iLeft = rectCtrl.left;

            int iTop = rectCtrl.top;

            int iWidth = rectCtrl.Width();

            int iHeight = rectCtrl.Height();



            switch (iFlag)

            {

            case MOVEX:  //  X方向移动

                iLeft += (iIncrementX * iPercent / 100);

                break;



            case MOVEY:  //  Y方向移动

                iTop += (iIncrementY * iPercent / 100);

                break;



            case MOVEXY:  //  X方向和Y方向同时移动

                iLeft += (iIncrementX * iPercent / 100);

                iTop += (iIncrementY * iPercent / 100);

                break;



            case ELASTICX:  //  X方向改变大小

                iWidth += (iIncrementX * iPercent / 100);

                break;



            case ELASTICY:  //  Y方向改变大小

                iHeight += (iIncrementY * iPercent / 100);

                break;



            case ELASTICXY:  //  X方向和Y方向同时改变大小

                iWidth += (iIncrementX * iPercent / 100);

                iHeight += (iIncrementY * iPercent / 100);

                break;



            default:

                ;

            }



            //  把控件移动到新位置

            pWndCtrl->MoveWindow(iLeft, iTop, iWidth, iHeight);

            }

    }



    //  把图标移动到对话框右下角

    if (IsWindow(m_wndSizeIcon.GetSafeHwnd()))

        m_wndSizeIcon.MoveWindow(cx - m_bitmap.bmWidth, cy - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);



    //  记录对话框client区域的大小

    if (nType != SIZE_MINIMIZED)

    {

        m_iClientWidth = cx;

        m_iClientHeight = cy;

    }

}



void ClxDialog::OnSizing(UINT nSide, LPRECT lpRect)

{

    CDialog::OnSizing(nSide, lpRect);



    //  对话框不能小于初始大小



    int iWidth = lpRect->right - lpRect->left;

    int iHeight = lpRect->bottom - lpRect->top;



    if (iWidth <= m_iMinWidth)

        lpRect->right = lpRect->left + m_iMinWidth;

  

    if(iHeight <= m_iMinHeight)

        lpRect->bottom = lpRect->top + m_iMinHeight;

}



BOOL ClxDialog::SetControlProperty(PDLGCTLINFO lp, int nElements)

{

    //  设置控件数组信息



    if (NULL == lp)

        return FALSE;



    if (nElements <= 0)

        return FALSE;



    m_pControlArray = lp;

    m_iControlNumber = nElements;



    return TRUE;

}



void ClxDialog::ShowSizeIcon(BOOL bShow /*=NULL*/)

{

    m_bShowSizeIcon = bShow;

}

这个类的使用方法:

有几个要点,一:派生自ClxDialog的对话框类,在OnInitDialog中要把CDialog::OnInitDialog改为ClxDialog::OnInitDialog
二:派生类要添加窗口消息响应函数,响应WM_SIZE 和WM_SIZING,在这两个响应函数内只需分别调用ClxDialog的OnSize 和OnSizing函数即可
三:在派生类的OnInitDialog内需要添加如下一段代码:

// 控件信息数组

	static DLGCTLINFO dcMenuGroup[] = 

	{

		//{IDOK, MOVEX, 100},

		//{IDCANCEL, MOVEX, 100},

		//{IDC_SAVELOG, MOVEX, 100},

		//{IDC_HOSTINFO, MOVEX, 100},

		//{IDC_SETADDR, MOVEX, 100},

		{IDC_STATIC1, ELASTICY, 100},

		{IDC_STATIC2, ELASTICXY, 100},

		{IDC_INFO, ELASTICY, 100},

		{IDC_STINFO, ELASTICXY, 100}

	//	{IDC_EDIT5, ELASTICX, 100},

	//	{IDC_EDIT5, ELASTICY, 50},

	//	{IDC_EDIT6, ELASTICX, 100},

	//	{IDC_EDIT6, ELASTICY, 50},

	//	{IDC_EDIT6, MOVEY, 50},

	};

	

	// 设置控件信息

	SetControlProperty(dcMenuGroup, sizeof(dcMenuGroup)/sizeof(DLGCTLINFO));

转自:如何在改变窗体大小时,所有控件也随之改变,保持相对位置不变 - 开发者知识库 (itdaan.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值