MFC项目实战(1)文件管理器--界面设计篇
2013-09-25 21:45
363 查看
1.创建项目
文件管理器是一个基于对话框的应用程序。首先新建一个“MFC应用程序”类型的项目,然后输入新建项目的名称“FileMng”,并指定该项目保存的位置,单击“确定”按钮,如图所示。
在弹出的“应用程序类型”向导对话框中,选择“应用程序类型”为“基于对话框”,并取消对“使用Unicode库”复选框的选择,如图所示。
点击Next按钮,在弹出的“用户界面接口”向导对话框中,选择Minimizebox和Maximizebox复选框,并取消对“Aboutbox”复选框的选择,如图所示。
接下来点击Finish完成FileMng项目的创建。
2.设计程序主界面
在向对话框资源上添加控件前,先将对话框上自动创建的ok和cancel按钮删除掉,然后右键对话框属性设置Font(Size)属性为“宋体(9)”。
(1)首先需要向项目导入一些图标和位图。其中图标用来显示在树形控件及列表控件中,而位图主要用来创建位图按钮。在资源视图中项目名的根节点上右键,在弹出的快捷键菜单中选择“添加”->“资源”菜单命令,在弹出的“添加资源”对话框中单击“导入”按钮并导入相应的位图和图标,如图所示。
(2)在对话框资源上添加一个静态图片控件
和两个组框
,在属性窗口中设置静态图片控件的Type属性为“Frame”,Color属性设置为“Gray”,设置控件ID号为“IDC_STATIC_BAN”以及修改组框的Caption属性分别为“目录结构(&D)”和“文件列表(&F)”,同时设置它们的控件ID号分别为“IDC_STATIC_MULU”和“IDC_STATIC_FILE”并适当调整它们的大小和位置,如图所示。
记得把那个紫色的虚框往上拉一点,留出添加状态栏的宽度。
同时添三个静态图片控件,在属性窗口中设置它们的Type属性为Bitmap,指定它们的控件ID号分别为“IDC_STATIC_LEFT”、“IDC_STATIC_MID”和“IDC_STATIC_RIGHTT”并分别指定Image属性为IDB_BITMAP1、IDB_BITMAP3和IDB_BITMAP2。添加位图后的对话框资源如图所示。
(3)添加状态栏,首先资源视图中添加一个Stringtable并在里面添加两个字符串,ID分别为IDS_INDICATOR_MESSAGE和IDS_INDICATOR_TIME,把它们的Caption分别设置为Msg和星期%d上午00:00:00
接着声明int型index1,index2用来保存IDS_INDICATOR_MESSAGE面板和IDS_INDICATOR_TIME面板的索引,另外声明两个int变量nWidth1,nWidth2用来保存IDS_INDICATOR_MESSAGE面板和IDS_INDICATOR_TIME面板的宽度。
接着再声明UINT型变量nID和nStyle分别用来接收面板ID和面板风格,还要声明一个CString变量str用来接收Msg的内容,然后在FileMng.h文件中声明一个CStatusBar的变量m_wndStatusBar;在FileMng.h文件中代码如下:
[code]CStatusBarm_wndStatusBar;
[/code]
然后在FileMng.cpp文件开头添加如下数组:
[code]{
[/code]
然后在FileMng.cpp文件中的OnInitDialog()函数添加状态栏创建代码:
[code]{
[/code]
上面代码中的第11行和18行的ModifyStyle()代码分别是关闭和开启对话框边框可调属性,因为CStatusBar在创建状态栏时如果它的父窗口也就是对话框的属性是边框可调的话,那么它创建的状态栏就会自动带有一个右下角的可调三角按钮,比如单独注释掉第11和18号,效果如下:
这个时候你看到鼠标可以放在那个三角按钮对状态栏包括大小和长度的可调,这是我们不希望看到,但是我们又想要FileMng边框是可调的,而CStatusBar的父窗口如果具有可调属性,那么它就默认创建可调的三角按钮,那我们怎么实现父窗口可调的情况下,CStatusBar不创建可调的三角按钮呢?答案就是恢复注释掉到第11和18行代码,就是在创建CStatusBar时,我们暂时关闭FileMng窗口的可调属性,让CStatusBar误以为它的父窗口没有可调边框属性,等CStatusBar创建完了之后,我们在打开FileMng的可调边框属性,这样就通过欺骗CStatusBar,而达到我们的目的。
F5运行之后,当窗口最大化时你会发现状态栏并没有跟着发生大小和位置的改变,那怎么让它不管在窗口大小变化的时候,一直是处于窗体的底部,并且大小也跟着窗体的大小而变化呢?其实当窗体发生大小改变时它都会发送一个WM_SIZE的消息,所以要使得状态栏跟着窗体大小发生变化就可以在WM_SIZE中来做了,首先给FileMng类添加一个WM_ONSIZE消息,然后在OnSize()函数中添加如下代码:
[code]{
[/code]
注意到第14行代码重新设置IDS_INDICATOR_MESSAGE面板的宽度,如果注释掉它,则最大化时IDS_INDICATOR_MESSAGE和IDS_INDICATOR_TIME面板平分状态栏,而我们希望IDS_INDICATOR_TIME一直是在右下角,并且希望它的长度大小不变。
好但现在为止,状态栏上时间和提示Msg都还没有变化,时间的获取可以通过CTime类来完成,由此我们自定义一个GetTimeInfo()函数,并返回一个CString字符串,在FileMng.h添加函数声明:
[code]CStringGetTimeInfo();
[/code]
在FileMng.cpp文件中实现如下:
[code]{
[/code]
现在得到了系统时间,那么怎么在状态栏上动态显示时间呢?这里就需要添加一个WM_TIMER消息来响应了,首先在FileMng类中添加一个WM_TIMER消息,然后在OnTimer()消息添加相应的操作代码,具体如下:
[code]{
[/code]
F5运行可以看到Msg的字符滚动显示,右下角动态显示时间,但是这里有个问题就是程序刚启动的时候右下角并没有立即显示时间而是过了一会,那这怎么解决呢?在OnInitDialog的设置IDS_INIDCATOR_MESSAGE内容语句下面添加一个设置IDS_INDICATOR_TIEM的语句,这样初始化时就会立即显示系统时间。
[code]//设置IDS_INDICATOR_TIME的内容
[/code]
这里有些人就要问了,这个SetTimer(1,500,NULL)中的1,500,NULL都是指的啥?这个1就是这个定时器的标识符,有时候要定义多个定时器就需要这个参数来标识是哪个定时器,500是指每0.5秒触发一次定时器,执行一次OnTimer函数,这个值的设置就需要注意了,如果你设置一个比较大的值比如1000,5000之类的可能你就会看到那个时间有点闪,此时就要设置一个比较小的值比如500,为什么会这样呢?这个跟每个机子的配置有关,机子好的可以设置大一点没关系,机子差的就最后设置小一点,免得闪烁。最后一个参数表示你要调用的是哪个函数,比如你要调用一个自定义的函调函数这里就需要写上你自定义的回调函数名称,如果写NULL,则表示调用WM_TIMER生成的OnTimer()函数执行。
关于SetTimer函数的用法,请参考:SetTimer函数的用法
(4)接着设计主界面,使用控件工具箱向对话框资源中加入树形控件、列表控件、按钮、复选框、单选框等控件,并按照下面的表格设置相应的属性值,适当调整控件的大小,最终如图所示。
按照上面的步骤搭建好了之后,界面如图:
哇,这个界面真是丑爆了!但是设计的时候不是挺好的看的吗?你看下图不是挺好看的吗?
为什么呢?这是因为新建项目的时候没有选择Unicode字符那个复选框,那还有什么方法可以挽救吗?答案是有的,把下面的XML代码保存为XPStyle.manifest文件,然后把它拷贝到res目录下
[code]
[/code]
在资源视图中通过添加资源的方式把这个XPStyle.manifest文件添加进来,ResourceType填入:IDR_XP_STYLE然后把它的ID改为1编译运行就可以解决界面风格问题了。
现在还有一个问题就是当最大化窗体时,那个什么树形控件,什么控件的都不会随着放大和移动位置,那怎么办呢?也许你会想到之前状态栏在OnSize进行了大小和位置的调整设置,那这里还可以这样用吗?回答是当然可以的,但是你想一下这么多控件要移动,而且要计算每个控件的大小,更恼火的是哪些控件要保持大小位置不变,哪些只变大小,或只变位置,或只变长度不变宽度等等都要计算,做起来这么琐碎,还要采取这种方法吗?可以但是难免会出错啊,那怎么办呢?到网上找了一个别人写好控件随窗体变化大小位置的类,这里我们直接用就可以了。
首先把ResizeControl.cpp/.h
文件拷贝到项目目录中,然后通过添加存在项把它添加到项目中,然后在FileMngDlg.h中包含ResizeControl.h头文件并声明一个变量m_Reszie.然后在OnInitDialog()中添加m_Resize.SetOwner(this);启用ResizeControl类,接下来通过m_Resize的SetResize()函数来设置各个控件的跟随效果,具体代码如下:
[code]////////////////////////////////////////////////////////控件随窗体大小发生移动或发生大小变化//////////////
[/code]
然后在OnSize()消息函数中先把//CDialogEx::OnSize(nType,cx,cy);这行给注释掉,然后加入m_Resize.OnSize(cx,cy);然后F5效果出来了。至此界面设计亦完结了。
文件管理器是一个基于对话框的应用程序。首先新建一个“MFC应用程序”类型的项目,然后输入新建项目的名称“FileMng”,并指定该项目保存的位置,单击“确定”按钮,如图所示。
在弹出的“应用程序类型”向导对话框中,选择“应用程序类型”为“基于对话框”,并取消对“使用Unicode库”复选框的选择,如图所示。
点击Next按钮,在弹出的“用户界面接口”向导对话框中,选择Minimizebox和Maximizebox复选框,并取消对“Aboutbox”复选框的选择,如图所示。
接下来点击Finish完成FileMng项目的创建。
2.设计程序主界面
在向对话框资源上添加控件前,先将对话框上自动创建的ok和cancel按钮删除掉,然后右键对话框属性设置Font(Size)属性为“宋体(9)”。
(1)首先需要向项目导入一些图标和位图。其中图标用来显示在树形控件及列表控件中,而位图主要用来创建位图按钮。在资源视图中项目名的根节点上右键,在弹出的快捷键菜单中选择“添加”->“资源”菜单命令,在弹出的“添加资源”对话框中单击“导入”按钮并导入相应的位图和图标,如图所示。
(2)在对话框资源上添加一个静态图片控件
和两个组框
,在属性窗口中设置静态图片控件的Type属性为“Frame”,Color属性设置为“Gray”,设置控件ID号为“IDC_STATIC_BAN”以及修改组框的Caption属性分别为“目录结构(&D)”和“文件列表(&F)”,同时设置它们的控件ID号分别为“IDC_STATIC_MULU”和“IDC_STATIC_FILE”并适当调整它们的大小和位置,如图所示。
记得把那个紫色的虚框往上拉一点,留出添加状态栏的宽度。
同时添三个静态图片控件,在属性窗口中设置它们的Type属性为Bitmap,指定它们的控件ID号分别为“IDC_STATIC_LEFT”、“IDC_STATIC_MID”和“IDC_STATIC_RIGHTT”并分别指定Image属性为IDB_BITMAP1、IDB_BITMAP3和IDB_BITMAP2。添加位图后的对话框资源如图所示。
(3)添加状态栏,首先资源视图中添加一个Stringtable并在里面添加两个字符串,ID分别为IDS_INDICATOR_MESSAGE和IDS_INDICATOR_TIME,把它们的Caption分别设置为Msg和星期%d上午00:00:00
接着声明int型index1,index2用来保存IDS_INDICATOR_MESSAGE面板和IDS_INDICATOR_TIME面板的索引,另外声明两个int变量nWidth1,nWidth2用来保存IDS_INDICATOR_MESSAGE面板和IDS_INDICATOR_TIME面板的宽度。
接着再声明UINT型变量nID和nStyle分别用来接收面板ID和面板风格,还要声明一个CString变量str用来接收Msg的内容,然后在FileMng.h文件中声明一个CStatusBar的变量m_wndStatusBar;在FileMng.h文件中代码如下:
public:
[code]CStatusBarm_wndStatusBar;
intindex1,//保存IDS_INDICATOR_MESSAGE,IDS_INDICATOR_TIME索引
index2,
nWidth1,//保存IDS_INDICATOR_MESSAGE,IDS_INDICATOR_TIME宽度
nWidth2;
UINTnID,//面板ID
nStyle;//面板Style
CStringstr;//接收Msg内容
[/code]
然后在FileMng.cpp文件开头添加如下数组:
staticUINTindicators[]=
[code]{
IDS_INDICATOR_MESSAGE,
IDS_INDICATOR_TIME
};
[/code]
然后在FileMng.cpp文件中的OnInitDialog()函数添加状态栏创建代码:
BOOLCFileMngDlg::OnInitDialog()
[code]{
CDialogEx::OnInitDialog();
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
//TODO:Addextrainitializationhere
ModifyStyle(WS_THICKFRAME,0);
if(!m_wndStatusBar.Create(this)||
!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Can'tcreatestatusbar");
returnfalse;
}
ModifyStyle(0,WS_THICKFRAME);
//获取IDS_INDICATOR_MESSAGE,IDS_INDICATOR_TIME的索引和对应的宽度
index1=this->m_wndStatusBar.CommandToIndex(IDS_INDICATOR_MESSAGE);
index2=this->m_wndStatusBar.CommandToIndex(IDS_INDICATOR_TIME);
m_wndStatusBar.GetPaneInfo(index2,nID,nStyle,nWidth2);
//设置IDS_INDICATOR_MESSAGE面板的宽度
CRectrect;
GetClientRect(rect);
this->m_wndStatusBar.SetPaneInfo(index1,nID,nStyle,rect.Width()-nWidth2-15);
//设置IDS_INDICATOR_TIME面板的宽度
this->m_wndStatusBar.SetPaneInfo(index2,nID,nStyle,rect.Width());
//重新摆放控件,因为增加状态栏之后,控件相对位置发生变化,重新摆放才能显示出来
RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);
//使用UNICODE设置字幕文本可以做成一个函数动态的改变滚动字幕的文本
str=_T("欢迎使用本软件...........");
//设置文本index=0处的即设置IDS_INDICATOR_MESSAGE面板的文本内容
m_wndStatusBar.SetPaneText(0,str);
//设置定时器
SetTimer(1,500,NULL);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
[/code]
上面代码中的第11行和18行的ModifyStyle()代码分别是关闭和开启对话框边框可调属性,因为CStatusBar在创建状态栏时如果它的父窗口也就是对话框的属性是边框可调的话,那么它创建的状态栏就会自动带有一个右下角的可调三角按钮,比如单独注释掉第11和18号,效果如下:
这个时候你看到鼠标可以放在那个三角按钮对状态栏包括大小和长度的可调,这是我们不希望看到,但是我们又想要FileMng边框是可调的,而CStatusBar的父窗口如果具有可调属性,那么它就默认创建可调的三角按钮,那我们怎么实现父窗口可调的情况下,CStatusBar不创建可调的三角按钮呢?答案就是恢复注释掉到第11和18行代码,就是在创建CStatusBar时,我们暂时关闭FileMng窗口的可调属性,让CStatusBar误以为它的父窗口没有可调边框属性,等CStatusBar创建完了之后,我们在打开FileMng的可调边框属性,这样就通过欺骗CStatusBar,而达到我们的目的。
F5运行之后,当窗口最大化时你会发现状态栏并没有跟着发生大小和位置的改变,那怎么让它不管在窗口大小变化的时候,一直是处于窗体的底部,并且大小也跟着窗体的大小而变化呢?其实当窗体发生大小改变时它都会发送一个WM_SIZE的消息,所以要使得状态栏跟着窗体大小发生变化就可以在WM_SIZE中来做了,首先给FileMng类添加一个WM_ONSIZE消息,然后在OnSize()函数中添加如下代码:
voidCFileMngDlg::OnSize(UINTnType,intcx,intcy)
[code]{
CDialogEx::OnSize(nType,cx,cy);
CRectrectDlg,
rectBar;
GetClientRect(rectDlg);
//当程序刚开始创建时,它会先执行到OnSize()这里再去执行OnInitDialog()函数,所以开始的时候要检测m_wndStatusBar是否已经存在
//此外到窗体最小化时,此时rectDlg.width()的宽度就是0,那么此时就不能进行状态栏的movewindow()工作,因为窗体都没有了,还move个p啊
if(m_wndStatusBar&&(0!=rectDlg.Width()))
{
CStatusBar*m_pwndStatusBar=(CStatusBar*)&m_wndStatusBar;//获取指向StatusBar句柄的指针
m_pwndStatusBar->GetClientRect(&rectBar);//获取当前StatusBar的矩形大小
m_pwndStatusBar->SetPaneInfo(index1,nID,nStyle,rectDlg.Width()-nWidth2-15);//重新设置IDS_INDICATOR_MESSAGE面板的宽度
m_pwndStatusBar->MoveWindow(0,cy-rectBar.Height(),rectDlg.Width(),rectBar.Height());//移动StatusBar的位置并重新设置它的大小
}
}
[/code]
注意到第14行代码重新设置IDS_INDICATOR_MESSAGE面板的宽度,如果注释掉它,则最大化时IDS_INDICATOR_MESSAGE和IDS_INDICATOR_TIME面板平分状态栏,而我们希望IDS_INDICATOR_TIME一直是在右下角,并且希望它的长度大小不变。
好但现在为止,状态栏上时间和提示Msg都还没有变化,时间的获取可以通过CTime类来完成,由此我们自定义一个GetTimeInfo()函数,并返回一个CString字符串,在FileMng.h添加函数声明:
public:
[code]CStringGetTimeInfo();
[/code]
在FileMng.cpp文件中实现如下:
CStringCFileMngDlg::GetTimeInfo()
[code]{
CTimetime=CTime::GetCurrentTime();
CStrings=time.Format("%H:%M:%S");
CStringstrweek;
switch(time.GetDayOfWeek())
{
case1:strweek=_T("星期天");break;
case2:strweek=_T("星期一");break;
case3:strweek=_T("星期二");break;
case4:strweek=_T("星期三");break;
case5:strweek=_T("星期四");break;
case6:strweek=_T("星期五");break;
case7:strweek=_T("星期六");break;
default:TRACE(_T("Error"));break;
}
//time.GetHour()=0表示凌晨12;00到12:59
//time.GetHour()=4表示凌晨4:00到4:59
CStringstrtime;
if((time.GetHour()>=0)&&(time.GetHour()<=4))
{
strtime=_T("凌晨");
}
elseif((time.GetHour()>4)&&(time.GetHour()<=8))
{
strtime=_T("早上");
}
elseif((time.GetHour()>8)&&(time.GetHour()<=11))
{
strtime=_T("上午");
}
elseif((time.GetHour()>11)&&(time.GetHour()<=13))
{
strtime=_T("中午");
}
elseif((time.GetHour()>13)&&(time.GetHour()<=17))
{
strtime=_T("下午");
}
else
{
strtime=_T("晚上");
}
CStringclock=strweek+""+strtime+""+s;
returnclock;
}
[/code]
现在得到了系统时间,那么怎么在状态栏上动态显示时间呢?这里就需要添加一个WM_TIMER消息来响应了,首先在FileMng类中添加一个WM_TIMER消息,然后在OnTimer()消息添加相应的操作代码,具体如下:
voidCFileMngDlg::OnTimer(UINT_PTRnIDEvent)
[code]{
staticintindex=0;//初始化字符串的长度
if(index<0)
index=str.GetLength();//获取字符串的长度
m_wndStatusBar.SetPaneText(0,str.Right(index));//从右向左读取字符串
index-=2;//使得index<0,循环加载字符串,实现字符滚动显示效果
//设置IDS_INDICATOR_TIMER的时间
CStringclock=GetTimeInfo();
m_wndStatusBar.SetPaneText(1,clock);
CDialogEx::OnTimer(nIDEvent);
}
[/code]
F5运行可以看到Msg的字符滚动显示,右下角动态显示时间,但是这里有个问题就是程序刚启动的时候右下角并没有立即显示时间而是过了一会,那这怎么解决呢?在OnInitDialog的设置IDS_INIDCATOR_MESSAGE内容语句下面添加一个设置IDS_INDICATOR_TIEM的语句,这样初始化时就会立即显示系统时间。
//……
[code]//设置IDS_INDICATOR_TIME的内容
CStringclock=GetTimeInfo();
m_wndStatusBar.SetPaneText(1,clock);
//设置定时器
SetTimer(1,500,NULL);
[/code]
这里有些人就要问了,这个SetTimer(1,500,NULL)中的1,500,NULL都是指的啥?这个1就是这个定时器的标识符,有时候要定义多个定时器就需要这个参数来标识是哪个定时器,500是指每0.5秒触发一次定时器,执行一次OnTimer函数,这个值的设置就需要注意了,如果你设置一个比较大的值比如1000,5000之类的可能你就会看到那个时间有点闪,此时就要设置一个比较小的值比如500,为什么会这样呢?这个跟每个机子的配置有关,机子好的可以设置大一点没关系,机子差的就最后设置小一点,免得闪烁。最后一个参数表示你要调用的是哪个函数,比如你要调用一个自定义的函调函数这里就需要写上你自定义的回调函数名称,如果写NULL,则表示调用WM_TIMER生成的OnTimer()函数执行。
关于SetTimer函数的用法,请参考:
(4)接着设计主界面,使用控件工具箱向对话框资源中加入树形控件、列表控件、按钮、复选框、单选框等控件,并按照下面的表格设置相应的属性值,适当调整控件的大小,最终如图所示。
类型 | ID标识符 | 属性 |
静态文本 | IDC_STATIC_ADDR | Caption:地址(&A): |
组合框 | IDC_DIRPATH | Type:DropDown |
按钮 | IDC_STEPADDR | Caption:转到(&G)DefaultButton:true |
树形控件 | IDC_DIRTREE | AlwaysShowSelection:trueHasButton:trueHasLine:true |
列表控件 | IDC_FILELIST | AlwaysShowSelection:trueView:report |
复选框 | IDC_HIDEFILE | Caption:隐藏文件(&H) |
复选框 | IDC_SYSFILE | Caption:系统文件(&S) |
组框 | IDC_STATIC_DEL | Caption:删除选项 |
单选按钮 | IDC_DELOPT | Caption:到回收站(&R)Group:true |
单选按钮 | IDC_RADIO2 | Caption:切底删除(&V) |
按钮 | IDC_OPENTO | Caption:打开OwnerDraw:true |
按钮 | IDC_RENAME | Caption:重命名OwnerDraw:true |
按钮 | IDC_COPYTO | Caption:复制到OwnerDraw:true |
按钮 | IDC_MOVETO | Caption:移动到OwnerDraw:true |
按钮 | IDC_DELETE | Caption:删除OwnerDraw:true |
静态文本 | IDC_STATIC_MSG | Caption:信息(&M) |
静态文本 | IDC_MSGINFO | Caption:提示信息 |
哇,这个界面真是丑爆了!但是设计的时候不是挺好的看的吗?你看下图不是挺好看的吗?
为什么呢?这是因为新建项目的时候没有选择Unicode字符那个复选框,那还有什么方法可以挽救吗?答案是有的,把下面的XML代码保存为XPStyle.manifest文件,然后把它拷贝到res目录下
<?xmlversion="1.0"encoding="UTF-8"standalone="yes"?>
[code]
<assemblyxmlns="urn:schemas-microsoft-com:asm.v1"manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="XPstylemanifest"
type="Win32"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="Win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
[/code]
在资源视图中通过添加资源的方式把这个XPStyle.manifest文件添加进来,ResourceType填入:IDR_XP_STYLE然后把它的ID改为1编译运行就可以解决界面风格问题了。
现在还有一个问题就是当最大化窗体时,那个什么树形控件,什么控件的都不会随着放大和移动位置,那怎么办呢?也许你会想到之前状态栏在OnSize进行了大小和位置的调整设置,那这里还可以这样用吗?回答是当然可以的,但是你想一下这么多控件要移动,而且要计算每个控件的大小,更恼火的是哪些控件要保持大小位置不变,哪些只变大小,或只变位置,或只变长度不变宽度等等都要计算,做起来这么琐碎,还要采取这种方法吗?可以但是难免会出错啊,那怎么办呢?到网上找了一个别人写好控件随窗体变化大小位置的类,这里我们直接用就可以了。
首先把ResizeControl.cpp/.h
文件拷贝到项目目录中,然后通过添加存在项把它添加到项目中,然后在FileMngDlg.h中包含ResizeControl.h头文件并声明一个变量m_Reszie.然后在OnInitDialog()中添加m_Resize.SetOwner(this);启用ResizeControl类,接下来通过m_Resize的SetResize()函数来设置各个控件的跟随效果,具体代码如下:
[code]////////////////////////////////////////////////////////控件随窗体大小发生移动或发生大小变化//////////////
m_Resize.SetOwner(this);
//左上角固定,右上角向右移动,大小发生变化,向右延伸
m_Resize.SetResize(IDC_STATIC_BAN,PK_TOP_LEFT,PK_TOP_RIGHT);
//随窗口左移动,不会改变大小
m_Resize.SetResize(IDC_STATIC_LEFT,PK_TOP_LEFT,PK_TOP_LEFT);
//左上角固定,右上角向右移动,大小发生变化,向右延伸
m_Resize.SetResize(IDC_STATIC_MID,PK_TOP_LEFT,PK_TOP_RIGHT);
//随窗口右移动,不会改变大小
m_Resize.SetResize(IDC_STATIC_RIGHT,PK_TOP_RIGHT,PK_TOP_RIGHT);
//随窗口左移动,不会改变大小
m_Resize.SetResize(IDC_STATIC_ADDR,PK_TOP_LEFT,PK_TOP_LEFT);
//左上角固定,右上角向右移动,大小发生变化,向右延伸
m_Resize.SetResize(IDC_DIRPATH,PK_TOP_LEFT,PK_TOP_RIGHT);
//随窗口右移动,不会改变大小
m_Resize.SetResize(IDC_STEPADDR,PK_TOP_RIGHT,PK_TOP_RIGHT);
//左上角固定,左下角随窗口变化
m_Resize.SetResize(IDC_STATIC_MULU,PK_TOP_LEFT,PK_BOTTOM_LEFT);
//左上角固定,右下角随窗口变化
m_Resize.SetResize(IDC_STATIC_FILE,PK_TOP_LEFT,PK_BOTTOM_RIGHT);
//左上角固定,左下角随窗口变化
m_Resize.SetResize(IDC_DIRTREE,PK_TOP_LEFT,PK_BOTTOM_LEFT);
//左上角固定,右下角随窗口变化
m_Resize.SetResize(IDC_FILELIST,PK_TOP_LEFT,PK_BOTTOM_RIGHT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_HIDEFILE,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_SYSFILE,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_STATIC_DEL,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_DELOPT,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_RADIO2,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_OPENTO,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_RENAME,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_COPYTO,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_MOVETO,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_DELETE,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,也不会改变大小
m_Resize.SetResize(IDC_STATIC_MSG,PK_BOTTOM_LEFT,PK_BOTTOM_LEFT);
//只随窗口上下移动,大小发生变化,右边向右延伸
m_Resize.SetResize(IDC_MSGINFO,PK_BOTTOM_LEFT,PK_BOTTOM_RIGHT);
////////////////////////////////////////////////////////控件随窗体大小发生移动或发生大小变化//////////////
[/code]
然后在OnSize()消息函数中先把//CDialogEx::OnSize(nType,cx,cy);这行给注释掉,然后加入m_Resize.OnSize(cx,cy);然后F5效果出来了。至此界面设计亦完结了。
相关文章推荐
- MFC项目实战(1)文件管理器--界面设计篇
- MFC项目实战(1)文件管理器--准备篇
- MFC项目实战(1)文件管理器--准备篇
- 基于MFC设计NX二次开发界面——项目配置注意点
- 2017.7.7 慕课网-Java从零打造企业级电商项目实战:for3 category模块接口设计
- 2017.7.1 慕课网-Java从零打造企业级电商项目实战:3 category模块设计与开发
- iOS项目开发实战——storyboard设置界面技巧与注意事项
- React Native商城项目实战08 - 设置“More”界面cell
- [thinkPHP5项目实战_12]文章管理界面创建
- MVVM项目实战之路-搭建一个登录界面
- 团队项目:界面设计
- ASP.NET MVC + ADO.NET EF 项目实战(一):应用程序布局设计
- React Native商城项目实战07 - 设置“More”界面导航条
- C#Windows窗体界面设计_攻击决策项目_03_数据绘图_03_绘制雷点
- Kafka项目实战-用户日志上报实时统计之分析与设计
- 测试设计与测试项目实战训练
- 设计模式——Android 常用设计模式之MVP详解及项目实战
- 2017.7.1 慕课网-Java从零打造企业级电商项目实战:3 category模块设计与开发
- 03(maven+SSH)网上商城项目实战之数据库设计(PMD)
- quick cocos2d-x 实战:做一个手机横版格斗游戏2:游戏开始界面设计