用MFC编程时在源文件里经常看到的AFX或afx是什么意思?

AFX最初指代Application Framework,是微软为简化Windows编程而创建的应用程序框架。随着发展,AFX演变成MFC的一部分,许多全局函数和宏仍保留AFX前缀。本文探讨了AFX的起源及其与MFC的关系。
      AFX是MFC小组早期的代号,AFX,当时是指 applecation freamwork ,如果你的程序用到了MFC,那这个头文件是一定要包含的。
      Microsoft的程序员开始试图将C++和面向对象的编程概念应用于Windows编程中,经编写出一个可以使windows编程工作更加简便的应用程序框架。他们把这个应用程序框架叫做AFX(AFX这个词来源于Application FrameWork,但奇怪的是这个词组中并没有包含"X"这个字母,X含意现在已经不可考究了,有人说只是为了好听。直到今天,AFX小组早已不存在了,AFX这个名称也于1994年初不再使用,但在Visual C++和MFC中,AFX的影子却随处可见,很多全局函数、结构和宏的标识符都被加上了AFX的前缀。

    历史:

         在九十年代初的时候OO被炒得很热,许多人以为OO是无所不能的。微软也这么认为,所以他们想搞出一套类库来封装全部的OS特性。使得程序可以在WINDOWS OS/2 X等等任何的GUI系统上运行。结果可想而知,这个东西当然是没做出来。到94年微软放弃AFX。把AFX中已经完工的部分做了一点改进形成了MFC,至今MFC还有LINUX版本,也算是AFX计划的一点残留吧。

所以现在,AFX的意思是:表示MFC类库中的宏和全局函数、变量

<think>我们正在讨论MFC中的OnNcPaint函数。根据用户的问题,我们需要解释OnNcPaint函数的作用和使用方法。首先,OnNcPaint是MFC框架中的一个成员函数,用于绘制窗口的非客户区(non-client area)。非客户区包括窗口的边框、标题栏、菜单栏、滚动条等,而客户区(client area)则是窗口中除非客户区以外的部分,通常由OnPaint函数处理。作用: OnNcPaint函数的主要作用是绘制窗口的非客户区。当非客户区需要重绘(例如窗口大小改变、窗口被移动等),系统会发送WM_NCPAINT消息,而OnNcPaint就是该消息的处理函数。使用方法:1.通常,我们可以重写OnNcPaint函数来自定义非客户区的绘制。例如,我们可能想要自定义窗口的边框、标题栏等。2.在重写OnNcPaint,我们首先需要获取窗口的设备上下文(DC),然后使用绘图工具进行绘制。3.注意:在绘制非客户区,我们通常使用CWindowDC,因为它可以在整个窗口(包括非客户区)上绘制。示例代码:假设我们有一个继承自CFrameWnd(其他窗口类)的类CMyFrame,我们想要重绘非客户区。步骤: a.在类的头文件中声明消息映射和OnNcPaint函数。b.在消息映射中添加ON_WM_NCPAINT()。c.实现OnNcPaint函数。示例:在头文件中:class CMyFrame: publicCFrameWnd{...protected:afx_msgvoid OnNcPaint();DECLARE_MESSAGE_MAP() };在源文件中: BEGIN_MESSAGE_MAP(CMyFrame,CFrameWnd)ON_WM_NCPAINT() END_MESSAGE_MAP() voidCMyFrame::OnNcPaint() {//默认实现(如果需要保留默认绘制,可以调用基类的OnNcPaint)// CFrameWnd::OnNcPaint();//者自定义绘制CWindowDCdc(this); //获取整个窗口的DC//获取非客户区矩形CRect rect;GetWindowRect(&rect);rect.OffsetRect(-rect.left, -rect.top); //转换为窗口坐标//绘制非客户区边框dc.Draw3dRect(rect, RGB(255,0,0), RGB(0,0,255)); //红色外框,蓝色内框//注意:如果我们要完全自定义非客户区,可能需要处理更多细节,比如标题栏、按钮等。//另外,如果我们不调用基类的OnNcPaint,那么默认的非客户区绘制将被覆盖。}注意:在自定义非客户区绘制,可能需要处理其他非客户区消息(如WM_NCCALCSIZE、WM_NCHITTEST等)以确保窗口行为正确。此外,根据引用[1]中提到的内容,有在自定义按钮等控件可能会用到非客户区绘制,但该引用主要讨论的是使用PNG图片的问题,与OnNcPaint没有直接关系。不过,我们可以参考类似的思路,即在非客户区绘制中使用透明效果,但OnNcPaint本身并不直接支持PNG,需要我们自己处理。另外,引用[2][3][4][5]主要介绍了一些开源项目,这些项目可能包含自定义窗口绘制的例子,但用户的问题集中在OnNcPaint函数上,因此我们主要关注该函数的用法。最后,我们需要提醒用户,自定义非客户区绘制可能会涉及复杂的细节,比如系统按钮(最小化、最大化、关闭)的位置和绘制,以及窗口的拖拽等。因此,在重写OnNcPaint,需要谨慎处理。现在,生成相关问题:1.如何自定义MFC窗口的标题栏?2. OnNcPaint与OnPaint有什么区别?3.在MFC中如何处理非客户区的鼠标消息?4.如何使MFC窗口具有透明边框效果?5.在自定义非客户区,如何保留系统菜单和按钮的功能?注意:以上问题都是围绕非客户区绘制和消息处理展开的,与用户当前问题紧密相关。</think>### MFC 中 `OnNcPaint` 函数的作用及使用方法 #### 一、作用 `OnNcPaint` 是 MFC 框架中用于**绘制窗口非客户区(Non-Client Area)** 的虚函数[^1]。非客户区指窗口边框、标题栏、系统菜单(最小化/最大化/关闭按钮)、滚动条等区域(如下图所示): ``` ┌───────────────────────┐ │ 标题栏 (非客户区) │ ├──────────┬────────────┤ │ 系统菜单 │ 客户区内容 │ │ (非客户区)│ (客户区) │ └──────────┴────────────┘ ``` 其核心作用包括: 1. **响应 `WM_NCPAINT` 消息**:当系统检测到非客户区需要重绘(如窗口大小改变、激活状态变化),自动触发此函数。 2. **自定义非客户区外观**:通过重写此函数,可实现标题栏渐变填充、自定义边框、透明效果等高级界面效果[^1][^5]。 3. **兼容系统默认行为**:若不重写,MFC 会调用默认实现绘制标准非客户区。 --- #### 二、使用方法 ##### 步骤 1:声明重写函数 在窗口类头文件中声明: ```cpp class CMyWnd : public CWnd { protected: afx_msg void OnNcPaint(); // 声明重写 DECLARE_MESSAGE_MAP() }; ``` ##### 步骤 2:添加消息映射 在源文件中绑定 `WM_NCPAINT` 消息: ```cpp BEGIN_MESSAGE_MAP(CMyWnd, CWnd) ON_WM_NCPAINT() // 绑定消息 END_MESSAGE_MAP() ``` ##### 步骤 3:实现自定义绘制 ```cpp void CMyWnd::OnNcPaint() { // 1. 获取非客户区设备上下文 CWindowDC dc(this); // 2. 获取非客户区矩形 CRect rcNonClient; GetWindowRect(&rcNonClient); rcNonClient.OffsetRect(-rcNonClient.left, -rcNonClient.top); // 转换为窗口坐标 // 3. 自定义绘制示例:渐变标题栏 TRIVERTEX vertices[2] = { {0, 0, 0xFF00, 0x0000, 0x0000, 0xFF00}, // 左上角 (蓝色) {rcNonClient.Width(), 30, 0x0000, 0x8000, 0x0000, 0xFF00} // 右下角 (绿色) }; GRADIENT_RECT rect = {0, 1}; dc.GradientFill(vertices, 2, &rect, 1, GRADIENT_FILL_RECT_V); // 4. 保留系统按钮(可选) Default(); // 调用默认绘制绘制系统按钮 } ``` ##### 关键注意事项: 1. **使用 `CWindowDC`**: 必须用 `CWindowDC`(而非 `CPaintDC`),因其支持非客户区绘制。 2. **坐标系转换**: `GetWindowRect` 返回屏幕坐标,需通过 `OffsetRect` 转换为窗口坐标。 3. **保留系统控件**: 调用 `Default()` 可保留最小化/最大化/关闭按钮的默认样式。 4. **性能优化**: 复杂绘制建议使用双缓冲,避免闪烁。 --- #### 三、典型应用场景 1. **自定义标题栏样式**(如渐变填充、透明效果)[^1][^5] 2. **实现异形窗口**(通过绘制透明边框) 3. **动态皮肤切换**(如夜间模式切换重绘非客户区) 4. **高亮活动窗口**(改变非激活窗口的边框颜色) ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值