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

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

 虽然说.NET为我们提供了很多打印设置的功能,比如PrintDialog。 可是有的功能是没有实现的,比如PrintDialog的窗体中,按下“打印机”后,出来的打印机设置窗口。 会发现,这个打印机设置会根据不同的打印机而不同。 而它更改的,是打印机的默认设置。 怎么实现这个功能呢? 这个难题让我在网上寻觅了一个星期。 也没有找到实现这个功能的代码。 要么就是只能弹出这个对话框,不能保存修改。 要么就是只能直接修改设置,不能弹出对话框。 经过一番摸索和尝试。我终于得出了以下的一个类。调用这个类唯一的公共方法,ChangePrinterSetting(string PrinterName),即可以修改相应名字的打印机默认设置。

VS2005下调试通过。

view plaincopy to clipboardprint?

 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
}
}

 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/fujie724/archive/2010/03/16/5386443.aspx

打印方法小议,页面设置对话框、打印预览对话框、打印对话框等功能,C#源代码 //字符串流对 象,一行一行读取文本 private StringReader MyReader; private void button1_Click(object sender, EventArgs e) { //显示页面设置对话框 PageSetupDialog MyDlg = new PageSetupDialog(); MyDlg.Document = this.printDocument1; MyDlg.ShowDialog(); } private void button2_Click(object sender, EventArgs e) { //显示打印预览对话框 PrintPreviewDialog MyDlg = new PrintPreviewDialog(); MyDlg.Document = this.printDocument1; this.MyReader = new StringReader(this.richTextBox1.Text); MyDlg.ShowDialog(); } private void button3_Click(object sender, EventArgs e) { //显示打印对话框 PrintDialog MyDlg = new PrintDialog(); MyDlg.Document = this.printDocument1; MyDlg.ShowDialog(); } private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { Graphics g = e.Graphics; //每一页的行数 float MyLines = e.MarginBounds.Height / this.richTextBox1.Font.GetHeight (g); //打印时的行计数器 int MyLineNumber = 0; //打印时的纵坐标 float MyYPosition = 0; float MyMarginLeft = e.MarginBounds.Left; float MyMarginTop = e.MarginBounds.Top; //每一行要打印的文本 string MyLine = ""; while ((MyLineNumber < MyLines) && ((MyLine = MyReader.ReadLine()) != null)) { MyYPosition = MyMarginTop + MyLineNumber * this.richTextBox1.Font.GetHeight(g); g.DrawString(MyLine, this.richTextBox1.Font, new SolidBrush (Color.Black), MyMarginLeft, MyYPosition, new StringFormat()); MyLineNumber++; } if (MyLine != null) { //发出下一次PrintPage事件 e.HasMorePages = true; }
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值