获得的PaperSize可以用在CrystalReport中设置PrintOptions.PaperSize的值,从而达到可使用自定义纸张的目的。
using System;
using System.Security;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
namespace PaperSizeTest
{
class PaperSizeTest
{
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
internal struct PRINTER_INFO_5
{
[MarshalAs(UnmanagedType.LPTStr)] public String PrinterName;
[MarshalAs(UnmanagedType.LPTStr)] public String PortName;
[MarshalAs(UnmanagedType.U4)] public Int32 Attributes;
[MarshalAs(UnmanagedType.U4)] public Int32 DeviceNotSelectedTimeout;
[MarshalAs(UnmanagedType.U4)] public Int32 TransmissionRetryTimeout;
}
const int PRINTER_ENUM_LOCAL = 2;
const int PRINTER_ENUM_CONNECTIONS = 4;
const int DC_PAPERNAMES = 16;
const int DC_PAPERS = 2;
const int DC_PAPERSIZE = 3;
[DllImport("winspool.drv", EntryPoint="DeviceCapabilitiesA", SetLastError=true)]
static extern Int32 DeviceCapabilities(
[MarshalAs(UnmanagedType.LPStr)] String device,
[MarshalAs(UnmanagedType.LPStr)] String port,
Int16 capability,
IntPtr outputBuffer,
IntPtr deviceMode);
[DllImport("winspool.drv", SetLastError=true)]
static extern bool EnumPrintersW(Int32 flags,
[MarshalAs(UnmanagedType.LPTStr)] string printerName,
Int32 level, IntPtr buffer, Int32 bufferSize, out Int32
requiredBufferSize, out Int32 numPrintersReturned);
[DllImport("kernel32.dll", EntryPoint="GetLastError", SetLastError=false,
ExactSpelling=true, CallingConvention=CallingConvention.StdCall),
SuppressUnmanagedCodeSecurityAttribute()]
internal static extern Int32 GetLastError();
public static void GetDefinedPapers(string printerName)
{
PRINTER_INFO_5 info5;
int requiredSize;
int numPrinters;
bool foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
String.Empty, 5, IntPtr.Zero, 0, out requiredSize, out numPrinters);
int info5Size = requiredSize;
IntPtr info5Ptr = Marshal.AllocHGlobal(info5Size);
IntPtr buffer = IntPtr.Zero;
try
{
foundPrinter = EnumPrintersW(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
String.Empty, 5, info5Ptr, info5Size, out requiredSize, out numPrinters);
string port = null;
for (int i = 0; i < numPrinters; i++)
{
info5 = (PRINTER_INFO_5)Marshal.PtrToStructure(
(IntPtr)((i * Marshal.SizeOf(typeof(PRINTER_INFO_5))) + (int)info5Ptr),
typeof(PRINTER_INFO_5));
if (info5.PrinterName == printerName)
{
port = info5.PortName;
}
}
int numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES, IntPtr.Zero, IntPtr.Zero);
if (numNames < 0)
{
int errorCode = GetLastError();
Console.WriteLine("Number of names = {1}: {0}", errorCode, numNames);
return;
}
buffer = Marshal.AllocHGlobal(numNames * 64);
numNames = DeviceCapabilities(printerName, port, DC_PAPERNAMES, buffer, IntPtr.Zero);
if (numNames < 0)
{
int errorCode = GetLastError();
Console.WriteLine("Number of names = {1}: {0}", errorCode, numNames);
return;
}
string[] names = new string[numNames];
for (int i = 0; i < numNames; i++)
{
names[i] = Marshal.PtrToStringAnsi((IntPtr)((i * 64) + (int)buffer));
}
Marshal.FreeHGlobal(buffer);
buffer = IntPtr.Zero;
int numPapers = DeviceCapabilities(printerName, port, DC_PAPERS, IntPtr.Zero, IntPtr.Zero);
if (numPapers < 0)
{
Console.WriteLine("No papers");
return;
}
buffer = Marshal.AllocHGlobal(numPapers * 2);
numPapers = DeviceCapabilities(printerName, port, DC_PAPERS, buffer, IntPtr.Zero);
if (numPapers < 0)
{
Console.WriteLine("No papers");
return;
}
short[] kinds = new short[numPapers];
for (int i = 0; i < numPapers; i++)
{
kinds[i] = Marshal.ReadInt16(buffer, i * 2);
}
for(int i = 0; i < numPapers; i++)
{
Console.WriteLine("Paper {0} : {1}", kinds[i], names[i]);
}
}
finally
{
Marshal.FreeHGlobal(info5Ptr);
}
}
public static void Main()
{
PrintDocument pd = new PrintDocument();
string sPrinterName = pd.PrinterSettings.PrinterName;
GetDefinedPapers("Adobe PDF");
}
}
}
使用C#获得指定打印机所支持的所有PaperSize及PaperName
最新推荐文章于 2023-09-25 11:16:48 发布