📄 generatorview.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 + -