求CHtmlView + ie7 的自动选择打印机方案

seeku 2009-05-24 02:47:01
程序架构:CHtmlView 单文档SDI程序。如何在ie7/8环境下能通过程序自动选择打印机,在不用人工选择的情况下自动打印到指定打印机?

拒绝修改默认打印机的方案,也就是选择打印机仅对当前程序会话有效。

谢谢各位老大!搞了几天,毫无收获,现在头都大了。如果提供可执行代码的样例工程,可提供现金报酬500元,绝不食言!
...全文
289 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
java8825 2009-06-26
  • 打赏
  • 举报
回复
太累, 用现成的 jatoolsPrinter控件,就可以实现啊,这个ie控件,可以用javascript选择打印机
skyxie 2009-05-31
  • 打赏
  • 举报
回复
端午快乐!

如果打印机是确定的,你可以hook到底嘛~
选中打印机之后,点击preferences,然后在弹出的对话框里面选择纸型。不同打印机的对话框不同,针对你需要的打印机的对话框进行hook!
seeku 2009-05-28
  • 打赏
  • 举报
回复
端午节快乐!hook 方式目前有个不足,比如下面情景:

电脑上有2个打印机,A和B
A 是默认打印机,支持P1、P2两种纸型
B 支持P1、P2、P3 三种纸型

如果你的任务是自动选择B打印机+P3纸型,就不知道怎么做到。
因为默认情况下Page setup对话框中列出的是默认打印机A的纸型,所以你就选择不到P3。
要使用B打印过(使用非P3纸型),Page setup对话框中列出的纸型才包含P3。



jameshooo 2009-05-26
  • 打赏
  • 举报
回复
变通的解决方案:
1、保存旧的默认打印机
2、设置新的默认打印机
3、打印
4、恢复旧的默认打印机
skyxie 2009-05-26
  • 打赏
  • 举报
回复
print template 并不是指打印机名,而是打印时页面外观的一些定义,如页眉页脚边距之类的.
(设定print template,可以customize打印预览窗口)
skyxie 2009-05-26
  • 打赏
  • 举报
回复
在我记忆中print template什么都可以设置,就是不能修改打印时使用的打印机

你可以研究一下看看print template能不能修改打印机名

Beyond Print Preview: Print Customization for Internet Explorer 5.5
http://msdn.microsoft.com/en-us/library/bb250434(VS.85).aspx

Print Preview 2: The Continuing Adventures of Internet Explorer 5.5 Print Customization
http://msdn.microsoft.com/en-us/library/bb250460(VS.85).aspx

btw, 为什么始终坚持不使用hook的方式呢?
seeku 2009-05-26
  • 打赏
  • 举报
回复
print template 看上去可行,不过以前没有用过,不知道什么时候开始支持的,那里有介绍?
jameshooo 2009-05-25
  • 打赏
  • 举报
回复
微软的东西不开放就没办法,我是按照MSDN的说明来解答的,如果说明跟实际情况不一致,只能说明微软的文档没有做好。
如果有必要,你可以在汇编一级跟踪ExecWB的执行过程。

下面是MSDN上的解释(关注红色部分):
Command group CGID_MSHTML (defined in mshtmhst.h)
Symbolic constant IDM_PRINT
User interface Optional. Set nCmdExecOpt to OLECMDEXECOPT_DODEFAULT or OLECMDEXECOPT_PROMPTUSER to display the print dialog. Set nCmdExecOpt to OLECMDEXECOPT_DONTPROMPTUSER to send the document directly to the current printer without invoking the dialog.
IOleCommandTarget::Exec parameters pvaIn VARIANT of type VT_BSTR, VT_I2, or VT_ARRAY.
If pvaIn is a VARIANT of type VT_BSTR, pvaIn specifies the path to a custom print template.

If pvaIn is a VARIANT of type VT_I2, pvaIn can be set with the flags PRINT_DONTBOTHERUSER(0x01) and PRINT_WAITFORCOMPLETION(0x02) defined in mshtmhst.h . If 0 is specified, then the default behavior (show print dialog and do not wait for completion) occurs unless otherwise defined by the nCmdExecOpt parameter.

If pvaIn is a VARIANT of type VT_ARRAY, pvaIn specifies a SAFEARRAY containing (in the following order) a header BSTR, a footer BSTR, the address of an IStream pointer for a Microsoft Outlook Express header document, an alternate URL BSTR used for MSHTML in Outlook Express, and a DWORD containing flags.

Can be set to NULL to use the Microsoft Internet Explorer default print template.

pvaOut Set to NULL.

Header file mshtmcid.h
seeku 2009-05-24
  • 打赏
  • 举报
回复
我现在也在搞hook方式。这种方式不够优雅,作为后备方案。

不过现在还没有搞定,选中打印机以后立刻发送点击“打印”按钮的消息还是会用默认打印机进行打印,
如果选中以后不发送消息,就能看到的确选中了,当然对话框不会关闭,也不会开始打印。
skyxie 2009-05-24
  • 打赏
  • 举报
回复
直接通过ExecWB的方式无解。

需要编程实现模拟用户点击打印菜单项,hook IE弹出的打印对话框,选择打印机,点击打印按钮。
(同时这个弹出的对话框还不能是可见的,不然用户看到会很不舒服哈~)
seeku 2009-05-24
  • 打赏
  • 举报
回复
pdfFactory Pro是从“打印机和传真”那个窗口拷贝过来的,不会有错的。

我为了检验,我设置pdfFactory Pro为默认打印机,把输出的打印机设置为"Microsoft Office Document Image Writer";

使用下面的代码,无法打印。

VARIANT v;
::VariantInit(&v);
v.vt = VT_BSTR;
v.bstrVal = ::SysAllocString(L"Microsoft Office Document Image Writer");

HRESULT hr = m_pWebBrowser->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, &v, NULL);

如果去掉 &v,就可以打印到默认打印机pdfFactory Pro。

我用的是ie8。
jameshooo 2009-05-24
  • 打赏
  • 举报
回复
1、确保pdfFactory Pro是正确的打印机实例名称
2、确信该打印机实例不会对用户做出进一步的提示(例如保存的文件路径)
oyljerry 2009-05-24
  • 打赏
  • 举报
回复
http://support.microsoft.com/kb/q247671/
http://support.microsoft.com/default.aspx?scid=kb%3BEN-US%3BQ267240
seeku 2009-05-24
  • 打赏
  • 举报
回复
不行哦,修改后我的代码如下:

VARIANT v;
::VariantInit(&v);
v.vt = VT_BSTR;
v.bstrVal = ::SysAllocString(L"pdfFactory Pro");
HRESULT hr = m_pWebBrowser->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, &v, NULL);

执行情况是没有反应。

如果取消 &v,也就是

HRESULT hr = m_pWebBrowser->ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);

就会打印到默认打印机
jameshooo 2009-05-24
  • 打赏
  • 举报
回复

VARIANT v;
::VariantInit(&v);
v.vt = VT_BSTR;
v.bstrVal = ::SysAllocString(L"打印机显示名称");

pWebBrowser2->ExecWB(IDM_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, &v, NULL);
::VariantClear(&v);
seeku 2009-05-24
  • 打赏
  • 举报
回复
找到微软上的一篇文章
http://support.microsoft.com/kb/267240/en-us

其中第5点似乎用得上。
When you use an OLECMDID enumeration of the OLECMDID_PRINT element together with the ExecWB method, you can specify extended printing information by passing in the SAFEARRAY structure through the VARIANT argument pvaIn. This SAFEARRAY data type takes a maximum of five items:
A string (BSTR) that contains a custom header.
A string (BSTR) that contains a custom footer.
An IStream object that contains an HTML file that serves as an "optional header." This is the e-mail header that you see in Microsoft Outlook and Microsoft Outlook Express e-mail messages when you print them. This IStream object must point to a full, valid HTML document, not to HTML fragments, or it will print incorrectly.
An alternative URL to use for the document. This is only relevant to Outlook and to Outlook Express.
A set of printing flags (dwFlags) to configure the printer. This is only relevant to Outlook and to Outlook Express.

不过更详细的说明就找不到了。

3,055

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC HTML/XML
社区管理员
  • HTML/XML社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧