7

私のC#アプリケーションでは、進行状況ダイアログが画面に表示されずに印刷プレビューを生成しようとしています。

PrintDocument.PrintControllerを使用して、実際に印刷する場合(つまり、印刷プレビューではない場合)にこれを防ぐことができると思いますが、印刷プレビューを実行する場合は機能しないようです。

私のコードは次のとおりです。

public FrmDeliveryNotePrintPreview(DeliveryNote deliveryNote)
{
    InitializeComponent();

    this.Text = "Delivery Note #" + deliveryNote.Id.ToString();


    // The print preview window should occupy about 90% of the
    // total screen height

    int height = (int) (Screen.PrimaryScreen.Bounds.Height * 0.9);


    // Making an assumption that we are printing to A4 landscape,
    // then adjust the width to give the correct height:width ratio
    // for A4 landscape.

    int width = (int) (height / 1.415);


    // Set the bounds of this form. The PrintPreviewControl is
    // docked, so it should just do the right thing

    this.SetBounds(0, 0, width, height);

    PrinterSettings printerSettings = new PrinterSettings();
    PrintDeliveryNotes pdn = new PrintDeliveryNotes(
        new DeliveryNote[] { deliveryNote },
        printerSettings);
    PrintDocument printDocument = pdn.PrintDocument;
    printDocument.PrintController = new PreviewPrintController();
    ppcDeliveryNote.Document = printDocument;
}

印刷プレビューの進行状況ダイアログが表示されることを除けば、印刷プレビューは希望どおりに機能します。

提案をお願いします?

4

8 に答える 8

6

これは私のために働きます:

ドキュメントのプリントコントローラをに設定しますStandardPrintController

static class Program
    {

        static void Main()
        {
            PrintDocument doc = new PrintDocument();
            doc.PrintController = new StandardPrintController();
            doc.PrintPage += new PrintPageEventHandler(doc_PrintPage);

            doc.Print();
        }

        static void doc_PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.DrawString("xxx", Control.DefaultFont, Brushes.Black, new PointF(e.PageBounds.Width / 2, e.PageBounds.Height / 2));
        }
    }
于 2009-09-01T08:22:05.567 に答える
3

Poovenからの回答を確認するためだけに。私は同じ問題を抱えて解決しようとしましたが、Stefanの解決策もうまくいきませんでした。それから私はついにソースコードを調べて、それがハードコーディングされているので変更できないことを知りました。ステータスダイアログを非表示にする必要がある場合は、PrintPreviewControl以外の解決策を探してください。PrintPreviewControlのソースコードは次のとおりです。

 private void ComputePreview() {
        int oldStart = StartPage;

        if (document == null)
            pageInfo = new PreviewPageInfo[0];
        else {
            IntSecurity.SafePrinting.Demand();

            PrintController oldController = document.PrintController;

// --> HERE they have hardcoded it! Why they do this!

            PreviewPrintController previewController = new PreviewPrintController();
            previewController.UseAntiAlias = UseAntiAlias;
            document.PrintController = new PrintControllerWithStatusDialog(previewController,
                                                                           SR.GetString(SR.PrintControllerWithStatusDialog_DialogTitlePreview));

            // Want to make sure we've reverted any security asserts before we call Print -- that calls into user code
            document.Print();
            pageInfo = previewController.GetPreviewPageInfo();
            Debug.Assert(pageInfo != null, "ReviewPrintController did not give us preview info");

// --> and then swap the old one
            document.PrintController = oldController;
        }

        if (oldStart != StartPage) {
            OnStartPageChanged(EventArgs.Empty);
        }
    }

ソース http://reflector.webtropy.com/default.aspx/4@0/4@0/DEVDIV_TFS/Dev10/Releases/RTMRel/ndp/fx/src/WinForms/Managed/System/WinForms/Printing/PrintPreviewControl@cs / 1305376 / PrintPreviewControl @ cs

于 2014-10-17T18:04:28.430 に答える
3

やったと思います。PrintPreviewControlの代わりにこのクラスを使用します。

public class PrintPreviewControlSilent : PrintPreviewControl
{
    public new PrintDocument Document
    {
        get { return base.Document; }
        set
        {
            base.Document = value;

            PreviewPrintController ppc = new PreviewPrintController();

            Document.PrintController = ppc;
            Document.Print();

            FieldInfo fi = typeof(PrintPreviewControl).GetField("pageInfo", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            fi.SetValue(this, ppc.GetPreviewPageInfo());
        }
    }
}
于 2016-12-16T16:03:09.517 に答える
2

私は自分の質問に答えるのは嫌いですが、解決策は私を正面から見つめていました。

納品書を印刷する機能をすでにコーディングしているので、次のステップは画面上のコピーを提供することでした(つまり、ハードコピーを印刷する意図はありません)。印刷プレビューダイアログは簡単な方法のように見えました。

結局、私はカスタムフォームを作成し、印刷プレビューコントロールが見えない状態で、そのフォームに直接ペイントしました。

残念ながら、私は、より大きな問題を検討するのではなく、印刷プレビューダイアログを希望どおりに動作させることに集中しすぎました。

于 2009-10-11T09:55:15.403 に答える
1

StandardPrintControllerの代わりにPreviewPrintControllerを使用すると運が良いかもしれません。

于 2009-08-31T13:48:08.220 に答える
1

私にとって有効な解決策は、Harmony(v1.2)を使用して、上記のComputePreview機能にパッチを適用することです。PrintPreviewControl

パッチクラスは次のようになります

[Harmony.HarmonyPatch(typeof(System.Windows.Forms.PrintPreviewControl))]
[Harmony.HarmonyPatch("ComputePreview")]
class PrintPreviewControlPatch
{
    static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
    {
        var cis = new List<CodeInstruction>(instructions);
        // the codes 26 to 28 deal with creating the
        // progress reporting preview generator that
        // we don't want. We replace them with No-Operation
        // code instructions. 
        cis[26] = new CodeInstruction(OpCodes.Nop);
        cis[27] = new CodeInstruction(OpCodes.Nop);
        cis[28] = new CodeInstruction(OpCodes.Nop);
        return cis;
    }
}

パッチを適用するには、アプリケーションの起動時に次の2行を含める必要があります。

var harmony = Harmony.HarmonyInstance.Create("Application.Namespace.Reversed");
harmony.PatchAll(Assembly.GetExecutingAssembly());
于 2018-10-16T06:27:21.590 に答える
0

回避策は、EnumChildWindows APIを使用してウィンドウへのハンドルを検索し、見つかった場合は、SW_HIDEフラグを指定してShowWindowAPIを使用してウィンドウを非表示にすることです。

ウィンドウのタイトルがわかっている場合にFindWindowを使用する例を次に示します。

#region Constants 

private const int SW_HIDE = 0;

private const int SW_SHOWNORMAL = 1;

private const int SW_SHOW = 5;

#endregion Constants

#region APIs

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] 

private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); 

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] 

private static extern bool ShowWindow(IntPtr hwnd, int nCmdShow); 

[System.Runtime.InteropServices.DllImport("user32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto)] 

private static extern bool EnableWindow(IntPtr hwnd, bool enabled);

#endregion APIs

public static void ShowProgress()

{

IntPtr h = FindWindow(null, "titleofprogresswindow");

ShowWindow(h, SW_SHOW); 

EnableWindow(h, true); 

}

public static void HideProgress()

{

IntPtr h = FindWindow(null, "titleofprogresswindow");

ShowWindow(h, SW_HIDE); 

EnableWindow(h, false); 

}
于 2009-08-31T14:46:36.590 に答える
0

によってPrintPreviewControl使用されるのは、のPrintPreviewDialogを置き換えるため、プレビューレンダリングプロセス中にを使用するようです。操作が完了すると、は以前の値に復元されます。他のを使用するようにをカスタマイズすることはできないようです。PrintControllerPrintDocumentPrintControllerWithStatusDialogPrintPrintControllerPrintPreviewControlPrintController

于 2012-05-24T09:34:31.040 に答える