在Awesomium打印到打印机?

Den*_*Hiu 4 c# printing awesomium

如何在Awesomium中处理window.print()事件到实际打印(不打印到PDF)?我知道它会使用WebView.PrintRequest事件,但我不知道该怎么做

http://docs.awesomium.net/1_7_0/html/E_Awesomium_Core_WebView_PrintRequest.htm

Ste*_*sen 6

Awesomium不支持打印到打印机设备.相反,Awesomium支持打印到PDF文件.

正确的方式

我对Windows打印的有限理解是,您通常需要使用传递到打印事件的自定义事件处理程序的GDI +绘图表面"绘制"到打印机. System.Drawing.Printing.PrintDocument类的MSDN文档很好地提供了一个示例实现.

我想可以使用Awesomium .Net SDK实现这种较低级别的打印,但是,它可能是一场艰苦的战斗,没有Awesomium开发人员的支持.

备择方案

一个体面的"黑客"可能是将Awesomium的打印与PDF功能粘合在一起并打印PDF文件.我可以想到至少3种方法从C#打印PDF文件:

  1. 在最终用户的计算机上使用Acrobat Reader,以便在Acrobat的COM自动化对象周围使用.Net运行时可调用包装器(RCW)进行打印.请参阅在VB.NET中使用Acrobat RCW的示例.

  2. 使用用户机器上的任何PDF阅读器来处理打印.请参阅将.Net ProcessStartInfo与打印动词一起使用的示例,以使用用户计算机上的默认PDF应用程序.

  3. 使用Windows常用对话框选择打印机,然后将PDF发送到打印机进行原始(直接)打印.(这类似于将PostScript [.ps]文件直接发送到打印机).这仅适用于直接接受PDF文件的打印机.

使用#3实现示例

下面是一个解决方法选项#3的示例,使用将Awesomium PDF文件直接发送到最终用户选择的打印机.

这个答案结合了两个现有的例子:使用.Net进行原始打印Microsoft KB用于打印Awesomium答案.

运行该演示加载Microsoft KB的URL,其中包括一个调用的"打印"UI按钮window.print().

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Awesomium.Core;

namespace Demo
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new PrinterDemo());
        }
    }

    public class PrinterDemo : Form
    {
        private Awesomium.Windows.Forms.WebControl webControl;
        private PrinterSettings printerSettings;
        private string printerName;

        public PrinterDemo()
        {
            InitializeComponent();
            WindowState = FormWindowState.Maximized;
        }

        private void InitializeComponent()
        {
            this.webControl = new Awesomium.Windows.Forms.WebControl();
            this.SuspendLayout();
            // 
            // webControl1
            // 
            this.webControl.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webControl.Location = new System.Drawing.Point(0, 0);
            this.webControl.Size = new System.Drawing.Size(784, 562);
            this.webControl.Source = new System.Uri("http://support.microsoft.com/kb/322091", System.UriKind.Absolute);
            this.webControl.TabIndex = 0;

            this.webControl.PrintRequest += WebControl_PrintRequest;
            this.webControl.PrintComplete += WebControl_PrintComplete;
            this.webControl.PrintFailed += WebControl_PrintFailed;

            // 
            // PrinterDemo
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(784, 562);
            this.Controls.Add(this.webControl);
            this.Name = "PrinterDemo";
            this.Text = "PrinterDemo";
            this.ResumeLayout(false);
        }

        /// <summary>Handle `window.print()` events</summary>
        private void WebControl_PrintRequest(object sender, PrintRequestEventArgs e)
        {
            this.Print();
            e.Handled = true;
        }


        /// <summary>Event handler for successful printing</summary>
        private void WebControl_PrintComplete(object sender, PrintCompleteEventArgs e)
        {
            // Print the file to the printer.
            if (String.IsNullOrWhiteSpace(printerName))
            {
                return;
            }

            foreach (string file in e.Files)
            {
                System.Diagnostics.Debug.Print("Printing file {0}", file);
                RawPrinterHelper.SendFileToPrinter(printerName, file);
            }
        }

        /// <summary>Event handler for unsuccessful printing</summary>
        private void WebControl_PrintFailed(object sender, PrintOperationEventArgs e)
        {
            MessageBox.Show("MyApp", "Printing failed", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }

        /// <summary>Sends a PDF file to the printer</summary>
        private void Print()
        {
            PrintDialog printerDialog;
            int requestId;
            string path = System.IO.Path.GetTempPath();

            if (!webControl.IsLive)
                return;

            printerDialog = new PrintDialog();
            printerSettings = new PrinterSettings();
            printerDialog.PrinterSettings = printerSettings;

            if (DialogResult.OK == printerDialog.ShowDialog(this))
            {
                printerName = printerDialog.PrinterSettings.PrinterName;
                requestId = webControl.PrintToFile(path, PrintConfig.Default);
            }
        }
    }

    public class RawPrinterHelper
    {
        // Structure and API declarions:
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public 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)]
        public 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)]
        public static extern bool ClosePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public 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)]
        public static extern bool EndDocPrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool StartPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool EndPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

        // SendBytesToPrinter()
        // When the function is given a printer name and an unmanaged array
        // of bytes, the function sends those bytes to the print queue.
        // Returns true on success, false on failure.
        public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
        {
            Int32 dwError = 0, dwWritten = 0;
            IntPtr hPrinter = new IntPtr(0);
            DOCINFOA di = new DOCINFOA();
            bool bSuccess = false; // Assume failure unless you specifically succeed.

            di.pDocName = "My C#.NET RAW Document";
            di.pDataType = "RAW";

            // Open the printer.
            if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
            {
                // Start a document.
                if (StartDocPrinter(hPrinter, 1, di))
                {
                    // Start a page.
                    if (StartPagePrinter(hPrinter))
                    {
                        // Write your bytes.
                        bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
                        EndPagePrinter(hPrinter);
                    }
                    EndDocPrinter(hPrinter);
                }
                ClosePrinter(hPrinter);
            }
            // If you did not succeed, GetLastError may give more information
            // about why not.
            if (bSuccess == false)
            {
                dwError = Marshal.GetLastWin32Error();
            }
            return bSuccess;
        }

        public static bool SendFileToPrinter(string szPrinterName, string szFileName)
        {
            // Open the file.
            FileStream fs = new FileStream(szFileName, FileMode.Open);
            // Create a BinaryReader on the file.
            BinaryReader br = new BinaryReader(fs);
            // Dim an array of bytes big enough to hold the file's contents.
            Byte[] bytes = new Byte[fs.Length];
            bool bSuccess = false;
            // Your unmanaged pointer.
            IntPtr pUnmanagedBytes = new IntPtr(0);
            int nLength;

            nLength = Convert.ToInt32(fs.Length);
            // Read the contents of the file into the array.
            bytes = br.ReadBytes(nLength);
            // Allocate some unmanaged memory for those bytes.
            pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
            // Copy the managed byte array into the unmanaged array.
            Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
            // Send the unmanaged bytes to the printer.
            bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
            // Free the unmanaged memory that you allocated earlier.
            Marshal.FreeCoTaskMem(pUnmanagedBytes);
            return bSuccess;
        }
        public static bool SendStringToPrinter(string szPrinterName, string szString)
        {
            IntPtr pBytes;
            Int32 dwCount;
            // How many characters are in the string?
            dwCount = szString.Length;
            // Assume that the printer is expecting ANSI text, and then convert
            // the string to ANSI text.
            pBytes = Marshal.StringToCoTaskMemAnsi(szString);
            // Send the converted ANSI string to the printer.
            SendBytesToPrinter(szPrinterName, pBytes, dwCount);
            Marshal.FreeCoTaskMem(pBytes);
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我能够将此示例编译并运行为demo.cs使用以下命令行命名的单个文件:

SETLOCAL
PATH C:\Windows\Microsoft.NET\Framework\v4.0.30319\;%PATH%
IF EXIST demo.exe DEL demo.exe
csc.exe /target:winexe /lib:"%ProgramFiles%\Awesomium Technologies LLC\Awesomium SDK\1.7.3.0\wrappers\Awesomium.NET\Assemblies" /reference:Awesomium.Core.dll,Awesomium.Windows.Forms.dll demo.cs 
demo.exe
ENDLOCAL
Run Code Online (Sandbox Code Playgroud)