winform使用Barcodex控件预览和打印一维码

控件下载

包含barcodex.ocx控件、barcodex帮助文档、两个winform控件的dll文件
https://files.cnblogs.com/files/masonblog/barcodex.zip

控件的注册

(1)检测控件是否注册(方法不唯一)
本例使用的是判断注册表中 HKEY_CLASSES_ROOT\TypeLib\ 是否包含barcodex.ocx的项。
如果注册了barcodex.ocx控件,则会生成对应的项。
HKEY_CLASSES_ROOT\TypeLib{8E515444-86DF-11D3-A630-444553540001} 。
注:该项最后的 {8E515444-86DF-11D3-A630-444553540001} 为barcodex.ocx控件唯一GUID值。

(2)注册ocx控件(提供三种方法)
①调用命令提示符。(barcodex.ocx必须在应用程序的根目录)
System.Diagnostics.Process.Start("regsvr32", "barcodex.ocx /s");进行注册。
②调用bat。(与①类似,未使用过)
在应用程序的根目录编辑好一个bat。命名为" install.bat ",内容为“ regsvr32.exe barcodex.ocx ”。barcodex.ocx必须在应用程序的根目录。
再调用System.Diagnostics.Process.Start("regsvr32", "install.bat ");进行注册。
③调用ocx的注册入口函数。(本例使用)
Ⅰ、将文件复制到" C:\windows\ "目录下(文件目录是次要,笔者是考虑误删,才选择此目录。)
Ⅱ、声明调用的函数(需要引用 using System.Runtime.InteropServices;)

[DllImport("C:\\Windows\\barcodex.ocx")]
public static extern int DllRegisterServer();//注册时用
[DllImport("C:\\Windows\\barcodex.ocx")]
public static extern int DllUnregisterServer();//取消注册时用

Ⅲ、自定义的注册方法。      

public static bool DLLRegister()
{

  int i = DllRegisterServer();
  if (i >= 0)
  {
    return true;
  }
  else
  {
    return false;
  }
}

控件的引用

(1)引用AxInterop.BARCODEXLib.dll和Interop.BARCODEXLib.dll文件。
(2)工具箱->所有windows窗体->右键 选择项->选择com组件 。
找到名称为BarcodeX by Fath Software,路径为c:\windows\barcodex.ocx 的项,选中,添加。即可完成添加。

拖入控件

拖入条形码控件到winform窗体中,设置Name为axBCX。

预览一维码

(1)axBCX.BarcodeType=BARCODEXLib.bcxTypeEnum.bcxCode128;//设置条形码类型,
(2)axBCX.Caption = "123456789";//要显示的条形码
(3)axBCX.Height=150;//条形码的高度
(4)axBCX.Width=80;//条形码的宽度
(5)axBCX.Title="条形码的预览";//条形码的标题
至此,即可完成Barcodex条形码的预览功能。

打印条形码

(1)原理:将条形码区域截取为image进行打印(两种方法)。
①使用axBCX.Picture 属性,即可获取其对应的image对象,但是此属性需要ComAliasName("stdole.IPictureDisp")的支持,此为office扩展,客户机器不一定安装,所以不建议使用。
②使用axBCX.CreateBMP();方法,将条形码截取为bmp图片,再进行打印。
(2)打印实现。
①基本流程

/// <summary>
/// 打印按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnPrint_Click(object sender, EventArgs e)
{
    /*获取值*/
    string sSchoolName = txtSchoolName.Text.Trim();//学校名称
    //开始截至次数
    string sBeginBarcode = txtBeginBarcode.Text.Trim();//(000001)
    string sEndBarcode = txtEndBarcode.Text.Trim();//(000009)
    string sRepeatCount = txtRepeatCount.Text.Trim();//3,代表每个条形码打印的次数
    //标签高宽
    decimal dLabelHeight = nudLabelHeight.Value;
    decimal dLabelWidth = nudLabelWidth.Value;
    //边距
    decimal dTopMargin = nudTopMargin.Value;//条形码在整个标签的上边距
    decimal dLeftMargin = nudLeftMargin.Value;//条形码在整个标签的左边距 
    //显示内容
    bool bIsShowSchoolName = chkShowSchoolName.Checked;//是否显示标题
    //条形码的码制
    string sBarcode = cmbBarcode.SelectedItem.ToString();//选择的条形码的码制。可以写死,可以使用下拉框供选择。
   PrintDocument pd=null; //打印对象的声明,之后在循环再进行对象的实例化。
    try
    {
        /*转换*/
        //开始截至次数
        //判断条形码中是否含有字母
        bool bIsHaveLetter = false;
        string sLetterBeginBarcode = string.Empty;//开始条形码字母部分
        string sNumberBeginBarcode = string.Empty;//开始条形码数字部分
        string sLetterEndBarcode = string.Empty;//截止条形码字母部分
        string sNumberEndBarcode = string.Empty;//截止条形码数字部分
        if (char.IsLetter(sBeginBarcode[0]))
        {
            bIsHaveLetter = true;
            sLetterBeginBarcode = sBeginBarcode.Substring(0, 1);
            sNumberBeginBarcode = sBeginBarcode.Substring(1, sBeginBarcode.Length - 1);
        }

        if (char.IsLetter(sEndBarcode[0]))
        {
            bIsHaveLetter = true;
            sLetterEndBarcode = sEndBarcode.Substring(0, 1);
            sNumberEndBarcode = sEndBarcode.Substring(1, sEndBarcode.Length - 1);
        }
        long lBeginBarcode = bIsHaveLetter ? long.Parse(sNumberBeginBarcode) : long.Parse(sBeginBarcode);
        long lEndBaecode = bIsHaveLetter ? long.Parse(sNumberEndBarcode) : long.Parse(sEndBarcode);
        int iRepeatCount = int.Parse(sRepeatCount);

        //删除之前生成的图片
        Utility.DeletePreviewBarcode();
        //预览图片的地址
        string sPreviewPath = Utility.ConfigGetItem("PreviewPath"); //<add key="PreviewPath" value="C:\\BarcodePreview"/> 生成的bmp文件保存的路径。
        //设置边距
        Margins margin = new Margins(Utility.GetPixelByWidth(dLeftMargin), 0, Utility.GetPixelByHeight(dTopMargin), 0);
        59                 //控件设置
        axBCX.BarcodeType = Utility.GetbcxTypeByBarcode(sBarcode);
        axBCX.Height = Utility.GetPixelByWidth(dLabelHeight - dTopMargin);
        axBCX.Width = Utility.GetPixelByHeight(dLabelWidth - dLeftMargin);

        for (long i = lBeginBarcode; i <= lEndBaecode; i++)
        {
            for (int j = 0; j < iRepeatCount; j++)
            {
                pd=new PrintDocument();//重新示例化打印对象,防止pd_PrintPage()方法附加多次导致堆积。 69                         pd.DefaultPageSettings.Margins = margin; 
                axBCX.Title = "";
                //条形码控件重新赋值(打印时获取image)
                if (bIsHaveLetter)
                {
                    axBCX.Caption = sLetterBeginBarcode + i.ToString().PadLeft(sBeginBarcode.Length - 1, '0');
                }
                else
                {
                    axBCX.Caption = i.ToString().PadLeft(sBeginBarcode.Length, '0');
                }
                //创建对应的条形码图片
                string sFileName = sPreviewPath + "\\" + axBCX.Caption + ".bmp";
                axBCX.CreateBMP(sFileName, axBCX.Width, axBCX.Height);
                //横向打印
                pd.DefaultPageSettings.Landscape = true;
                //页面尺寸
                pd.DefaultPageSettings.PaperSize = new PaperSize("Custom", Utility.GetPixelByWidth(dLabelWidth), Utility.GetPixelByWidth(dLabelHeight));
                pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
                pd.Print();
            }
        }
        //删除之前生成的图片
        Utility.DeletePreviewBarcode();
    }
    catch (Exception ex)
    {
        string str = Utility.GetExceptionMsg(ex, ex.ToString());
        Utility.WriteLog(str);
        //获取程序执行异常的提示信息
        MessageBox.Show("打印失败!");
    }
}

//打印事件处理
private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
    //显示内容
    bool bIsShowSchoolName = chkShowSchoolName.Checked;
    //左边距
    float fLeftMargin = float.Parse(nudLeftMargin.Value.ToString());
    //1、获取对应的条形码图片
    string sPreviewPath = Utility.ConfigGetItem("PreviewPath");
    string sFileName = sPreviewPath + "\\" + axBCX.Caption + ".bmp";
    Image imgBarcode = Image.FromFile(sFileName);
    Image imgAll;
    //2.1、显示学校名称
    if (bIsShowSchoolName)
    {
        //2.1.1、Title的图片
        Image imgTitle = Utility.CreateImage(txtSchoolName.Text, false, 8, imgBarcode.Width, imgBarcode.Height, Utility.MarginLeftByBarcodeLength(axBCX.Caption, fLeftMargin));
        //2.1.2、合并图片
        imgAll = Utility.MergeImage(imgBarcode, imgTitle);
        imgTitle.Dispose();
    }
    //2.2、不显示学校名称
    else
    {
        imgAll = imgBarcode;
    }
    //Image image = axBCX.Picture;
    int x = e.MarginBounds.X;
    int y = e.MarginBounds.Y;
    int width = imgAll.Width;
    int height = imgAll.Height;
    //打印区域的大小,是Rectangle结构,元素包括左上角坐标:Left和Top,宽和高.
    Rectangle destRect = new Rectangle(x, y, width, height);
    e.Graphics.DrawImage(imgAll, destRect, 0, 0, imgAll.Width, imgAll.Height, System.Drawing.GraphicsUnit.Pixel);
    //释放资源(否则删除操作无法完成)                        
    imgBarcode.Dispose();
    imgAll.Dispose();
}

②Utility类中使用的方法。

public static class Utility
{        
        /// <summary>
        /// 获取键为keyName的项的值
        /// </summary>
        /// <param name="keyName"></param>
        /// <returns></returns>
        public static string ConfigGetItem(string keyName)
        {
            //返回配置文件中键为keyName的项的值  
            return ConfigurationManager.AppSettings[keyName];
        }
        #region 输入长度(毫米mm)获取匹配分辨率下的像素数
        /// <summary> 
        /// 根据输入的宽度获取对应的 x 轴的像素
        /// </summary>
        /// <param name="dWidth"></param>
        /// <returns></returns>
        public static int GetPixelByWidth(decimal dWidth)
        {
            //声明变量
            int iDpiX = 96;//x轴DPI默认为96
            double dPixelX = 0;//讲过计算的像素数
            //获取屏幕x轴的DPI
            iDpiX = PrimaryScreen.DpiX;
            //根据换算关系计算对应的像素数
            dPixelX = ((double)dWidth) * iDpiX / 25.4;
            //转换为int类型返回
            return (int)dPixelX;
        }
        /// <summary>
        /// 根据输入的高度获取对应的 y 轴的像素
        /// </summary>
        /// <param name="dHeight"></param>
        /// <returns></returns>
        public static int GetPixelByHeight(decimal dHeight)
        {
            //声明变量
            int iDpiY = 96;//Y轴DPI默认为96
            double dPiYelY = 0;//讲过计算的像素数
            //获取屏幕Y轴的DPI
            iDpiY = PrimaryScreen.DpiY;
            //根据换算关系计算对应的像素数
            dPiYelY = ((double)dHeight) * iDpiY / 25.4;
            //转换为int类型返回
            return (int)dPiYelY;
        }
        #endregion
         #region 图片操作方法(生成文字图片、合并图片等)
        /// <summary>
        /// 生成文字图片
        /// </summary>
        /// <param name="text"></param>
        /// <param name="isBold"></param>
        /// <param name="fontSize"></param>
        public static Image CreateImage(string text, bool isBold, int fontSize, int wid, int high, float leftMargin)
        {
            Font font;
            if (isBold)
            {
                font = new Font("Arial", fontSize, FontStyle.Bold);
            }
            else
            {
                font = new Font("Arial", fontSize, FontStyle.Regular);
            }
            //绘笔颜色
            SolidBrush brush = new SolidBrush(Color.Black);
            StringFormat format = new StringFormat(StringFormatFlags.NoClip);

            Bitmap image = new Bitmap(wid, high);
            Graphics g = Graphics.FromImage(image);

            SizeF sizef = g.MeasureString(text, font, PointF.Empty, format);//得到文本的宽高
            int width = (int)(sizef.Width + 1);
            int height = (int)(sizef.Height + 2);
            image.Dispose();
            
            image = new Bitmap(wid, height);
            g = Graphics.FromImage(image);
            g.Clear(Color.White);//透明            
            float fLeft = leftMargin; //左边距
            RectangleF rect = new RectangleF(fLeft, 0, width, height);
            //绘制图片
            g.DrawString(text, font, brush, rect);

            //释放对象
            g.Dispose();
            return image;
        }

        /// <summary>
        /// 合并图片
        /// </summary>
        /// <returns></returns>
        public static Bitmap MergeImage(Image imgBack, Image img, int xDeviation = 0, int yDeviation = 0)
        {
            Bitmap bmp = new Bitmap(imgBack.Width, imgBack.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.Clear(Color.White);
            g.DrawImage(imgBack, 0, 0, imgBack.Width, imgBack.Height); //g.DrawImage(imgBack, 0, 0, 相框宽, 相框高);     
            //g.FillRectangle(System.Drawing.Brushes.White, imgBack.Width / 2 - img.Width / 2 - 1, imgBack.Width / 2 - img.Width / 2 - 1,1,1);//相片四周刷一层黑色边框    
            //g.DrawImage(img, 照片与相框的左边距, 照片与相框的上边距, 照片宽, 照片高);    
            g.DrawImage(img, 0, 0, img.Width, img.Height);
            GC.Collect();
            return bmp;
        }
        #endregion
}

③PrimaryScreen类

/// <summary>
/// 获取屏幕分辨率属性
/// </summary>
public class PrimaryScreen
{
    #region Win32 API
    [DllImport("user32.dll")]
    static extern IntPtr GetDC(IntPtr ptr);
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(
   IntPtr hdc, // handle to DC
   int nIndex // index of capability
   );
    [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
    static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
    #endregion
    #region DeviceCaps常量
    const int HORZRES = 8;
    const int VERTRES = 10;
    const int LOGPIXELSX = 88;
    const int LOGPIXELSY = 90;
    const int DESKTOPVERTRES = 117;
    const int DESKTOPHORZRES = 118;
    #endregion

    #region 属性
    /// <summary>
    /// 获取屏幕分辨率当前物理大小
    /// </summary>
    public static Size WorkingArea
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            Size size = new Size();
            size.Width = GetDeviceCaps(hdc, HORZRES);
            size.Height = GetDeviceCaps(hdc, VERTRES);
            ReleaseDC(IntPtr.Zero, hdc);
            return size;
        }
    }
    /// <summary>
    /// 当前系统DPI_X 大小 一般为96
    /// </summary>
    public static int DpiX
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
            ReleaseDC(IntPtr.Zero, hdc);
            return DpiX;
        }
    }
    /// <summary>
    /// 当前系统DPI_Y 大小 一般为96
    /// </summary>
    public static int DpiY
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
            ReleaseDC(IntPtr.Zero, hdc);
            return DpiX;
        }
    }
    /// <summary>
    /// 获取真实设置的桌面分辨率大小
    /// </summary>
    public static Size DESKTOP
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            Size size = new Size();
            size.Width = GetDeviceCaps(hdc, DESKTOPHORZRES);
            size.Height = GetDeviceCaps(hdc, DESKTOPVERTRES);
            ReleaseDC(IntPtr.Zero, hdc);
            return size;
        }
    }

    /// <summary>
    /// 获取宽度缩放百分比
    /// </summary>
    public static float ScaleX
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            int t = GetDeviceCaps(hdc, DESKTOPHORZRES);
            int d = GetDeviceCaps(hdc, HORZRES);
            float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
            ReleaseDC(IntPtr.Zero, hdc);
            return ScaleX;
        }
    }
    /// <summary>
    /// 获取高度缩放百分比
    /// </summary>
    public static float ScaleY
    {
        get
        {
            IntPtr hdc = GetDC(IntPtr.Zero);
            float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
            ReleaseDC(IntPtr.Zero, hdc);
            return ScaleY;
        }
    }
    #endregion
}

④删除之前生成的图片

Utility.DeletePreviewBarcode();

#region 删除条形码预览文件夹下的所有图片
/// <summary>
/// 删除预览的条形码图片
/// </summary>
public static void DeletePreviewBarcode()
{
    string sPath = string.IsNullOrEmpty(ConfigGetItem("PreviewPath")) ? "C:\\BarcodePreview" : Utility.ConfigGetItem("PreviewPath");
    //如果存在先删除其中的文件
    if (Directory.Exists(sPath))
    {
        Directory.Delete(sPath, true);
    }
    Directory.CreateDirectory(sPath);
}
#endregion
posted @ 2017-07-26 11:05  我有我奥妙  阅读(2838)  评论(0)    收藏  举报