mfc4
2010年03月17日
VC编程技术点滴(一)MFC编程基础
(2009-05-11 11:07:43)
标签: vcmfc编程sdk编程it分类:VC学习点滴
[b]一、传统的Windows编程--SDK编程[/b]
SDK 就是 Software Development Kit 的缩写,即“软件开发工具包”。这是一个覆盖面相当广泛的名词,应该说,辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”,如Java SDK等,这里只讨论开发 Windows 平台下的应用程序所使用的SDK。
上面只是说了一个 SDK 大概的概念而已,为了解释什么是 SDK 我们不得不引入 API、动态链接库、导入库等等概念。
首先要接触的是“API”,也就是 Application Programming Interface,其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(动作)。其实早在 DOS 时代就有 API 的概念,只不过那个时候的 API 是以中断调用的形式(INT 21h)提供的,在 DOS 下跑的应用程序都直接或间接的通过中断调用来使用操作系统功能,比如将 AH 置为 30h 后调用 INT 21h 就可以得到 DOS 操作系统的版本号。而在 Windows 中,系统 API 是以函数调用的方式提供的。同样是取得操作系统的版本号,在 Windows 中你所要做的就是调用 GetVersionEx() 函数。可以这么说,DOS API 是“Thinking in 汇编语言”的,而 Windows API 则是“Thinking in 高级语言”的。DOS API 是系统程序的一部分,他们与系统一同被载入内存并且可以通过中断矢量表找到他们的入口,那么 Windows API 呢?要说明白这个问题就不得不引入我们下面要介绍得这个概念--DLL。
DLL,即 Dynamic Link Library(动态链接库)。我们经常会看到一些 .dll 格式的文件,这些文件就是动态链接库文件,其实也是一种可执行文件格式。跟 .exe 文件不同的是,.dll 文件不能直接执行,他们通常由 .exe 在执行时装入,内含有一些资源以及可执行代码等。其实 Windows 的三大模块就是以 DLL 的形式提供的(Kernel32.dll,User32.dll,GDI32.dll),里面就含有了 API 函数的执行代码。为了使用 DLL 中的 API 函数,我们必须要有 API 函数的声明(.H)和其导入库(.LIB),函数的原型声明不难理解,那么导入库又是做什么用的呢?我们暂时先这样理解:导入库是为了在 DLL 中找到 API 的入口点而使用的。
所以,为了使用 API 函数,我们就要有跟 API 所对应的 .H 和 .LIB 文件,而 SDK 正是提供了一整套开发 Windows 应用程序所需的相关文件、范例和工具的“工具包”。到此为止,我们才真正的解释清楚了 SDK 的含义。
由于 SDK 包含了使用 API 的必需资料,所以人们也常把仅使用 API 来编写 Windows 应用程序的开发方式叫做“SDK 编程”。而 API 和 SDK 是开发 Windows 应用程序所必需的东西,所以其它编程框架和类库都是建立在它们之上的,比如 VCL 和 MFC,虽然他们比起“SDK 编程”来有着更高的抽象度,但这丝毫不妨碍它们在需要的时候随时直接调用 API 函数。 【1】
[b] [/b] *动态链接的概念:如果多个应用程序同时运行,而且都是用了某一静态库中的某一个函数,那么系统会出现该函数的多个代码,而动态链接库允许这些程序共享这个函数的单个代码,从而节省了内存。【2】
*在Windows应用程序中,调用Windows API中函数的方法通常与调用C库函数的方法相同,主要区别是C库函数的目标代码直接放到程序目标代码中,而Windows API函数的目标代码则位于程序之外的某个动态链接库(DLL)中。
*Windows的API是包含在Windows操作系统中的,另外还有单独的驱动程序开发包(DDK),用来开发Windows驱动程序。
*Windows环境下的最佳编程语言就是C/C++语言,因为Windows API函数本身就是用C语言编写的,C和C++调用C语言的API函数是直接引用,而其他语言则多一道转换。C/C++编程可以很方便地利用计算机的底层资源,其程序运行速度远远高于其他语言。
[b]二、MFC编程[/b]【2】
Visual C++的微软基础类库(Microsoft Foundation Class Library,MFC)封装了大部分API函数,并提供一个应用程序框架,简化了和标准化了Windows程序设计,所以用MFC编写的Windows应用程序也称为标准Windows程序设计。MFC约有200个类,提供了Windows应用程序框架和创建应用程序的组件。其中只有5个核心类对应用程序框架有影响:CWinApp,CDocument,CView,CFrameWnd和CDocTemplate。这5个类之中只有CWinApp是必不可少的类,CWinApp的对象在应用程序中必须且只能有一个,并且是一个全局对象,它建立了应用程序执行的主线程。全局对象是在Windows操作系统调用WinMain()之前建立的,它建立了程序的主线程。形象地说,它开通了程序执行的道路。
在MFC编程中,入口函数WinMain()被封装在MFC的应用程序框架内,称为AfxWinMain(),已经不用也不可以再定义另一个WinMain()函数。
MFC编程最好的办法是使用MFC的应用程序向导AppWizard。
[b]1、MFC基础类及其层次结构[/b]
MFC类库的开发者是微软应用程序框架(Application Framework)开发小组(AFX,成立于1989年)。MFC类库的开发经历了一个曲折的过程,从最初的纯粹面向对象的理想模式,转而追求实用性,通过用类封装Windows API和Windows对象,并按照API的方式进行工作,从而建立起一个切实可行的类库,使得用户可以方便地调用API函数直接完成某些任务。
通过这种MFC和Windows很好的连接,使Windows下的C语言程序设计,成为面向对象的MFC。这里没有追求纯粹,而是包容和实用!MFC采用单一继承,从根类Cobject层层派生出绝大多数MFC中的类,其层次结构是最典型的。如下图示,该图表示一个分类的层次结构,并不严格对应派生结构。
下图给出了Cobject主要派生类的派生层次:
Cobject根类派生的最重要的类组成一个应用程序结构(Application Architecture)的集合,它是由CCmdTarget为基类派生出来的,其中主要部分如下图所示:
[b]2、MFC定义的宏、全局函数及全局变量[/b]
MFC和Windows程序一样,使用大量的宏,宏不带任何前缀,全由大写字母表示。
(1)MFC提供的主要宏:
• 消息映射宏: 声明消息映射表 (将于3.2.2节介绍)宏DECLARE_MESSAGE_MAP、定义消息映射表宏BEGIN_MESSAGE_MAP和END_MESSAGE_MAP对、消息映射表入口宏ON_加消息名。MFC程序处理消息非常轻松,得益于其庞大的消息宏系统,使程序设计人员从记忆大量的消息参数中解脱出来。
• 动态 MFC对象宏: DECLARE_DYNCREATE和DECLARE_DYNAMIC, IMPLEMENT_DYNCREATE和IMPLEMENT_DYNAMIC
• 运行时类宏: RUNTIME_CLASS
• 序列化宏: DECLARE_SERIAL和IMPLEMENT_SERIAL
• 诊断服务宏: ASSERT、VERIFY
• 跟踪服务宏: TRACE
• 异常处理宏: THROW
(2)全局函数
MFC提供一些不属于任何类的全局函数,函数名以Afx开头,可以被应用程序中的所有类和函数所调用。如AfxAbort,无条件终止一个应用程序的执行;AfxGetAppName,返回指向应用程序名的字符串指针;AfxWinInit由WinMain调用,对MFC应用程序进行图形用户界面(GUI)的初始化等等。
(3)全局变量
全局变量名以 afx开头,如afxTraceFlag、afxDump等,主要与异常处理有关。
[b]3、MFC对象和Windows对象的关系[/b]
MFC对象是C++对象,而且是特指封装了Windows对象的C++对象,不是任意的C++对象。下图以最典型的窗口类(CWnd)为例,介绍CWnd类对象与Windows窗口对象的关系:
MFC的窗口对象wnd是C++类的实例,即CWnd类或其派生类的实例,是由CWnd类或其派生类的构造函数创建的,最终由CWnd类或其派生类的析构函数撤消。hwnd是HWND句柄类型的实例,为它建立了一个Windows操作系统的对象。然后把这个句柄放入CWnd类对象wnd的成员数据m_hwnd中。这样wnd就包含了一个Windows操作系统的窗口对象。程序段如下:
CWnd wnd;//定义窗口类(CWnd)的对象wnd
HWND hwnd;//定义窗口句柄hwnd
hwnd=CreateWindow(......);//调用API函数CreateWindow(...)建立一个Windows窗口类实例
wnd.Attach(hwd);//把Windows窗口实例的句柄链到CWnd对象hwnd上
......
DestroyWindow(hwnd);//调用API函数撤消Windows窗口
MFC封装了Windows的几乎所有的API函数,所以上面的API函数,可以用CWnd的成员函数代替。成员函数Create()可以代替API函数CreateWindows()并加上另一个成员函数Attach()的全部功能,建立一个Windows操作系统的窗口对象,并把句柄自动保存在MFC窗口对象wnd的m_hwnd成员数据中。通常MFC程序员不需要通过Windows窗口对象的句柄去使用win32API函数,而只需直接使用CWnd的成员函数。
其它的MFC对象和对应Windows对象也有类似的关系。见下表:
项目MFC类对象句柄应用程序
CWinApp
HINSTANCE m_hInstance
窗口
CWnd
HWND m_hWnd
菜单
CMenu
HMENU m_hMenu
设备环境
CDC
HDC m_hDC
矩形区域
CRgn
HRGN m_hRgn
画刷
CBrush
HBRUSH m_hBrush
画笔
CPen
HPEN m_hPen
字体
CFont
HFONT m_hFont
位图
CBitmap
HBITMAP m_hBitmap
调色板
CPalatte
HPALATTE m_hPalatte
Windows窗口句柄通常是全局量,动态建立的Windows窗口对象也是全局变量。所以一个进程或线程可以取得另一个进程或线程的窗口句柄,并给它发送消息。但一个线程只能使用本线程创建的MFC窗口对象,不能使用其它线程创建的MFC窗口对象。
注意:
(1) Windows对象是Windows操作系统的一个内部数据结构的实例,由一个Windows系统全局的窗口句柄来唯一标志,由API函数CreatWindow()创建,而由DestroyWindow()撤消。
(2) 在MFC编程中,通常在MFC对象建立以后,调用Create()成员函数建立Windows对象,并链接在MFC对象上。下面的程序段用来建立应用程序的主框架窗口。
CFrameWnd *pFrame=new CFrameWnd; //动态建立框架窗口对象
pFrame->Create(NULL,”Ex2_xx”,ws_OVERLAPPENDWINDOW,rect,NULL,
MAKEINTRESOURCE(IDR_MENUI),0,NULL);
//建立与pFrame指向的动态框架窗口对象相连的Windows框架窗口
[b]三、使用向导工具创建MFC文档应用程序的基本文件[/b]
使用Microsoft Visual Studio C++6.0开发工具,创建MFC多文档应用程序的步骤如下:
1、创建基于MFC的工程文件:
2、选择创建多文档应用程序:
3、因为本文只是要分析和使用MFC基本程序文件,所以保持工具向导的默认设置,点击Next,一直到下图所示,点击Finish结束基本应用程序的自动创建:
2010年03月17日
VC编程技术点滴(一)MFC编程基础
(2009-05-11 11:07:43)
标签: vcmfc编程sdk编程it分类:VC学习点滴
[b]一、传统的Windows编程--SDK编程[/b]
SDK 就是 Software Development Kit 的缩写,即“软件开发工具包”。这是一个覆盖面相当广泛的名词,应该说,辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”,如Java SDK等,这里只讨论开发 Windows 平台下的应用程序所使用的SDK。
上面只是说了一个 SDK 大概的概念而已,为了解释什么是 SDK 我们不得不引入 API、动态链接库、导入库等等概念。
首先要接触的是“API”,也就是 Application Programming Interface,其实就是操作系统留给应用程序的一个调用接口,应用程序通过调用操作系统的 API 而使操作系统去执行应用程序的命令(动作)。其实早在 DOS 时代就有 API 的概念,只不过那个时候的 API 是以中断调用的形式(INT 21h)提供的,在 DOS 下跑的应用程序都直接或间接的通过中断调用来使用操作系统功能,比如将 AH 置为 30h 后调用 INT 21h 就可以得到 DOS 操作系统的版本号。而在 Windows 中,系统 API 是以函数调用的方式提供的。同样是取得操作系统的版本号,在 Windows 中你所要做的就是调用 GetVersionEx() 函数。可以这么说,DOS API 是“Thinking in 汇编语言”的,而 Windows API 则是“Thinking in 高级语言”的。DOS API 是系统程序的一部分,他们与系统一同被载入内存并且可以通过中断矢量表找到他们的入口,那么 Windows API 呢?要说明白这个问题就不得不引入我们下面要介绍得这个概念--DLL。
DLL,即 Dynamic Link Library(动态链接库)。我们经常会看到一些 .dll 格式的文件,这些文件就是动态链接库文件,其实也是一种可执行文件格式。跟 .exe 文件不同的是,.dll 文件不能直接执行,他们通常由 .exe 在执行时装入,内含有一些资源以及可执行代码等。其实 Windows 的三大模块就是以 DLL 的形式提供的(Kernel32.dll,User32.dll,GDI32.dll),里面就含有了 API 函数的执行代码。为了使用 DLL 中的 API 函数,我们必须要有 API 函数的声明(.H)和其导入库(.LIB),函数的原型声明不难理解,那么导入库又是做什么用的呢?我们暂时先这样理解:导入库是为了在 DLL 中找到 API 的入口点而使用的。
所以,为了使用 API 函数,我们就要有跟 API 所对应的 .H 和 .LIB 文件,而 SDK 正是提供了一整套开发 Windows 应用程序所需的相关文件、范例和工具的“工具包”。到此为止,我们才真正的解释清楚了 SDK 的含义。
由于 SDK 包含了使用 API 的必需资料,所以人们也常把仅使用 API 来编写 Windows 应用程序的开发方式叫做“SDK 编程”。而 API 和 SDK 是开发 Windows 应用程序所必需的东西,所以其它编程框架和类库都是建立在它们之上的,比如 VCL 和 MFC,虽然他们比起“SDK 编程”来有着更高的抽象度,但这丝毫不妨碍它们在需要的时候随时直接调用 API 函数。 【1】
[b] [/b] *动态链接的概念:如果多个应用程序同时运行,而且都是用了某一静态库中的某一个函数,那么系统会出现该函数的多个代码,而动态链接库允许这些程序共享这个函数的单个代码,从而节省了内存。【2】
*在Windows应用程序中,调用Windows API中函数的方法通常与调用C库函数的方法相同,主要区别是C库函数的目标代码直接放到程序目标代码中,而Windows API函数的目标代码则位于程序之外的某个动态链接库(DLL)中。
*Windows的API是包含在Windows操作系统中的,另外还有单独的驱动程序开发包(DDK),用来开发Windows驱动程序。
*Windows环境下的最佳编程语言就是C/C++语言,因为Windows API函数本身就是用C语言编写的,C和C++调用C语言的API函数是直接引用,而其他语言则多一道转换。C/C++编程可以很方便地利用计算机的底层资源,其程序运行速度远远高于其他语言。
[b]二、MFC编程[/b]【2】
Visual C++的微软基础类库(Microsoft Foundation Class Library,MFC)封装了大部分API函数,并提供一个应用程序框架,简化了和标准化了Windows程序设计,所以用MFC编写的Windows应用程序也称为标准Windows程序设计。MFC约有200个类,提供了Windows应用程序框架和创建应用程序的组件。其中只有5个核心类对应用程序框架有影响:CWinApp,CDocument,CView,CFrameWnd和CDocTemplate。这5个类之中只有CWinApp是必不可少的类,CWinApp的对象在应用程序中必须且只能有一个,并且是一个全局对象,它建立了应用程序执行的主线程。全局对象是在Windows操作系统调用WinMain()之前建立的,它建立了程序的主线程。形象地说,它开通了程序执行的道路。
在MFC编程中,入口函数WinMain()被封装在MFC的应用程序框架内,称为AfxWinMain(),已经不用也不可以再定义另一个WinMain()函数。
MFC编程最好的办法是使用MFC的应用程序向导AppWizard。
[b]1、MFC基础类及其层次结构[/b]
MFC类库的开发者是微软应用程序框架(Application Framework)开发小组(AFX,成立于1989年)。MFC类库的开发经历了一个曲折的过程,从最初的纯粹面向对象的理想模式,转而追求实用性,通过用类封装Windows API和Windows对象,并按照API的方式进行工作,从而建立起一个切实可行的类库,使得用户可以方便地调用API函数直接完成某些任务。
通过这种MFC和Windows很好的连接,使Windows下的C语言程序设计,成为面向对象的MFC。这里没有追求纯粹,而是包容和实用!MFC采用单一继承,从根类Cobject层层派生出绝大多数MFC中的类,其层次结构是最典型的。如下图示,该图表示一个分类的层次结构,并不严格对应派生结构。
下图给出了Cobject主要派生类的派生层次:
Cobject根类派生的最重要的类组成一个应用程序结构(Application Architecture)的集合,它是由CCmdTarget为基类派生出来的,其中主要部分如下图所示:
[b]2、MFC定义的宏、全局函数及全局变量[/b]
MFC和Windows程序一样,使用大量的宏,宏不带任何前缀,全由大写字母表示。
(1)MFC提供的主要宏:
• 消息映射宏: 声明消息映射表 (将于3.2.2节介绍)宏DECLARE_MESSAGE_MAP、定义消息映射表宏BEGIN_MESSAGE_MAP和END_MESSAGE_MAP对、消息映射表入口宏ON_加消息名。MFC程序处理消息非常轻松,得益于其庞大的消息宏系统,使程序设计人员从记忆大量的消息参数中解脱出来。
• 动态 MFC对象宏: DECLARE_DYNCREATE和DECLARE_DYNAMIC, IMPLEMENT_DYNCREATE和IMPLEMENT_DYNAMIC
• 运行时类宏: RUNTIME_CLASS
• 序列化宏: DECLARE_SERIAL和IMPLEMENT_SERIAL
• 诊断服务宏: ASSERT、VERIFY
• 跟踪服务宏: TRACE
• 异常处理宏: THROW
(2)全局函数
MFC提供一些不属于任何类的全局函数,函数名以Afx开头,可以被应用程序中的所有类和函数所调用。如AfxAbort,无条件终止一个应用程序的执行;AfxGetAppName,返回指向应用程序名的字符串指针;AfxWinInit由WinMain调用,对MFC应用程序进行图形用户界面(GUI)的初始化等等。
(3)全局变量
全局变量名以 afx开头,如afxTraceFlag、afxDump等,主要与异常处理有关。
[b]3、MFC对象和Windows对象的关系[/b]
MFC对象是C++对象,而且是特指封装了Windows对象的C++对象,不是任意的C++对象。下图以最典型的窗口类(CWnd)为例,介绍CWnd类对象与Windows窗口对象的关系:
MFC的窗口对象wnd是C++类的实例,即CWnd类或其派生类的实例,是由CWnd类或其派生类的构造函数创建的,最终由CWnd类或其派生类的析构函数撤消。hwnd是HWND句柄类型的实例,为它建立了一个Windows操作系统的对象。然后把这个句柄放入CWnd类对象wnd的成员数据m_hwnd中。这样wnd就包含了一个Windows操作系统的窗口对象。程序段如下:
CWnd wnd;//定义窗口类(CWnd)的对象wnd
HWND hwnd;//定义窗口句柄hwnd
hwnd=CreateWindow(......);//调用API函数CreateWindow(...)建立一个Windows窗口类实例
wnd.Attach(hwd);//把Windows窗口实例的句柄链到CWnd对象hwnd上
......
DestroyWindow(hwnd);//调用API函数撤消Windows窗口
MFC封装了Windows的几乎所有的API函数,所以上面的API函数,可以用CWnd的成员函数代替。成员函数Create()可以代替API函数CreateWindows()并加上另一个成员函数Attach()的全部功能,建立一个Windows操作系统的窗口对象,并把句柄自动保存在MFC窗口对象wnd的m_hwnd成员数据中。通常MFC程序员不需要通过Windows窗口对象的句柄去使用win32API函数,而只需直接使用CWnd的成员函数。
其它的MFC对象和对应Windows对象也有类似的关系。见下表:
项目MFC类对象句柄应用程序
CWinApp
HINSTANCE m_hInstance
窗口
CWnd
HWND m_hWnd
菜单
CMenu
HMENU m_hMenu
设备环境
CDC
HDC m_hDC
矩形区域
CRgn
HRGN m_hRgn
画刷
CBrush
HBRUSH m_hBrush
画笔
CPen
HPEN m_hPen
字体
CFont
HFONT m_hFont
位图
CBitmap
HBITMAP m_hBitmap
调色板
CPalatte
HPALATTE m_hPalatte
Windows窗口句柄通常是全局量,动态建立的Windows窗口对象也是全局变量。所以一个进程或线程可以取得另一个进程或线程的窗口句柄,并给它发送消息。但一个线程只能使用本线程创建的MFC窗口对象,不能使用其它线程创建的MFC窗口对象。
注意:
(1) Windows对象是Windows操作系统的一个内部数据结构的实例,由一个Windows系统全局的窗口句柄来唯一标志,由API函数CreatWindow()创建,而由DestroyWindow()撤消。
(2) 在MFC编程中,通常在MFC对象建立以后,调用Create()成员函数建立Windows对象,并链接在MFC对象上。下面的程序段用来建立应用程序的主框架窗口。
CFrameWnd *pFrame=new CFrameWnd; //动态建立框架窗口对象
pFrame->Create(NULL,”Ex2_xx”,ws_OVERLAPPENDWINDOW,rect,NULL,
MAKEINTRESOURCE(IDR_MENUI),0,NULL);
//建立与pFrame指向的动态框架窗口对象相连的Windows框架窗口
[b]三、使用向导工具创建MFC文档应用程序的基本文件[/b]
使用Microsoft Visual Studio C++6.0开发工具,创建MFC多文档应用程序的步骤如下:
1、创建基于MFC的工程文件:
2、选择创建多文档应用程序:
3、因为本文只是要分析和使用MFC基本程序文件,所以保持工具向导的默认设置,点击Next,一直到下图所示,点击Finish结束基本应用程序的自动创建: