当前位置:编程学习 > C#/ASP.NET >>

用api函数添加自定义纸张,能成功添加,却获取不到,求救!

//具体的问题在代码的注释上,用红字标出

using System;
using System.Text;
using System.Runtime;
using System.Security;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace ClientCommon.CustomControls
{
    /// <summary>
    /// 添加自定义纸张
    /// </summary>
    public class DBPaperSize
    {
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

        internal 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()]
        internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPTStr)]   
        string printerName, out IntPtr phPrinter, structPrinterDefaults pd);

        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern bool ClosePrinter(IntPtr phPrinter);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal struct structSize
        {
            public Int32 width;
            public Int32 height;
        }

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

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

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        internal 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;

        }

        [DllImport("winspool.Drv", EntryPoint = "AddForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern int AddForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.I4)]   int level, ref   structFormInfo1 form);

        [DllImport("winspool.Drv", EntryPoint = "DeleteForm", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal 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()]
        internal static extern bool SetForm(IntPtr phPrinter, [MarshalAs(UnmanagedType.LPTStr)]   string pName, [MarshalAs(UnmanagedType.I4)]   int level, ref   structFormInfo1 form);

        [DllImport("kernel32.dll", EntryPoint = "GetLastError", SetLastError = false, ExactSpelling = true, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal static extern Int32 GetLastError();

        [DllImport("GDI32.dll", EntryPoint = "CreateDC", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall), SuppressUnmanagedCodeSecurityAttribute()]
        internal 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()]
        internal 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()]
        internal static extern bool DeleteDC(IntPtr hDC);

        public System.Drawing.Printing.PaperSize GetPrintForm(string printerName, string 易做图Name)
        {
            System.Drawing.Printing.PaperSize 易做图 = null;
            System.Drawing.Printing.PrinterSettings printer = new System.Drawing.Printing.PrinterSettings();
            
            printer.PrinterName = printerName;
            foreach (System.Drawing.Printing.PaperSize ps in printer.PaperSizes)
            {
                if (ps.PaperName.ToLower() == 易做图Name.ToLower())
                {
                    易做图 = ps;
                    break;
                }
            }
            return 易做图;
        }
--------------------编程问答--------------------         /// <summary>
        /// 设置打印的纸张为指定名称的自定义纸张
        /// </summary>
        /// <param name="printerName">打印机名称</param>
        /// <param name="易做图Name">纸张名称</param>
        /// <param name="width">纸张宽度</param>
        /// <param name="height">纸张高度</param>
        public void SetPrintForm(string printerName, string 易做图Name, float width, float height)
        {
            if (PlatformID.Win32NT == Environment.OSVersion.Platform)
            {
                const int PRINTER_ACCESS_USE = 0x00000008;
                const int PRINTER_ACCESS_ADMINISTER = 0x00000004;
                const int STANDARD_RIGHTS_REQUIRED = 0xf0000;
                const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE); 
                structPrinterDefaults defaults = new structPrinterDefaults();
                defaults.pDatatype = null;
                defaults.pDevMode = IntPtr.Zero;
                defaults.DesiredAccess = PRINTER_ALL_ACCESS;
                IntPtr hPrinter = IntPtr.Zero;
                if (OpenPrinter(printerName, out   hPrinter, defaults))
                {
                    try
                    {
                        structFormInfo1 formInfo = new structFormInfo1();
                        formInfo.Flags = 0;
                        formInfo.pName = 易做图Name;
                        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 rslt = false;
                        if (GetPrintForm(printerName, 易做图Name) != null)
                        {
                            //如果手工添加的自定义纸张经过此函数设置后,原来能获取的现在也获取不到了 ????
                            rslt = SetForm(hPrinter, 易做图Name, 1, ref formInfo);
                        }
                        else
                        {
                            this.AddCustomPaperSize(printerName, 易做图Name, width, height);
                            rslt = true;
                        }
                        if (!rslt)
                        {
                            StringBuilder strBuilder = new StringBuilder();
                            strBuilder.AppendFormat("添加纸张{0}时发生错误!,   系统错误号:   {1}", 易做图Name, GetLastError());
                            BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
                        }

                    }
                    finally
                    {
                        ClosePrinter(hPrinter);
                    }
                }
            }

        }
        /// <summary>
        /// 为打印机添加自定义纸张
        /// </summary>
        /// <param name="printerName">打印机名称</param>
        /// <param name="易做图Name">自定义纸张名称</param>
        /// <param name="width">纸张宽度</param>
        /// <param name="height">纸张高度</param>
        public void AddCustomPaperSize(string printerName, string 易做图Name, float width, float height)
        {
            if (PlatformID.Win32NT == Environment.OSVersion.Platform)
            {
                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, defaults))
                {
                    try
                    {
                        DeleteForm(hPrinter, 易做图Name);
                        structFormInfo1 formInfo = new structFormInfo1();
                        formInfo.Flags = 0;
                        formInfo.pName = 易做图Name;
                        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) == 0)
                        {
                            StringBuilder strBuilder = new StringBuilder();
                            strBuilder.AppendFormat("添加纸张{0}时发生错误!,系统错误号:{1}", 易做图Name, GetLastError());
                            BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
                        }
                    }
                    finally
                    {
                        ClosePrinter(hPrinter);
                    }
                }
                else
                {
                    StringBuilder strBuilder = new StringBuilder();
                    strBuilder.AppendFormat("打开打印机{0}时出现异常!,系统错误号:{1}", printerName, GetLastError());
                    BaseClass.MessageError.OnlyShowErrorMessage.Show(strBuilder.ToString());
                }
            }
            else
            {
                structDevMode pDevMode = new structDevMode();
                IntPtr hDC = CreateDC(null, printerName, null, ref   pDevMode);
                if (hDC != IntPtr.Zero)
                {
                    const long DM_PAPERSIZE = 0x00000002L;
                    const long DM_PAPERLENGTH = 0x00000004L;
                    const long DM_PAPERWIDTH = 0x00000008L;
                    pDevMode.dmFields = (int)(DM_PAPERSIZE | DM_PAPERWIDTH | DM_PAPERLENGTH);
                    pDevMode.dmPaperSize = 256;
                    pDevMode.dmPaperWidth = (short)(width * 2.54 * 10000.0);
                    pDevMode.dmPaperLength = (short)(height * 2.54 * 10000.0);
                    ResetDC(hDC, ref   pDevMode);
                    DeleteDC(hDC);
                }
            }
        }
    }
}


调用 :
DBPaperSize myDBPaperSize = new DBPaperSize();
myDBPaperSize = new DBPaperSize();
myDBPaperSize.SetPrintForm(printDocument1.PrinterSettings.DefaultPageSettings.PrinterSettings.PrinterName,
                    "测试", 1400, 750);
//执行到这儿,在打印服务器属性中能看到这个新增的自定义纸张,但是在下面的函数中却获取不到。
//如果在打印服务器属性中手工加自定义纸张的话,是能获取的,所以怀疑程序添加自定义纸张哪里有问题,请各位大虾指教
//????
printDocument1.DefaultPageSettings.PaperSize = myDBPaperSize.GetPrintForm(printDocument1.PrinterSettings.DefaultPageSettings.PrinterSettings.PrinterName,
                "测试");
--------------------编程问答-------------------- 代码的关键部分没啥问题,如果PaperSize没在PrinterSettings.PaperSizes出现的话,说明该打印机不支持该定义的纸张大小(长宽和边距,不在该打印机支持的泛围内)

你可以通过打印机文件夹中选定的打印首选项,看它是否支持你定义的纸张,如果列表中没有出现,说明不支持

--------------------编程问答-------------------- 同样的纸张大小如果在打印服务器属性中手工加自定义纸张的话,是能获取的,我怀疑是不是有什么权限或者其他什么问题 --------------------编程问答-------------------- --------------------编程问答-------------------- 跟踪一下GetPrintForm方法的返回值,只要不是返回null问题就不大

你这个方法其实多余

正式设置打印页面时,还得从PrintDocument.PrinterSettings.PaperSizes中去取,否则还是容易出现设定不过去(A4之类的没问题,自定义的就是这种样) --------------------编程问答-------------------- jointan能不能给俺一段参考代码?我的QQ是149302885,能否在线讨论 --------------------编程问答-------------------- 难道就没有真正的高手帮俺看一下吗
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,