MetaFile Cliphttp://nicholas.piasecki.name/blog/2009/06/drawingoaninmemorymetafileincsharp/

/// <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);
    }
}
原文地址:https://www.cnblogs.com/si812cn/p/1534068.html