《MFC 学习笔记》 1 —— 窗口
文章目录
一、绪论
官方文档——微软MFC学习文档
- MFC (Microsoft Foundation Classes),微软基础类库,是一个微软公司提供的类库(class libraries),以 C++ 类的形式封装了 Windows 的 API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含大量 Windows 句柄封装类和很多 Windows 的内建控件和组件的封装类。
- MFC 实际上是微软提供的,用于在 C++ 环境下编写应用程序的一个框架和引擎。
- MFC 是 VC++ 的一个辅助软件开发包。
- 特点: 基于应用程序框架之上,使用提供的类库快速开发,提高项目的开发效率,减少开发周期和成本。
- 注意: MFC提供的类绝大部分用来进行界面开发,关联一个窗口的动作,但不只是一个功能单纯的界面开发系统,它提供的类中有好多不与一个窗口关联,而是一些在Windows中实现内部处理的类。
二、窗口
窗口,是屏幕上的一个矩形区域(通常是矩形),应用程序在该区域中显示数据并等待鼠标点击。
1、窗口分类
- 基本类型只有三种:重叠 (Overlapped) 窗口,弹出 (Popup) 窗口和子窗口 (Child)。
- 重叠窗口:通常用于建立应用程序主窗口。事实上,有时也叫做 “主”窗口 或者 “框架”窗口。
- 弹出窗口:通常以对话框和消息框的形式与用户对话。
- 子窗口:通常用在视图 (View) 中,如在文本编辑器中的文本显示,也用在控件中,如在对话框中的 OK 按钮。而对那些看起来像按钮或控件的子窗口,也称为“控件”窗口。子窗口是唯一不能有菜单条的窗口。
- 其他分类:
- 控件窗口
- 对话框
- 消息框
- 工具栏
- 对话条
- 状态栏
- 框架窗口
- 文档/视图
- 文档模板
2、窗口组成
- 每个窗口都有由系统绘制的 “非客户区” 和 由应用程序绘制的 “客户区”。
3、微软API窗口和MFC窗口
- Microsoft Windows 所属的窗口类创建窗口对象,在 API 环境中可以对窗口对象进行直接控制。

Microsoft Windows 所属的窗口类创建的窗口对象
- MFC 窗口是 C++ 和 Windows API 调用的综合。 MFC 库的 CWnd 可以创建一个窗口,但它只是在 API 环境中使用的 API 调用的封装。

应用两个对象创建MFC窗口
4、用 MFC 创建一个窗口
CWnd wnd; // 创建一个 CWnd 类的对象
BOOL b = wnd.CreateEx(
DWORD dwExStyle, //窗口的“外观”和类型 (重叠、弹出、子窗口 )
LPCTSTR lpszClassName, //创建窗口时使用的窗口类
LPCTSTR lpszWindowName, //窗口标题内容
DWORD dwStyle, //窗口的“外观”和类型 (重叠、弹出、子窗口 )
int x, //决定窗口的位置和大小
int y,
int nWidth,
int nHeight,
HWND hwndParent, //拥有该窗口的窗口指针
HMENU nIDorHMenu, //菜单使用的内存对象
LPVOID lpParam = NULL //窗口类使用的指针(非强制)
);
-
dwExStyle
指定了要创建的CWnd的扩展风格。对窗口应用任何扩展的窗口风格。- WM_CHILD 创建一个子窗口
- WM_POPUP 创建一个弹出窗口
- WM_OVERLAPPED 创建一个重叠窗口(默认)
- W S _ V S C R O L L为窗口添加一个垂直滚动条
非客户窗口风格用来增添窗口的特色 -
lpszClassName
指向一个以null结尾的字符串,命名了Windows的窗口类(一个WNDCLASS结构)。类名可以是用全局函数 -
lpszWindowName
指向一个用null结尾的字符串,包含了窗口的名字。 -
dwStyle
指定了窗口风格属性。对可能取值的描述参见“窗口风格”和CWnd::Create。 -
x
指定了CWnd窗口的初始x轴位置。 -
y
指定了CWnd窗口的初始y轴位置。 -
nWidth
指定了CWnd窗口的宽度(设备单位)。 -
nHeight
指定了CWnd窗口的高度(设备单位)。 -
hwndParent
标识了要创建的CWnd窗口的父窗口或拥有者窗口。对顶层窗口,使用NULL。 -
nIDorHMenu
标识了菜单或子窗口的标识符。其含义依赖于窗口的风格。 -
lpParam
指向 CREATESTRUCT 结构的 lpCreateParams 字段所代表的数据。
5、用 MFC 销毁一个窗口
需要在销毁窗口的同时销毁 CWnd 对象,则应该在 CWnd 的派生类中添加下面的重载函数:
CYourWnd::PostNcDestroy( )
{
delete this;
}
6、捆绑到一个已有的窗口
把一个窗口封装到 CWnd 类中:
CWnd wnd;
wnd.Attach (hwnd); // hwnd 是已有窗口的句柄, Attach( )只是把 CWnd 的成员变量 m_hWnd 赋给 hwnd。
7、用MFC创建一个窗口类
7.1 介绍
-
一个窗口类不是一个 C++ 类,而是早于并存在于 C++ 之外的窗口专有的类。窗口类的作用就像一个模板,可以由此创建其他窗口,并可共享某些特征,包括下面所示的特征:
- 类风格 :包括能给予窗口的一些微小的特征。
- 类图标 :如果窗口有图标,用它来指定在窗口的左上角处所画的图标。
- 类菜单 :如果窗口有菜单,用它来指定窗口中显示的菜单。
- 类光标 :当光标通过窗口的客户区时,用它来指定显示哪种鼠标形状。
- 背景色 :定义用什么颜色来擦除窗口的背景色。窗口的客户区将显示该颜色。
- 窗口进程 :定义处理任何发送到该窗口的消息时应该调用的函数。定义窗口进程可能是窗口类唯一最重要的前提。(如果系统要求窗口自己进行绘制,系统给它发送一个 WM_PAINT 消息;如果系统要求窗口销毁自己,则发送一个 WM_DESTROY 消息。)
-
窗口类类型:
- 系统全局类(System Global Class) :在系统启动时注册,且必须注册,对所有应用程序都有效。
- 应用程序全局类(Application Global Class) :由应用程序注册,只对应用程序及应用程序的线程有效。
- 应用程序局部类(Application Local Class) :由应用程序注册,并只对注册它们的应用程序或 DLL有效。
7.2 创建窗口类
-
要创建一个窗口类,可以先创建 WNDCLASS 结构的实例,然后用 MFC 类库的 AfxRegisterClass( ) 注册它
BOOL AFXAPI AfxRegisterClass (WNDCLASS• lpWndClass)
,lpWndClass 为窗口类名字WNDCLASS
:typedef struct_WNDCLASS { UINT style; //类风格 WNDPROC lpfnWndProc; //指向窗口过程的指针。 int cbClsExtra; //窗口类结构之后分配的额外的字节数。系统将该值初始化为0. int cbWndExtra; //窗口实例之后分配的额外的字节数。 HINSTANCE hInstance; //包含该类实例的句柄,该实例包含了窗口过程。 HICON hIcon; //类图标的句柄。该成员必须为一个图标资源的句柄。如果hIcon为NULL,系统将提供默认图标。 HCURSOR hCursor; //鼠标指针的句柄。改成员必须为一个指针资源的句柄。如果hCursor为NULL,应用程序必须在指针移入应用程序窗口时显式设置指针类型。 HBRUSH hbrBackground; //背景画刷的句柄。 LPCTSTR lpszMenuName; //字符串,描述菜单的资源名 LPCTSTR lpszClassName; //字符串,类原型 } WNDCLASS;
-
style
:描述类风格。该成员可以是“Class Styles”的任意组合。
窗口类风格 -
hbrBackground
:背景画刷的句柄。- 也可以不创建画刷对象,而指定下面所列系统颜色之一:
COLOR_ACTIVEBORDER
,COLOR_ACTIVECAPTION
,COLOR_APPWORKSPACE
,COLOR_BACKGROUND
,COLOR_BTNFACE
,COLOR_BTNSHADOW
,COLOR_BTNTEXT
,COLOR_CAPTIONTEXT
,COLOR_GRAYTEXT
,COLOR_HIGHLIGHT
,COLOR_HIGHLIGHTTEXT
,COLOR_INACTIVEBORDER
,COLOR_INACTIVECAPTION
,COLOR_MENU
,COLOR_MENUTEXT
,COLOR_SCROLLBAR
,COLOR_WINDOW
,COLOR_WINDOWFRAME
,COLOR_WINDOWTEXT
- 必须分配颜色到一个画刷句柄类型,并加 1。
- 也可以不创建画刷对象,而指定下面所列系统颜色之一:
-
-
也可以用 MFC 类库的 AfxRegisterWndClass( ) 来创建一个基于调用参数的 WNDCLASS 对象。
LPCTSTR lpszClassName = AfxRegisterWndClass( //窗口类名字 UINT nClassStyle, //窗口类风格 HCURSOR hCursor = 0, //鼠标移经应用程序窗口的客户区时,将要显示的鼠标光标句柄。 HBRUSH hbrBackground = 0, //窗口区域的背景色 HICON hIcon = 0 //显示在窗口左上角的图标的句柄 );
-
nClassStyle
指定 Windows 的类风格或通过 位或(|)操作符生成的风格的组合。举例同上。 -
hCursor
指定了一个鼠标光标资源句柄,将被用于该窗口类所创建的每个窗口。如果你使用缺省值 0,你将得到标准的 IDC_ARROW 光标。 -
hbrBackground
指定了一个刷子资源句柄,将被用于该窗口类所创建的每个窗口。如果你使用缺省值 0,你将获得一个 Null 背景刷子,同时在 WM_ERASEBKGND 进程中,窗口将不会释放其背景。 也可以不创建画刷对象,而指定系统颜色,举例同上。
(HBRUSH) (COLOR_WINDOW+1)
hIcon
指定了一个图标资源句柄,将被用于该窗口类所创建的每个窗口。如果你使用缺省值0,你将得到标准的波浪标志的 Windows 徽标。
-
8、销毁一个MFC窗口类
通过取消窗口类的注册销毁窗口类。但是,如果用 AfxRegisterWnd( ) 或 AfxRegisterWndClass() 注册一个类的话,那么在应用程序结束的时候,类的注册会自动取消,即使应用程序不取消窗口类的注册,操作系统也会取消。
9、桌面窗口
桌面窗口 (Desktop Window),所有其他窗口都显示在它的上面,并最终属于它。桌面窗口自身是一个弹出窗口,并且是最高阶弹出窗口。最高阶窗口列表是由窗口管理器维护的,因此也叫做窗口管理器列表 ( Windows Manager List)。窗口管理器应用该列表维护桌面窗口。

窗口管理器通过使用窗口管理器列表维护桌面窗口