9

再会!

我需要从 RichTextBox 打印短卡。卡片尺寸为 10x14 厘米。

由于客户的打印机功能,我们只能通过这种方式将卡片放入打印机:

示例图像

我尝试通过两种方式设置 PageSettings:

  1. PageSettings.Width = 10; PageSettings.Height = 14。
  2. PageSettings.Width = 14; PageSettings.Height = 10。

可打印区域如下所示:

在此处输入图像描述

这是如何发布打印的代码:

btnRotate.CheckedChanged += (s, e) => InitPaperSize();

private void InitPaperSize()
    {
        string name = btnRotate.Checked ? "ShortCard (rotate)" : "ShortCard";
        int width = Centimeters(btnRotate.Checked ? 14 : 10);
        int height = Centimeters(btnRotate.Checked ? 10 : 14);

        System.Drawing.Printing.PaperSize ps = new System.Drawing.Printing.PaperSize(name, width, height);
        printDocument.DefaultPageSettings.PaperSize = ps;
    }

private int Centimeters(int centimeters)
    {
        return (int)((centimeters * 100) / 2.54);
    }

public int PrintRotate(bool rotate, PrintPageEventArgs e, int charFrom, int charTo)
    {
        //Calculate the area to render and print
        RECT rectToPrint;
        rectToPrint.Top = (int)(e.MarginBounds.Top * anInch);
        rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch);
        rectToPrint.Left = (int)(e.MarginBounds.Left * anInch);
        rectToPrint.Right = (int)(e.MarginBounds.Right * anInch);

        //Calculate the size of the page
        RECT rectPage;
        rectPage.Top = (int)(e.PageBounds.Top * anInch);
        rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch);
        rectPage.Left = (int)(e.PageBounds.Left * anInch);
        rectPage.Right = (int)(e.PageBounds.Right * anInch);

        IntPtr hdc = e.Graphics.GetHdc();

        FORMATRANGE fmtRange;
        fmtRange.chrg.cpMax = charTo;               //Indicate character from to character to 
        fmtRange.chrg.cpMin = charFrom;
        fmtRange.hdc = hdc;                    //Use the same DC for measuring and rendering
        fmtRange.hdcTarget = hdc;              //Point at printer hDC
        fmtRange.rc = rectToPrint;             //Indicate the area on page to print
        fmtRange.rcPage = rectPage;            //Indicate size of page

        SetGraphicsMode(fmtRange.hdc, GM_ADVANCED);

        XFORM par = new XFORM();

        par = new XFORM();
        par.eM11 = 1;
        par.eM12 = 0;
        par.eM21 = 0;
        par.eM22 = 1;
        par.eDx = -e.PageSettings.Margins.Left / 100 * e.PageSettings.PrinterResolution.X;//делим на 100 так как границы указываются в сотых долях дюйма
        par.eDy = -e.PageSettings.Margins.Top / 100 * e.PageSettings.PrinterResolution.Y;

        ModifyWorldTransform(fmtRange.hdc, ref par, MWT_LEFTMULTIPLY);

        IntPtr res = IntPtr.Zero;

        IntPtr wparam = IntPtr.Zero;
        wparam = new IntPtr(1);

        //Get the pointer to the FORMATRANGE structure in memory
        IntPtr lparam = IntPtr.Zero;
        lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange));
        Marshal.StructureToPtr(fmtRange, lparam, false);

        //Send the rendered data for printing 
        res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam);

        //Free the block of memory allocated
        Marshal.FreeCoTaskMem(lparam);

        //Release the device context handle obtained by a previous call
        e.Graphics.ReleaseHdc(hdc);

        //Return last + 1 character printer
        return res.ToInt32();
    }

唯一的问题是我们只能水平地将卡片放入打印机中。

4

2 回答 2

1

正如有人之前所说,您应该简单地设置 PageSettings.Landscape 属性。您还可以使用PrintPageEventArgs.Graphics的图形上下文直接绘制。然后您可以绘制任何旋转的元素或旋转的文本。这给出了一个很好的例子。然后,您不需要使用指针 (IntPtr) 或设备上下文 (GetHDC)。

于 2013-02-08T12:17:07.613 回答
0

我在使用专业打印机时也遇到过类似的问题。驱动程序可能会忽略您设置的某些设置。

我的解决方案是从文本中制作图像并仅使用默认打印机设置,而不是尝试使您的文档适合某些奇怪的打印机驱动程序。

这是将文本转换为图像的方法

于 2012-11-21T11:09:53.047 回答