深入理解MFC中的GDI对象CPen:绘制直线与矩形

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在Windows编程中,MFC提供了一个用于图形绘制的框架,其中GDI对象包括画笔CPen、画刷CBrush和字体CFont等。本文将详细介绍如何在MFC应用程序中使用CPen类来绘制直线和矩形,包括处理鼠标消息以实现交互式绘图,并实时显示鼠标位置。
CPen

1. MFC框架与GDI对象

MFC(Microsoft Foundation Classes)是微软提供的一个C++类库,它封装了Windows API,极大地简化了Windows应用程序的开发。MFC框架提供了一个文档-视图结构,这使得应用程序能够容易地处理图形用户界面(GUI)和文档数据。了解MFC框架的结构和工作原理是开发高效、稳定Windows应用程序的基础。

在图形界面的编程中,GDI(Graphics Device Interface)对象扮演了至关重要的角色。GDI是一个抽象的图形设备接口,它允许应用程序在不同的显示设备上执行绘图操作。在MFC中,GDI对象如画笔(CPen)、画刷(CBrush)、字体(CFont)和位图(CBitmap)等,都是用来进行图形绘制的基础工具。

理解MFC框架与GDI对象之间的关系是实现高质量图形界面的关键。GDI对象在MFC框架中通过特定的类进行封装和管理,使得开发者可以更加直观和方便地使用这些图形对象。在接下来的章节中,我们将深入探讨CPen类的具体应用,以及如何在MFC应用程序中有效地创建和配置GDI对象,实现各种图形绘制任务。

2. CPen类介绍及其在图形绘制中的作用

2.1 CPen类基础概念解析

2.1.1 CPen类的定义和结构

CPen 是MFC(Microsoft Foundation Classes)库中一个封装了GDI(Graphics Device Interface)中Pen对象的类。在图形应用程序中, CPen 被用来定义绘图时线条的颜色、宽度和样式。 CPen 对象常被用在 CDC (设备上下文)类中,以执行线条绘制等操作。

CPen 类继承自 CGdiObject ,这个类是所有GDI对象的基类。 CPen 对象可以在 CWind 类的 CreatePen CreatePenIndirect 等方法中创建。

下面是一个简单的 CPen 对象的创建示例:

CPen pen;
pen.CreatePen(PS_SOLID, 2, RGB(255, 0, 0)); // 创建一个实线,宽度为2的红色画笔

创建 CPen 对象时,至少需要指定三种参数:线型( PS_SOLID 表示实线)、宽度以及颜色( RGB(255, 0, 0) 表示红色)。线型还包括了点线、虚线等多种类型。

2.1.2 GDI对象与CPen类的关系

GDI对象是一类封装了与设备相关的图形对象的类,这些对象包括画笔、字体、位图、调色板等。在MFC中, CGdiObject 是所有GDI对象的基类。 CPen 就是 CGdiObject 的一个具体实现,它封装了GDI中的Pen对象的所有功能。

GDI对象在创建后,需要被选入一个设备上下文中,才能够被使用。在MFC中, CDC 类代表了一个设备上下文,用于封装与设备相关的绘图操作。比如,当使用 CDC::SelectObject 方法将一个 CPen 对象选入 CDC 对象后,就可以使用该 CDC 对象进行绘图操作了。

2.2 CPen在绘制中的功能

2.2.1 实现图形边框的颜色和样式

CPen 类的主要功能是在图形绘制中设置线条的颜色和样式。这些线条可以是图形的边框,也可以是线条本身。使用 CPen 对象,开发者能够指定线条的颜色,样式(例如实线、虚线、点划线等),以及线条的宽度。

如下示例展示了如何使用 CPen 来绘制不同样式的线条:

CPen penSolid, penDash, penDot;
penSolid.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));   // 黑色实线
penDash.CreatePen(PS_DASH, 1, RGB(0, 255, 0));   // 绿色虚线
penDot.CreatePen(PS_DOT, 1, RGB(255, 0, 0));     // 红色点线

// 在CDC对象中使用CPen
pDC->SelectObject(&penSolid);
pDC->MoveTo(10, 10);
pDC->LineTo(100, 10);

pDC->SelectObject(&penDash);
pDC->MoveTo(10, 30);
pDC->LineTo(100, 30);

pDC->SelectObject(&penDot);
pDC->MoveTo(10, 50);
pDC->LineTo(100, 50);

// 清理
penSolid.DeleteObject();
penDash.DeleteObject();
penDot.DeleteObject();

2.2.2 理解不同笔触对图形的影响

笔触即画笔的样式和属性,在图形绘制中,不同的笔触会产生不同的视觉效果。 CPen 类支持多种笔触,包括但不限于 PS_SOLID (实线)、 PS_DASH (虚线)、 PS_DOT (点线)、 PS_DASHDOT (点划线)等。

不同的笔触在视觉上的差异主要体现在线条的连续性和重复模式上。例如:

  • 实线笔触用于绘制不中断的线条,是默认的笔触样式。
  • 虚线笔触适用于需要在图形中表达某种“间隔”或“断开”效果。
  • 点线笔触则常用于绘制有明显的点状分割的线条,例如“快速绘制”或“地图上的路径”。
  • 点划线笔触用于需要同时表达点和线的图形效果。

这些笔触的不同,会对图形的外观和表达意图产生重要影响,选择合适的笔触可以增强图形的表达力。

接下来,我们将探讨如何在实际的MFC应用中创建和配置 CPen 对象,以及如何管理和优化 CPen 对象,以便在不同的场景中充分利用其功能。

3. 在MFC应用中实现CPen对象的创建与配置

3.1 创建CPen对象的方法和步骤

3.1.1 构造函数的使用和参数解析

在MFC(Microsoft Foundation Classes)应用程序中,创建和使用GDI(Graphics Device Interface)对象是进行图形绘制的基础。其中, CPen 类是用于创建画笔(Pen)对象的关键类,它是GDI资源的一种,用于定义绘图中的线条颜色、宽度和样式。在构造一个 CPen 对象时,通常需要指定其样式、宽度以及颜色,这些参数共同决定了绘制图形的外观。

下面是一个典型的 CPen 构造函数调用示例:

CPen pen(PS_SOLID, width, color);

在此代码中:

  • PS_SOLID 代表画笔的样式,它可以是以下几种预定义样式之一:

    • PS_SOLID :实线
    • PS_DASH :虚线
    • PS_DOT :点状线
    • PS_DASHDOT :点划线
    • PS_DASHDOTDOT :双点划线
    • 其他样式可以通过组合 PS_ENDCAP_round PS_ENDCAP_flat PS_ENDCAP_square PSジョイン_round PSジョイン_flat PSジョイン_miter 来创建自定义样式。
  • width 表示画笔的宽度,单位为像素。

  • color 是一个 COLORREF 类型,表示颜色值。 COLORREF 值是一个32位无符号整数,其中最高的8位是红色分量,中间8位是绿色分量,最低的8位是蓝色分量。

3.1.2 配置画笔属性的常用函数

一旦创建了 CPen 对象,接下来就需要对画笔的属性进行配置,以便在绘图时应用。以下是一些常用的 CPen 成员函数,用于配置和管理画笔属性:

  • CreatePen :创建一个 CPen 对象,并指定样式、宽度和颜色。
  • CreatePenIndirect :根据 LOGPEN 结构体的定义,创建一个 CPen 对象。
  • SelectObject :将 CPen 对象选入一个设备上下文(CDC)对象中,以便在该DC上使用该画笔进行绘图。
CPen newPen;
newPen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));  // 创建新的红色实线画笔
CClientDC dc(this);  // 创建一个设备上下文DC对象
CFont* pOldFont = dc.SelectObject(&newPen);  // 将新画笔选入DC中
// 在这里进行绘图操作
dc.SelectObject(pOldFont);  // 完成绘图后,将原画笔重新选入DC中

在这里, RGB(255, 0, 0) 表示红色。 CClientDC 类是从 CDC 派生而来,提供了窗口客户区的设备上下文,通常用于绘图操作。

以上代码示例展示了如何在MFC应用中创建和使用一个红色的实线画笔对象。在MFC中,为了管理资源,通常会在绘制完成后将原先的GDI对象重新选入DC中。

3.2 CPen对象的管理与优化

3.2.1 画笔对象的资源管理技巧

在使用 CPen 对象进行绘图时,必须注意GDI资源的管理,以避免资源泄漏和性能下降。良好的资源管理可以通过以下步骤实现:

  1. 资源的初始化和分配 :在需要用到 CPen 对象时,确保正确初始化并分配资源。
  2. 资源的使用 :通过 CDC::SelectObject 方法将 CPen 对象选入设备上下文中。
  3. 资源的恢复 :在绘图操作完成后,使用 CDC::SelectObject 将原始的GDI对象重新选回设备上下文,这一步很关键,因为它可以释放掉 CPen 对象占用的资源。
  4. 资源的删除 :当画笔不再被使用时,调用 CPen::DeleteObject 方法释放GDI资源。在MFC中,通常通过重载 CObject 的析构函数来实现这一点。
CPen* pOldPen = dc.SelectObject(&newPen);  // 选入新画笔
// 执行绘图操作...
dc.SelectObject(pOldPen);  // 恢复旧画笔,释放新画笔资源
newPen.DeleteObject();  // 删除GDI对象

3.2.2 提升绘图效率的实践方法

绘图效率直接影响到用户界面的响应性。为了提升绘图效率,可以遵循以下几点最佳实践:

  1. 避免在高频调用的绘图函数中创建和删除GDI对象 。频繁创建和销毁GDI对象会导致资源开销,降低绘图性能。应尽量重用现有的GDI对象。
  2. 使用内存设备上下文( CMemoryDC )进行离屏绘制 。在内存中进行绘图可以减少对屏幕的重绘次数,特别是在进行复杂绘图操作时,可以显著提升性能。

  3. 使用双缓冲技术 。双缓冲技术通过先在内存中绘制好整个画面,再将其一次性拷贝到屏幕上,可以有效减少屏幕闪烁和重绘次数。

  4. 减少不必要的绘图操作 。例如,可以通过检测鼠标移动事件的速度或距离来决定是否重新绘制,这样可以避免在用户快速移动鼠标时进行频繁的重绘操作。

  5. 利用GDI+进行复杂图形处理 。如果MFC的GDI功能无法满足需求,可以考虑使用更为强大的GDI+库进行图形处理,虽然GDI+的使用超出了本章节的范围,但理解GDI与GDI+之间的关系和性能差异对提高绘图性能也是有益的。

通过这些方法,不仅可以提升程序的绘图效率,还可以优化用户的体验。需要注意的是,在实际应用中,应结合具体场景和需求灵活选择合适的优化策略。

4. 处理WM_MOUSEMOVE消息以绘制直线和矩形

4.1 WM_MOUSEMOVE消息的响应机制

4.1.1 鼠标消息在MFC中的处理流程

在MFC(Microsoft Foundation Classes)框架中,鼠标消息是通过消息映射机制来处理的。应用程序通过声明消息映射宏来指定消息处理函数。对于鼠标移动事件,最常见的消息是 WM_MOUSEMOVE 。当用户在窗口中移动鼠标时,这个消息会被发送到窗口的消息队列中。

处理鼠标消息的第一步是重载窗口类中的消息处理函数,例如 OnMouseMove ,并使用消息映射宏将其与 WM_MOUSEMOVE 消息关联。例如:

BEGIN_MESSAGE_MAP(CYourClass, CWnd)
    ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

然后实现 OnMouseMove 函数来响应鼠标移动事件:

void CYourClass::OnMouseMove(UINT nFlags, CPoint point)
{
    // 处理鼠标移动事件
}

在这个函数中, nFlags 参数提供了有关鼠标按钮状态的信息,而 point 参数给出了鼠标光标的当前位置。

4.1.2 如何捕捉和处理WM_MOUSEMOVE消息

捕捉和处理 WM_MOUSEMOVE 消息的关键在于正确地在消息映射中关联鼠标消息和处理函数,并在处理函数中实现逻辑。为了捕捉并处理 WM_MOUSEMOVE 消息,你需要执行以下步骤:

  1. 声明消息映射宏 在类的声明中,确保使用 BEGIN_MESSAGE_MAP END_MESSAGE_MAP 宏,并通过 ON_WM_MOUSEMOVE() 来关联 WM_MOUSEMOVE 消息和对应的处理函数。

  2. 实现消息处理函数 在类的实现文件中,编写 OnMouseMove 函数的定义。在这个函数中,你可以获取鼠标位置,并根据需求进行绘图或其他操作。

cpp void CYourClass::OnMouseMove(UINT nFlags, CPoint point) { // 调用基类处理函数 CWnd::OnMouseMove(nFlags, point); // 获取绘图设备上下文 CDC* pDC = GetDC(); // 使用CPen和CDC对象进行绘制操作 // ... // 释放设备上下文 ReleaseDC(pDC); }

  1. 执行绘图操作 OnMouseMove 函数中,根据应用程序的需求,你可以进行诸如更新图形界面、记录鼠标位置、计算绘制图形等操作。通常,这会涉及到获取设备上下文( CDC 对象)以及调用绘图相关的函数。

cpp // 使用CDC对象绘制线条 pDC->MoveTo(prevPoint); // 移动到前一个点 pDC->LineTo(point); // 从前一个点绘制到当前位置

在这里, prevPoint 应该记录了上一次鼠标位置,以便于画线操作。

  1. 保存当前鼠标位置 在处理函数中,更新一个变量来保存当前鼠标位置,以便于下一次鼠标移动时使用。

4.2 利用CPen绘制图形

4.2.1 在WM_MOUSEMOVE中绘制直线

OnMouseMove 函数中,你可以使用 CPen 类来绘制直线。以下是使用 CPen 绘制直线的步骤:

  1. 创建一个 CPen 对象,设置所需的样式、宽度和颜色。
  2. 获取设备上下文( CDC )。
  3. 选择 CPen 对象到设备上下文中。
  4. 使用 MoveTo LineTo 函数绘制线条。
  5. 在绘制完成后,从设备上下文中删除 CPen 对象。
void CYourClass::OnMouseMove(UINT nFlags, CPoint point)
{
    CDC* pDC = GetDC();
    // 定义一个CPen对象
    CPen pen(PS_SOLID, 1, RGB(0, 0, 255));
    // 选择CPen到DC
    CPen* pOldPen = pDC->SelectObject(&pen);
    // 绘制线条
    pDC->MoveTo(prevPoint); // 移动到前一个点
    pDC->LineTo(point);     // 从前一个点绘制到当前位置
    // 恢复旧的CPen
    pDC->SelectObject(pOldPen);
    // 保存当前鼠标位置
    prevPoint = point;
    // 释放设备上下文
    ReleaseDC(pDC);
}

4.2.2 利用CPen绘制矩形及其他图形

除了直线, CPen 类也可以用于绘制矩形和其他闭合图形的边框。在 OnMouseMove 函数中,你可以修改代码以绘制矩形,通过在四个角落绘制直线,形成矩形的边框。

void CYourClass::OnMouseMove(UINT nFlags, CPoint point)
{
    CDC* pDC = GetDC();
    // 选择或创建CPen对象
    CPen pen(PS_SOLID, 1, RGB(0, 255, 0));
    CPen* pOldPen = pDC->SelectObject(&pen);
    // 定义矩形的左上角和右下角点
    CRect rect(prevPoint, point);
    // 绘制矩形的边框
    pDC->Rectangle(rect);
    // 恢复旧的CPen
    pDC->SelectObject(pOldPen);
    // 更新记录的点位置
    prevPoint = point;
    ReleaseDC(pDC);
}

在上述代码中, Rectangle 函数使用当前选中的 CPen 来绘制矩形。当你移动鼠标时,每次调用 OnMouseMove 都会在鼠标当前位置绘制一个矩形。通过这种方式,你可以使用 CPen 来绘制各种图形,不仅限于直线和矩形。通过调整 Rectangle 函数中的逻辑,你还可以绘制椭圆、多边形等。

CPen 类在MFC中提供了灵活的方式来绘制各种图形的边框。通过使用 CPen ,你可以控制线条的样式、宽度和颜色,以此来创建复杂的图形界面。记住,当使用完 CPen 后,应该确保将其从设备上下文中恢复,以避免内存泄漏和其他潜在问题。在实际应用程序中,对于更复杂的图形绘制需求,可能还会涉及 CBrush 和其他GDI对象来填充图形区域,但是 CPen 为图形的外轮廓提供了基础。

5. 实现鼠标交互式绘制的基本步骤

5.1 鼠标交互式绘制的设计思路

5.1.1 交互式绘制的流程与框架

在MFC(Microsoft Foundation Classes)中,实现鼠标交互式绘制涉及到对鼠标事件的监听和响应。设计思路的首要步骤是构建一个合理的交互流程与框架,它应该包括:

  1. 初始化阶段 :创建绘图视图类并初始化绘图所需的GDI对象,如画笔(CPen)、画刷(CBrush)等。
  2. 事件捕获 :通过 OnMouseMove OnLButtonDown OnLButtonUp 等消息映射函数捕获用户的鼠标操作事件。
  3. 绘制反馈 :根据用户在视图上的操作实时绘制反馈,如绘制线条、图形等。
  4. 状态管理 :跟踪鼠标状态和绘制状态,如是否正在绘制、是否移动鼠标等。
  5. 撤销和重做机制 :实现基本的编辑功能,允许用户撤销上一步操作或重做被撤销的操作。

5.1.2 鼠标事件在绘制中的应用

鼠标事件是与用户直接交互的重要手段。在交互式绘制中,主要使用以下鼠标事件:

  1. OnLButtonDown :左键按下时触发,通常是绘图的开始点。
  2. OnMouseMove :鼠标移动时触发,可实时捕捉鼠标位置,根据位置绘制图形。
  3. OnLButtonUp :左键释放时触发,标志着绘制操作的结束。
  4. OnRButtonDown :右键按下时触发,可以用于调出上下文菜单等操作。

在绘制过程中,这些事件之间相互配合,共同完成用户界面的绘制任务。 OnMouseMove 事件尤为关键,它不仅用于绘制,还能实时更新鼠标坐标显示,增加交互的直观性和用户体验。

5.2 交互式绘制的实践操作

5.2.1 实现基本的鼠标拖动绘制

实现鼠标拖动绘制时,需要跟踪鼠标拖动事件,并在视图上进行相应的绘制。以下是一个简化的MFC视图类中实现线条绘制的示例代码:

void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
    m_pointOld = point;  // 捕获初始点
    m_bIsDrawing = true; // 标记开始绘制
    m_lineToDraw.AddPoint(point); // 添加初始点到绘图数组
    CView::OnLButtonDown(nFlags, point);
}

void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
    if (m_bIsDrawing)
    {
        m_pointNew = point; // 更新新点
        m_lineToDraw.AddPoint(point); // 添加新点到绘图数组
        Invalidate(); // 重绘视图
    }
    CView::OnMouseMove(nFlags, point);
}

void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
    m_bIsDrawing = false; // 标记结束绘制
    CView::OnLButtonUp(nFlags, point);
}

void CMyView::OnDraw(CDC* pDC)
{
    CRect rect;
    GetClientRect(&rect); // 获取绘图区域

    CPen pen(PS_SOLID, 2, RGB(0, 0, 0)); // 创建黑色画笔,宽2像素
    CPen* pOldPen = pDC->SelectObject(&pen); // 选择画笔对象

    pDC->MoveTo(m_pointOld); // 移动到旧点
    pDC->LineTo(m_pointNew); // 从旧点画线到新点

    pDC->SelectObject(pOldPen); // 恢复旧画笔
}

5.2.2 优化用户体验的交互式绘制技巧

为了提升用户体验,可以考虑以下技巧:

  1. 平滑绘制 :添加算法对鼠标移动的点进行平滑处理,避免绘制的线条过于“锯齿”。
  2. 撤销与重做 :实现一个撤销栈( CUndoStack )和重做栈,以便用户撤销和重做绘制动作。
  3. 橡皮擦功能 :实现一个橡皮擦工具,让用户能够擦除已绘制的线条或图形。
  4. 多工具支持 :提供不同类型的绘图工具,如铅笔、毛笔、不同粗细的线条等。
  5. 颜色和画笔选择器 :让用户能够选择不同的颜色和画笔样式进行绘制。

通过这些交互式绘制的实践操作和优化技巧,可以显著提升用户的绘图体验,并使得应用更加灵活和实用。

6. 在OnMouseMove函数中更新鼠标坐标显示

6.1 OnMouseMove函数的作用与实现

6.1.1 OnMouseMove函数的定义和作用

在MFC(Microsoft Foundation Classes)应用程序中,OnMouseMove函数是响应WM_MOUSEMOVE消息的主要函数,用于获取鼠标移动事件并作出相应处理。每当鼠标在窗口客户区移动时,系统都会发送WM_MOUSEMOVE消息,然后由OnMouseMove函数接收并处理此消息,从而允许我们跟踪鼠标位置并作出相应的绘制或处理。

6.1.2 显示鼠标坐标的实现方法

要实时显示鼠标坐标,我们可以在OnMouseMove函数中更新一个CStatic控件或直接在客户区绘制坐标文本。以下是使用CStatic控件显示鼠标坐标的步骤:

  1. 创建一个CStatic控件,并为其关联一个变量。
  2. 在OnMouseMove函数中,获取当前鼠标位置。
  3. 将获取到的坐标格式化为字符串。
  4. 更新CStatic控件显示的文本为坐标字符串。
void CYourView::OnMouseMove(UINT nFlags, CPoint point)
{
    // CView::OnMouseMove(nFlags, point);
    CPaintDC dc(this); // device context for painting

    // Convert screen coordinates to client coordinates
    CRect rect;
    GetClientRect(&rect);
    point.x -= rect.left;
    point.y -= rect.top;

    // Format and set the coordinates
    CString str;
    str.Format(_T("X: %d, Y: %d"), point.x, point.y);
    m_MyStatic.SetWindowText(str); // Assuming m_MyStatic is the associated CStatic variable

    CDocument* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add your specialized code here and call CView::OnMouseMove
}

6.2 鼠标坐标与图形绘制的关联

6.2.1 鼠标坐标数据的实时获取

在OnMouseMove函数中,我们可以利用CPoint参数 point 获取实时的鼠标坐标。这个坐标是相对于窗口客户区的坐标系统,如果我们需要屏幕坐标或其他形式的坐标,可以通过相应的转换函数进行转换。例如, ScreenToClient 函数可以将屏幕坐标转换为客户区坐标。

6.2.2 坐标数据在图形绘制中的应用实例

使用鼠标坐标数据可以增强用户交互体验,如允许用户在应用程序中直接绘图。下面是如何使用OnMouseMove函数结合CPen对象绘制线条的示例:

void CYourView::OnMouseMove(UINT nFlags, CPoint point)
{
    // ... (前面的鼠标坐标获取和更新控件的代码)

    // Draw a line using the current CPen object starting from the last point to the current point
    CPen* pOldPen = (CPen*)dc.SelectObject(&m_yourPen); // your CPen object
    dc.MoveTo(m_lastPoint); // m_lastPoint is the last mouse position
    dc.LineTo(point);
    dc.SelectObject(pOldPen); // Restore the old pen to the device context
}

上面的代码展示了如何根据鼠标移动实时绘制线条。 m_lastPoint 存储了上一次鼠标的位置,而 point 是当前鼠标的位置。通过调用CDC对象的 MoveTo LineTo 方法,我们可以绘制从上一个点到当前点的线条。注意,在绘制完成后,我们使用 SelectObject 方法将旧的画笔对象恢复到设备上下文中,以避免内存泄漏。

通过这种方式,用户可以利用鼠标实时地绘制图形,并且在界面上实时地看到鼠标坐标的变化。这不仅提高了应用程序的交互性,也使得绘制过程更加直观。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:在Windows编程中,MFC提供了一个用于图形绘制的框架,其中GDI对象包括画笔CPen、画刷CBrush和字体CFont等。本文将详细介绍如何在MFC应用程序中使用CPen类来绘制直线和矩形,包括处理鼠标消息以实现交互式绘图,并实时显示鼠标位置。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值