3

IE 中的打印模板在用户关闭“打印”对话框后使用此属性来确定有关所选打印机的信息。如何使用 Visual C++ 中的代码将此属性设置为 DEVMODE 结构。 如何将 DEVMODE 结构转换为 variant。如果可能的话,我可以将变量传递给打印模板,然后在 jscript 中设置 __IE_PrinterCmd_DevMode 属性。

4

2 回答 2

3

Marc Durdin 有一篇优秀的博客文章,其中包含 Delphi 中的详细示例。它很容易移植到 C++ 和其他语言:

使用 Microsoft WebBrowser 控件和 ShowHTMLDialogEx 揭开打印的神秘面纱

特别是,__IE_PrinterCmd_DevMode应该是未锁定的HGLOBAL(通常是来自GlobalAllocor的有效返回值GlobalReAlloc)。这在任何地方都没有记录,我猜 Marc 通过反复试验发现了艰难的方法,最终发现它可以与PRINTDLG.hDevModeandPRINTDLG.hDevNames字段中的值一起使用,直接通过调用PrintDlg.

我已经能够将HGLOBALs 作为整数传递给模板的脚本,__IE_PrinterCmd_DevMode__IE_PrinterCmd_DevNames在创建TemplatePrinter. 如果您不想调用ShowHTMLDialogEx自己并且您已经在您的应用程序中有一个钩子,这很方便。我正在使用原始窗口的external脚本对象。要从模板访问它,我使用:

dialogArguments.__IE_BrowseDocument.parentWindow.external

PS:将 anHGLOBAL作为整数传递适用于 32 位进程,因为 JScript 的数字实际上是双浮点数,它可以表示高达 53 位的连续整数。但是由于这个限制,HGLOBAL在 64 位进程上传递一个整数是不可靠的。

也许你可以让你的window.external对象有一个方法,它需要一个打印模板的dialogArguments对象,用整数s(或)设置__IE_PrinterCmd_DevModeand 。__IE_PrinterCmd_DevNamesVARIANTVT_I8VT_UI8

我还没有测试过这个。

如果只想选择系统默认以外的打印机,也可以设置__IE_PrinterCMD_Printer属性。您可以在 JScript 中执行此操作,它会影响TemplatePrinter您在设置后创建的行为对象。但是,仅凭此属性,您无法控制初始设置或知道用户最终选择了哪台打印机。

于 2013-02-06T18:15:49.407 回答
1

我刚刚遇到同样的问题,发现可以从 IntPtr 设置 __IE_PrinterCmd_DevMode 和 __IE_PrinterCmd_DevNames。

这是在 X86 应用程序上,所以不确定在 x64 或 AnyCPU 上会发生什么。

正如建议的那样,我使用一个类通过外部对象传入 DevMode 和 DevNames。

这是代码的主要部分,为此:

Public Class PrintObjCls
 Public Printer As String
 Public DevMode As IntPtr
 Public DevNames As IntPtr
 Public Printing As Boolean
 Public Failed As Boolean 
 Public Progress As Integer
End Class

Sub PrintToTemplate(Web as WebBrowser, Settings as PrinterSettings)
 Dim Obj As New PrintObjCls
 Obj.Printer = Settings.PrinterName
 Obj.DevMode = Settings.GetHdevmode
 Obj.DevNames = Settings.GetHdevnames
 Web.ObjectForScripting = Obj
End Sub

然后在打印模板中

var ext = doc.parentWindow.external;
dialogArguments.__IE_PrinterCMD_Printer = ext.Printer;
dialogArguments.__IE_PrinterCmd_DevMode = ext.DevMode;
dialogArguments.__IE_PrinterCmd_DevNames = ext.DevNames;
于 2017-02-27T10:47:44.390 回答