IE 中的打印模板在用户关闭“打印”对话框后使用此属性来确定有关所选打印机的信息。如何使用 Visual C++ 中的代码将此属性设置为 DEVMODE 结构。 如何将 DEVMODE 结构转换为 variant。如果可能的话,我可以将变量传递给打印模板,然后在 jscript 中设置 __IE_PrinterCmd_DevMode 属性。
2 回答
Marc Durdin 有一篇优秀的博客文章,其中包含 Delphi 中的详细示例。它很容易移植到 C++ 和其他语言:
特别是,__IE_PrinterCmd_DevMode
应该是未锁定的HGLOBAL
(通常是来自GlobalAlloc
or的有效返回值GlobalReAlloc
)。这在任何地方都没有记录,我猜 Marc 通过反复试验发现了艰难的方法,最终发现它可以与PRINTDLG.hDevMode
andPRINTDLG.hDevNames
字段中的值一起使用,直接通过调用PrintDlg
.
我已经能够将HGLOBAL
s 作为整数传递给模板的脚本,__IE_PrinterCmd_DevMode
并__IE_PrinterCmd_DevNames
在创建TemplatePrinter
. 如果您不想调用ShowHTMLDialogEx
自己并且您已经在您的应用程序中有一个钩子,这很方便。我正在使用原始窗口的external
脚本对象。要从模板访问它,我使用:
dialogArguments.__IE_BrowseDocument.parentWindow.external
PS:将 an
HGLOBAL
作为整数传递适用于 32 位进程,因为 JScript 的数字实际上是双浮点数,它可以表示高达 53 位的连续整数。但是由于这个限制,HGLOBAL
在 64 位进程上传递一个整数是不可靠的。也许你可以让你的
window.external
对象有一个方法,它需要一个打印模板的dialogArguments
对象,用整数s(或)设置__IE_PrinterCmd_DevMode
and 。__IE_PrinterCmd_DevNames
VARIANT
VT_I8
VT_UI8
我还没有测试过这个。
如果只想选择系统默认以外的打印机,也可以设置__IE_PrinterCMD_Printer
属性。您可以在 JScript 中执行此操作,它会影响TemplatePrinter
您在设置后创建的行为对象。但是,仅凭此属性,您无法控制初始设置或知道用户最终选择了哪台打印机。
我刚刚遇到同样的问题,发现可以从 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;