【问题标题】:Modifying PrinterSettings after PrintDialog was shown显示 PrintDialog 后修改 PrinterSettings
【发布时间】:2012-03-31 01:43:50
【问题描述】:

在向用户显示对话框后,我正在尝试修改从 System.Windows.Forms.PrintDialog 获得的 System.Drawing.Printing.PrinterSettings 对象。虽然我可以更改 PrinterSettings 对象的属性值,但在打印文档时实际上并没有考虑我在显示对话框后所做的任何更改。

这是我的意思的一个例子:

//Show the printdialog and retreive the printersettings    
var printDialog = new PrintDialog();
if (printDialog.ShowDialog() != DialogResult.OK) 
            return;
var printerSettings = printDialog.PrinterSettings;

//Now modify the printersettings object
printerSettings.ToPage = 8;

现在使用printerSettings 对象进行打印。我为此使用了 3rd Party dll Aspose.Words,因为我需要打印 Word,但这似乎不是问题。似乎在显示对话框后,所有设置都已提交给打印机,而更改 PrinterSettings 没有任何效果。关于如何让它发挥作用的任何想法?

编辑:我有一些解决方法。我在这里想要得到这些特定问题的答案:是否可以在显示对话框后更改 PrinterSettings 对象,以及在打印中是否考虑了这些更改。如果有人只知道一种工作方式(您可以决定要使用什么 API 进行打印,只要使用 PrinterSettings 对象就没有关系),我将非常感激。

【问题讨论】:

  • 打开对话框之前没有更改设置的任何原因?
  • 是的,在我的应用程序中,我有“合并文档”,其中包含许多不同的文档。在打印对话框中,它们应该显示为一个文档,但对于打印,我需要单独处理它们。所以更准确地说:一些 PrinterSettings 应该适用于所有文档,其他我需要为每个文档单独设置。我可以在没有用户交互的情况下计算单个属性/设置,但对于打印,我需要将它们注入打印机设置。
  • 从 sn-p 中完全不清楚printerSettings 对象是如何应用于实际打印作业的。您的代码中也缺少该内容可以解释问题的原因。
  • 不,它没有。请阅读我的帖子,不仅是代码。我使用 Aspose 进行打印,但根本问题与 Apsose 无关。

标签: c# .net winforms printing printer-properties


【解决方案1】:

不知道为什么你的问题被否决了,对我来说似乎很合理???

无论如何,我注意到 PrintDialog 的一些事情(可能会或可能不会回答您的问题)。

首先,它只是 windows com 对话的包装类。

[DllImport("comdlg32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        public static extern bool PrintDlg([In, Out] NativeMethods.PRINTDLG lppd);

第二个,也是最重要的关于你的问题,我猜: PrintDialog 类有这个例程,它在 PrintDlg 调用关闭后调用

if (!UnsafeNativeMethods.PrintDlg(data))
                return false;

            IntSecurity.AllPrintingAndUnmanagedCode.Assert();
            try { 
                UpdatePrinterSettings(data.hDevMode, data.hDevNames, data.nCopies, data.Flags, settings, PageSettings); 
            }
            finally { 
                CodeAccessPermission.RevertAssert();
            }

。 . .

// VSWhidbey 93449: Due to the nature of PRINTDLGEX vs PRINTDLG, separate but similar methods 
// are required for updating the settings from the structure utilized by the dialog.
// Take information from print dialog and put in PrinterSettings
private static void UpdatePrinterSettings(IntPtr hDevMode, IntPtr hDevNames, short copies, int flags, PrinterSettings settings, PageSettings pageSettings) {
        // Mode 
        settings.SetHdevmode(hDevMode);
        settings.SetHdevnames(hDevNames); 

        if (pageSettings!= null)
            pageSettings.SetHdevmode(hDevMode); 

        //Check for Copies == 1 since we might get the Right number of Copies from hdevMode.dmCopies...
        //this is Native PrintDialogs
        if (settings.Copies == 1) 
            settings.Copies = copies;

        settings.PrintRange = (PrintRange) (flags & printRangeMask); 
    }

这里还有一个相当有趣的相互作用(记住您设置了 PrinterSettings.ToPage):

public PrinterSettings PrinterSettings {
   get { 
        if (settings == null)
        {
            settings = new PrinterSettings(); 
        }
        return settings; 
    } 
    set {
        if (value != PrinterSettings) 
        {
            settings = value;
            **printDocument = null;**
        } 
    }
} 

然后

public PrintDocument Document {
            get { return printDocument;}
            set {
                printDocument = value; 
                **if (printDocument == null)
                    settings = new PrinterSettings();** 
                else 
                    settings = printDocument.PrinterSettings;
            } 
        }

我知道这不是一个直接的答案,但我认为应该为您指出为什么它不起作用的正确方向。在我看来,在对话的使用过程中,它可以愉快地取消更改设置,因为它将在完成时重新创建,但是当对话完成时,更改设置实际上会使文档打印设置无效,直到再次设置。可以手动执行此操作,或者它可能被 M$ 以通常的内部/私有方式锁定在许多内部。

当然有一个选项(不是我知道的那么好)在调用后直接使用 Win API - 如果需要,可以从上述对话中提取代码来构建自己的包装器。

祝你好运。

【讨论】:

  • 我有一段时间没有检查这个了,因此我的回放有点晚了:非常感谢。
  • 顺便说一句。我认为这个问题被否决了,因为这个网站上的一些人倾向于不考虑问题的真正问题和内容。不愿意承认作者对编程的想法不仅仅是肤浅的。关于这个问题,最简单的方法是认为我在代码的其他部分犯了一些错误,而这个问题实际上并不存在。抱歉,我没有足够的积分或积分或其他任何东西来支持您的答案。
【解决方案2】:

来自 Aspose 文档:

AsposeWordsPrintDocument awPrintDoc = new AsposeWordsPrintDocument(doc);
awPrintDoc.PrinterSettings = printDlg.PrinterSettings;

因此,您似乎可以将修改后的 PrinterSettings 对象传递给您尝试打印的 word 文档。你能告诉我这是否有效吗?

【讨论】:

  • 嗨史蒂夫,结果是一样的。仅考虑 printDialog 中的设置。不是手动更改。我现在采用另一种方法,将所有文档转换为 xps(使用 Aspose),将它们合并为一个 xps,然后使用 wpf printdialog 打印这个 xps(或选定的页面)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-24
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
相关资源
最近更新 更多