9

良い一日!

RichTextBoxから短いカードを印刷する必要があります。カードのサイズは10x14cmです。

お客様のプリンタ機能により、カードをプリンタに挿入できるのは次の方法のみです。

サンプル画像

PageSettingsを2つの方法で設定しようとしました。

  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 に答える