The print template in IE uses this property to determine information about the selected printer after a user closes the Print dialog box. How can I set this property to a DEVMODE structure with code in Visual C++. How can I convert DEVMODE structure to variant. If it possible, I can pass variant to print template and then set __IE_PrinterCmd_DevMode property in jscript.
-
You can't set this property, it is readonly. – Hans Passant Jan 05 '12 at 18:35
-
It is read-only for print template. But the print dialog box set it. I want to implement a custom print dialog box and want to pass user setting to print template through this property. – A.Danesh Jan 06 '12 at 16:26
2 Answers
Marc Durdin has an excelent blog post with a detailed example in Delphi. It's easily portable to C++ and other languages:
Demystifying printing with the Microsoft WebBrowser control and ShowHTMLDialogEx
In particular, __IE_PrinterCmd_DevMode
should be an unlocked HGLOBAL
(typically a valid return value from GlobalAlloc
or GlobalReAlloc
). This is not documented anywhere, I guess Marc discovered the hard way by trial and error, finally finding it working with the values in the PRINTDLG.hDevMode
and PRINTDLG.hDevNames
fields, as directly provided by a call to PrintDlg
.
I've been able to pass HGLOBAL
s as integers to a template's script and use them to initialize __IE_PrinterCmd_DevMode
and __IE_PrinterCmd_DevNames
, before creating a TemplatePrinter
. This is handy if you don't want to call ShowHTMLDialogEx
yourself and you already have a hook into your application. I'm using the original window's external
scripting object. To access it from the template, I use:
dialogArguments.__IE_BrowseDocument.parentWindow.external
PS: Passing an
HGLOBAL
as an integer works on a 32-bit process, because JScript's numbers are actually double floats, which can represent sequential integers up to 53-bit. But due to this limitation, passing anHGLOBAL
as an integer on a 64-bit process is not reliable.Maybe you can make your
window.external
object have a method, which expects a print template'sdialogArguments
object, that sets the__IE_PrinterCmd_DevMode
and__IE_PrinterCmd_DevNames
with integerVARIANT
s (VT_I8
orVT_UI8
).I haven't tested this yet.
If you just want to select a printer other than the system default, you may just as well set the __IE_PrinterCMD_Printer
property. You can do it in JScript, it'll affect the TemplatePrinter
behavior objects that you create after setting it. However, with this property alone, you cannot control the initial settings or know which printer the user finally chose.
I have just had this same issue and have found that __IE_PrinterCmd_DevMode and __IE_PrinterCmd_DevNames can be set from an IntPtr.
This is on a X86 application, so not sure what would happen on x64 or AnyCPU.
As suggested, I use a class to pass in the DevMode and DevNames through the external object.
Here's the main parts of the code, for this:
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
Then in the Print Template
var ext = doc.parentWindow.external;
dialogArguments.__IE_PrinterCMD_Printer = ext.Printer;
dialogArguments.__IE_PrinterCmd_DevMode = ext.DevMode;
dialogArguments.__IE_PrinterCmd_DevNames = ext.DevNames;

- 43
- 5
-
-
Honestly, sometimes the trolls just can't wait!! It is an answer of how to pass a DevMode to a print template – AndrewC Feb 27 '17 at 15:15