五、MFC视图窗口和文档

一、视图窗口

        提供一个用于显示数据的窗口

1、视图窗口相关类

        CView及其子类,父类为CWnd类,封装了关于视图窗口的各种操作,以及和文档类的数据交互

2、视图窗口的使用

(1)定义了一个自己的视图类(CMyView),派生自CView,并重写父类成员纯虚函数void OnDraw(CDC* pDC),可以用于绘图

(2)其余框架类和应用类程序代码不变

(3)处理框架的WM_CREATE消息时,定义CMyView类对象,并调用Create函数创建视图窗口,视图窗口的ID为 AFX_IDW_PANE_FIRST

3、创建项目(MFCView)

(1)创建项目

(2)编写程序

#include <afxwin.h>
#include "resource.h"

class CMyView:public CView
{
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnDraw(CDC* pDC);
	afx_msg void OnPaint();
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyView, CView)
	//ON_WM_PAINT()
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

//父类处理绘图消息时会调用OnDraw,当本类由绘图消息处理,则OnDraw不会被调用
void CMyView::OnDraw(CDC* pDC)
{
	pDC->TextOut(100, 100, "CMyView::OnDraw");
}
void CMyView::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 200, 200, "CMyView::OnPaint", strlen("CMyView::OnPaint"));
	::EndPaint(m_hWnd, &ps);
}
void CMyView::OnNew()
{
	AfxMessageBox("视图类处理了OnNew消息");
}

class CMyFrameWnd:public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnPaint();
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
{
	CMyView* pView = new CMyView;
	pView->Create(NULL, "MFCView", WS_CHILD|WS_VISIBLE|WS_BORDER, CRect(0, 0, 200, 200), 
				this, AFX_IDW_PANE_FIRST);		//AFX_IDW_PANE_FIRST 生成的视图窗口会平铺在框架窗口
	m_pViewActive = pView;	//将窗口赋值给活动窗口
	return CFrameWnd::OnCreate(pcs);
}

void CMyFrameWnd::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 100, 100, "框架窗口客户区", strlen("框架窗口客户区"));
	::EndPaint(m_hWnd, &ps);
}
void CMyFrameWnd::OnNew()
{
	AfxMessageBox("框架类处理了OnNew消息");
}


class CMyWinApp:public CWinApp
{
	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL InitInstance();
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()
void CMyWinApp::OnNew()
{
	AfxMessageBox("框架类处理了OnNew消息");
}

BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd* pFrame = new CMyFrameWnd;
	pFrame->Create(NULL, "MFCView", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault,NULL,
				(char*)IDR_MENU1);
	m_pMainWnd = pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}

CMyWinApp theApp;

(3)命令消息处理顺序

        视图类 -》 框架类 -》 应用程序类

(4)对象关系图

theApp
    theApp->m_pMainWnd = pFrame
        pFrame->m_pViewActive = pView
        
    

二、文档类

        相关类 CDocument,提供了用于管理数据的类,封装了关于数据的管理(数据提取,数据转换,数据存储等),并和视图类进行数据交互。

1、创建项目

(1)创建项目(MFCDoc)

(2)编写程序

#include <afxwin.h>
#include <afxext.h>
#include "resource.h"

class CMyDoc:public CDocument
{

};

class CMyView:public CView
{
	DECLARE_DYNCREATE(CMyView)
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnDraw(CDC* cDC);
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
};
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
	ON_WM_CREATE()
END_MESSAGE_MAP()

void CMyView::OnDraw(CDC* cDC)
{
	cDC->TextOut(100, 100, "视图窗口");
}
int CMyView::OnCreate(LPCREATESTRUCT pcs)
{
	return CView::OnCreate(pcs);
}

class CMyFrameWnd:public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnPaint();
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
END_MESSAGE_MAP()
int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
{
	return CFrameWnd::OnCreate(pcs);
}
void CMyFrameWnd::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
	::EndPaint(m_hWnd, &ps);
}

class CMyWinApp:public CWinApp
{
public:
	virtual BOOL InitInstance();
};
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd* pFrame = new CMyFrameWnd;
	CCreateContext cct;
	CMyDoc* pDoc = new CMyDoc;
	cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
	cct.m_pCurrentDoc = pDoc;
	pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
	m_pMainWnd = pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}
CMyWinApp theApp;

(3)创建过程

        利用框架类对象地址(pFrame)调用LoadFrame函数,创建框架窗口

        在处理框架窗口的WM_CREATE消息时,(父类CFrameWnd)动态创建视图类对象,并创建视图窗口

        在处理视图窗口的WM_CREATE消息时,(父类CView)将文档类和视图类对象见理关系

2、创建流程

CMyFrameWnd* pFrame = new CMyFrameWnd;
CMyDoc* pDoc = new CMyDoc;

CCreateContext cct;
cct.m_pCurrentDoc = pDoc;//文档类对象地址
cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);//&CMyView::classCMyView

pFrame->LoadFrame(... &cct)//函数内部this为pFrame
{
  Create(...,&cct)//函数内部this为pFrame
  {
    CreateEx(...&cct)//函数内部this为pFrame
    {
      CREATESTRUCT cs;
      ....
      cs.lpCreateParams = &cct;
      ::CreateWindowEx(...,&cct);//创建主框架窗口
    }
  }
}
//处理框架窗口的WM_CREATE消息
CFrameWnd::OnCreate( pcs )//函数内部this为pFrame,参数可以获取::CreateWindowEx的12个参数
{
  CCreateContext* pContext = (CCreateContext*)pcs->lpCreateParams;//获取&cct
  OnCreateHelper(pcs, pContext)//函数内部this为pFrame,pContext===&cct
  {
    OnCreateClient(pcs, pContext)//函数内部this为pFrame,pContext===&cct
    {
      CreateView(pContext..)//函数内部this为pFrame,pContext===&cct
      {
        CWnd* pView = pContext->m_pNewViewClass->CreateObject();
                            //动态创建视图类对象,并返回对象地址
        pView->Create(..,pContext)//函数内部this为pView,pContext===&cct
        {
          CreateEx(..,pContext)//函数内部this为pView,pContext===&cct
          {
            CREATESTRUCT cs;
            ....
            cs.lpCreateParams = pContext;//pContext===&cct
            ::CreateWindowEx(...,pContext);//创建视图窗口         
          }
        }
      }
    }
  }
}

//处理视图窗口的WM_CREATE消息
CView::OnCreate( pcs )//函数内部this为pView,参数可以获取::CreateWindowEx函数的12个参数
{
  CCreateContext* pContext = (CCreateContext*)lpcs->lpCreateParams;//获取&cct
  pContext->m_pCurrentDoc->AddView(pView)//函数内部this为pDoc,参数为视图类对象地址
  {
    m_viewList.AddTail(pView);//文档类对象用一个链表成员变量,保存视图类对象地址
    pView->m_pDocument = this;//视图类对象用一个普通成员变量,保存文档类对象地址
  }
}

3、对象关系

(1)文档类对象用一个链表成员变量,保存视图类对象地址

(2)视图类对象用一个普通成员变量,保存文档类对象地址

        一个文档类对象可以对应多个视图类对象(视图窗口)

        一个视图类对象(视图窗口)只能对应一个文档类对象

4、视图切分

(1)相关类

CSplitterWnd 不规则框架窗口类,分装了关于不规则框架窗口的操作

(2)窗口切分的使用

重写CFrameWnd类的成员虚函数OnCreateClient

        在虚函数中调用CSplitterWnd::CreateStatic创建不规则框架窗口

        在虚函数中调用CSplitterWnd::CreateView创建视图窗口

(3)编写程序

#include <afxwin.h>
#include <afxext.h>
#include "resource.h"

class CMyDoc:public CDocument
{

};

class CMyView:public CView
{
	DECLARE_DYNCREATE(CMyView)
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnDraw(CDC* cDC);
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
};
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
	ON_WM_CREATE()
END_MESSAGE_MAP()

void CMyView::OnDraw(CDC* cDC)
{
	cDC->TextOut(100, 100, "视图窗口");
}
int CMyView::OnCreate(LPCREATESTRUCT pcs)
{
	return CView::OnCreate(pcs);
}

class CMyFrameWnd:public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnPaint();
	virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
private:
	CSplitterWnd m_split;	//不规则框架窗口
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
END_MESSAGE_MAP()
int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
{
	return CFrameWnd::OnCreate(pcs);
}
void CMyFrameWnd::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
	::EndPaint(m_hWnd, &ps);
}
BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	//创建两个视图窗口	
	m_split.CreateStatic(this, 1, 2);
	m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
	m_split.CreateView(0, 1, pContext->m_pNewViewClass, CSize(100, 100), pContext);
    m_pViewActive = (CView*)m_split.GetPane(0,0);	//设置活动窗口
	return TRUE;
}
class CMyWinApp:public CWinApp
{
public:
	virtual BOOL InitInstance();
};
BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd* pFrame = new CMyFrameWnd;
	CCreateContext cct;
	CMyDoc* pDoc = new CMyDoc;
	cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
	cct.m_pCurrentDoc = pDoc;
	pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
	m_pMainWnd = pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}
CMyWinApp theApp;

三、命令消息(WM_COMMAND)处理顺序

        对象关系图

1、编写程序

#include <afxwin.h>
#include <afxext.h>
#include "resource.h"

class CMyDoc:public CDocument
{
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
	//ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyDoc::OnNew()
{
	AfxMessageBox("CMyDoc::OnNew");
}

class CMyView:public CView
{
	DECLARE_DYNCREATE(CMyView)
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnDraw(CDC* cDC);
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnNew();
};
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
	ON_WM_CREATE()
	//ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyView::OnDraw(CDC* cDC)
{
	cDC->TextOut(100, 100, "视图窗口");
}
int CMyView::OnCreate(LPCREATESTRUCT pcs)
{
	return CView::OnCreate(pcs);
}
void CMyView::OnNew()
{
	AfxMessageBox("CMyView::OnNew");
}

class CMyFrameWnd:public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnPaint();
	virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
	afx_msg void OnNew();
private:
	CSplitterWnd m_split;	//不规则框架窗口
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()
int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
{
	return CFrameWnd::OnCreate(pcs);
}
void CMyFrameWnd::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
	::EndPaint(m_hWnd, &ps);
}
BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	//创建两个视图窗口	
	m_split.CreateStatic(this, 1, 2);
	m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
	m_split.CreateView(0, 1, pContext->m_pNewViewClass, CSize(100, 100), pContext);
	m_pViewActive = (CView*)m_split.GetPane(0,0);	//设置活动窗口
	return TRUE;
}
void CMyFrameWnd::OnNew()
{
	AfxMessageBox("CMyFrameWnd::OnNew");
}
class CMyWinApp:public CWinApp
{
	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL InitInstance();
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyWinApp::OnNew()
{
	AfxMessageBox("CMyWinApp::OnNew");
}

BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd* pFrame = new CMyFrameWnd;
	CCreateContext cct;
	CMyDoc* pDoc = new CMyDoc;
	cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
	cct.m_pCurrentDoc = pDoc;
	pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
	m_pMainWnd = pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}
CMyWinApp theApp;

2、处理顺序

视图类 -》文档类 -》框架列 -》 应用类

3、消息执行流程

//WM_COMMAND消息的路线
OnCommand(wParam, lParam)//函数内部this为pFrame
{
  CWnd::OnCommand(..)//函数内部this为pFrame
  {
    OnCmdMsg(...)//函数内部this为pFrame   *****CFrameWnd::OnCmdMsg 起点
    {
      CView* pView = GetActiveView()//函数内部this为pFrame
      {
        return this->m_pViewActive;//活动视图窗口对象地址
      }对象
      pView->OnCmdMsg(..) ===>终点 CCmdTarget::OnCmdMsg 此函数内部this为pView
      m_pDocument->OnCmdMsg(.)==>终点CCmdTarget::OnCmdMsg 此函数内部this为文档类对象
      CWnd::OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为pFrame

      CWinApp* pApp = AfxGetApp();//获取&theApp
      pApp->OnCmdMsg(..)==>终点 CCmdTarget::OnCmdMsg 此函数内部this为&theApp      
    }
  }
}

四、文档类和视图类的关系

1、使用文档类更新视图类数据

(1)更新与文档类绑定的视图窗口

方式1:

        使用this->UpdateAllViews(NULL);更新视图窗口        //NULL为所有窗口

方式2:

        POSITION pos = this->GetFirstViewPosition();    //获取m_viewList(保存与文档类绑定的视图列表)迭代器前一个地址
        CView* pView = this->GetNextView(pos);    //获取第一个视图视图窗口
         this->UpdateAllViews(pView);    //刷新除pView的所有窗口

(2)使用文档类数据

        CMyDoc* pDoc = this->GetDocument();        ‘//this->m_pDocument

        cDC->TextOut(100, 100, pDoc->m_strData);

2、程序

#include <afxwin.h>
#include <afxext.h>
#include "resource.h"

class CMyDoc:public CDocument
{
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnNew();
	CString m_strData;
};
BEGIN_MESSAGE_MAP(CMyDoc, CDocument)
	ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyDoc::OnNew()
{
	AfxMessageBox("CMyDoc::OnNew");
	m_strData = "hello word";
	//this->UpdateAllViews(NULL);
	POSITION pos = this->GetFirstViewPosition();	//获取m_viewList(保存与文档类绑定的视图列表)迭代器前一个地址
	CView* pView = this->GetNextView(pos);	//获取第一个视图视图窗口
	this->UpdateAllViews(pView);	//刷新除pView的所有窗口

}

class CMyView:public CView
{
	DECLARE_DYNCREATE(CMyView)
	DECLARE_MESSAGE_MAP()
public:
	virtual void OnDraw(CDC* cDC);
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnNew();
};
IMPLEMENT_DYNCREATE(CMyView, CView)
BEGIN_MESSAGE_MAP(CMyView, CView)
	ON_WM_CREATE()
	//ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyView::OnDraw(CDC* cDC)
{
	CMyDoc* pDoc = (CMyDoc*)this->m_pDocument;
	cDC->TextOut(100, 100, pDoc->m_strData);
}
int CMyView::OnCreate(LPCREATESTRUCT pcs)
{
	return CView::OnCreate(pcs);
}
void CMyView::OnNew()
{
	AfxMessageBox("CMyView::OnNew");
}

class CMyFrameWnd:public CFrameWnd
{
	DECLARE_MESSAGE_MAP()
	afx_msg int OnCreate(LPCREATESTRUCT pcs);
	afx_msg void OnPaint();
	virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
	afx_msg void OnNew();
private:
	CSplitterWnd m_split;	//不规则框架窗口
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	//ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()
int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs)
{
	return CFrameWnd::OnCreate(pcs);
}
void CMyFrameWnd::OnPaint()
{
	PAINTSTRUCT ps = {0};
	HDC hdc = ::BeginPaint(m_hWnd, &ps);
	::TextOutA(hdc, 200, 200, "CMyFrameWnd::OnPaint", strlen("CMyFrameWnd::OnPaint"));
	::EndPaint(m_hWnd, &ps);
}
BOOL CMyFrameWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
	//创建两个视图窗口	
	m_split.CreateStatic(this, 1, 2);
	m_split.CreateView(0, 0, RUNTIME_CLASS(CMyView), CSize(100, 100), pContext);
	m_split.CreateView(0, 1, pContext->m_pNewViewClass, CSize(100, 100), pContext);
	m_pViewActive = (CView*)m_split.GetPane(0,0);	//设置活动窗口
	return TRUE;
}
void CMyFrameWnd::OnNew()
{
	AfxMessageBox("CMyFrameWnd::OnNew");
}
class CMyWinApp:public CWinApp
{
	DECLARE_MESSAGE_MAP()
public:
	virtual BOOL InitInstance();
	afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)
	//ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()

void CMyWinApp::OnNew()
{
	AfxMessageBox("CMyWinApp::OnNew");
}

BOOL CMyWinApp::InitInstance()
{
	CMyFrameWnd* pFrame = new CMyFrameWnd;
	CCreateContext cct;
	CMyDoc* pDoc = new CMyDoc;
	cct.m_pNewViewClass = RUNTIME_CLASS(CMyView);
	cct.m_pCurrentDoc = pDoc;
	pFrame->LoadFrame(IDR_MENU1, WS_OVERLAPPEDWINDOW, NULL, &cct);
	m_pMainWnd = pFrame;
	pFrame->ShowWindow(SW_SHOW);
	pFrame->UpdateWindow();
	return TRUE;
}
CMyWinApp theApp;

程序源代码:https://download.csdn.net/download/liutit/86738794

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值