对话框大小变化自动调整控件大小ClxDialog及使用方法

ClxDialog类

分类: MFC/C++   174人阅读  评论(0)  收藏  举报

//从此类派生出的对话框可以根据对话框大小变化自动调整控件大小

//头文件

  1. ///  
  2. //      自动改变控件位置和大小的对话框类  
  3. //      文件名:lxDialog.h  
  4. //      作者:StarLee(coolstarlee@sohu.com)  
  5. //  
  6.   
  7. class ClxDialog : public CDialog  
  8. {  
  9. public:  
  10.     ClxDialog(UINT nID, CWnd* pParent = NULL);  
  11.   
  12.     typedef struct _dlgControlTag  
  13.     {  
  14.         int iId;  
  15.         int iFlag;  
  16.         int iPercent;  
  17.     } DLGCTLINFO, *PDLGCTLINFO;  
  18.   
  19.     enum  
  20.     {  
  21.         MOVEX = 0,  
  22.         MOVEY,  
  23.         MOVEXY,  
  24.         ELASTICX,  
  25.         ELASTICY,  
  26.         ELASTICXY  
  27.     };  
  28.   
  29.     //  设置控件信息  
  30.     BOOL SetControlProperty(PDLGCTLINFO lp, int nElements);  
  31.   
  32.     //  是否在对话框右下角显示表示可改变大小的图标  
  33.     void ShowSizeIcon(BOOL bShow = TRUE);  
  34.   
  35. protected:  
  36.     virtual BOOL OnInitDialog();  
  37.     afx_msg void OnSize(UINT nType, int cx, int cy);  
  38.     afx_msg void OnSizing(UINT nSide, LPRECT lpRect);  
  39.     DECLARE_MESSAGE_MAP()  
  40.   
  41. private:  
  42.     int m_iClientWidth;  //  对话框client区域的宽度  
  43.     int m_iClientHeight;  //  对话框client区域的高度  
  44.     int m_iMinWidth;  //  对话框的最小宽度  
  45.     int m_iMinHeight;  //  对话框的最小高度  
  46.     PDLGCTLINFO m_pControlArray;  //  控件信息数组指针  
  47.     int m_iControlNumber;  //  设置控件信息的控件个数  
  48.     BOOL m_bShowSizeIcon;  //  是否显示表示可改变大小的图标  
  49.     CStatic m_wndSizeIcon;  //  放图标的静态控件  
  50.     //  保存图标的bitmap  
  51.     CBitmap m_bmpSizeIcon;  
  52.     BITMAP m_bitmap;  
  53. };  


//实现文件

  1. ///  
  2. //      自动改变控件位置和大小的对话框类  
  3. //      文件名:lxDialog.cpp  
  4. //      作者:StarLee(coolstarlee@sohu.com)  
  5. //  
  6.   
  7. #include "stdafx.h"  
  8. #include "lxDialog.h"  
  9.   
  10. //  表示可改变大小的图标ID  
  11. #ifndef OBM_SIZE  
  12. #define OBM_SIZE 32766  
  13. #endif  
  14.   
  15. ClxDialog::ClxDialog(UINT nID, CWnd* pParent /*=NULL*/)  
  16.     : CDialog(nID, pParent)  
  17.     , m_iClientWidth(0)  
  18.     , m_iClientHeight(0)  
  19.     , m_iMinWidth(0)  
  20.     , m_iMinHeight(0)  
  21.     , m_pControlArray(NULL)  
  22.     , m_iControlNumber(0)  
  23.     , m_bShowSizeIcon(TRUE)  
  24. {}  
  25.   
  26. BEGIN_MESSAGE_MAP(ClxDialog, CDialog)  
  27.     ON_WM_SIZE()  
  28.     ON_WM_SIZING()  
  29. END_MESSAGE_MAP()  
  30.   
  31. BOOL ClxDialog::OnInitDialog()  
  32. {  
  33.     CDialog::OnInitDialog();  
  34.   
  35.     //  设置对话框为可变大小的  
  36.     ModifyStyle(0, WS_SIZEBOX);  
  37.   
  38.     //  以对话框的初始大小作为对话框的宽度和高度的最小值  
  39.     CRect rectDlg;  
  40.     GetWindowRect(rectDlg);  
  41.     m_iMinWidth = rectDlg.Width();  
  42.     m_iMinHeight = rectDlg.Height();  
  43.   
  44.     //  得到对话框client区域的大小  
  45.     CRect rectClient;  
  46.     GetClientRect(rectClient);  
  47.     m_iClientWidth = rectClient.Width();  
  48.     m_iClientHeight = rectClient.Height();  
  49.   
  50.     //  Load图标  
  51.     m_bmpSizeIcon.LoadOEMBitmap(OBM_SIZE);  
  52.     m_bmpSizeIcon.GetBitmap(&m_bitmap);  
  53.   
  54.     //  创建显示图标的静态控件并放在对话框右下角  
  55.     m_wndSizeIcon.Create(NULL, WS_CHILD | WS_VISIBLE | SS_BITMAP, CRect(0, 0, m_bitmap.bmWidth, m_bitmap.bmHeight), this, 0);  
  56.     m_wndSizeIcon.SetBitmap(m_bmpSizeIcon);  
  57.     m_wndSizeIcon.MoveWindow(m_iClientWidth - m_bitmap.bmWidth, m_iClientHeight - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);  
  58.   
  59.     //  显示图标  
  60.     m_wndSizeIcon.ShowWindow(m_bShowSizeIcon);  
  61.   
  62.     return TRUE;  
  63. }  
  64.   
  65. void ClxDialog::OnSize(UINT nType, int cx, int cy)  
  66. {  
  67.     CDialog::OnSize(nType, cx, cy);  
  68.   
  69.     //  对话框宽度和高度的增量  
  70.     int iIncrementX = cx - m_iClientWidth;  
  71.     int iIncrementY = cy - m_iClientHeight;  
  72.   
  73.     //  最小化时增量为0  
  74.     if (nType == SIZE_MINIMIZED)  
  75.     {  
  76.         iIncrementX = iIncrementY = 0;  
  77.     }  
  78.   
  79.     for (int i = 0; i < m_iControlNumber; i++)  
  80.     {  
  81.         CWnd *pWndCtrl = NULL;  
  82.   
  83.         int iId = m_pControlArray[i].iId;  
  84.         int iFlag = m_pControlArray[i].iFlag;  
  85.         int iPercent = m_pControlArray[i].iPercent;  
  86.   
  87.         //  无效值  
  88.         if ((iPercent < 0) || (iPercent > 100))  
  89.             continue;  
  90.   
  91.         //  得到控件指针  
  92.         pWndCtrl = GetDlgItem(iId);  
  93.         if ((NULL != pWndCtrl) && IsWindow(pWndCtrl->GetSafeHwnd()))  
  94.         {  
  95.             CRect rectCtrl;  
  96.             pWndCtrl->GetWindowRect(rectCtrl);  
  97.   
  98.             ScreenToClient(rectCtrl);  
  99.   
  100.             int iLeft = rectCtrl.left;  
  101.             int iTop = rectCtrl.top;  
  102.             int iWidth = rectCtrl.Width();  
  103.             int iHeight = rectCtrl.Height();  
  104.   
  105.             switch (iFlag)  
  106.             {  
  107.             case MOVEX:  //  X方向移动  
  108.                 iLeft += (iIncrementX * iPercent / 100);  
  109.                 break;  
  110.   
  111.             case MOVEY:  //  Y方向移动  
  112.                 iTop += (iIncrementY * iPercent / 100);  
  113.                 break;  
  114.   
  115.             case MOVEXY:  //  X方向和Y方向同时移动  
  116.                 iLeft += (iIncrementX * iPercent / 100);  
  117.                 iTop += (iIncrementY * iPercent / 100);  
  118.                 break;  
  119.   
  120.             case ELASTICX:  //  X方向改变大小  
  121.                 iWidth += (iIncrementX * iPercent / 100);  
  122.                 break;  
  123.   
  124.             case ELASTICY:  //  Y方向改变大小  
  125.                 iHeight += (iIncrementY * iPercent / 100);  
  126.                 break;  
  127.   
  128.             case ELASTICXY:  //  X方向和Y方向同时改变大小  
  129.                 iWidth += (iIncrementX * iPercent / 100);  
  130.                 iHeight += (iIncrementY * iPercent / 100);  
  131.                 break;  
  132.   
  133.             default:  
  134.                 ;  
  135.             }  
  136.   
  137.             //  把控件移动到新位置  
  138.             pWndCtrl->MoveWindow(iLeft, iTop, iWidth, iHeight);  
  139.             }  
  140.     }  
  141.   
  142.     //  把图标移动到对话框右下角  
  143.     if (IsWindow(m_wndSizeIcon.GetSafeHwnd()))  
  144.         m_wndSizeIcon.MoveWindow(cx - m_bitmap.bmWidth, cy - m_bitmap.bmHeight, m_bitmap.bmWidth, m_bitmap.bmHeight);  
  145.   
  146.     //  记录对话框client区域的大小  
  147.     if (nType != SIZE_MINIMIZED)  
  148.     {  
  149.         m_iClientWidth = cx;  
  150.         m_iClientHeight = cy;  
  151.     }  
  152. }  
  153.   
  154. void ClxDialog::OnSizing(UINT nSide, LPRECT lpRect)  
  155. {  
  156.     CDialog::OnSizing(nSide, lpRect);  
  157.   
  158.     //  对话框不能小于初始大小  
  159.   
  160.     int iWidth = lpRect->right - lpRect->left;  
  161.     int iHeight = lpRect->bottom - lpRect->top;  
  162.   
  163.     if (iWidth <= m_iMinWidth)  
  164.         lpRect->right = lpRect->left + m_iMinWidth;  
  165.    
  166.     if(iHeight <= m_iMinHeight)  
  167.         lpRect->bottom = lpRect->top + m_iMinHeight;  
  168. }  
  169.   
  170. BOOL ClxDialog::SetControlProperty(PDLGCTLINFO lp, int nElements)  
  171. {  
  172.     //  设置控件数组信息  
  173.   
  174.     if (NULL == lp)  
  175.         return FALSE;  
  176.   
  177.     if (nElements <= 0)  
  178.         return FALSE;  
  179.   
  180.     m_pControlArray = lp;  
  181.     m_iControlNumber = nElements;  
  182.   
  183.     return TRUE;  
  184. }  
  185.   
  186. void ClxDialog::ShowSizeIcon(BOOL bShow /*=NULL*/)  
  187. {  
  188.     m_bShowSizeIcon = bShow;  
  189. }  

使用方法

//使用方法,添加到工程文件中,然后从ClxDialog派生对话框 
1,在非模态对话框类的头文件(.h)顶部加上#include "lxDialog.h",然后把非模态对话框类的基类改成ClxDialog,也就是在头文件里class C****** : public CDialog 改成: class C****** : public ClxDialog 
2,在非模态对话框类的.cpp函数里,把构造函数 
C*****::C*****(CWnd* pParent ): CDialog(C*****::IDD, pParent) 改成: 
C*****::C*****(CWnd* pParent ): ClxDialog(C*****::IDD, pParent) 2,用类向导给非模态对话框添加一个OnInitDialog()函数;也就是在双击类向导->Message Maps-> 选非模态对话框类;Messages选WM_INITDIALOG双击它,这样在你的非模态对话框的cpp文件里就生成了ON_WM_INITDIALOG和OnInitDialog()函数; 
3,在这个OnInitDialog函数里添加代码:  ClxDialog::OnInitDialog(); 
 ClxDialog::ShowSizeIcon(TRUE);//显示可以调整大小的图标
 static DLGCTLINFO dcMenuGroup[] =     {   
        {IDCANCEL, MOVEX, 100},        
{IDCANCEL, MOVEY, 100}, 
        {IDC_EDIT_RECDSPDLG, ELASTICX, 100},       
{IDC_EDIT_RECDSPDLG, ELASTICY, 100},  
 }; 
// 设置控件信息
  SetControlProperty(dcMenuGroup, sizeof(dcMenuGroup)/sizeof(DLGCTLINFO));
 return TRUE;  
//IDCANCEL是关闭按钮的ID,IDOK按钮我去掉了所以没加,IDC_EDIT_RECDSPDLG是一个EDIT控件 
4,再用类向导添加OnSize()函数,也就是双击ON_WM_SIZE,这样就增加了 
void C******::OnSize(UINT nType, int cx, int cy) 这个函数,然后在这个函数里添加代码:ClxDialog::OnSize(nType, cx, cy); 
5,别忘了在资源里右键你的非模态对话框,把属性栏Styles里Border选成Resizing。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值