MFC项目实战(1)文件管理器--准备篇
本程序主要实现如下功能:
程序通过左边的树形控件显示本地计算机中目录的结构,右边的列表控件则负责响应树形控件中选择的目录节点并把此节点中的所有项在列表框中显示出来,列表框支持奇偶行颜色设置,选中颜色设置和热点颜色设置;
本程序支持显示或不显示隐藏文件和系统文件,支持文件的重命名、打开、复制、移动和删除操作,删除操作支持删除到回收站和彻底删除选择。
同时支持地址栏跳转功能。支持属性栏的时间显示
程序主界面:
1. 模式与无模式对话框
本程序是基于对话框而设计的,对话框分为模式对话框和无模式对话框。对于模式对话框,当该对话框在关闭之前,用户不能够在同一应用程序中进行其它的操作,这类对话框如“打开文件”对话框等;而对于无模式对话框,当该对话框显示后用户可以进行其它的操作,这类对话框仅仅是一个弹出窗口,如“替换查找”对话框等。
新建一个MFC的Demo对话框程序,默认设置,Finished 完成新建。然后在资源视图中再新建两个Dialog,右键这新建的Dialog 把它们的Caption,改为ModeDlg 和NonModeDlg 把ID号分别改为IDD_MODEDLG 和IDD_NONMODEDLG ,改好后,ModeDlg 和NonModeDlg对话框模版就新建好了,那么如何来使用它们呢?若要在这些新建的对话框上进行消息响应,就要为这些对话框模版生成一个CDialog派生类才行,那么如何为ModeDlg和NonModeDlg生成它们的派生类呢?在ModeDlg对话框点击右键,选择类向导(Class Wizard)
,然后点击添加类(Add class)新建一个CModeDlg类(即在弹出的MFC类向导对话中,在对话框的“类名”栏中输入CModeDlg,并选择该类的基类为CDialog类。单击“完成”按钮以新建CModeDlg类。)如图:
同样,在NonModeDlg对话框中右键,选择类向导(Class Wizard)然后添加一个CNonModeDlg类。然后打开IDD_DEMO_DIALOG对话框,在它上面添加两个按钮,分别命名为ModeDlg和NonModeDlg ,同时这两个按钮的ID号分别换成IDC_MDlg ,IDC_NMDlg。然后右键点击ModeDlg按钮选择添加事件句柄(Add Event Handler...),在弹出的事件句柄向导对话框中,为按钮选择单击事件,所以消息类型选择BN_CLICKED,按钮是在IDD_DEMO_DIALOG对话框上,所以它的消息事件应该建立在CDemoDlg这个类里面,最后函数句柄的名称默认即可。具体如图:
单击添加并编辑以新建ModeDlg按钮响应函数OnBnClickedMdlg,以同样的方式为NonModeDlg按钮在CDemoDlg类中添加BN_CLICKED事件句柄函数OnBnClickedNmdlg,
为了在CDemoDlg类中使用ModeDlg对话框和NonModeDlg的类,首先需要将它们的头文件包含到DemoDlg.h文件中,即在DemoDlg.h文件添加:
#include"ModeDlg.h"
#include"NonModeDlg.h"
然后回到DemoDlg.cpp文件,在刚添加的ModeDlg按钮响应函数中,创建CModeDlg类的实例,并调用DoModal函数显示对话框,代码如下:
void CDemoDlg::OnBnClickedMdlg()
{
CModeDlg dlg; //创建CModeDlg类实例dlg
dlg.DoModal(); //调用DoModal()函数显示对话框
}
下面在添加的NonModeDlg按钮函数OnBnClickedNmdlg()来创建并显示无模式对话框,创建无模式对话框,首先生成一个CNonModeDlg类的实例,然后调用Create()函数来创建无模式对话框,最后调用ShowWindow()来显示无模式对话框,添加代码如下:
void CDemoDlg::OnBnClickedNmdlg()
{
CNonModeDlg *pDlg = new CNonModeDlg();// 创建一个CNonModeDlg类的实例
pDlg->Create(IDD_NONMODEDLG,this); // 创建无模式对话框
pDlg->CenterWindow(); //对话框居中显示
pDlg->ShowWindow(SW_SHOW); //显示对话框
}
注意Create()函数中的第一个参数是无模式对话框的ID号,当编写完
pDlg->Create(IDD_NONMODEDLG,this); 这行代码后,提示IDD_NONMODEDLG 没有定义,这是因为没有包含Resouce.h头文件,导致它找不到这个ID号,所以在DemoDlg.cpp中包含这个头文件即可。
还需要注意的是,关闭调用DoModal()函数创建的模式对话框时,系统会自动回收模式对话框申请的资源,但是当关闭无模式对话框时,系统不会自动回收和释放创建无模式对话框时所申请的资源,所以在无模式对话框被关闭时需要手动回收它创建时申请的资源,否则会造成内存泄露!那么如何手动来回收它申请的资源呢?
在“类视图“窗口中选择CNonModeDlg类,并单击属性窗口中的属性按钮,然后重写PostNcDestroy函数。在该函数中添加一条delete语句以销毁对话框,回收资源,代码如下:
void CNonModeDlg::PostNcDestroy()
{
delete this;
CDialog::PostNcDestroy();
}
下面介绍一下本程序需要程序的控件,在后面的程序中用到时再做更详细的使用说明。
控件名称 |
MFC类 |
说明 |
静态控件 |
CStatic |
用于显示一些固定不变的文字或图形 |
按钮 |
CButton |
用于产生某些命令消息,包括单选,复选和按键按钮 |
编辑框 |
CEdit |
用于完成文本和数字的输入和编辑 |
列表框 |
CListBox |
显示一个列表,让用户从中选取一个或多个项 |
组合框 |
CComboBox |
是一个列表框和编辑框组合的控件 |
列表控件 |
CListCtrl |
包含图标,标签显示内容的控件 |
树形控件 |
CTreeCtrl |
以树结构形式显示一组信息,能够反映这些信息的结构 |
默认情况下,所有静态控件的ID标识符都是IDC_STATIC,其表示是静态的并且显示的内容不能够改变,不能够为这类控件添加成员变量,消息响应函数等。如果需要动态地改变静态控件上的显示,则需要为这些控件重新指定一个非IDC_STATIC的ID标识符,然后才能在程序中为静态控件添加成员变量,消息响应函数等。
可以调用CWnd类的GetDlgItem成员函数来获取该控件的CWnd指针,或者通过调用GetDlgItemText或SetDlgItemText函数来改变静态控件显示的文本内容。
常见的按钮主要有三种类型:按键按钮、单选按钮和复选按钮。一般而言,需要为按钮添加单击事件BN_CLICKED消息的消息响应函数。同时可以调用CButton类的成员函数SetCheck和GetCheck分别来设置或获取指定按钮的选中状态,原型如下:
void SetCheck(int nCheck);
int GetCheck() const;
其中nCheck和GetCheck函数返回的值可是:0表示不选中,1表示选中,2表示不确定(仅用于三态按钮)。对于同组多个单选按钮的选中状态的设置或获取,需要调用窗口类Cwnd的成员函数CheckRadioButton 和GetCheckedRadioButton ,原型如下:
void CheckRadioButton (int nIDFirstButton, int nIDLastButton,int nIDCheckButton);
int GetCheckedRadioButton(int nIDFirstButton,int nIDLastButton);
其中nIDFirstButton 和nIDLastButton 分别指定同组单选按钮的第一个和最后一个按钮的ID值;nIDCheckButton 用来指定要设置选中状态的按钮的ID值;函数GetCheckedRadioButton返回被选中的按钮ID值。
在MFC中提供支持位图按钮的CBitmapButton类,它是CButton类的派生类,最多可以为位图按钮指定按钮的正常、按下、获得焦点和被禁用的四副状态位图。
在创建位图按钮时,首先需要为按钮定义CBitmapButton类型的变量,然后调用CWnd类的成员函数SubclassDlgItem将变量关联到按钮控件上,再调用该类的的成员函数LoadBitmaps为按钮加载相应状态的位图,最后还可以调用SizeToContent函数来调整按钮的大小以适合位图。这些函数的声明如下:
BOOL SubclassDlgItem(UINT ID,CWnd* pParent);
BOOL LoadBitmaps(LPCTSTR lpszBitmapResource,
LPCTSTR lpszBitmapResourceSel = NULL,
LPCTSTR lpszBitmapResourceFocus = NULL,
LPCTSTR lpszBitmapResourceDisabled =NULL);
BOOL LoadBitmaps(UINT nIDBitmapResource,
UINT nIDBitmapResourceSel = 0,
UINT nIDBitmapResourceFocus = 0,
UINT nIDBitmapResourceDisabled = 0);
在创建位图按钮时,需要设置按钮的OwnerDraw属性为TRUE.
编辑框,作为一个让用户从键盘输入和编辑文本的矩形框,当文本被修改或呗滚动时,会向父窗口发送一些消息,由此可以在属性窗口中为编辑框控件添加这些消息的响应函数。
消息列表:
EN_CHANGE 当编辑框中的文本已被修改,在新的文本显示之后发送此消息
EN_HSCROLL 当编辑框的水平滚动条被使用,在更新显示之前发送此消息
EN_KILLFOCUS 编辑框失去键盘输入焦点时发送此消息
EN_MAXTEXT 文本数目达到了限制值时发送此消息
EN_SETFOCUS 编辑框得到键盘输入焦点时发送此消息
EN_UPDATE 编辑框的文本已被修改,新的文本显示之前发送此消息
EN_VSCROLL 当编辑框的垂直滚动条被使用,在更新显示之前发送此消息
当编辑框显示多行文本内容时,通常需要使用LineScroll 成员函数来滚动显示文本,使用GetLineCount来获取多行文本的行数。
int GetLineCount() const;
void LineScroll( int nLine, int nChars = 0);
其中, nLine 指定了纵向滚动的行数,nChars指定了水平滚动的字符数。但是如果指定了编辑框的对齐属性,则nChars值无效。
列表框可分为单选,多选,扩展多选以及非选择四种类型,默认风格下的单选列表框让用户一次只能选择一个项;多选列表框则一次可以选择多个项,而扩展多选列表框则充许用户用鼠标拖动或其他特殊组合键进行选择;非选列表框则不提供选择功能。
当列表框创建之后,往往要添加、删除、修改或获取列表框中的列表项,这些操作都可调用MFC的CListBox类成员函数来实现。此外,列表框的项除了用字符串来标识外,还常常通过索引来确定。索引表明项目在列表框中排列的位置,它是以0为基准,即列表框中的第一项的索引是0,第二项为1等。列表框控件类CListBox常用的成员函数如下:
AddString 向列表框中添加一个字符串
InsertString 在列表框中指定位置插入一个字符串
DeleteString 从列表框中删除一个字符串
ResetContent 清空列表框所有入口
FindString 在列表框中删除一个字符串
GetCurSel 返回列表框中当前选择项的索引
SetCurSel 选择一个列表框字符串
GetText 从列表框中获取某项的字符串
组合框是一个列表框和编辑框组合的控件。组合框大致可分为两类,一类是对组合框中的列表框进行操作,另一类是对组合框中的编辑框进行操作,这些操作都可以调用CComboBox成员函数来实现,常用的成员函数如下:
AddString 在组合框中列表框的列表末尾添加一个字符串
DeleteString 删除组合框中列表框中的一个字符串
InsertString 在组合框的列表框中插入一个字符串
ResetContent 删除组合框中列表框和编辑框中的所有项
FindString 在组合框的列表框中查找具有指定前缀的第一个字符串
GetCurSel 取得组合框的列表框中当前选中项的索引
SetCurSel 在组合框的列表框中选择一个字符串
GetLBText 从组合框的列表框中取得第一个字符串
GetCount 取得组合框的项数
最后再来谈谈DDX和DDV技术
MFC提供的DDX和DDV技术使用户方便地对控件中的数据进行操作。DDX将数据成员变量与对话框中的控件相关联,使得数据在控件之间或者控件与对话框之间能够直接交换;DDV用于对控件中的数据进行校验,以保证数据的合法性和有效性。
在为对话框资源创建对话框类时,MFC类向导将会自动为对话框类中添加数据交换函数DoDataExchange, 并在该函数中添加相应的数据交换函数或数据校验函数。
需要注意的是,用户不能直接调用DoDataExchange 函数,数据交换和校验是由MFC负责处理的。数据交换和校验机制都是由MFC框架实现的,MFC通过一组DDX交换函数和DDV验证函数来实现控件数据的交换和数据的验证。根据不同的控件类型,MFC提供了不同的数据交换函数,它们都是以DDX_作为前缀的。同样数据校验函数也都是以DDV_作为前缀,这些函数都不需要用户自己添加,MFC会自动添加的。
需要注意的是: DoDataExchange 数据交换和数据校验函数都具有双向性。当为控件定义了数据变量后,可以通过CWnd::UpdateData函数实现对控件数据的输入和读取。当以TRUE参数调用UpdateData函数时,控件中的数据被保存到相关联的成员变量中;如果以FALSE为参数调用UpdateData函数时,则成员变量的值将被传递到控件上。
MFC项目实战(1)文件管理器--准备篇的更多相关文章
- php小项目-web在线文件管理器
php小项目-web在线文件管理器 一 项目结果相关视图 二 项目经验 通过简单的实现小项目,对php的文件相关操作更加熟悉,主要用于熟悉文件的相关操作 三 源代码下载地址 http://files. ...
- MFC项目实战(1)文件管理器--界面设计篇
1.创建项目 文件管理器是一个基于对话框的应用程序.首先新建一个“MFC应用程序”类型的项目,然后输入新建项目的名称“FileMng”,并指定该项目保存的位置,单击“确定”按钮,如图所示. 在弹出的“ ...
- 【WEB API项目实战干货系列】- 导航篇(十足干货分享)
在今天移动互联网的时代,作为攻城师的我们,谁不想着只写一套API就可以让我们的Web, Android APP, IOS APP, iPad APP, Hybired APP, H5 Web共用共同的 ...
- 从零开始Vue项目实战(一)-准备篇
从前参与过一个react项目的代码编写,大神搭建的框架,我主要负责业务逻辑代码编写,现在回想起来似乎又什么都不会,现在为了巩固前端知识,决定用Vue来做这个项目的移动端网站,我本人Vue是从零开始的, ...
- python 项目实战之装饰器
import logging def use_logging(func): def writelog(*args, **kwargs): logging.warning("%s is run ...
- 【项目实战】sass使用基础篇(上)
Sass是一种CSS预处理语言.CSS预处理语言是一种新的专门的编程语言,编译后形成正常的css文件,为css增加一些编程特性,无需考虑浏览器的兼容性(完全兼容css3),让css更加简洁.适应性更强 ...
- mxgraph进阶(三)Web绘图——mxGraph项目实战(精华篇)
Web绘图--mxGraph项目实战(精华篇) 声明 本文部分内容所属论文现已发表,请慎重对待. 需求 由于小论文实验需求,需要实现根据用户日志提取出行为序列,然后根据行为序列生成有向图的形式 ...
- 【.NET Core项目实战-统一认证平台】第八章 授权篇-IdentityServer4源码分析
[.NET Core项目实战-统一认证平台]开篇及目录索引 上篇文章我介绍了如何在网关上实现客户端自定义限流功能,基本完成了关于网关的一些自定义扩展需求,后面几篇将介绍基于IdentityServer ...
- 洗礼灵魂,修炼python(82)--全栈项目实战篇(10)—— 信用卡+商城项目(模拟京东淘宝)
本次项目相当于对python基础做总结,常用语法,数组类型,函数,文本操作等等 本项目在博客园里其他开发者也做过,我是稍作修改来的,大体没变的 项目需求: 信用卡+商城: A.信用卡(类似白条/花呗) ...
随机推荐
- python中unicode, hex, bin之间的转换
python中unicode, hex, bin之间的转换 背景 在smb中有个feature change notify, 需要改动文件权限dacl,然后确认是否有收到notify.一直得不到这个d ...
- python-with管理文件上下文(基本文件操作)
什么是文件 文件是操作系统为用户提供的一个读写硬盘的虚拟单位,文件的操作就是文件的读.写. 操作过程:当我们双击文件 -<- 操作系统接收到指令请求(将用户或应用程序的读写操作转换成集体的硬盘指 ...
- scrollLeft属性设置无效的一个记录
首先应该明确scrollLeft这个属性,只有当div中的内容长度大于当前div的长度是才能working,根据这个我我找到了一个很神奇的地方,而且我注意到这个${}连注释里面都能替换过来! 以下是正 ...
- C++实现链队类——合肥工业大学数据结构实验5:链式队列
实验5 5.1 实验目的 熟练掌握队列的顺序链式存储结构. 熟练掌握队列的有关算法设计,并在链队列上实现. 根据具体给定的需求,合理设计并实现相关结构和算法. 5.2 实验要求 5.2.1链队列实验要 ...
- 【转】Entity Framework6 with Oracle(可实现code first)
Oracle 已在2014年底提供对EF6的支持.以前只支持到EF5.EF6有很多有用的功能 值得升级.这里介绍下如何支持Oracle 一.Oracle 对.net支持的一些基础知识了解介绍. 1 ...
- Task(TPL)简单的实现Winform(WPF)异步
很多时候,我们要实现Winform异步操作,你可以用传统的方法,但个人感觉代码不好理解,而且使用真有点不舒服.也可以用Task来实现,Task(.net4.0新添加的对象)其实就是对线程池线程的一个封 ...
- 大数据学习——hive基本操作
1 建表 create table student(id int,name string ,age int) row format delimitedfields terminated by ','; ...
- The more, The Better(树形DP)
Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有 ...
- 复(学)习化学时突然的一个 idea
期中考试成功探底...但是某些化学问题还是很有信息学价值的... n 烷同分异构体计数. 这个题 fanhq666 出过,就是一个 dp. 设 f[i] 表示含有 i 个节点的无标号不同构的度数限制为 ...
- HDU 3527 SPY
http://poj.org/problem?id=3615 基础题 狂STL #include <bits/stdc++.h> using namespace std; set<s ...