⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 generatorview.cpp

📁 条形码技术 用来共享 大家多多交流 大家多多交流
💻 CPP
字号:
/******************************************************************************
 * 文件名:GeneratorView.cpp
 * 功能  :条形码打印
 * Modified by PRTsinghua@hotmail.com
******************************************************************************/

#include "stdafx.h"
#include "Generator.h"
#include "GiveCodeDlg.h"
#include "GiveSizeDlg.h"
#include "GeneratorDoc.h"
#include "GeneratorView.h"
#include <map>
#include <algorithm>

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


IMPLEMENT_DYNCREATE(CGeneratorView, CView)

BEGIN_MESSAGE_MAP(CGeneratorView, CView)
	ON_COMMAND(ID_EDIT_GIVE, OnEditGive)
	ON_COMMAND(ID_FILE_SAVE, OnFileSave)
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/******************************************************************************
 * 构造函数
******************************************************************************/
CGeneratorView::CGeneratorView()
{
	m_bModified=FALSE;
	picWidth	= 384;
	picHeight	= 182;
    lineWidth	= 2;
	shortLine	= 160;
	longLine	= 178;

	BldFirstTable();
	BldSecondTable();
	dcMem=new CDC();
	pBitmap=new CBitmap();
}

/******************************************************************************
 * 析构函数
******************************************************************************/
CGeneratorView::~CGeneratorView()
{
}

BOOL CGeneratorView::PreCreateWindow(CREATESTRUCT& cs)
{
	return CView::PreCreateWindow(cs);
}


/******************************************************************************
 * OnDraw函数
******************************************************************************/
void CGeneratorView::OnDraw(CDC* pDC)
{
	CGeneratorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	if(!m_bModified)
		return;

	if(dcMem->m_hDC)
		dcMem->Detach();
    pDC->SetMapMode(MM_TEXT);
	dcMem->CreateCompatibleDC(pDC);
	if(pBitmap)
		pBitmap->Detach();
	pBitmap->CreateCompatibleBitmap(pDC, picWidth, picHeight);
	dcMem->SelectObject(pBitmap);
	dcMem->SelectStockObject(WHITE_BRUSH);
	dcMem->SelectStockObject(WHITE_PEN);
	dcMem->Rectangle(0, 0, picWidth, picHeight);
    
	DrawStart(dcMem);
    DrawLeft(dcMem);
    DrawMiddle(dcMem);
	DrawRight(dcMem);
	DrawEnd(dcMem);
	DrawNumber(dcMem);
	pDC->BitBlt(0, 0, picWidth, picHeight, dcMem, 0, 0, SRCCOPY);
}

/////////////////////////////////////////////////////////////////////////////
// CGeneratorView printing

BOOL CGeneratorView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	pInfo->SetMaxPage(1);
	return DoPreparePrinting(pInfo);
}

void CGeneratorView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CGeneratorView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CGeneratorView diagnostics

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

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

CGeneratorDoc* CGeneratorView::GetDocument()
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGeneratorDoc)));
	return (CGeneratorDoc*)m_pDocument;
}
#endif

/******************************************************************************
 * 消息处理函数
******************************************************************************/

/******************************************************************************
 * 指定EAN编码
******************************************************************************/
void CGeneratorView::OnEditGive() 
{
	CGiveCodeDlg myDialog;
    if(myDialog.DoModal()==IDOK)
	{
		if (myDialog.m_code.GetLength() != 13)
		{
			AfxMessageBox("位数不对,请输入13个数字!");
			return;
		}
        
		for (int j=0; j<=12; j++)
		{
			code[j]=(int)myDialog.m_code.GetAt(j)-48;
		}
	    
		m_bModified=TRUE;
	    if(code[12] != CheckBit())
		{
			AfxMessageBox("校验码有误,系统自动计算!"); 
			code[12] = CheckBit();
		}
		CWnd::Invalidate();
	}
}

/******************************************************************************
 * 建立编码规则表一
******************************************************************************/
void CGeneratorView::BldFirstTable()
{
    firstcode[0]=_T("AAAAAA");
	firstcode[1]=_T("AABABB");
	firstcode[2]=_T("AABBAB");
	firstcode[3]=_T("AABBBA");
	firstcode[4]=_T("ABAABB");
	firstcode[5]=_T("ABBAAB");
	firstcode[6]=_T("ABBBAA");
	firstcode[7]=_T("ABABAB");
	firstcode[8]=_T("ABABBA");
	firstcode[9]=_T("ABBABA");
}

/******************************************************************************
 * 建立编码规则表二
******************************************************************************/
void CGeneratorView::BldSecondTable()
{
    coderule[_T("0A")]=_T("0001101");
	coderule[_T("0B")]=_T("0100111");
	coderule[_T("0C")]=_T("1110010");
	coderule[_T("1A")]=_T("0011001");
	coderule[_T("1B")]=_T("0110011");
	coderule[_T("1C")]=_T("1100110");
	coderule[_T("2A")]=_T("0010011");
	coderule[_T("2B")]=_T("0011011");
	coderule[_T("2C")]=_T("1101100");
    coderule[_T("3A")]=_T("0111101");
    coderule[_T("3B")]=_T("0100001");
	coderule[_T("3C")]=_T("1000010");
    coderule[_T("4A")]=_T("0100011");
	coderule[_T("4B")]=_T("0011101");
    coderule[_T("4C")]=_T("1011100");
    coderule[_T("5A")]=_T("0110001");
    coderule[_T("5B")]=_T("0111001");
	coderule[_T("5C")]=_T("1001110");
    coderule[_T("6A")]=_T("0101111");
	coderule[_T("6B")]=_T("0000101");
    coderule[_T("6C")]=_T("1010000");
    coderule[_T("7A")]=_T("0111011");
    coderule[_T("7B")]=_T("0010001");
	coderule[_T("7C")]=_T("1000100");
    coderule[_T("8A")]=_T("0110111");
	coderule[_T("8B")]=_T("0001001");
    coderule[_T("8C")]=_T("1001000");
    coderule[_T("9A")]=_T("0001011");
    coderule[_T("9B")]=_T("0010111");
	coderule[_T("9C")]=_T("1110100");
}

/******************************************************************************
 * 计算检验码
******************************************************************************/
int CGeneratorView::CheckBit()
{
    int odd=0,even=0,result=0;
	for(int i=1; i<=11; i+=2)
	    odd += code[i];
	for(int j=0; j<=10; j+=2)
		even += code[j];
	result = 10 - (odd*3+even)%10;
	return result;
}

/******************************************************************************
 * 画起始线
******************************************************************************/
void CGeneratorView::DrawStart(CDC *ptDC)
{
    for(int i=0; i<=8; i++)
		DrawZero(ptDC, CPoint(i * lineWidth,0));
	DrawOne(ptDC,CPoint(9 * lineWidth, 0),TRUE);
	DrawZero(ptDC,CPoint(10 * lineWidth,0));
	DrawOne(ptDC,CPoint(11 * lineWidth,0),TRUE);
}

/******************************************************************************
 * 画空白线
******************************************************************************/
void CGeneratorView::DrawZero(CDC *ptDC,CPoint point)
{
    CPen zpen(PS_NULL, lineWidth, RGB(255,255,255));
    CPen *oldPen=ptDC->SelectObject(&zpen);
    ptDC->MoveTo(point);
	ptDC->LineTo(point.x, point.y+shortLine);
	ptDC->SelectObject(oldPen);
}

/******************************************************************************
 * 画黑线
******************************************************************************/
void CGeneratorView::DrawOne(CDC *ptDC,CPoint point,BOOL b_long)
{
    CPen epen(PS_SOLID, lineWidth, RGB(0,0,0));
    CPen *oldPen=ptDC->SelectObject(&epen);
	if(b_long)
	{   
		ptDC->MoveTo(point);
		ptDC->LineTo(point.x, point.y+longLine);
	}
	else
	{
		ptDC->MoveTo(point);
		ptDC->LineTo(point.x, point.y+shortLine);
	}
	ptDC->SelectObject(oldPen);
}    

/******************************************************************************
 * 画条形码的左半部
******************************************************************************/
void CGeneratorView::DrawLeft(CDC *ptDC)
{
    CString temp1 = firstcode[code[0]];
	CString YorN[6];			//用于存贮左边的六位数的编码
	for(int i=0;i<=5;i++)
	{
		char temp2;
		ToChar(code[i+1],temp2);
		CString temp3(temp2);
		temp3+=temp1.GetAt(i);	//将数字和字母连接成串
        coderule.Lookup(temp3,YorN[i]);		//查表得出编码
	}
	
	int x;
	for(int j=0;j<=5;j++)
	{
		for(int k=0;k<=6;k++)				//每个数字有七位编码
		{
			x=12+j*7+k;						//计算每个模块的横坐标
			if(YorN[j].GetAt(k)=='1')
				DrawOne(ptDC,CPoint(x*lineWidth,0),FALSE);
			else
				DrawZero(ptDC,CPoint(x*lineWidth,0));
		}
	}
}

/******************************************************************************
 * 画条形码中间的部分
******************************************************************************/
void CGeneratorView::DrawMiddle(CDC *ptDC)
{
    DrawZero(ptDC,CPoint(54*lineWidth,0));
	DrawOne(ptDC,CPoint(55*lineWidth,0),TRUE);
    DrawZero(ptDC,CPoint(56*lineWidth,0));
    DrawOne(ptDC,CPoint(57*lineWidth,0),TRUE);
	DrawZero(ptDC,CPoint(58*lineWidth,0));
}

/******************************************************************************
 * 画条形码的右半部
******************************************************************************/
void CGeneratorView::DrawRight(CDC *ptDC)
{
    char temp1;
	CString YorN[6];				//用于存储后面六位的编码
	for(int i=7;i<=12;i++)
	{
		ToChar(code[i],temp1);
		CString temp2(temp1);
		temp2+='C';
		coderule.Lookup(temp2,YorN[i-7]);
	}
    
	int x;
	for(int j=0;j<=5;j++)
	{
		for(int k=0;k<=6;k++)		//每个数字有七位编码
		{
			x=59+j*7+k;				//计算每个模块的横坐标
			if(YorN[j].GetAt(k)=='1')
				DrawOne(ptDC,CPoint(x*lineWidth,0),FALSE);
			else DrawZero(ptDC,CPoint(x*lineWidth,0));
		}
	}
}

/******************************************************************************
 * 画条形码的结束部分
******************************************************************************/
void CGeneratorView::DrawEnd(CDC *ptDC)
{
    DrawOne(ptDC,CPoint(101*lineWidth,0),TRUE);
	DrawZero(ptDC,CPoint(102*lineWidth,0));
	DrawOne(ptDC,CPoint(103*lineWidth,0),TRUE);
	for(int i=104;i<=112;i++)
		DrawZero(ptDC,CPoint(i*lineWidth,0));
}

/******************************************************************************
 * 数字转换成字符串
******************************************************************************/
void CGeneratorView::ToChar(int no,char &c)
{
    c=(char) no+48;
}

/******************************************************************************
 * 画条形码的数字标识
******************************************************************************/
void CGeneratorView::DrawNumber(CDC *ptDC)
{
     char No[13];
	 for(int i=0;i<=12;i++)
	 {
		 ToChar(code[i],No[i]);
	 }
	 CFont font;
	 LOGFONT lf;
	 lf.lfHeight=20;
	 lf.lfWidth=5*lineWidth;
	 lf.lfEscapement=0;
	 lf.lfOrientation=0;
	 lf.lfWeight=FW_NORMAL;
	 lf.lfItalic=FALSE;
	 lf.lfUnderline=FALSE;
	 lf.lfStrikeOut=FALSE;
	 lf.lfCharSet=ANSI_CHARSET;
	 lf.lfClipPrecision=CLIP_DEFAULT_PRECIS;
	 lf.lfQuality=DEFAULT_QUALITY;
	 lf.lfPitchAndFamily=FF_ROMAN|DEFAULT_PITCH;
     ::lstrcpy(lf.lfFaceName,_T("Times New Roman"));
	 font.CreateFontIndirect(&lf);
	 CFont *oldFont=ptDC->SelectObject(&font);

	 ptDC->TextOut(2*lineWidth,162,&No[0],1);
	 ptDC->TextOut(15*lineWidth,162,&No[1],6);
     ptDC->TextOut(61*lineWidth,162,&No[7],6);
}

/******************************************************************************
 * 保存条形码图像
******************************************************************************/
void CGeneratorView::OnFileSave() 
{
	if(!m_bModified) return;
	TCHAR szFilters[]=_T("位图文件(*.bmp)|*.bmp||");
	CFileDialog dlg(FALSE,_T("bmp"),_T("*.bmp"),OFN_HIDEREADONLY,szFilters);
	if(dlg.DoModal()==IDOK)
	{
		CFile file(_T(dlg.GetFileName()),CFile::modeWrite|CFile::modeCreate);
		if(!file)
			AfxMessageBox("Cannot save the file!");
		
		BITMAPINFO *m_pBMI;
        BYTE *m_pDIBData;
        BITMAPFILEHEADER bfh;
        BITMAPINFOHEADER bi;
        BITMAP BM;
		RGBQUAD rgb[2]=
					{	{0,0,0,0},
						{255,255,255,0}	
					};
        pBitmap->GetObject(sizeof(BM),&BM);
        CClientDC dc(this);
        bi.biSize			= sizeof(BITMAPINFOHEADER);
        bi.biWidth			= picWidth;
        bi.biHeight			=picHeight;
        bi.biPlanes			= 1;
        bi.biBitCount		= 1;
        bi.biCompression	= 0;
        bi.biSizeImage		= 0;
        bi.biXPelsPerMeter	= 0;
        bi.biYPelsPerMeter	= 0;
        bi.biClrUsed		= 0;
        bi.biClrImportant	= 0;

		bfh.bfType=0x4d42;
        bfh.bfOffBits=sizeof(bfh)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD);
        bfh.bfSize=bfh.bfOffBits+BM.bmWidth*BM.bmHeight;
        bfh.bfReserved1=0;
        bfh.bfReserved2=0;
		
		m_pBMI=(BITMAPINFO*)new char[sizeof(BITMAPINFO)];
        m_pDIBData=(BYTE*)new char[bfh.bfSize-bfh.bfOffBits];

		memcpy(m_pBMI,&bi,sizeof(BITMAPINFOHEADER));
        GetDIBits(dc.GetSafeHdc(), (HBITMAP)pBitmap->GetSafeHandle(), 0l, (DWORD)bi.biHeight,
        (LPVOID)m_pDIBData,(LPBITMAPINFO)m_pBMI, (DWORD)DIB_RGB_COLORS);

		file.Write(&bfh,sizeof(bfh));
        file.Write(m_pBMI,sizeof(BITMAPINFOHEADER));
        file.Write(rgb,2*sizeof(RGBQUAD));		
        file.Write(m_pDIBData,BM.bmWidth*BM.bmHeight);
		file.Close();
	}
}

/******************************************************************************
 * 打印条形码
******************************************************************************/
void CGeneratorView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
{
	DrawStart(pDC);
    DrawLeft(pDC);
    DrawMiddle(pDC);
	DrawRight(pDC);
	DrawEnd(pDC);
	DrawNumber(pDC);
	CView::OnPrint(pDC, pInfo);
}

void CGeneratorView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	pDC->SetMapMode(MM_ISOTROPIC);
	pDC->SetWindowExt(500,300);
	CView::OnPrepareDC(pDC, pInfo);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -