MFC 打印预览自定义,重写,打印预览菜单栏英文问题1

文章描述了如何使用MFC在CMainFF窗口中创建一个自定义的打印预览界面,以解决系统默认打印预览中英文菜单和打印机选择问题,包括创建CMainFF类、WrapperView子类,以及处理打印和预览的相关函数和事件。
摘要由CSDN通过智能技术生成

mfc调用系统的打印预览总是出现英文菜单栏,很烦,而且可选用的打印机也不清楚,为了解决,觉得重绘一个打印预览界面,网上也查了很久,最后自己写了一个基本符合的预览界面。

首先,在要调用的窗口view下,CFrameWnd创建MainFF窗口,(class CMainFF : public CFrameWnd),用CFrameWnd是因为下面还要在该窗口下建立数据页(WrapperView类)。直接上代码

包含文件随自己而定

头文件.h

// MainFrm.h : interface of the CMainFrame class
//
/

#if !defined(AFX_MAINFF_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_)
#define AFX_MAINFF_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//
//#include "stdafx.h"
#include "WrapperView.h"

class CMainFF : public CFrameWnd
{
public:
	
	void tcdClose();
	afx_msg LRESULT  MYClose(WPARAM w, LPARAM l);
	CMainFF(DRAWFUN pDraw, CWnd*pOldW, CWnd* pCallW, BOOL bDirect, LPCTSTR stTitle = NULL);
	CWnd*   pOldWnd;
	CWnd*   pCallWnd;
	DRAWFUN Draw;
	BOOL    bDirectPrint;
protected:
	DECLARE_DYNAMIC(CMainFF)

public:
	bool open=false;
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
	virtual BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);
	// Implementation
public:
	
	CToolBarCtrl m_tool;
	virtual ~CMainFF();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:  // control bar embedded members
	CStatusBar  m_wndStatusBar;
	CToolBar    m_wndToolBar;
	CWrapperView  *m_pView;
	
	// Generated message map functions
protected:
	//{{AFX_MSG(CMainFrame)
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnClose();
};
/
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MAINFRM_H__5C3F89A6_932E_11D3_8420_FC56F1C91E86__INCLUDED_)

.cpp文件

// MainFrm.cpp : implementation of the CMainFF class
//
//#include "tcdMultiView.h"
#include "stdafx.h"
#include "MainFF.h"
#include "msgdef.h"
#include "GlobalVar.h"
//#include "tcdMultiView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/
// CMainFF

IMPLEMENT_DYNAMIC(CMainFF, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFF, CFrameWnd)
	ON_WM_PAINT()
	ON_WM_CREATE()
	ON_WM_CLOSE()
	ON_MESSAGE(WM_MYCLOSE, MYClose)//zzy
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
	ID_INDICATOR_CAPS,
	ID_INDICATOR_NUM,
	ID_INDICATOR_SCRL,
};

/
// CMainFF construction/destruction

CMainFF::CMainFF(DRAWFUN pDraw, CWnd*pOldW, CWnd* pCallW, BOOL bDirect, LPCTSTR stTitle)
{
	Draw = pDraw;
	
	CString ss;
	ss = _T("打印预览");

	if (!Create(NULL, ss, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, CRect(200, 200, 500, 500)))
		TRACE0("Failed to create view window\n");
}


CMainFF::~CMainFF()
{
	bDirectPrint = FALSE;
}
void CMainFF::tcdClose() {
	this->CloseWindow();
}
LRESULT CMainFF::MYClose(WPARAM w, LPARAM l)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	open = true;
	CFrameWnd::OnClose();
	return 0;
}

int CMainFF::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	ModifyStyle(WS_MAXIMIZEBOX, 0);
	ModifyStyle(WS_MINIMIZEBOX, 0);
	//ModifyStyle(WS_SYSMENU, 0);
	CCreateContext context;

	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	context.m_pNewViewClass = RUNTIME_CLASS(CWrapperView);
	context.m_pCurrentFrame = this;
	context.m_pCurrentDoc = NULL;
	context.m_pLastView = NULL;

	m_pView = STATIC_DOWNCAST(CWrapperView, CreateView(&context)); //CreateView(&context);
	if (NULL != m_pView) {
		if (!bDirectPrint)
			m_pView->ShowWindow(SW_SHOW);
		SetActiveView(m_pView);
	}
	
	ShowWindow(SW_MAXIMIZE);

	CWinApp *pApp = AfxGetApp();
	pApp->m_pMainWnd = this;
	if (bDirectPrint)
	{
		m_pView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
	}
	else
	{
		m_pView->OnFilePrintPreview(this);
	
	}

	return 0;
}

BOOL CMainFF::PreCreateWindow(CREATESTRUCT& cs)
{
	if (!CFrameWnd::PreCreateWindow(cs))
		return FALSE;

	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);
	return TRUE;
}

/
// CMainFF diagnostics

#ifdef _DEBUG
void CMainFF::AssertValid() const
{
	CMainFF::AssertValid();
}

void CMainFF::Dump(CDumpContext& dc) const
{
	CMainFF::Dump(dc);
}

#endif //_DEBUG

/
// CMainFF message handlers

BOOL CMainFF::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
	if (open)return TRUE;
	// let the view have first crack at the command
	if (m_pView->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;


	CWinApp* pApp = AfxGetApp();
	if (pApp != NULL && pApp->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	
	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}



//
// 源代码中使用的框架销毁函数有bug,这里暂时不使用正常销毁-AWEN
void CMainFF::OnClose()
{	
	CFrameWnd::OnClose();
}

数据类 WrapperView

.h

//WrapperView.h

#if !defined(AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_)
#define AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// WrapperView.h : header file
//

#include "MyPreviewView.h"

#include "scanwnd/PrintData.h"	
/
// CWrapperView view

class CWrapperView : public CScrollView
{
protected:
	DECLARE_DYNCREATE(CWrapperView)

	CFrameWnd*    m_pFrameWnd;
public:
	
	
	CPrintData m_printdata1;
	friend class CTcdMultiView;
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	
	CDialogBar dialogbar;
	CToolBar m_toolbar;//工具栏
	CWrapperView();
	virtual ~CWrapperView();
	afx_msg  void OnPreviewPrint();
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);


	void OnFilePrintPreview(CFrameWnd *pFrame);
	BOOL DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState);
	void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT, CMyPreviewView* pView);
	// Overrides
	// ClassWizard generated virtual function overrides
	virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);      // overridden to draw this view
protected:
	
	virtual void OnDraw(CDC* pDC);      // overridden to draw this view
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnActivateView(BOOL bActivate, CView*, CView*);



	// Implementation
protected:

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// Generated message map functions
protected:
	
	// NOTE - the ClassWizard will add and remove member functions here.
	afx_msg void OnFilePrint();
	
	DECLARE_MESSAGE_MAP()
public:
	CDialogBar *m_pToolBar;

};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_WRAPPERVIEW_H__AC579D20_8E3D_11D3_8410_E1CD9A2C01DC__INCLUDED_)

.cpp

// WrapperView.cpp : implementation file
//

#include "stdafx.h"
#include "WrapperView.h"
#include "MyPreviewView.h"
#include "MainFF.h"
#include "const.h"
#include "GlobalVar.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd);

/
// CWrapperView

IMPLEMENT_DYNCREATE(CWrapperView, CScrollView)

CWrapperView::CWrapperView()
{
	m_pFrameWnd = NULL;
	m_nMapMode = MM_TEXT; //default
}

CWrapperView::~CWrapperView()
{
	delete m_pToolBar;
}


BEGIN_MESSAGE_MAP(CWrapperView, CScrollView)
	// NOTE - the ClassWizard will add and remove mapping macros here.
	ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
	ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
END_MESSAGE_MAP()

void CWrapperView::OnDraw(CDC *pDC)
{

}

void CWrapperView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
	
	if (pDC)
	{
		m_printdata1.Print(pDC, pInfo);//zzy 230821
	}
}

void CWrapperView::OnPreviewPrint()
{
	SendMessage(WM_COMMAND, ID_FILE_PRINT);

}
/
// CWrapperView diagnostics

#ifdef _DEBUG
void CWrapperView::AssertValid() const
{
	CView::AssertValid();
}

void CWrapperView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}
#endif //_DEBUG

/
// CWrapperView message handlers
void CWrapperView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// TODO: add extra initialization before printing
	int nPageCount = 1;

	if (dlogset1.ReportType != 0)
		nPageCount = m_printdata1.GetPrintPageCount(pDC, pInfo);
	else
		nPageCount = m_printdata1.GetPrintPageCount2(pDC, pInfo);
	pInfo->SetMaxPage(nPageCount);
}


BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd)
{
	ASSERT_VALID(pFrameWnd);

	CMyPreviewView* pView = (CMyPreviewView*)pFrameWnd->GetDlgItem(AFX_IDW_PANE_FIRST);
	ASSERT_KINDOF(CPreviewView, pView);

	pView->OnPreviewClose();
	return FALSE;
}

BOOL CWrapperView::OnPreparePrinting(CPrintInfo* pInfo)
{
	
	return DoPreparePrinting(pInfo);
}
void CWrapperView::OnActivateView(BOOL bActivate, CView*, CView*)
{

}

void CWrapperView::OnFilePrint()
{
	CMainFF* pf = (CMainFF*)::AfxGetMainWnd();
	if (pf->bDirectPrint)
		pf->ShowWindow(SW_HIDE);
	CView::OnFilePrint();
	if (pf->bDirectPrint)
	{
		CWinApp *pApp = AfxGetApp();
		pApp->m_pMainWnd = pf->pOldWnd;
		pf->DestroyWindow();
	}
}


void CWrapperView::OnFilePrintPreview(CFrameWnd *pFrame)
{
	m_pFrameWnd = pFrame;
	CPrintPreviewState* pState = new CPrintPreviewState;
	pState->lpfnCloseProc = _AfxMyPreviewCloseProc;
	if (!DoPrintPreview(AFX_IDD_PREVIEW_TOOLBAR, this, RUNTIME_CLASS(CPreviewView), pState))
	{

		TRACE0("Error: DoPrintPreview failed.\n");
		AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
		delete pState;
	}

}

BOOL CWrapperView::DoPrintPreview(UINT nIDResource, CView* pPrintView, CRuntimeClass* pPreviewViewClass, CPrintPreviewState* pState)
{
	CToolBar newToolBar;
	ASSERT_VALID_IDR(nIDResource);
	ASSERT_VALID(pPrintView);
	ASSERT(pPreviewViewClass != NULL);
	ASSERT(pPreviewViewClass->IsDerivedFrom(RUNTIME_CLASS(CPreviewView)));
	ASSERT(pState != NULL);

	ASSERT(m_pFrameWnd != NULL);
	CFrameWnd* pParent = m_pFrameWnd; //STATIC_DOWNCAST(CFrameWnd, AfxGetMainWnd()); //
	ASSERT_VALID(pParent);

	CCreateContext context;
	context.m_pCurrentFrame = pParent;
	context.m_pCurrentDoc = GetDocument();
	context.m_pLastView = this;

	// Create the preview view object
	CMyPreviewView* pView = (CMyPreviewView*)pPreviewViewClass->CreateObject();

	if (pView == NULL)
	{
		TRACE0("Error: Failed to create preview view.\n");
		return FALSE;
	}
	ASSERT_KINDOF(CPreviewView, pView);
	pView->m_pPreviewState = pState;        // save pointer

	pParent->OnSetPreviewMode(TRUE, pState);    // Take over Frame Window

	pView->m_pToolBar = new CDialogBar;

	if (!pView->m_pToolBar->Create(pParent, MAKEINTRESOURCE(nIDResource),
		CBRS_TOP, AFX_IDW_PREVIEW_BAR))
	{
		TRACE0("Error: Preview could not create toolbar dialog.\n");
		pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
		delete pView->m_pToolBar;       // not autodestruct yet
		pView->m_pToolBar = NULL;
		pView->m_pPreviewState = NULL;  // do not delete state structure
		delete pView;
		return FALSE;
	}
	
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_PRINT, _T("打印(&P)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_NEXT, _T("下一页(&N)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_PREV, _T("上一页(&V)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_NUMPAGE, _T("分页(&T)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_ZOOMIN, _T("放大(&I)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_ZOOMOUT, _T("缩小(&O)"));
	pView->m_pToolBar->SetDlgItemText(AFX_ID_PREVIEW_CLOSE, _T("关闭(&C)"));
	pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_CLOSE)->ShowWindow(false);
	//pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NUMPAGE)
	
	pView->m_pToolBar->m_bAutoDelete = TRUE;    // automatic cleanup
	CString str;
	pView->m_pToolBar->GetDlgItem(AFX_ID_PREVIEW_NUMPAGE)->GetWindowTextA(str);
	
	

	if (!pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
		CRect(0, 0, 0, 0), pParent, AFX_IDW_PANE_FIRST, &context))
	{
		TRACE0("Error: couldn't create preview view for frame.\n");
		pParent->OnSetPreviewMode(FALSE, pState);   // restore Frame Window
		pView->m_pPreviewState = NULL;  // do not delete state structure
		delete pView;
		return FALSE;
	}

	pState->pViewActiveOld = pParent->GetActiveView();
	CWrapperView* pActiveView = (CWrapperView*)pParent->GetActiveFrame()->GetActiveView();
	if (pActiveView != NULL)
		pActiveView->OnActivateView(FALSE, pActiveView, pActiveView);

	if (!pView->SetPrintView(pPrintView))
	{
		pView->OnPreviewClose();
		return TRUE;            // signal that OnEndPrintPreview was called
	}

	pParent->SetActiveView(pView);  // set active view - even for MDI

									// update toolbar and redraw everything
	pView->m_pToolBar->SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE);
	pParent->RecalcLayout();            // position and size everything
	pParent->UpdateWindow();

	return TRUE;
}

// OnEndPrintPreview is here for swap tuning reasons
//  (see viewprev.cpp for complete preview mode implementation)
void CWrapperView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT, CMyPreviewView* pView)
{
	ASSERT_VALID(pDC);
	ASSERT_VALID(pView);
	ASSERT(m_pFrameWnd != NULL);

	if (pView->m_pPrintView != NULL)
		OnEndPrinting(pDC, pInfo);

	CFrameWnd *pParent = m_pFrameWnd;
	ASSERT_VALID(pParent);

	// restore the old main window
	pParent->OnSetPreviewMode(FALSE, pView->m_pPreviewState);

	// Force active view back to old one
	pParent->SetActiveView(pView->m_pPreviewState->pViewActiveOld);
	if (pParent != GetParentFrame())
		OnActivateView(TRUE, this, this);   // re-activate view in real frame
	pView->DestroyWindow();     // destroy preview view
								// C++ object will be deleted in PostNcDestroy

								// restore main frame layout and idle message
	pParent->RecalcLayout();
	pParent->SendMessage(WM_SETMESSAGESTRING, (WPARAM)AFX_IDS_IDLEMESSAGE, 0L);
	pParent->UpdateWindow();
}

void CWrapperView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{

	

	CView::OnEndPrinting(pDC, pInfo);
	::SendMessage(::AfxGetMainWnd()->m_hWnd, WM_MYCLOSE, 0, 0);

	return;
}

/
//zzy 230818 
IMPLEMENT_DYNCREATE(CMyPreviewView, CPreviewView)

CMyPreviewView::CMyPreviewView()
{
}

CMyPreviewView::~CMyPreviewView()
{
}

BEGIN_MESSAGE_MAP(CMyPreviewView, CPreviewView)
	ON_COMMAND(AFX_ID_PREVIEW_CLOSE, OnPreviewClose)
	ON_COMMAND(AFX_ID_PREVIEW_PRINT, OnPreviewPrint)	
END_MESSAGE_MAP()

/
// CMyPreviewView drawing

void CMyPreviewView::OnDraw(CDC* pDC)
{
	CPreviewView::OnDraw(pDC);
}

/
// CMyPreviewView diagnostics

#ifdef _DEBUG
void CMyPreviewView::AssertValid() const
{

}

void CMyPreviewView::Dump(CDumpContext& dc) const
{
}
#endif //_DEBUG

/
// CMyPreviewView message handlers

void CMyPreviewView::OnActivateView(BOOL bActivate, CView* pView1, CView *pView2)
{
	CPreviewView::OnActivateView(bActivate, pView1, pView2);
}

void CMyPreviewView::OnPreviewClose()
{
	CMainFF* pf = (CMainFF*)::AfxGetMainWnd();
	CWinApp *pApp = AfxGetApp();
	pApp->m_pMainWnd = pf->pOldWnd;
	//pf->OnClose();
	pf->DestroyWindow();
}

void CMyPreviewView::OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView)
{

	CPreviewView::OnEndPrintPreview(pDC, pInfo, point, pView);
}

void CMyPreviewView::OnPreviewPrint()
{
	m_pPrintView->SendMessage(WM_COMMAND, ID_FILE_PRINT);
	OnPreviewClose();               // force close of Preview
}

以及重写的·MyPreviewView.h

//MyPreviewView.h

#if !defined(AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_)
#define AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MyPreviewView.h : header file
//
#include <afxpriv.h>

/
// CMyPreviewView view

class CMyPreviewView : public CPreviewView
{
protected:
	CMyPreviewView();           // protected constructor used by dynamic creation
	virtual ~CMyPreviewView();
	DECLARE_DYNCREATE(CMyPreviewView)

public:
	
	friend class CWrapperView;
protected:
	virtual void OnDraw(CDC* pDC);      // overridden to draw this view
	virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
	
	// Implementation
protected:

#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
	
	// Generated message map functions

	afx_msg void OnPreviewClose();
	afx_msg void OnPreviewPrint();


	friend BOOL CALLBACK _AfxMyPreviewCloseProc(CFrameWnd* pFrameWnd);

	DECLARE_MESSAGE_MAP()
};

/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MYPREVIEWVIEW_H__9FCA8680_907C_11D3_8412_9D0C7145F5C4__INCLUDED_)

最后需要调用打印预览界面地方加上

	m_PreFrame = new CMainFF(DRWAPRINTER, 0, 0, FALSE);//zzy 230908 新打印预览的单文档创建
			if (!m_PreFrame) return false;
			m_PreFrame->ShowWindow(SW_SHOWNORMAL);//SW_SHOWNORMAL

DRWAPRINTER是导入数据的函数,放在调用打印预览函数的上方即可

void DRWAPRINTER(CDC* pDC, CPrintInfo* pInfo, void* pVoid)
{
	
	CWrapperView wrapview;// 生成的打印预览数据读取
	wrapview.OnPrint(pDC, pInfo);

}

这个方法其实是有一个问题,菜单栏的关闭按钮我给隐藏了,因为点击会崩,没找到好方法处理,所有我直接关闭MainFF界面一起关闭了,有大神知道怎么解决望告知谢谢啦。新人代码不太严谨!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值