MFC 课程总结
《基于MFC框架开发》
马志国 149198978
1 MFC课程的组成
1.1 MFC应用程序的组成部分、执行机制和执行流程(10.5天)。
1.2 Windows平台上的数据库访问技术(1.5天)
MFC的ODBC类和Ado组件
1.3 Windows平台上的网络通信编程 (1天)
基本的socket函数和MFC的socket类
1.4 项目:远程控制系统 (3天)
2 MFC课程目标
2.1 掌握MFC的原理和机制
2.2 熟练掌握断点调试和查看堆栈调用,了解函数的调用关系。
2.3 熟练掌握类向导的使用
2.4 熟练使用MSDN
3 对大家的要求
3.1 不要缺课
3.2 营造良好的学习气氛
----------------------------------------------------
day01 MFC的基础
1 什么是MFC?
Microsoft Foundation Class Library,微软基础类库。一方面是
一个应用程序的编程框架。另一方面是一个庞大的类库。
2 为什么要使用MFC?
提高项目的开发效率,缩短项目的开发周期,降低开发费用。
3 MFC开发的程序的类型
3.1 应用程序
3.1.1 单文档视图程序
1> CWinApp类-应用程序类。维护整个应用程序的运行过程
2> CFrameWnd类-主框架窗口类。创建主框架窗口。
3> CEditView类-视图类。创建视图窗口,显示数据。
4> CDocument类-文档类。管理数据,包括数据的保存和加载
3.1.2 多文档视图程序
1> CMDIFrameWnd类-多文档的主框架窗口类。
2> CMDIChildWnd类-多文档的子框架窗口类。
3> CWinApp类-应用程序类。维护整个应用程序的运行过程
4> CEditView类-视图类。创建视图窗口,显示数据。
5> CDocument类-文档类。管理数据,包括数据的保存和加载
3.1.3 基于对话框的程序
1> CWinApp类-应用程序类。维护整个应用程序的运行过程
2> CDialogEx类-对话框类。创建对话框窗口。
任何一个MFC的应用程序,都必然存在一个CWinApp的子类,和
由子类创建的一个全局应用程序对象theApp。
3.2 库程序
3.2.1 规则库,接口是规则的,意味着任何windows平台上的C++
程序都可以使用规则库。(本身仍然是一个动态库)
1> 在内部静态链接MFC库
2> 在内部动态链接MFC库
3.2.2 扩展库,接口是MFC的,意味着只能被MFC程序调用。一般
只用来扩展MFC的功能。
3.3 控制台程序
4 MFC常用的类
4.1 CObject类-MFC中最顶层的类,提供MFC基本的机制,例如:
运行时类信息以及动态创建等。
4.2 CCmdTarget类-父类是CObject类,提供了对命令消息的查找处理
4.3 CWinApp类-应用程序类,负责维护MFC程序的运行。
4.4 CWnd类-窗口类,封装了操作窗口的Win32 API。主要包括框架窗 口类、对话框类、视图类和控件类。
4.5 CDocument类-文档类,管理数据的,包括对数据的存储和加载。
4.6 CException类-异常类。
4.7 CFile类-文件操作。
4.8 MFC的绘图类-包括绘图设备和绘图对象。
4.9 MFC的集合类-包括动态数组、链表和映射。
4.10 非CObject类的子类
CString类、CTime类、CTimeSpan类、CSize类、CRect类等。
5 第一个MFC程序
5.1 使用Win32向导创建空项目,通过项目属性设置MFC环境。
5.2 在项目中添加源文件MFCBase.cpp,开始编码。
5.3 添加头文件afxwin.h
5.4 添加CWinApp的子类CMyWinApp类,并且使用子类创建全局的
应用程序对象theApp。
5.5 添加CFrameWnd的子类CMyFrameWnd类。
5.6 在CMyWinApp类中重写InitInstance函数,在函数中使用
CMyFrameWnd类创建并显示窗口。
6 MFC的程序启动机制(入口函数机制)
与Win32程序一样,MFC程序也是从WinMain函数开始执行。只不过
MFC程序的WinMain函数是由MFC框架在底层代码提供的,用户不用
也不能自己编写WinMain函数。
7 MFC程序的执行流程
参考辅助文件中的注释
8 CWinApp类的总结:
8.1 虚函数
InitInstance-必须重写的函数,在函数中完成对象以及窗口的 创建,各种库的加载。
ExitInstance-一般会重写的函数,在函数中完成资源的释放以 及各种库的卸载。
OnIdle-很少会重写的函数,在函数中主要完成空闲处理。
Run -一般不会重写的函数,在函数中主要完成消息循环。
8.2 成员
m_pMainWnd-保存主窗口对象的地址
快捷键:
F5-调试的方式启动程序
Ctrl+F5-直接启动
Shift+F5-停止调试
F9-设置/取消断点
F10-单步执行,遇到函数调用,当成一条语句执行过去。
F11-单步执行,遇到函数调用,进入被调用的函数内部。
day2
一 窗口创建过程
Win32: 设计和注册窗口类 ->创建窗口 ->消息循环 ->窗口处理函数
MFC: PreCreateWindow() ->::AfxctxCreateWindow-> Run( ) -> AfxWndProc
Hook-钩子,是Windows编程的一个机制,关联一个钩子处理函数,是一个回调函数。
当满足钩子条件时,钩子处理函数会被系统调用。
1 设置钩子的函数
HHOOK SetWindowsHookEx(
int idHook, // 钩子类型
HOOKPROC lpfn, // 钩子处理函数
HINSTANCE hMod, // 一般是一个包含钩子处理函数的动态库句柄
DWORD dwThreadId //当前线程ID
);
1 创建过程(Create函数的执行过程)
1.1 调用LoadMenu()函数加载菜单
1.2 调用CreateEx()函数创建窗口
1.2.1 调用PreCreateWindow()函数设计和注册窗口类。
1.2.2 调用AfxHookWindowCreate()函数设置CBT类型的钩子
1.2.3 调用AfxctxCreateWindowEx()函数创建窗口
1.2.4 一旦创建窗口,触发钩子处理函数_AfxCbtFilterHook()调用,在函数中:
1>连接窗口对象地址和窗口句柄
2>将窗口处理函数设置为MFC框架提供的AfxWndProc函数。
1.2.5 重写回到1.2.3 以下的代码继续执行...
2 CFrameWnd类的总结:
2.1 虚函数
2.1.1 PreCreateWindow()-函数功能是设计和注册窗口类。通过重写该函数可以通 过传参的方式设置窗口的特征。
2.1.2 WindowProc()-它是一个窗口处理函数。通过重写该函数,我们处理消息。
2.2 成员变量
m_hWnd-保存窗口句柄。
day3
一 消息映射
1 概念
消息映射是指消息ID与消息处理函数的对应关系。
2 实现
2.1 在类的定义中添加消息映射的声明宏
DECLARE_MESSAGE_MAP( )
在类的实现中添加消息映射的实现宏
BEGIN_MESSAGE_MAP( theClass,baseClass)
END_MESSAGE_MAP( )
2.2 在消息映射的实现宏中添加具体的消息映射
BEGIN_MESSAGE_MAP( theClass,baseClass)
ON_MESSAGE(消息ID,消息处理函数)
END_MESSAGE_MAP( )
2.3 添加消息处理函数的声明和实现
3 实现原理
3.1 展开宏
......
3.2 成员函数介绍
3.2.1 GetThisMessageMap( )-静态的成员函数
3.2.2 GetMessageMap( )-虚函数,在函数中,只是调用了GetThisMessageMap( )
这个函数。
3.3 GetThisMessageMap( )函数的执行过程
3.3.1 _messageEntries[]-静态的结构体数组,类型是AFX_MSGMAP_ENTRY。保存
了当前类对消息的处理的信息
struct AFX_MSGMAP_ENTRY
{
UINT nMessage; // 窗口消息的ID
UINT nCode; // 通知消息的通知码
UINT nID; // 控件或菜单ID
UINT nLastID; // 在一个ID范围中表示最后一个控件或菜单ID
UINT_PTR nSig; // 消息处理函数的类型,根据函数的返回值和参数划分
AFX_PMSG pfn; //消息处理函数的指针
};
3.3.2 messageMap-静态的结构体变量。类型是AFX_MSGMAP。
struct AFX_MSGMAP
{
//函数指针,保存了父类的GetThisMessageMap函数的地址。
const AFX_MSGMAP* (PASCAL* pfnGetBaseMap)();
//结构体指针,保存了当前类的 _messageEntries[]这是数组的地址
const AFX_MSGMAP_ENTRY* lpEntries;
};
3.3.3 return &messageMap; ,返回3.3.2 这个结构体变量的地址。
3.4 各部分之间的关系
GetMessageMap( )
|->GetThisMessageMap( )
|->&messageMap
|->&_messageEntries[0]
|->消息ID与消息处理函数的对应关系
WM_CREATE----OnCreate
WM_PAINT ----OnPaint
|->&CFrameWnd::GetThisMessageMap
|->&CFrameWnd::messageMap
|->&CFrameWnd::_messageEntries[0]
|->消息ID与消息处理函数的对应关系
WM_CREATE ---- OnCreate
WM_SIZE ----OnSize
......
|->&CWnd::GetThisMessageMap
|->&CWnd::messageMap
|->&CWnd::_messageEntries[0]
WM_CLOSE --OnClose
...
|->......
分析关系,形成一个继承层次关系上的消息的处理信息的链表。
4 实现过程
二 MFC对消息的分类
1 窗口消息(标准消息)-与创建过程相关的消息以及鼠标、键盘和定时器等消息。
消息映射宏的一般格式:
ON_WM_XXX( )
例如:ON_WM_CREATE、ON_WM_SIZE( )、ON_WM_MOUSEMOVE( )
2 命令消息-菜单、工具栏和加速键等消息
消息映射宏的一般格式:
ON_COMMAND(消息ID,消息处理函数)
3 通知消息-大部分的控件的消息都是通知消息
ON_EN_CHANGE(控件ID,消息处理函数)
day4
一 MFC的菜单
1 相关类
CMenu类-封装了菜单句柄和操作菜单的API函数。
2 CMenu类的使用
2.1 加载菜单资源
CMenu::LoadMenu
2.2 将菜单设置到窗口
CWnd::SetMenu
2.3 上下文菜单,在窗口的ON_WM_CONTEXTMENU( )消息处理函数中添加
2.3.1 加载菜单资源
CMenu::LoadMenu
2.3.2 获取某个菜单项下的子菜单
CMenu::GetSubMenu
2.3.3 显示
CMenu::TrackPopupMenu
2.4 菜单的显示状态
ON_UPDATE_COMMAND_UI
2.5 命令消息
窗口消息对消息链表的遍历查找过程是在CWnd::OnWndMsg函数中完成的。
命令消息对消息链表的遍历查找过程是在CCmdTarget::OnCmdMsg函数中完成的。
处理顺序:
CFrameWnd->App
二 MFC工具栏
1 相关类
CToolBar类-提供了工具栏的相关操作。
#include <afxext.h>
2 CToolBar类的使用
2.1 创建工具栏窗口
CToolBar::Create
2.2 加载工具栏资源
CToolBar::LoadToolBar
2.3 停靠工具栏(船坞化)
2.3.1 工具栏允许停靠
CToolBar::EnableDocking
2.3.2 框架窗口允许被停靠
CFrameWnd::EnableDocking
2.3.3 停靠工具栏
CFrameWnd::DockControlBar
课堂练习:创建一个工具栏,停靠在窗口的右边,并通过菜单控制它的显示状态。
三 MFC的状态栏
1 相关类
CStatusBar类-提供了状态栏的相关操作。
2 CStatusBar类的使用
2.1 创建状态栏窗口
CStatusBar::Create
2.2 设置状态栏指示器
CStatusBar::SetIndicates
2.3 设置状态栏文本
CStatusBar::SetPaneText
day5
一 MFC视图
1 相关类
CView类-父类是CWnd类,是专门用来显示数据的窗口。包含了纯虚函数OnDraw,它
是一个抽象类。使用时,通常在子类中重写OnDraw函数。
2 CView的使用
2.1 CWnd::PostNcDestroy- 在窗口被销毁后,默认的被成员函数OnNcDestroy调用。
派生类可以使用该函数完成用户的资源清理工作,例如:
delete this。
void CView::PostNcDestroy()
{
delete this;//对象的自销毁
}
void CFrameWnd::PostNcDestroy()
{
delete this;//对象的自销毁
}
2.2 视图窗口的大小能够自适应框架窗口
在框架窗口的WM_SIZE消息处理函数中,根据框架窗口的客户区大小设置视图。
另外,设置视图的ID为AFX_IDW_PANE_FIRST,也可以达到自适应的效果。
2.3 活动视图
2.3.1 CFrameWnd::SetActiveView-设置活动视图的函数。
2.3.2 在函数内部存在一个指针变量的赋值操作
m_pViewActive=m_pwndView;
2.4 对命令消息的处理顺序
ActiveView->Frame->App
2.5 OnDraw和OnPaint
CView::OnPaint函数调用CMyView::OnDraw函数。
CMyView::OnPaint
二 运行时类信息
1 概念
程序在运行的时候,获取对象的类信息和判断对象是否属于某个类。
2 实现
2.1 实现条件
2.1.1 直接或者间接的从CObject派生。
2.1.2 在类的定义中添加运行时类信息的声明宏
DECLARE_DYNAMIC(theClass)
在类的实现中添加运行时类信息的实现宏
IMPLEMENT_DYNAMIC(theClass,baseClass)
2.2 相关函数
2.2.1 CObject::GetRuntimeClass-获取当前类的运行时类信息
struct CRuntimeClass
{
LPCSTR m_lpszClassName;//类的名称字符串
int m_nObjectSize;//对象大小
UINT m_wSchema//类的版本
CObject* (PASCAL* m_pfnCreateObject)( );//NULL
CRuntimeClass* m_pBaseClass;//指向下一个节点的指针
};
2.2.2 CObject::IsKindOf -判断对象是否属于某个类
3 实现原理
3.1 展开宏
......
3.2 成员的作用
3.2.1 classCDog-静态的结构体变量,类型是CRuntimeClass。保存了当前类的
名称、大小、版本等信息。还保存了父类的运行时类信息变量
classCAnimal的地址。
3.2.2 GetRuntimeClass-虚函数,作用是获取classCDog的地址。
3.3 成员之间的关系
GetRuntimeClass( )
|->&classCDog
|->CDog类的名称、大小和版本等信息
|->&classCAnimal
|->CAnimal类的名称、大小和版本等信息
|->&classCObject
|->CObject了的名称、大小和版本等信息
|->NULL
形成一个继承层次关系上的类的信息链表。
3.4 IsKindOf函数的执行流程:
dog.IsKindOf(RUNTIME_CLASS(CObject)) CWnd
&classCDog &classCObject &classCWnd
&classCAnimal
&classCObject TRUE
FALSE
三 动态创建
1 概念
创建未知类型的对象
2 定义支持动态创建的类
2.1 直接或者间接的派生自CObject类。
2.2 在类的定义中添加动态创建的声明宏
DECLARE_DYNCREATE(theClass)
在类的实现中添加动态创建的实现宏
IMPLEMENT_DYNCREATE(theClass,baseClass)
3 实现原理
3.1 展开宏
.......
在运行时类信息的基础上,多了一个CreateObject()函数.
3.2 成员的作用
3.2.1 CreateObject-静态的成员函数,作用是new CDog对象。
3.2.2 classCDog-静态的结构体变量,类型是CRuntimeClass。在它的成员
m_pfnCreateObject变量中保存了3.2.1 函数的地址。
3.3 创建过程
day6
一 MFC的切分窗口
1 分类
静态切分-在程序编写时,就已经确定了窗口切分的数量。每个切分窗口对应的视图类
可以不相同。最大切分数量16*16.
动态切分-在程序运行时,由用户根据需要实时的切分窗口。一般情况,每个切分窗口
使用相同的视图类。最大切分数量2*2.
2 相关类
CSplitterWnd类-功能主要是完成窗口切分。
#include <afxwin.h>
3 静态切分
3.1 在OnCreateClient函数中完成窗口切分。
3.2 调用 CSplitterWnd::CreateStatic-完成窗口静态切分。
BOOL CreateStatic(
CWnd* pParentWnd, //父窗口对象的地址
int nRows,//行数,不能超过16
int nCols, //列数,不能超过16
DWORD dwStyle = WS_CHILD | WS_VISIBLE, //窗口的风格
UINT nID = AFX_IDW_PANE_FIRST //窗口ID
);
3.3 调用 CSplitterWnd::CreateView创建视图
virtual BOOL CreateView(
int row, //行号
int col, //列号
CRuntimeClass* pViewClass,//视图类的运行时类信息
SIZE sizeInit, //初始尺寸
CCreateContext* pContext//创建上下文结构体
);
3.4 根据位置获取某个视图
CSplitterWnd::GetPance
3.5 设置活动视图
CSplitterWnd::SetActivePane
练习:创建一个3*3的静态切分窗口,每一个视图窗口使用CMyView这是视图类,而且
每个视图窗口大小大致相同。10分钟
4 动态切分窗口
BOOL Create(
CWnd* pParentWnd, //父窗口
int nMaxRows, //行数的最大值。不能超过2
int nMaxCols, //列数的最大值。不能超过2
SIZE sizeMin, //最小尺寸
CCreateContext* pContext, //创建上下文的结构体,在这儿使用它指定视图类的运行时类信息
DWORD dwStyle = WS_CHILD | WS_VISIBLE, //窗口的风格
UINT nID = AFX_IDW_PANE_FIRST//窗口ID
);
二 MFC的文档
1 相关类
CDocument类-文档类,主要功能是用来管理数据的。
2 CDocument类的使用
在视图窗口中显示来自于文档的数据
2.1 CView::OnInitialUpdate-视图的初始化更新函数,是一个虚函数。在视图第一次附加
文档之后,视图窗口显示之前被框架调用。
2.2 CView::GetDocument-获取与视图关联的文档
2.3 CFrameWnd::InitialUpdateFrame-框架的初始化更新函数,在创建一个新的框架窗口
之后调用该函数,它会引起框架中所有视图的OnInitialUpdate函数的调用。
3 创建过程
3.1 框架的WM_CREATE消息的处理函数(视图对象的创建以及视图窗口的创建)
CFrameWnd::OnCreate(...);
{
return OnCreateHelper(lpcs, pContext);
{
OnCreateClient(lpcs, pContext);
{
CreateView(pContext, AFX_IDW_PANE_FIRST);
{
// 3.1.1 动态创建视图对象
CWnd* pView = (CWnd*)pContext->m_pNewViewClass->CreateObject();
// 3.1.2 创建视图窗口
pView->Create(...);
}
}
}
}
3.2 视图的WM_CREATE消息的处理函数(文档与视图之间的关系)
CView::OnCreate(...);
{
pContext->m_pCurrentDoc->AddView(this);
{
//3.2.1 在文档的成员变量m_viewList这个链表中保存了视图对象地址
m_viewList.AddTail(pView);
//3.2.2 在视图的成员变量m_pDocument中保存了文档对象的地址
pView->m_pDocument = this;
}
}
一个文档可以保存多个视图对象地址,即一个文档可以对应多个视图。
一个视图可以保存一个文档对象地址,即一个视图只对应一个文档。
4 App、Frame、View和Doc之间的关系
CWinApp
|->m_pMainWnd (CFrameWnd )
|->m_pViewActive ( CView)
|->m_pDocument (CDocument)
|-> m_viewList (CView List)
5 命令消息的处理顺序
View->Doc ->Frame->App
三 使用文档模板类创建文档视图程序
1 文档模板类
CDocTemplate类-文档模板类,抽象基类,提供了文档模板的基本功能。
CSingleDocTemplate类-单文档模板类,父类是CDocTemplate类。用来创建单文档
视图程序。
CMultiDocTemplate类-多文档模板类,父类也是 CDocTemplate类。用来创建多文档
视图程序。
day7
一 使用文档模板类创建文档视图程序
1 文档模板类
CDocTemplate类-文档模板类,抽象基类,提供了文档模板的基本功能。
CSingleDocTemplate类-单文档模板类,父类是CDocTemplate类。用来创建单文档
视图程序。
CMultiDocTemplate类-多文档模板类,父类也是 CDocTemplate类。用来创建多文档
视图程序。
2 使用单文档模板类创建单文档视图程序
CSingleDocTemplate(
UINT nIDResource, //资源ID
CRuntimeClass* pDocClass, //文档类的运行时类信息
CRuntimeClass* pFrameClass, //框架类的运行时类信息
CRuntimeClass* pViewClass//视图类的运行时类信息
);
从参数我们可以推断出,文档类、框架类和视图类在定义时都需要支持动态创建。
2.1创建过程
2.1.1 创建单文档模板对象
2.1.2 添加到应用程序
2.1.3 新建文档
2.2 各个类(对象)之间的关系
CWinApp
|->m_pDocManager (CDocManager)
|->m_templateList (CSingleDocTemplate)
|->m_pOnlyDoc (CDocument)
|->m_pMainWnd (CFrameWnd)
|->m_pViewActive (CView)
|->m_pDocument (CDocument)
|->m_viewList (CView List)
|->m_pDocTemplate (CSingleDocTemplate)
2.3获取四个对象(App、Frame、View、Doc)的函数
2.3.1 应用程序对象(theApp)
AfxGetApp()/AfxGetThread()
2.3.2 主框架窗口对象(Frame)
AfxGetMainWnd()
2.3.3 视图对象(View)
((CFrameWnd*)AfxGetMainWnd())->GetActiveView( )
2.3.4 文档对象
((CFrameWnd*)AfxGetMainWnd())->GetActiveView( )->GetDocument( )
3 使用多文档模板类创建多文档视图程序
CMultiDocTemplate(
UINT nIDResource, //子框架窗口对应的资源ID
CRuntimeClass* pDocClass,
CRuntimeClass* pFrameClass, //多文档的子框架窗口类的运行时类信息
CRuntimeClass* pViewClass
);
多文档的主框架和子框架分别拥有自己的资源。
4 多文档视图程序中多个视图数据同步的例子
4.1 "新建"菜单:创建新的文档、子框架和视图。OnFileNew
4.2 "新建窗口"菜单:基于原有活动视图对应的文档,创建新的子框架和视图。
产生的结果就是一个文档对应多个视图。
4.3 捕获视图内容发生变化的消息
day8
一 MFC绘图
1 相关类
1.1 绘图设备类
1.2 绘图对象类
画笔、画刷、位图、字体、区域(可以进行几何运算)。
2 绘图设备类的使用
2.1 CDC类-绘图设备类中的基类。提供了绘图设备的基本功能。使用它描述一般的绘图
设备。例如:显示器、打印机等。
2.1.1 创建
virtual BOOL CreateDC(
LPCTSTR lpszDriverName,//设备的驱动名称
LPCTSTR lpszDeviceName, //设备的名称
LPCTSTR lpszOutput, //设备的接口
const void* lpInitData//设备的初始化参数
);
显示器: CreateDC("DISPLAY",NULL,NULL,NULL);
2.1.2 使用
TextOut/MoveTo/LineTo/Rectangle/Ellipse...
2.1.3 删除
DeleteDC( )
2.2 CClientDC类-父类是CDC类,表示的是某一个指定窗口的客户区。
2.3 CPaintDC类-父类也是CDC类,表示的也是某一个指定窗口的客户区。只在WM_PAINT
消息的处理函数中使用。
3 绘图对象类的使用
3.1 画笔、画刷和字体的使用
3.1.1 创建绘图对象
3.1.2 将绘图对象选入到绘图设备中
3.1.3 在绘图设备中使用绘图对象
3.1.4 恢复默认的绘图对象
3.1.5 删除绘图对象
3.2 位图的使用
3.2.1 创建位图对象,加载位图资源
3.2.2 创建与当前绘图设备兼容的一个内存设备
3.2.3 将位图选入到兼容设备中
3.2.4 将位图从兼容设备拷贝到当前设备
3.2.5 删除兼容设备
3.2.6 删除位图对象
3.3 区域的使用
3.3.1 创建区域
CRgn::CreateXXX
3.3.2 几何运算(可以多次)
CRgn::CombineRgn
3.3.3 在绘图设备填充区域
CDC::FillRgn
二 文件操作
1 相关类
1.1 CFile类-封装了文件句柄和操作文件的API。
1.2 CFileFind类-提供文件的查找操作。
2 CFile类的使用
2.1 打开或者新建文件
CFile::Open
2.2 文件读写
CFile::Read/Write
2.3 关闭
CFile::Close
注意的问题: 1>文件操作通常放到异常处理结构中
2>读写时注意文件的指针位置
3 CFileFind类的使用
3.1 开始查找(在哪个目录下查找)
CFileFind::FindFile
3.2 查找下一个
CFileFind::FindNextFile
3.3 获取和判断文件信息
CFileFind::GetXXX/IsXXX
3.4 结束查找
CFileFind::Close
练习: 1 查找指定目录下的文件和子目录(只查找一层)
练习:2 查找指定目录下的所有文件和子目录(遇到子目录继续查找)
1> 使用递归
2> CFileFind::GetFilePath
3>排除.目录 !CFileFind::IsDots()
三 序列化
1 概念
将数据以二进制流的方式依次写入到文件和从文件中读取的过程。
2 相关类
CArchive类-归档类,代替CFile::Read/Write完成具体的读写操作。
3 CArchive类的使用步骤
3.1 打开或者新建文件
CFile::Open
3.2 文件读写
3.2.1 定义CArchive对象
3.2.2 读写操作
<<,写操作
>>,读操作
3.2.3 关闭
CArchive::Close
3.3 关闭
CFile::Close
day9
一 MFC对话框
1 分类
模式对话框-阻塞的
非模式对话框
2 相关类
CDialog类-父类是CWnd类,提供了对话框的基本操作。
CCommonDialog类-父类是CDialog类,称为通用对话框类。包括以下六种不同的类型的
通用对话框,通过它的不同的子类实现的。分别是文件对话框、颜色对话框、
字体对话框、查找替换对话框、页面设置对话框和打印对话框。
CPropertyPage类-父类也是CDialog类,称为属性页对话框。
3 CDialog类的使用
3.1 创建基于模式对话框的程序
3.1.1 添加对话框的资源模板,并与对话框类关联
3.1.2 创建和显示对话框
CDialog::DoModal
3.1.3 关闭
CDialog::OnOK/OnCancel
3.2 创建基于非模式对话框的程序
3.2.1 添加对话框的资源模板,并与对话框类关联
3.2.2 创建和显示对话框
与一般的框架窗口的创建方式类似
3.2.3 非模式对话框的关闭需要用户处理
1> 重写 CDialog::OnOK和 OnCancel函数,在函数中:
DestroyWindow( )
2> 重写CWnd::PostNcDesroy函数,在函数中:
delete this;
4 在MFC向导程序中分别创建模式和非模式对话框
二 控件操作( 对话框数据交换技术)
1 概念
将控件与对话框类的成员变量绑定,通过操作变量的方式达到操作控件的目的。
2 实现步骤
2.1 在对话框类中添加变量
CButton m_wndOK;//控件类型的变量
CString m_strEdit;//值类型的变量
2.2 将控件与变量绑定(重写CWnd::DoDataExChange函数)
DDX_Control(pDX,控件ID,m_wndOK);//控件类型的绑定函数
DDX_Text(pDX,IDC_EDIT1,m_strEdit);
2.3 控件类型的变量的绑定,直接调用变量的相关函数即可,例如:
m_wndOK.MoveWindow( )
值类型的变量的绑定,需要调用UpdateData(BOOL) 函数。
UpdateData(TRUE)-表示将用户在控件中输入的值传递给变量。控件=>变量
UpdateData(FALSE)-表示将变量的值放到控件中显示。 变量=>控件
三 用户登录的例子
四 加法运算的例子
五 各种控件
1 静态控件,包括图片,静态文本和分组框。
2 按钮控件,包括下压式按钮、复选框和单选框。对应的控件类是CButton类。
3 组合框控件和列表框控件
3.1 组合框控件,可以接收用户的输入也可以在多个选项中选择一项。
对应的控件类CComboBox类。
3.2 列表框控件,可以在多个选项中选择一项,也可以选择多项。
对应的控件类CListBox类。
day10
一 MFC的 各种控件
1 静态控件,包括图片,静态文本和分组框。
2 按钮控件,包括下压式按钮、复选框和单选框。对应的控件类是CButton类。
3 组合框控件和列表框控件
3.1 组合框控件,可以接收用户的输入也可以在多个选项中选择一项。
对应的控件类CComboBox类。
3.2 列表框控件,可以在多个选项中选择一项,也可以选择多项。
对应的控件类CListBox类。
4 旋转按钮、进度条和滑块控件
4.1 旋转按钮,对应的控件类是CSpinButtonCtrl类。
4.2 进度条,对应的控件类是CProgressCtrl类。
4.3 滑块,对应的控件类是CSliderCtrl类。
5 列表控件,对应的控件类CListCtrl类。
5.1 列表控件有四种View:图标、小图标、列表和报表。
5.2 为控件添加图标列表
5.2.1 添加位图资源,设计图标列表。
5.2.2 使用位图资源创建图标列表
CImageList::Create
5.2.3 将图标列表设置到控件
CListCtrl::SetImageList
5.3 插入列
CListCtrl::InsertColumn
5.4 插入选项
CListCtrl::InsertItem
5.5 设置选项的文本
CListCtrl::SetItemText
5.6 清空列表控件中的数据
CListCtrl::DeleteAllItems
5.7 设置控件的背景图片
5.7.1 初始化Ole库
AfxOleInit
5.7.2 设置背景图片
CListCtrl::SetBkImage
5.7.3 设置字体的背景色透明
CListCtrl::SetTextBkColor(CLR_NONE)
6 树控件,控件类是CTreeCtrl类 。
6.1 为控件添加图标列表
6.1.1 添加位图资源,设计图标列表。
6.1.2 使用位图资源创建图标列表
CImageList::Create
6.1.3 将图标列表设置到控件
CTreeCtrl::SetImageList
6.2 插入树节点
HTREEITEM InsertItem(
LPCTSTR lpszItem,//节点的文本
int nImage, //节点的图标
int nSelectedImage,//节点被选中时的图标
HTREEITEM hParent = TVI_ROOT, //默认值表示要插入的节点是根节点;否则该参数为要插入节点的父节点。
HTREEITEM hInsertAfter = TVI_LAST//默认值表示在末尾添加节点;否则在该参数表示的节点之后插入节点。
);
6.3 获取当前选中的节点
CTreeCtrl::GetSelectedItem
6.4 删除节点
CTreeCtrl::DeleteItem
6.5 设置节点的文本
CTreeCtrl::SetItemText
7 属性页控件,控件类是CTabCtrl类。
day11
一 属性页对话框
1 分类
标签式
向导式
2 相关类
CPropertyPage类-父类是CDialog类,称为页面对话框类。
CPropertySheet类-父类是CWnd类,称为表单类。
一个完整的属性页对话框实例=一个表单对象+多个页面对象。
例子:通过属性页对话框中的控件,配置视图中图形的线宽和颜色。
3 标签式属性页的步骤
3.1 插入资源模板,双击生成对应的类,注意父类一定是CPropertyPage类。
3.2 在项目中添加CPropertySheet类的派生类CSetupSheet类。
3.3 在表单中添加页面
CPropertySheet::AddPage
3.4 显示对话框
CPropertySheet::DoModal
3.5 将应用按钮设置为可用
SetModified(TRUE)
3.6 消息处理 (虚函数)
CPropertyPage::OnApply
注意:当点击应用按钮时,所有页面的OnApply都会被调用。
4 向导式属性页的步骤
4.1 插入资源模板,双击生成对应的类,注意父类一定是CPropertyPage类。
4.2 在项目中添加CPropertySheet类的派生类CSetupSheet类。
4.3 在表单中添加页面
CPropertySheet::AddPage
4.4 设置为向导模式
CPropertySheet::SetWizardMode
4.5 显示对话框
CPropertySheet::DoModal
4.6 设置每个页面的向导按钮(在页面的OnSetActive虚函数中设置)
CPropertySheet::SetWizardButtons
入口函数(程序启动)、消息映射、(命令)消息路由、运行时类信息、
MFC的第二部分 Windows平台的数据库访问
1 简单介绍
1.1 ODBC-Open Database Connectivity,微软开放式数据互联。它是一组用于访问和
操作数据库的Win32 API。可以使用这组相同的API访问不同类型的数据库,
访问之前,首先需要设置ODBC数据源。MFC将这组API进行封装,形成了
ODBC类。
1.2 DAO-基于ODBC的,目前已经被淘汰
1.3 OLE DB-基于COM组件技术,提供了一组用于访问和操作数据库的接口。学习门槛高,
使用难度大,并没有流行起来。
1.4 ADO-基于OLE DB之上,做了封装和简化,提供了更加简单的访问和操作数据库的接口。
逐渐流行起来,成为广泛使用的技术之一。
2 ODBC类的使用
2.1 相关类
CDatabase类-主要提供了数据库的连接和关闭。
CRecordset类-主要提供了数据的操作(增删改查)。
#include <afxdb.h>
2.2 设置ODBC数据源
控制面板\管理工具\数据源ODBC。
2.3 ODBC类的使用步骤
day12
一 使用Ado访问数据库
1 Ado是一个单独的组件,VB、C++以及asp都可以使用它访问和操作数据库。
文件:msado15.dll
文件路径:C:\Program Files\Common Files\System\ado\msado15.dll
2 导入Ado组件
#import "文件路径" no_namespace rename("EOF","adoEOF")
一般对于MFC程序,导入组件的命令写到头文件 "stdafx.h"中。编译项目,会在项目的
Debug目录下生成msado15.tlh和msado15.tli两个文件。
3 COM库的初始化
3.1 通常在App::InitInstance()函数中完成COM库的初始化
CoInitialize(NULL);
3.2 通常在App::ExitInstance()函数中完成COM库的卸载
CoUninitialize( )
4 Ado组件的接口类
4.1 _ConnectionPtr类-功能类似于ODBC的CDatabase类。
4.2 _RecordsetPtr类-功能类似于ODBC的CRecordset类。
通常可以使用C++的类封装 Ado组件的接口类。
5 _ConnectionPtr类的使用
5.1 连接数据库
HRESULT Open (
_bstr_t ConnectionString,//连接字符串
_bstr_t UserID,//登录名称
_bstr_t Password,//登录密码
long Options//连接方式,一般不指定,值写 -1 即可。
);
不同类型的数据库连接字符串各不相同,即使相同类型的数据库由于版本不同,连接
字符串也可能不同。我们可以通过vs2010自带的工具通过配置生成连接字符串。
Access:"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\accounts.mdb"
5.2 关闭数据库
Close
6 _RecordsetPtr类的使用
6.1 打开表
HRESULT Open (
const _variant_t & Source,//表名、Sql语句、存储过程名称
const _variant_t & ActiveConnection,//活动连接
enum CursorTypeEnum CursorType,//游标类型
enum LockTypeEnum LockType,//记录集的锁定类型
long Options//adCmdTable/adCmdText/adCmdStoredProc
);
6.2 获取字段数量
Fields->GetCount( )
6.3 获取字段的名称
Fields->GetItem(nIndex)->GetName( )
6.4 获取字段的值
Fields->GetItem(nIndex)->GetValue( )
6.5 记录集的指针操作
MoveNext( )
MovePrevious( )
MoveFirst( )
MoveLast( )
IsEOF( )
IsBOF( )
7 执行Sql语句
7.1 _ConnectionPtr类的Execute()函数,侧重于完成对数据的增删改操作。
7.2 _RecordsetPtr类的Open()函数,侧重于完成查询操作,特别是需要制定记录集的
游标类型和锁定类型的时候。
day13
MFC的第三部分 Windows平台的网络通信编程(Socket)
1 简单介绍
1.1 基本的socket函数
1.2 以WSA开头的socket函数
1.3 MFC提供的Socket类
2 基本的socket函数的使用(以2.2版本的库为例)
2.1 相关文件
dll文件:ws2_32.dll
lib文件:ws2_32.lib
h文件:winsock2.h
2.2 使用步骤
2.2.1 初始socket库
int WSAStartup(
WORD wVersionRequested,//请求使用的库的版本
LPWSADATA lpWSAData//返回可用的库的信息
);
2.2.2 TCP或UDP通信
2.2.3 卸载socket库
WSACleanup( )
3 TCP通信
3.1 TCP服务器
3.1.1 创建
3.1.2 绑定
3.1.3 监听
3.1.4 接收客户端连接
3.1.5 通信
3.1.6 关闭
3.2 TCP客户端
3.2.1 创建
3.2.2 连接服务器 connect, inet_addr("127.0.0.1")
3.2.3 通信
3.2.4 关闭
测试1:客户端和服务器在不同的计算机。
测试2:启动以前在UC编写的socket服务器,使用vc编写的客户端去连接和通信 。
4 UDP通信
4.1 UDP服务器
4.1.1 创建
4.1.2 绑定
4.1.3 通信
4.1.4 关闭
4.2 UDP客户端
4.2.1 创建
4.2.2 通信
4.2.3 关闭
5 使用MFC的socket类完成文件传输
5.1 CAsyncSocket类-异步socket类。
5.2 CSocket类-同步socket类,父类是 CAsyncSocket类。
查看网络端口状态: netstat -an