活动地址:毕业季·进击的技术er
夏日炎炎,热浪中我们迎来毕业季,这是告别,也是迈向新起点的开始,CSDN诚邀各毕业生/在校生/职场人讲述自己的毕业季故事,分享自己的经验,技术er的进击之路,等你来书写!你可以选择适合自己的对应身份从以下相关内容方向着笔,也可从自身经历出发,贴合活动主题参与投稿,文章题目自拟。
大家好,我是乘风偷月,下面给大家分享一份如何生成EAN-13条形码的内容,直接拷贝内容应该可以跑起来。希望大家会喜欢,如果喜欢,请点个赞,关注一下,谢谢!!
先上效果图
EAN-13介绍:European Article Number (欧洲物品编码的缩写),其中共计13位代码的EAN-13是比较通用的一般终端产品的条形码协议和标准,主要应用于超级市场和其它零售业,因此这种是我们比较常见的,随便拿起身边的一个从超市买来的商品都可以从包装上看得到。
链接:EAN-13_百度百科
在项目中,需要根据文本内容生成条码,打印出来贴到商品上面,这里主要用到EAN-13,在市面上有一些第三方库可以使用,例如ZXing,但是这篇文章将根据百度百科的算法去实现逻辑,并显示出来。
如图所示
根据字符类型,得到前置码:
计算校验符:
以上这些理论的东西可以参考百度百科的详细说明,下面将根据这些理论编写代码。
直接上代码(WIN32 应用程序)
ean13util.h 文件
/*
========================================================================
File name: ean13util.h
Module:
Author: 中唐工作室(zt)18824182332
Create Time: 2016/12/12 10:41:00
Modify By:
Modify Date:
========================================================================
*/
#pragma once
#include "stdafx.h"
class Ean13Util
{
public:Ean13Util();Ean13Util(LPCTSTR pStrEan);void SetBarCode(LPCTSTR pStrEan);static TCHAR CalSNVerify(LPCTSTR sz);CString ConverCode(LPCTSTR pStrEan);~Ean13Util(void);void DrawBarCode(HDC* pDC, RECT rect);
protected:CString m_cEanCode;CString m_cBitCode;
};
ean13util.cpp
/*
========================================================================
File name: ean13util.cpp
Module:
Author: 中唐工作室(zt)18824182332
Create Time: 2016/12/12 10:41:00
Modify By:
Modify Date:
========================================================================
*/
#include "StdAfx.h"
#include "ean13util.h"
#include <assert.h>// 将12位EAN转换为01条码代码
CString Ean13Util::ConverCode(LPCTSTR pStrEan)
{// 拿到前置码LPCTSTR pStrFont = DICTIONTABLE[pStrEan[0] - _T('0')][0];CString strCode;for (int i = 0; i < 12; i++){strCode += DICTIONTABLE[pStrEan[i + 1] - _T('0')][pStrFont[i] - _T('A') + 1];}return CString(_T("101")) + strCode.Left(strCode.GetLength() / 2)+ _T("01010") + strCode.Right(strCode.GetLength() / 2) + _T("101");
}Ean13Util::Ean13Util()
{}Ean13Util::Ean13Util(LPCTSTR pStrEan)
{SetBarCode(pStrEan);
}Ean13Util::~Ean13Util(void)
{
}void Ean13Util::SetBarCode(LPCTSTR pStrEan)
{CString strCode = pStrEan;if (strCode.GetLength() == 12){strCode += CalSNVerify(strCode);}if (strCode.GetLength() != 13){assert(FALSE);throw - 1;return;}m_cEanCode = strCode;m_cBitCode = ConverCode(strCode);
}
// 计算EAN-13校验位,生成方法为:
// 前12位的偶数位(索引从1开始)之和*3 - 奇数位和
// 最后返回最接近且大于等于当前数的10倍数与当前值的差值
TCHAR Ean13Util::CalSNVerify(LPCTSTR pStrEan)
{if (_tcslen(pStrEan) != 12){return _T('0');}INT iSum = 0;for (int i = 0; i < 6; i++){iSum += pStrEan[i * 2] - _T('0');iSum += (pStrEan[i * 2 + 1] - _T('0')) * 3;}return (iSum % 10 == 0) ? _T('0') : 10 - iSum % 10 + _T('0');
}
void Ean13Util::DrawBarCode(HDC* pDC, RECT pRect)
{if (m_cBitCode.GetLength() == 0){return;}// 计算单个模组宽度INT iWidth = (pRect.right - pRect.left) / (m_cBitCode.GetLength() + 11 * 2);//设定文字大小和颜色LOGFONT logfont; //改变输出字体ZeroMemory(&logfont, sizeof(LOGFONT));logfont.lfCharSet = ANSI_CHARSET;logfont.lfHeight = iWidth * 9; //设置字体的大小logfont.lfEscapement = 0;logfont.lfOrientation = 0;logfont.lfWidth = 5.5 * iWidth;logfont.lfWeight = FW_NORMAL;logfont.lfItalic = FALSE;logfont.lfUnderline = FALSE;logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;logfont.lfQuality = DEFAULT_QUALITY;logfont.lfPitchAndFamily = (DEFAULT_PITCH | FF_SWISS);lstrcpy(logfont.lfFaceName, _T("Arial"));HFONT hFont = CreateFontIndirect(&logfont);HBRUSH hBrushBlack = CreateSolidBrush(RGB(0, 0, 0));HBRUSH hOldBrush2 = (HBRUSH)SelectObject(*pDC, hBrushBlack);for (int i = 0; i < m_cBitCode.GetLength(); i++){RECT rtCur = pRect;rtCur.left += (11 + i) * iWidth;rtCur.right = rtCur.left + iWidth;rtCur.bottom -= 7 * iWidth;if (m_cBitCode[i] == _T('1')){Rectangle(*pDC, rtCur.left, rtCur.top, rtCur.right, rtCur.bottom);//绘制黑色条形}}SelectObject(*pDC, hOldBrush2);DeleteObject(hBrushBlack);HBRUSH hBrushWhile = CreateSolidBrush(RGB(255, 255, 255));INT iOldMode = SetBkMode(*pDC, TRANSPARENT);HFONT* pOldFnt = (HFONT*)SelectObject(*pDC, hFont);RECT rtText = pRect;//文本绘制区域rtText.top = pRect.bottom - 10 * iWidth;rtText.right = pRect.left + 11 * iWidth;//Rectangle(*pDC, rtText.left, rtText.top, rtText.right, rtText.bottom);DrawText(*pDC, m_cEanCode, 1, &rtText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);rtText.left = pRect.left + 14 * iWidth;rtText.right = pRect.left + 57 * iWidth;FillRect(*pDC, &rtText, hBrushWhile);DrawText(*pDC, m_cEanCode.Mid(1, 6), -1, &rtText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);rtText.left = pRect.left + 60 * iWidth;rtText.right = pRect.left + 103 * iWidth;FillRect(*pDC, &rtText, hBrushWhile);DrawText(*pDC, m_cEanCode.Right(6), -1, &rtText, DT_SINGLELINE | DT_CENTER | DT_VCENTER);DeleteObject(hBrushWhile);SetBkMode(*pDC, iOldMode);SelectObject(*pDC, pOldFnt);
}
stdafx.h 文件
// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//#pragma once#include "targetver.h"#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的信息
// Windows 头文件:
#include <windows.h>// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // 某些 CString 构造函数将是显式的#include <atlbase.h>
#include <atlstr.h>// TODO: 在此处引用程序需要的其他头文件
const static LPCTSTR DICTIONTABLE[][4] =
{// TYPE 'A' 'B' 'C'{ _T("AAAAAACCCCCC"), _T("0001101"), _T("0100111"), _T("1110010") }, // 0{ _T("AABABBCCCCCC"), _T("0011001"), _T("0110011"), _T("1100110") }, // 1{ _T("AABBABCCCCCC"), _T("0010011"), _T("0011011"), _T("1101100") }, // 2{ _T("AABBBACCCCCC"), _T("0111101"), _T("0100001"), _T("1000010") }, // 3{ _T("ABAABBCCCCCC"), _T("0100011"), _T("0011101"), _T("1011100") }, // 4{ _T("ABBAABCCCCCC"), _T("0110001"), _T("0111001"), _T("1001110") }, // 5{ _T("ABBBAACCCCCC"), _T("0101111"), _T("0000101"), _T("1010000") }, // 6{ _T("ABABABCCCCCC"), _T("0111011"), _T("0010001"), _T("1000100") }, // 7{ _T("ABABBACCCCCC"), _T("0110111"), _T("0001001"), _T("1001000") }, // 8{ _T("ABBABACCCCCC"), _T("0001011"), _T("0010111"), _T("1110100") }, // 9
};
Resource.h 文件
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 供 Ean813Win.rc 使用
//
#define IDC_MYICON 2
#define IDD_EAN813WIN_DIALOG 102
#define IDS_APP_TITLE 103
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_EAN813WIN 107
#define IDI_SMALL 108
#define IDC_EAN813WIN 109
#define IDB_BUTTON_EAN813 111
#define IDR_MAINFRAME 128#define IDM_EAN813 32771
#define IDC_STATIC -1
#define IDC_RADBTN_EAN13 50001
#define IDC_RADBTN_EAN8 50002#define IDE_EDIT_ZOOM 50003// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 32772
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
测试调用:
// Ean813Win.cpp : 定义应用程序的入口点。
//#include "stdafx.h"
#include "Ean813Win.h"
#include "ean13util.h"
#include "ean8util.h"#define MAX_LOADSTRING 100// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名HWND hInputNum; //输入编辑框
HWND Ean813Button; //Ean813按钮
HWND hInputZoom; //放大编辑框
int m_izoom; //模宽Ean13Util ean13Build = Ean13Util();// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine,_In_ int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// TODO: 在此放置代码。MSG msg;HACCEL hAccelTable;// 初始化全局字符串LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_EAN813WIN, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// 执行应用程序初始化: if (!InitInstance(hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_EAN813WIN));// 主消息循环: while (GetMessage(&msg, NULL, 0, 0)){if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)){TranslateMessage(&msg);DispatchMessage(&msg);}}return (int)msg.wParam;
}//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX);wcex.style = CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc = WndProc;wcex.cbClsExtra = 0;wcex.cbWndExtra = 0;wcex.hInstance = hInstance;wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_EAN813WIN));wcex.hCursor = LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);wcex.lpszMenuName = MAKEINTRESOURCE(IDC_EAN813WIN);wcex.lpszClassName = szWindowClass;wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));return RegisterClassEx(&wcex);
}//
// 函数: InitInstance(HINSTANCE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{HWND hWnd;hInst = hInstance; // 将实例句柄存储在全局变量中hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, CW_USEDEFAULT, 600, 400, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);return TRUE;
}//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{int wmId, wmEvent;PAINTSTRUCT ps;HDC hdc;static int cxClient, cyClient;RECT rect;switch (message){case WM_SIZE:cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);return 0;case WM_COMMAND:wmId = LOWORD(wParam);wmEvent = HIWORD(wParam);// 分析菜单选择: switch (wmId){case IDM_ABOUT:DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);break;case IDM_EXIT:DestroyWindow(hWnd);break;case IDB_BUTTON_EAN813://TODO{TCHAR buf[256];SendMessage(hInputNum, WM_GETTEXT, sizeof(buf) / sizeof(TCHAR), (LPARAM)(void*)buf);if (AtlStrLen(buf) != 12 && AtlStrLen(buf) != 13){MessageBox(hWnd, _T("数字长度为12或者13位"), _T("提示"), 0);return 0;}ean13Build.SetBarCode(buf);TCHAR buf2[256];SendMessage(hInputZoom, WM_GETTEXT, sizeof(buf2) / sizeof(TCHAR), (LPARAM)(void*)buf2);m_izoom = atoi((char*)buf2) < 1 ? 1 : atoi((char*)buf2);rect.left = 0;rect.top = 0;rect.right = cxClient;rect.bottom = cyClient;InvalidateRect(hWnd, &rect, true);//擦除上次绘制的内容}break;default:return DefWindowProc(hWnd, message, wParam, lParam);}break;case WM_CREATE://添加编辑框hInputNum = CreateWindow(_T("edit"), NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,10, 20, 200, 30,hWnd, NULL, NULL, NULL);//添加编辑框hInputZoom = CreateWindow(_T("edit"), NULL,WS_CHILD | WS_VISIBLE | WS_BORDER,380, 20, 40, 30,hWnd, (HMENU)IDE_EDIT_ZOOM, NULL, NULL);m_izoom = 5;SetDlgItemText(hWnd, IDE_EDIT_ZOOM, _T("5"));//设置默认值5// 添加按钮Ean813Button = CreateWindow(TEXT("button"), TEXT("EAN13"),WS_CHILD | WS_VISIBLE,460, 20, 75, 30,hWnd, (HMENU)IDB_BUTTON_EAN813,((LPCREATESTRUCT)lParam)->hInstance, NULL);break;case WM_PAINT:hdc = BeginPaint(hWnd, &ps);// TODO//绘制区域,根据缩放倍数进行计算调整rect.left = cxClient / 2 - m_izoom * 50;rect.top = cyClient / 2 - m_izoom * 20;rect.right = cxClient / 2 + m_izoom * 50;rect.bottom = cyClient / 2 + m_izoom * 20;ean13Build.DrawBarCode(&hdc, rect);EndPaint(hWnd, &ps);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, message, wParam, lParam);}return 0;
}// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{UNREFERENCED_PARAMETER(lParam);switch (message){case WM_INITDIALOG:return (INT_PTR)TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL){EndDialog(hDlg, LOWORD(wParam));return (INT_PTR)TRUE;}break;}return (INT_PTR)FALSE;
}
职场人 |
---|
目前为止毕业11年,当初学习的是信息与计算科学 |
一直从事本专业工作,目前从事的行业为交通行业,一开始的入门导师给了我很大的帮助,教会了我很多技术,例如,对接海康,大华的网络摄像机SDK,指导一些与视频相关的知识点,让我很快了解掌握了入门技巧等等技术。 |
从毕业生到职场IT人,最大的感受是面对每天不一样的工作内容,每次都是挑战和机遇伴成长。 |
我觉得毕业季职场新人参与工作,要看重行业的发展前景,女怕嫁错郎,男怕入错行,就是这个道理。 |
工作中,技术er需要不断感悟及回顾已做过的一些事情,这样把问题弄懂弄通弄透。从而,会发现不一样的印象。 |
你用过哪些开源项目让你忍不住分享给朋友?若依框架,JEECGBOOT,等等 |
工作中用技术做过的事,申请的项目专利有我的名字,哈哈 |
程序员三十五岁瓶颈,这并不影响一个老程序员继续发光发热,我已经超过35了, |
路就在脚下,走稳每一步至关重要,一步一个脚印,创造美好生活,然后,贡献社会。 |
活动地址:毕业季·进击的技术er