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
Awesomium不支持打印到打印机设备.相反,Awesomium支持打印到PDF文件.
我对Windows打印的有限理解是,您通常需要使用传递到打印事件的自定义事件处理程序的GDI +绘图表面"绘制"到打印机. System.Drawing.Printing.PrintDocument类的MSDN文档很好地提供了一个示例实现.
我想可以使用Awesomium .Net SDK实现这种较低级别的打印,但是,它可能是一场艰苦的战斗,没有Awesomium开发人员的支持.
一个体面的"黑客"可能是将Awesomium的打印与PDF功能粘合在一起并打印PDF文件.我可以想到至少3种方法从C#打印PDF文件:
在最终用户的计算机上使用Acrobat Reader,以便在Acrobat的COM自动化对象周围使用.Net运行时可调用包装器(RCW)进行打印.请参阅在VB.NET中使用Acrobat RCW的示例.
使用用户机器上的任何PDF阅读器来处理打印.请参阅将.Net ProcessStartInfo与打印动词一起使用的示例,以使用用户计算机上的默认PDF应用程序.
使用Windows常用对话框选择打印机,然后将PDF发送到打印机进行原始(直接)打印.(这类似于将PostScript [.ps]文件直接发送到打印机).这仅适用于直接接受PDF文件的打印机.
下面是一个解决方法选项#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)