narsil/Tanshu.Accounts.Print/PrinterWindows.cs
tanshu 49faa9786d Moved to a new printer name format in PrintLocation
If printing from windows, then the printer name should be prefixed with smb.
If printing from linux, then the printer name should be prefixed with cups.
If printing directly, then the printer name should be prefixed with pdl.
2018-05-17 15:52:27 +05:30

95 lines
4.4 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace Tanshu.Accounts.Print
{
internal class PrinterWindows : PlatformPrinter
{
private string location;
// Cut Code for the printer Alt-29, Alt-86, Alt-49
#region API Declarations
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
internal static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
#endregion
internal PrinterWindows (string location)
{
this.location = location.Substring(4).Normalize();
}
internal override bool Print(string documentName, string printingText)
{
IntPtr hPrinter = new IntPtr(0);
// The printer handle.
// Last error -incase there was trouble.
DOCINFOA di = new DOCINFOA();
// Describes your document(name, port, data type).
var bSuccess = false; // Your success code.
// Set up the DOCINFO structure.
di.pDocName = documentName;
di.pDataType = "RAW";
if (OpenPrinter(location, out hPrinter, IntPtr.Zero))
{
if (StartDocPrinter(hPrinter, 1, di))
{
if (!StartPagePrinter(hPrinter))
return false;
//Write your printer - specific bytes to the printer.
bSuccess = SendLine(printingText, hPrinter);
EndPagePrinter(hPrinter);
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information about why not.
if (bSuccess == false)
{
Marshal.GetLastWin32Error();
}
return bSuccess;
}// SendBytesToPrinter()
internal static bool SendLine(string szString, IntPtr hPrinter)
{
Int32 dwWritten = 0;
Int32 dwCount = szString.Length; // How many characters are in the string?
IntPtr pBytes = Marshal.StringToCoTaskMemAnsi(szString);
// Assume that the printer is expecting ANSI text, and then convert
// the string to ANSI text.
// Write your bytes.
return WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
}
}
}