/// <summary>
/// Adds a new metafile page, selects it as the current metafile, and
/// returns its graphics object. The caller is responsible for disposing
/// the returned Graphics instance. The unit of measurement in the
/// returned Graphics instance is GraphicsUnit.Inch.
/// </summary>
/// <param name="pageSize">The size of the page, in inches.</param>
/// <returns>a Graphics instance to render the page onto; the caller is
/// responsible for disposing of this Graphics instance</returns>
protected Graphics GetNextPage(SizeF pageSize)
{
IntPtr deviceContextHandle;
Graphics offScreenBufferGraphics;
Graphics metafileGraphics;
MetafileHeader metafileHeader;
KeyValuePair<Metafile, MemoryStream> pair;
this.currentStream = new MemoryStream();
using (offScreenBufferGraphics = Graphics.FromHwndInternal(IntPtr.Zero))
{
deviceContextHandle = offScreenBufferGraphics.GetHdc();
this.currentMetafile = new Metafile(
this.currentStream,
deviceContextHandle,
new RectangleF(0, 0, pageSize.Width, pageSize.Height),
MetafileFrameUnit.Inch,
EmfType.EmfOnly);
pair = new KeyValuePair<Metafile, MemoryStream>(
this.currentMetafile,
this.currentStream);
this.metafiles.Add(pair);
offScreenBufferGraphics.ReleaseHdc();
metafileGraphics = Graphics.FromImage(this.currentMetafile);
metafileHeader = this.currentMetafile.GetMetafileHeader();
metafileGraphics.ScaleTransform(
metafileHeader.DpiX / metafileGraphics.DpiX,
metafileHeader.DpiY / metafileGraphics.DpiY);
metafileGraphics.PageUnit = GraphicsUnit.Inch;
metafileGraphics.SetClip(new RectangleF(0, 0, pageSize.Width, pageSize.Height));
}
return metafileGraphics;
}
/// <summary>
/// Prints the given document.
/// </summary>
/// <param name="document">the document, which is guaranteed not to be
/// null in and in a language that the printer supports</param>
/// <param name="copies">the number of copies, which is guaranteed to be
/// a positive number</param>
protected override void DoPrint(PrinterDocumentBase document, int copies)
{
IntPtr deviceContext;
NativeMethods.DOCINFO documentInfo;
int hardMarginLeft;
int hardMarginTop;
int pagesCount;
documentInfo = new NativeMethods.DOCINFO();
documentInfo.fwType = 0;
documentInfo.lpszDatatype = null;
documentInfo.lpszDocName = document.Name;
documentInfo.lpszOutput = null;
documentInfo.cbSize = Marshal.SizeOf(documentInfo);
pagesCount = document.Prepare();
deviceContext = NativeMethods.CreateDC(
"WINSPOOL",
this.Name.Normalize(),
null,
IntPtr.Zero);
if (deviceContext != IntPtr.Zero)
{
hardMarginLeft = NativeMethods.GetDeviceCaps(
deviceContext,
NativeMethods.DeviceCap.PHYSICALOFFSETX);
hardMarginTop = NativeMethods.GetDeviceCaps(
deviceContext,
NativeMethods.DeviceCap.PHYSICALOFFSETY);
hardMarginLeft = (int)(hardMarginLeft * 100F / NativeMethods.GetDeviceCaps(deviceContext, NativeMethods.DeviceCap.LOGPIXELSX));
hardMarginTop = (int)(hardMarginTop * 100F / NativeMethods.GetDeviceCaps(deviceContext, NativeMethods.DeviceCap.LOGPIXELSY));
for (int copyIdx = 0; copyIdx < copies; ++copyIdx)
{
if (NativeMethods.StartDoc(deviceContext, documentInfo) > 0)
{
for (int i = 0; i < pagesCount; ++i)
{
byte[] data;
data = document.GetPage(i);
using (var ms = new MemoryStream(data))
using (var metafile = Metafile.FromStream(ms))
{
using (var g = Graphics.FromHdcInternal(deviceContext))
{
g.TranslateTransform(-hardMarginLeft, -hardMarginTop);
if (NativeMethods.StartPage(deviceContext) > 0)
{
g.DrawImage(metafile, 0, 0);
g.Flush();
if (NativeMethods.EndPage(deviceContext) <= 0)
{
throw new Win32Exception();
}
}
else
{
throw new Win32Exception();
}
}
}
}
if (NativeMethods.EndDoc(deviceContext) <= 0)
{
throw new Win32Exception();
}
}
}
}
else
{
throw new Win32Exception();
}
if (deviceContext != IntPtr.Zero)
{
NativeMethods.DeleteDC(deviceContext);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类