C# 实现打印机新增自定义页面大小

5 篇文章 0 订阅
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct structSize
        {
            public Int32 width;
            public Int32 height;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct structRect
        {
            public Int32 left;
            public Int32 top;
            public Int32 right;
            public Int32 bottom;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct structFormInfo
        {
            [MarshalAs(UnmanagedType.I4)]
            public int Flags;
            [MarshalAs(UnmanagedType.LPTStr)]
            public String pName;
            public structSize Size;
            public structRect ImageableArea;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct structDevMode
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public String dmDeviceName;
            [MarshalAs(UnmanagedType.U2)]
            public short dmSpecVersion;
            [MarshalAs(UnmanagedType.U2)]
            public short dmDriverVersion;
            [MarshalAs(UnmanagedType.U2)]
            public short dmSize;
            [MarshalAs(UnmanagedType.U2)]
            public short dmDriverExtra;
            [MarshalAs(UnmanagedType.U4)]
            public int dmFields;
            [MarshalAs(UnmanagedType.I2)]
            public short dmOrientation;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperSize;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperLength;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPaperWidth;
            [MarshalAs(UnmanagedType.I2)]
            public short dmScale;
            [MarshalAs(UnmanagedType.I2)]
            public short dmCopies;
            [MarshalAs(UnmanagedType.I2)]
            public short dmDefaultSource;
            [MarshalAs(UnmanagedType.I2)]
            public short dmPrintQuality;
            [MarshalAs(UnmanagedType.I2)]
            public short dmColor;
            [MarshalAs(UnmanagedType.I2)]
            public short dmDuplex;
            [MarshalAs(UnmanagedType.I2)]
            public short dmYResolution;
            [MarshalAs(UnmanagedType.I2)]
            public short dmTTOption;
            [MarshalAs(UnmanagedType.I2)]
            public short dmCollate;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public String dmFormName;
            [MarshalAs(UnmanagedType.U2)]
            public short dmLogPixels;
            [MarshalAs(UnmanagedType.U4)]
            public int dmBitsPerPel;
            [MarshalAs(UnmanagedType.U4)]
            public int dmPelsWidth;
            [MarshalAs(UnmanagedType.U4)]
            public int dmPelsHeight;
            [MarshalAs(UnmanagedType.U4)]
            public int dmNup;
            [MarshalAs(UnmanagedType.U4)]
            public int dmDisplayFrequency;
            [MarshalAs(UnmanagedType.U4)]
            public int dmICMMethod;
            [MarshalAs(UnmanagedType.U4)]
            public int dmICMIntent;
            [MarshalAs(UnmanagedType.U4)]
            public int dmMediaType;
            [MarshalAs(UnmanagedType.U4)]
            public int dmDitherType;
            [MarshalAs(UnmanagedType.U4)]
            public int dmReserved1;
            [MarshalAs(UnmanagedType.U4)]
            public int dmReserved2;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        private struct structPrinterDefaults
        {
            [MarshalAs(UnmanagedType.LPTStr)]
            public String pDatatype;
            public IntPtr pDevMode;
            [MarshalAs(UnmanagedType.I4)]
            public int DesiredAccess;
        }

        [DllImport("winspool.Drv", EntryPoint = "OpenPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)]   string printerName, out IntPtr phPrinter, ref structPrinterDefaults pd);
        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool ClosePrinter(IntPtr phPrinter);
        [DllImport("winspool.Drv", EntryPoint = "AddForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool AddForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo form);
        [DllImport("winspool.Drv", EntryPoint = "DeleteForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool DeleteForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)] string pName);
        [DllImport("winspool.Drv", EntryPoint = "SetForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool SetForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)] string pName, [MarshalAs(UnmanagedType.I4)] int level, ref structFormInfo form);
        [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern Int32 GetLastError();
        [DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern IntPtr CreateDC([MarshalAs(UnmanagedType.LPTStr)]string pDrive, [MarshalAs(UnmanagedType.LPTStr)] string pName, [MarshalAs(UnmanagedType.LPTStr)] string pOutput, ref structDevMode pDevMode);
        [DllImport("GDI32.dll", EntryPoint = "ResetDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern IntPtr ResetDC(IntPtr hDC, ref structDevMode pDevMode);
        [DllImport("GDI32.dll", EntryPoint = "DeleteDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        private static extern bool DeleteDC(IntPtr hDC);

        public static void SetPrintForm(string printerName, string paperName, float width, float height)
        {
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                const int PRINTER_ACCESS_USE = 0x00000008;
                const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
                structPrinterDefaults defaults = new structPrinterDefaults();
                defaults.pDatatype = null;
                defaults.pDevMode = IntPtr.Zero;
                defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
                IntPtr hPrinter = IntPtr.Zero;
                if (OpenPrinter(printerName, out hPrinter, ref defaults))
                {
                    try
                    {
                        structFormInfo formInfo = new structFormInfo();
                        formInfo.Flags = 0;
                        formInfo.pName = paperName;
                        formInfo.Size.width = (int)(width * 100.0);
                        formInfo.Size.height = (int)(height * 100.0);
                        formInfo.ImageableArea.left = 0;
                        formInfo.ImageableArea.right = formInfo.Size.width;
                        formInfo.ImageableArea.top = 0;
                        formInfo.ImageableArea.bottom = formInfo.Size.height;
                        bool result = false;
                        short i = -1;
                        if (GetPrintForm(printerName, paperName, out i) != null)
                        {
                            result = SetForm(hPrinter, paperName, 1, ref formInfo);
                        }
                        else
                        {
                            AddCustomPaperSize(printerName, paperName, width, height);
                            result = true;
                        }

                        if (!result)
                        {
                            throw new Exception(string.Format("添加纸张“{0}”时发生错误,系统错误信息:{1}", paperName, GetLastError()));
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("添加纸张“{0}”时发生错误", paperName, GetLastError()), ex);

                    }
                    finally
                    {
                        ClosePrinter(hPrinter);
                    }
                }
            }
        }

        public static PaperSize GetPrintForm(string printerName, string paperName, out short id)
        {
            short i = 0;
            id = -1;
            System.Drawing.Printing.PrinterSettings printerSettings = new System.Drawing.Printing.PrinterSettings();
            printerSettings.PrinterName = printerName;
            foreach (System.Drawing.Printing.PaperSize ps in printerSettings.PaperSizes)
            {
                i++;
                if (ps.PaperName.ToLower() == paperName.ToLower())
                {
                    id = i;
                    return ps;
                }
            }
            return null;
        }

        public static void AddCustomPaperSize(string printerName, string paperName, float width, float height)
        {
            if (Environment.OSVersion.Platform == PlatformID.Win32NT)
            {
                const int PRINTER_ACCESS_USE = 0x00000008;
                const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
                structPrinterDefaults defaults = new structPrinterDefaults();
                defaults.pDatatype = null;
                defaults.pDevMode = IntPtr.Zero;
                defaults.DesiredAccess = PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE;
                IntPtr hPrinter = IntPtr.Zero;
                if (OpenPrinter(printerName, out hPrinter, ref defaults))
                {
                    try
                    {
                        DeleteForm(hPrinter, paperName);
                        structFormInfo formInfo = new structFormInfo();
                        formInfo.Flags = 0;
                        formInfo.pName = paperName;
                        formInfo.Size.width = (int)(width * 100.0);
                        formInfo.Size.height = (int)(height * 100.0);
                        formInfo.ImageableArea.left = 0;
                        formInfo.ImageableArea.right = formInfo.Size.width;
                        formInfo.ImageableArea.top = 0;
                        formInfo.ImageableArea.bottom = formInfo.Size.height;
                        if (!AddForm(hPrinter, 1, ref formInfo))
                        {
                            throw new Exception(string.Format("添加纸张“{0}”时发生错误,系统错误信息:{1}", paperName, GetLastError()));
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new Exception(string.Format("添加纸张“{0}”时发生错误", paperName, GetLastError()), ex);
                    }
                    finally
                    {
                        ClosePrinter(hPrinter);
                    }
                }
                else
                {
                    throw new Exception(string.Format("打开打印机“{0}”时发生错误,系统错误信息:{1}", printerName, GetLastError()));
                }
            }
            else
            {
                structDevMode devMode = new structDevMode();
                IntPtr hDC = CreateDC(null, printerName, null, ref devMode);
                if (hDC != IntPtr.Zero)
                {
                    const long DM_PAPERSIZE = 0x00000002L;
                    const long DM_PAPERLENGTH = 0x00000004L;
                    const long DM_PAPERWIDTH = 0x00000008L;
                    devMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
                    devMode.dmPaperSize = 256;
                    devMode.dmPaperWidth = (short)(width * 2.54 * 10000.0);
                    devMode.dmPaperLength = (short)(height * 2.54 * 10000.0);
                    ResetDC(hDC, ref devMode);
                    DeleteDC(hDC);
                }
            }
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VC 获得打印页面信息,主要是获得打印页面宽度、高度、物理页面宽度、高度、上、下、左、右页边距等信息。不想下载完整源码包的,可先看下面的核心代码段:   //打印对话框   DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS    | PD_NOSELECTION | PD_HIDEPRINTTOFILE;   CPrintDialog dlg(FALSE);   if (dlg.DoModal() == IDOK)   {    //获得打印机DC    HDC hDC = dlg.GetPrinterDC();    if (hDC == NULL)    {    return;    }    //通过HDC获得CDC指针    CDC* pDC = CDC::FromHandle(hDC);    //获得打印页面宽度    int nHorzSize = pDC->GetDeviceCaps(HORZRES);    //获得打印页面高度    int nVertSize = pDC->GetDeviceCaps(VERTRES);    //获得物理页面宽度    int nWidth = pDC->GetDeviceCaps(PHYSICALWIDTH);    //获得物理页面高度    int nHeight = pDC->GetDeviceCaps(PHYSICALHEIGHT);    //获得左、右边距    int nOffsetX = pDC->GetDeviceCaps(PHYSICALOFFSETX);    //获得上、下边距    int nOffsetY= pDC->GetDeviceCaps(PHYSICALOFFSETY);    CString strText = _T("");    strText.Format(_T("%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d"),    _T("打印页面宽度:"), nHorzSize,    _T("打印页面高度:"), nVertSize,    _T("物理页面宽度:"), nWidth,    _T("物理页面高度:"), nHeight,    _T("左右边距:"), nOffsetX,    _T("上下边距:"), nOffsetY);    AfxMessageBox(strText);   }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值