`
soboer
  • 浏览: 1307847 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

在用VC开发应用程序时,经常会要做一些可以改变大小的对话框,而这个时候就要求对话框上的控件会随着对话框大小的改变而改变自己的位置和大小。如果控件比较少,那可以在对话框的OnSize()事件里面添加代码,通过计算来调整各个控件的位置和大小;但是,如果对话框上的控件比较多的话,那这将是一件非常痛苦的事情!要是程序中又有很多可以改变大小的对话框,那一个一个的OnSize()写下来,那会使程序员崩溃的!
为了解决这个问题,我写了一个自动改变控件位置和大小的对话框类ClxDialog。从这个类继承的对话框类,只要在OnInitDialog()里对控件做一些简单的设置,对话框上的控件就会随着对话框大小的改变而改变自己的位置和大小(当然,别忘了把对话框的Border属性改为Resizing)。
为了保存控件信息,我定义了一个结构:

typedefstruct_dlgControlTag
{
intiId;//控件ID
intiFlag;//标志,表示怎样改变控件的位置或者大小
intiPercent;//改变值占对话框改变值的百分比
}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个单位。
下面是设置控件信息的函数:

BOOLSetControlProperty(PDLGCTLINFOlp,intnElements);

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

//控件信息数组
staticDLGCTLINFOdcMenuGroup[]=
{
{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));

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

对两张截图的比较我们可以很容易的理解上面那段代码。
我还提供了一个函数:

voidShowSizeIcon(BOOLbShow=TRUE);

来设置是否显示对话框右下角表示可以改变大小的图标。这个图标是从系统中读取的,我上面的截图是Windows2000下的,在WindowsXP中就会自动变成XP风格的。
好了,闲话不多说了,下面贴出该对话框类ClxDialog的源代码,里面有详细的注释:
lxDialog.h文件:

//
//自动改变控件位置和大小的对话框类
//文件名:lxDialog.h
//作者:StarLee(coolstarlee@sohu.com)
//

classClxDialog:publicCDialog
{
public:
ClxDialog(UINTnID,CWnd
*pParent=NULL);

typedef
struct_dlgControlTag
{
intiId;
intiFlag;
intiPercent;
}DLGCTLINFO,
*PDLGCTLINFO;

enum
{
MOVEX
=0,
MOVEY,
MOVEXY,
ELASTICX,
ELASTICY,
ELASTICXY
};

//设置控件信息
BOOLSetControlProperty(PDLGCTLINFOlp,intnElements);

//是否在对话框右下角显示表示可改变大小的图标
voidShowSizeIcon(BOOLbShow=TRUE);

protected:
virtualBOOLOnInitDialog();
afx_msg
voidOnSize(UINTnType,intcx,intcy);
afx_msg
voidOnSizing(UINTnSide,LPRECTlpRect);
DECLARE_MESSAGE_MAP()

private:
intm_iClientWidth;//对话框client区域的宽度
intm_iClientHeight;//对话框client区域的高度
intm_iMinWidth;//对话框的最小宽度
intm_iMinHeight;//对话框的最小高度
PDLGCTLINFOm_pControlArray;//控件信息数组指针
intm_iControlNumber;//设置控件信息的控件个数
BOOLm_bShowSizeIcon;//是否显示表示可改变大小的图标
CStaticm_wndSizeIcon;//放图标的静态控件
//保存图标的bitmap
CBitmapm_bmpSizeIcon;
BITMAPm_bitmap;
};

lxDialog.cpp文件:

//
//自动改变控件位置和大小的对话框类
//文件名:lxDialog.cpp
//作者:StarLee(coolstarlee@sohu.com)
//

#include
"stdafx.h"
#include
"lxDialog.h"

//表示可改变大小的图标ID
#ifndefOBM_SIZE
#defineOBM_SIZE32766
#endif

ClxDialog::ClxDialog(UINTnID,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()

BOOLClxDialog::OnInitDialog()
{
CDialog::OnInitDialog();

//设置对话框为可变大小的
ModifyStyle(0,WS_SIZEBOX);

//以对话框的初始大小作为对话框的宽度和高度的最小值
CRectrectDlg;
GetWindowRect(rectDlg);
m_iMinWidth
=rectDlg.Width();
m_iMinHeight
=rectDlg.Height();

//得到对话框client区域的大小
CRectrectClient;
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);

returnTRUE;
}

voidClxDialog::OnSize(UINTnType,intcx,intcy)
{
CDialog::OnSize(nType,cx,cy);

//对话框宽度和高度的增量
intiIncrementX=cx-m_iClientWidth;
intiIncrementY=cy-m_iClientHeight;

//最小化时增量为0
if(nType==SIZE_MINIMIZED)
{
iIncrementX
=iIncrementY=0;
}

for(inti=0;i<m_iControlNumber;i++)
{
CWnd
*pWndCtrl=NULL;

intiId=m_pControlArray[i].iId;
intiFlag=m_pControlArray[i].iFlag;
intiPercent=m_pControlArray[i].iPercent;

//无效值
if((iPercent<0)||(iPercent>100))
continue;

//得到控件指针
pWndCtrl=GetDlgItem(iId);
if((NULL!=pWndCtrl)&&IsWindow(pWndCtrl->GetSafeHwnd()))
{
CRectrectCtrl;
pWndCtrl
->GetWindowRect(rectCtrl);

ScreenToClient(rectCtrl);

intiLeft=rectCtrl.left;
intiTop=rectCtrl.top;
intiWidth=rectCtrl.Width();
intiHeight=rectCtrl.Height();

switch(iFlag)
{
caseMOVEX://X方向移动
iLeft+=(iIncrementX*iPercent/100);
break;

caseMOVEY://Y方向移动
iTop+=(iIncrementY*iPercent/100);
break;

caseMOVEXY://X方向和Y方向同时移动
iLeft+=(iIncrementX*iPercent/100);
iTop
+=(iIncrementY*iPercent/100);
break;

caseELASTICX://X方向改变大小
iWidth+=(iIncrementX*iPercent/100);
break;

caseELASTICY://Y方向改变大小
iHeight+=(iIncrementY*iPercent/100);
break;

caseELASTICXY://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);

if(nType==SIZE_MAXIMIZED)
m_wndSizeIcon.ShowWindow(FALSE);
else
m_wndSizeIcon.ShowWindow(TRUE);
}

Invalidate();

//记录对话框client区域的大小
if(nType!=SIZE_MINIMIZED)
{
m_iClientWidth
=cx;
m_iClientHeight
=cy;
}
}

voidClxDialog::OnSizing(UINTnSide,LPRECTlpRect)
{
CDialog::OnSizing(nSide,lpRect);

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

intiWidth=lpRect->right-lpRect->left;
intiHeight=lpRect->bottom-lpRect->top;

if(iWidth<=m_iMinWidth)
lpRect
->right=lpRect->left+m_iMinWidth;

if(iHeight<=m_iMinHeight)
lpRect
->bottom=lpRect->top+m_iMinHeight;
}

BOOLClxDialog::SetControlProperty(PDLGCTLINFOlp,
intnElements)
{
//设置控件数组信息

if(NULL==lp)
returnFALSE;

if(nElements<=0)
returnFALSE;

m_pControlArray
=lp;
m_iControlNumber
=nElements;

returnTRUE;
}

voidClxDialog::ShowSizeIcon(BOOLbShow/*=TRUE*/)
{
m_bShowSizeIcon
=bShow;
}
分享到:
评论

相关推荐

    VC PICTURE控件的使用

    对话框类为CTestDlg (一) vc picture控件非动态载入图片. 方法1.先从最简单的开始,用picture 控件来实现. 步骤: 先在资源里Import一张图片,ID为IDB_BITMAP2 然后在对话框上添加一个picture控件,右键点击打开...

    VC++6[1].0入门【第七章_windows标准控件】.doc

    静态创建是指在对话框模板创建控件,并设置控件的属性,这样,在调用该对话框时,窗口系统会自动按预先的设置为对话框创建控件,程序员可以使用ClassWizard为该控件在对话框类中创建一个控件类的对象。 动态创建是指...

    VC对话框控件基本操作1

    本文以一个简单的例子实现对话框控件的基本操作。博客地址:http://blog.csdn.net/bingdianlanxin,有问题欢迎留言!

    VC列表控件排序,VC++列表控件排序源码

    然后在对话框类的头文件中将CListCtrl m_ctlList;改为CSortListCtrl m_ctlList;并在文件中加上#include "SortListCtrl.h" 2.3 以下代码是设置列表控件的列头与表项 (void)m_ctlList.SetExtendedStyle( LVS_EX_...

    VC++.net MFC 控件设置

    改变控件的字体颜色和背景色 在对话框类中添加变量: HBRUSH m_hBrush=CreateSolidBrush(RGB(0,0,0)); //用所需的背景色定义画刷 用建立类向导为对话框添加OnCtlColor函数: HBRUSH CListBkChangeDlg::OnCtlColor...

    VC6.0+MFC类库参考手册中文完整版

    关于Microsoft基类库中的类按以下的种类给出:l 根类:CObjectl MFC应用结构类:l 应用和线程支持类l 命令例程类l 文档类l 视图类(结构)l 框架窗口类(结构)l 文档-模板类l 窗口、对话和控件类l 框架窗口类(窗口...

    对话框编程用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理

    对话框用户界面程序的编写,如何向对话框控件关联数据成员及其实现机理,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数...

    VC++常用功能实例

    问:如何获得CRichEditCtrl中字符的位置? 66 问:如何限制mdi子框架最大化时的大小? 66 问:如何切换视口而不破坏它们? 66 问:改变列表控制时发生闪烁现象? 68 问:处理列表控件可见项的问题? 68 问:产生线程的...

    VC学习大纲 VC学习讲义

    对话框用户界面程序的编写,如何向对话框控件联接数据成员及其实现机理,如何向对话框控关联控件类,如何利用对话框类的成员函数向控件发送消息和获取对话框控件的类指针,如何直接利用对话框控件类操纵对话框控件...

    VC++用对话框控件发消息、获取控件指针

     本源码演示如何利用VC++对话框类的成员函数向控件发送消息和获取对话框控件的类指针,以及如何直接利用对话框控件类操纵对话框控件(发送消息和直接调用成员函数)、如何在程序运行时产生和销毁控件。对话框控件的...

    VC++常用的共用函数100多页

    问:如何获得CRichEditCtrl中字符的位置? 66 问:如何限制mdi子框架最大化时的大小? 66 问:如何切换视口而不破坏它们? 66 问:改变列表控制时发生闪烁现象? 68 问:处理列表控件可见项的问题? 68 问:产生线程的...

    输入IP地址的编辑框

    Field0~Field3:是四个IP段; IP:是IP地址的值; Field0Range~Field3Range:是四个IP段的限制范围; 其它的属性和VCL其它控件是一样的。

    VC++ 登录对话框源码

    双击对话框,为登录对话框创建对话框类,类名为CDlgLogin 3、为登录"对话框添加控件并关联变量 4、在ProjectX.cpp的开头处添加头文件包含#include "DlgLogin.h" 5、在ProjectX.cpp中,找到启动入口函数InitInstance...

    Visual C++ 编程资源大全(控件 窗体)

    GIF_OCX.zip 包括agif11、agif11a、agif11b、anigif四个32位OCX控件和CRACK文件,可用于在应用程序中添加动画GIF对象,十分漂亮、重点推荐(943KB)&lt;END&gt;&lt;br&gt;101,MSGBLAST.zip WareWithAll公司出品的控件产品...

    vc 文件加密代码

    应用程序向导将创建一个对话框类: xmlEnctryDlg.h、xmlEnctryDlg.cpp - 对话框 这些文件包含 CxmlEnctryDlg 类。 此类定义 应用程序主对话框的行为。 此对话框的模板包含在 xmlEnctry.rc 中,而此文件可以在 ...

    vc++ 开发实例源码包

    LocalInfoDlg.h 查看本地信息对话框类文件 freeeim_FreeEIM_企业即时通讯软件源代码2010年8月份最新版 如题。 FTP、HTTP 多线程断点续传下载文件 源码 如题。 gdiplus应用实例 如题,自绘控件的实现。 gdiplus...

    Visual C++开发经验技巧宝典(第4章)

    0207 将一个全局函数指针关联到对话框类的某个方法 102 0208 修改应用程序的图标 102 0209 使用安全数组 103 0210 将子窗口的客户区域映射到父窗口中 103 0211 判断两个时间段的差距 103 0212 重新设置...

    VISUAL C MFC扩展编程实例与源码

    2.4.2 自动改变大小和移动 30 2.4.3 停靠栏小结 30 2.5 浮动条 31 2.6 MFC的高级控制条类小结 32 2.7 视和控制条如何共享客户区 32 2.7.1 CFrameWnd::RecalcLayout() 32 2.7.2 CWnd::RepositionBars() 33 ...

    MFC多窗口例程

    (要注意的是在ClassWizard中注意Class Name中应该选CSubClass1而不是之前的主对话框类) 按照相同方法建立第二个新对话框,类名“CSubClass2”,Caption为“关卡选择”。 在上面画一个Edit和一个Spin,注意先画...

Global site tag (gtag.js) - Google Analytics