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

本文介绍了一种自适应调整控件位置与大小的对话框类ClxDialog,通过设置控件属性实现对话框内控件随窗口变化而自动调整布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef struct _dlgControlTag

 

{

 int iId; // 控件ID

 int iFlag; // 标志,表示怎样改变控件的位置或者大小

 int iPercent; // 改变值占对话框改变值的百分比

} DLGCTLINFO, *PDLGCTLINFO;

  这里要对结构中的iFlag和iPercent进行一些解释。其中iFlag是下面的枚举值:

enum

 

{

 MOVEX = 0, // 控件在X方向(左右)移动

 MOVEY, // 控件在Y方向(上下)移动

 MOVEXY, // 控件在X方向和Y方向同时移动

 ELASTICX, // 控件在X方向(宽度)改变大小

 ELASTICY, // 控件在Y方向改(高度)改变大小

 ELASTICXY // 控件在X方向和Y方向同时改变大小

};

  iPercent表示改变值占对话框改变值的百分比。例如,一个控件的iPercent值为100,iFlag值为MOVEX,那么当对话框的宽度改变100个单位的时候,这个控件就在X方向移动100个单位;又如,一个控件的iPercent值为100,iFlag值为ELASTICXY,那么当对话框的宽度和高度分别改变100个单位的时候,控件的高度和宽度也相应的改变100个单位。

  下面是设置控件信息的函数:

BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);

  使用起来非常简单,在对话框的OnInitDialog()函数里面添加类似下面的代码就行了:

// 控件信息数组

 

static DLGCTLINFO dcMenuGroup[] =

{

 {IDOK, MOVEX, 100},

 {IDCANCEL, MOVEX, 100},

 {IDC_BUTTON1, MOVEX, 50},

 {IDC_BUTTON1, MOVEY, 100},

 {IDC_EDIT1, ELASTICX, 100},

 {IDC_EDIT2, ELASTICX, 50},

 {IDC_EDIT3, ELASTICX, 50},

 {IDC_EDIT3, MOVEX, 50},

 {IDC_EDIT4, ELASTICY, 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));

  下面就是使用上面这段代码的对话框改变大小前后的效果图:

 

  

  对两张截图的比较我们可以很容易的理解上面那段代码。

  我还提供了一个函数:

void ShowSizeIcon(BOOL bShow = TRUE);

  来设置是否显示对话框右下角表示可以改变大小的图标。这个图标是从系统中读取的,我上面的截图是Windows2000下的,在WindowsXP中就会自动变成XP风格的。

好了,闲话不多说了,下面贴出该对话框类ClxDialog的源代码,里面有详细的注释:

lxDialog.h文件:

 

/////////////////////////////////////////////////////////////////////////////////////

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

// 文件名: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文件:

//////////////////////////////////////////////////////////////////////

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

// 文件名: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;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值