C#:调用API函数,弹出对话框更改打印机默认设置(神贴啊)

转自:http://blog.csdn.net/fujie724/article/details/5386443

虽然说.NET为我们提供了很多打印设置的功能,比如PrintDialog。

可是有的功能是没有实现的,比如PrintDialog的窗体中,按下“打印机”后,出来的打印机设置窗口。

会发现,这个打印机设置会根据不同的打印机而不同。

而它更改的,是打印机的默认设置。

怎么实现这个功能呢?

这个难题让我在网上寻觅了一个星期。

也没有找到实现这个功能的代码。

要么就是只能弹出这个对话框,不能保存修改。

要么就是只能直接修改设置,不能弹出对话框。

经过一番摸索和尝试。我终于得出了以下的一个类。调用这个类唯一的公共方法,ChangePrinterSetting(string PrinterName),即可以修改相应名字的打印机默认设置。VS2005下调试通过。希望对需要的朋友有所帮助。希望转载的朋友能注明出处。谢谢。

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
namespace PrinterSetting
{
    //written by fujie
    public class PrinterSetting
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct PRINTER_DEFAULTS
        {
            public int pDatatype;
            public int pDevMode;
            public int DesiredAccess;
        }
        [StructLayout(LayoutKind.Sequential)]
        struct PRINTER_INFO_2
        {
            [MarshalAs(UnmanagedType.LPStr)]
            public string pServerName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pPrinterName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pShareName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pPortName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDriverName;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pComment;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pLocation;
            public IntPtr pDevMode;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pSepFile;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pPrintProcessor;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pDatatype;
            [MarshalAs(UnmanagedType.LPStr)]
            public string pParameters;
            public IntPtr pSecurityDescriptor;
            public Int32 Attributes;
            public Int32 Priority;
            public Int32 DefaultPriority;
            public Int32 StartTime;
            public Int32 UntilTime;
            public Int32 Status;
            public Int32 cJobs;
            public Int32 AveragePPM;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct DEVMODE
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string dmDeviceName;
            public short dmSpecVersion;
            public short dmDriverVersion;
            public short dmSize;
            public short dmDriverExtra;
            public int dmFields;
            public short dmOrientation;
            public short dmPaperSize;
            public short dmPaperLength;
            public short dmPaperWidth;
            public short dmScale;
            public short dmCopies;
            public short dmDefaultSource;
            public short dmPrintQuality;
            public short dmColor;
            public short dmDuplex;
            public short dmYResolution;
            public short dmTTOption;
            public short dmCollate;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string dmFormName;
            public short dmUnusedPadding;
            public short dmBitsPerPel;
            public int dmPelsWidth;
            public int dmPelsHeight;
            public int dmDisplayFlags;
            public int dmDisplayFrequency;
        }
        #region ■变量_____________________________________________________________
        private IntPtr hPrinter = new System.IntPtr();
        private PRINTER_DEFAULTS PrinterValues = new PRINTER_DEFAULTS();
        private PRINTER_INFO_2 pinfo = new PRINTER_INFO_2();
        private DEVMODE dm;
        private IntPtr ptrDM;
        private IntPtr ptrPrinterInfo;
        private int sizeOfDevMode = 0;
        private int lastError;
        private int nBytesNeeded;
        private long nRet;
        private int intError;
        private System.Int32 nJunk;
        private IntPtr yDevModeData;
        #endregion
        #region ■API___________________________________________________________
        [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true,
          ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool ClosePrinter(IntPtr hPrinter);
        [DllImport("winspool.Drv", EntryPoint = "DocumentPropertiesA", SetLastError = true,
          ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern int DocumentProperties(IntPtr hwnd, IntPtr hPrinter,
         [MarshalAs(UnmanagedType.LPStr)] string pDeviceNameg,
         IntPtr pDevModeOutput, ref IntPtr pDevModeInput, int fMode);
        [DllImport("winspool.Drv", EntryPoint = "GetPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
          ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool GetPrinter(IntPtr hPrinter, Int32 dwLevel,
         IntPtr pPrinter, Int32 dwBuf, out Int32 dwNeeded);
        [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi,
          ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter,
         out IntPtr hPrinter, ref PRINTER_DEFAULTS pd);
        [DllImport("winspool.drv", CharSet = CharSet.Ansi, SetLastError = true)]
        private static extern bool SetPrinter(IntPtr hPrinter, int Level, IntPtr
         pPrinter, int Command);
        #endregion
        #region ■常数_____________________________________________________________
        private const int DM_OUT_BUFFER = 2;
        private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
        private const int PRINTER_ACCESS_ADMINISTER = 0x4;
        private const int PRINTER_ACCESS_USE = 0x8;
        private const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
        #endregion
        #region ■方法_____________________________________________________________
        public void ChangePrinterSetting(string i_printerName)
        {
            DEVMODE dm;
            IntPtr pPrinter = IntPtr.Zero;
            IntPtr pDevModeOutput = IntPtr.Zero;
            IntPtr pDevModeInput = IntPtr.Zero;
            PrinterValues.pDatatype = 0;
            PrinterValues.pDevMode = 0;
            PrinterValues.DesiredAccess = PRINTER_ALL_ACCESS;
            OpenPrinter(i_printerName, out pPrinter, ref PrinterValues);
            int iNeeded = DocumentProperties(IntPtr.Zero, pPrinter, i_printerName, pDevModeOutput, ref pDevModeInput, 0);
            pDevModeOutput = Marshal.AllocHGlobal(iNeeded);
            int mode = 2 | 4;
            int nRet = DocumentProperties(IntPtr.Zero, pPrinter, i_printerName, pDevModeOutput, ref pDevModeInput, mode);
            if (nRet == 1)
            {
                dm = (DEVMODE)Marshal.PtrToStructure(pDevModeOutput, typeof(DEVMODE));
                ChangePrinterSetting(i_printerName, ref dm);
            }
            ClosePrinter(pPrinter);
        }
        private void ChangePrinterSetting(string i_printerName, ref DEVMODE i_fujie)
        {
            {
                dm = this.GetPrinterSettings(i_printerName);
                dm = i_fujie;
                Marshal.StructureToPtr(dm, yDevModeData, true);
                pinfo.pDevMode = yDevModeData;
                pinfo.pSecurityDescriptor = IntPtr.Zero;
                Marshal.StructureToPtr(pinfo, ptrPrinterInfo, true);
                lastError = Marshal.GetLastWin32Error();
                nRet = Convert.ToInt16(SetPrinter(hPrinter, 2, ptrPrinterInfo, 0));
                if (nRet == 0)
                {
                    lastError = Marshal.GetLastWin32Error();
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                if (hPrinter != IntPtr.Zero)
                    ClosePrinter(hPrinter);
            }
        }
        private DEVMODE GetPrinterSettings(string i_printerName)
        {
            DEVMODE dm;
            nRet = Convert.ToInt32(OpenPrinter(i_printerName, out hPrinter, ref PrinterValues));
            if (nRet == 0)
            {
                lastError = Marshal.GetLastWin32Error();
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            GetPrinter(hPrinter, 2, IntPtr.Zero, 0, out nBytesNeeded);
            if (nBytesNeeded <= 0)
            {
                throw new System.Exception("Unable to allocate memory by fujie");
            }
            else
            {
                ptrPrinterInfo = Marshal.AllocHGlobal(nBytesNeeded);
                nRet = Convert.ToInt32(GetPrinter(hPrinter, 2, ptrPrinterInfo, nBytesNeeded, out nJunk));
                if (nRet == 0)
                {
                    lastError = Marshal.GetLastWin32Error();
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                pinfo = (PRINTER_INFO_2)Marshal.PtrToStructure(ptrPrinterInfo, typeof(PRINTER_INFO_2));
                IntPtr Temp = new IntPtr();
                if (pinfo.pDevMode == IntPtr.Zero)
                {
                    IntPtr ptrZero = IntPtr.Zero;
                    sizeOfDevMode = DocumentProperties(IntPtr.Zero, hPrinter, i_printerName, ptrZero, ref ptrZero, 0);
                    ptrDM = Marshal.AllocCoTaskMem(sizeOfDevMode);
                    int i;
                    i = DocumentProperties(IntPtr.Zero, hPrinter, i_printerName, ptrDM, ref ptrZero, DM_OUT_BUFFER);
                    if ((i < 0) || (ptrDM == IntPtr.Zero))
                    {
                        throw new System.Exception("fujie:Cannot get DEVMODE data");
                    }
                    pinfo.pDevMode = ptrDM;
                }
                intError = DocumentProperties(IntPtr.Zero, hPrinter, i_printerName, IntPtr.Zero, ref Temp, 0);
                yDevModeData = Marshal.AllocHGlobal(intError);
                intError = DocumentProperties(IntPtr.Zero, hPrinter, i_printerName, yDevModeData, ref Temp, 2);
                dm = (DEVMODE)Marshal.PtrToStructure(yDevModeData, typeof(DEVMODE));
                if ((nRet == 0) || (hPrinter == IntPtr.Zero))
                {
                    lastError = Marshal.GetLastWin32Error();
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
                return dm;
            }
        }
        #endregion
    }
}


 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值