Шаблон печати в IE использует это свойство для определения информации о выбранном принтере после того, как пользователь закроет диалоговое окно «Печать». Как установить для этого свойства структуру DEVMODE с кодом на Visual C++. Как преобразовать структуру DEVMODE в вариант. Если это возможно, я могу передать вариант для шаблона печати, а затем установить свойство __IE_PrinterCmd_DevMode в jscript.
Как установить свойство __IE_PrinterCmd_DevMode в структуру DEVMODE в шаблоне печати в IE с Visual C++
Ответы (2)
У Марка Дурдина есть отличный пост в блоге с подробным примером в Delphi. Его легко переносить на C++ и другие языки:
Демистификация печати с помощью элемента управления Microsoft WebBrowser и ShowHTMLDialogEx
В частности, __IE_PrinterCmd_DevMode
должен быть разблокированным HGLOBAL
(обычно допустимое возвращаемое значение из GlobalAlloc
или GlobalReAlloc
). Это нигде не задокументировано, я думаю, что Марк обнаружил трудный путь методом проб и ошибок, наконец, обнаружив, что он работает со значениями в PRINTDLG.hDevMode
и PRINTDLG.hDevNames
, непосредственно предоставляемые вызовом PrintDlg
.
Мне удалось передать HGLOBAL
как целые числа в сценарий шаблона и использовать их для инициализации __IE_PrinterCmd_DevMode
и __IE_PrinterCmd_DevNames
перед созданием файла TemplatePrinter
. Это удобно, если вы не хотите сами вызывать ShowHTMLDialogEx
и у вас уже есть крючок в вашем приложении. Я использую объект сценария external
исходного окна. Чтобы получить к нему доступ из шаблона, я использую:
dialogArguments.__IE_BrowseDocument.parentWindow.external
PS: передача
HGLOBAL
в виде целого числа работает в 32-битном процессе, потому что числа JScript на самом деле являются двойными числами с плавающей запятой, которые могут представлять последовательные целые числа до 53-бит. Но из-за этого ограничения передачаHGLOBAL
как целого числа в 64-битном процессе ненадежна.Возможно, вы можете сделать так, чтобы ваш объект
window.external
имел метод, который ожидает объектdialogArguments
шаблона печати, который устанавливает__IE_PrinterCmd_DevMode
и__IE_PrinterCmd_DevNames
целыми числамиVARIANT
s (VT_I8
илиVT_UI8
).Я еще не тестировал это.
Если вы просто хотите выбрать принтер, отличный от системного по умолчанию, вы также можете установить __IE_PrinterCMD_Printer
свойство. Вы можете сделать это в JScript, это повлияет на поведение TemplatePrinter
объекты, которые вы создаете после его установки. Однако с помощью одного только этого свойства вы не можете управлять начальными настройками или знать, какой принтер в конечном итоге выбрал пользователь.
У меня только что была такая же проблема, и я обнаружил, что __IE_PrinterCmd_DevMode и __IE_PrinterCmd_DevNames можно установить из IntPtr.
Это приложение для 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;