CWebBrowser2加载打印心得

c++内嵌IWebBrowser2功能整理 目的:加深对IWebBrowser2的理解,整理。方便以后学习和使用。也方便需要这反面的朋友少点弯路。 声明:有些知识点是本人在使用和学习中借助网络搜索到的,所有难免会有雷同,我会尽量标注原著的出处,当然也可能找不到原著的出去了,如果牵扯到版权或者其他的可以通知我,我会跟你一同处理。本文的源码也有部分是来自网络和msdn上面,出处我也会尽量标明。 前言:前段时间,一个大学同学问我,在win下面 阅读详情
最近学习在VC6下使用CWebBrowser2,目的是打印指定路径的网页。遇到了奇怪的问题。

当我把Navigate函数和ExecWB函数放在一起,程序运行报错,弹出一个没有内容的消息框。


当我把ExecWB函数放在另外的按钮上(例如"打印按钮"),程序执行正常。


猜测可能是网页加载状态问题,于是在网上真的找到了这个函数GetReadyState()

typedef enum tagREADYSTATE {
    READYSTATE_UNINITIALIZED = 0,
    READYSTATE_LOADING = 1,
    READYSTATE_LOADED = 2,
    READYSTATE_INTERACTIVE = 3,
    READYSTATE_COMPLETE = 4
} READYSTATE;


READYSTATE_UNINITIALIZED
Default initialization state.
READYSTATE_LOADING
Object is currently loading its properties.
READYSTATE_LOADED
Object has been initialized.
READYSTATE_INTERACTIVE
Object is interactive, but not all of its data is available.
READYSTATE_COMPLETE
Object has received all of its data.

所以必须等到GetReadyState()返回值是READYSTATE_COMPLETE时,网页才加载完成。当然加载完成了才能干后面的事情呀。


于是写了下面的代码

class CDlgWebPrint : public CDialog
{
// Construction
public:
    //…………
    CDlgWebPrint(CWnd* pParent = NULL);   // standard constructor
// Dialog Data
    //{{AFX_DATA(CDlgWebPrint)
    enum { IDD = IDD_DIALOG_WEBPRINT };
    CWebBrowser2    m_pWebPrint;
    //}}AFX_DATA
}
 
BOOL CDlgWebPrint::OnInitDialog() 
{
    CDialog::OnInitDialog();
     
    // TODO: Add extra initialization here
 
 
    this->m_pWebPrint.Navigate(_T("E:/temp.htm");, NULL, NULL, NULL, NULL);//打开strURL文件
//打印  
//  this->m_pWebPrint.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
    LONG n = 0;
    while (TRUE)
    {
        if (this->m_pWebPrint.GetReadyState() == READYSTATE_COMPLETE )
//READYSTATE_COMPLETE = 4,表示网页加载完成。但这里一直是READYSTATE_LOADING = 1,
//等了十几分钟还是1.我确定打开这个网页不需要1秒钟。还有什么玄机吗?吗吗吗?
        {
            this->m_pWebPrint.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL);
            break;
        }
        else
        {
            if (n++ > 20)
            {
                AfxMessageBox(_T("加载网页失败"));
                return FALSE;
            }
 
            Sleep(500);
        }
    }  
     
    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}


于是在论坛发了个帖子(http://bbs.csdn.net/topics/390392474?page=1#post-393918625)。幸好得到了oldmanzhao、fishion的指点。

为什么一直等待,但是加载没完成呢?原来CWebBrowser2::Navigate是个异步函数。因为异步函数,所以调用Navigate函数且得到返回值后,网页并没有加载好。当主程序Sleep时,主线程被挂起,线程“睡觉”了,导致CWebBrowser2::Navigate这个异步函数也“睡觉”,所以Sleep时,加载工作也停了。所以,等到猴年八月也等不到加载完成。

知道原因了,那问题应该简单了。第一步:调用Navigate加载URL,第二步:用某种方式监测加载状态GetReadyState,第三步:加载完成后调用ExecWB打印。1、3步很简单。对于异步,第二步有2种方法:计时器、子线程。计时器就是OnTime。我使用了子线程的方法达到目标。


子线程方法会遇到一个问题,子线程中不能调用ExecWB函数,会报内存访问错误。网上查来,是跨线程调用COM函数导致的。

于是我使用自定义消息,通过子线程发送消息,由主线程调用ExecWB函数。问题解决。但是在子线程中发送消息时,必须使用POSTMESSAGE,不可用SENDMESSAGE。猜测原因该是SENDMESSAGE发送时,还属于子线程调用吧(个人猜测)。


屌丝解决BUG,与君共勉。


UltraScale+ FPGA中GTY收发器参考时钟的跨Bank共享机制解析 本文深入解析了UltraScale+ FPGA中GTY收发器参考时钟的跨Bank共享机制,详细介绍了时钟布线架构、SLR区域限制及Vivado工程配置要点。通过实际案例和优化建议,帮助工程师解决高速串行通信中的时钟共享问题,提升系统性能。 阅读详情

相关推荐

SAP 角色继承、派生

角色继承、派生 继承:是指两个角色Role形成母子关系。子角色的所有菜单、授权都源于母角色,并与母角色保持一致。母角色与子角色是1对多的关系。 继承关系:新建子角色继承母角色中的事务(后续通过复制,将母角色授权数据复制至子角色) 派生概念:将母角色中的授权数据派生至子角色中。 业务场景:方便批量修改子角色权限。若有继承关系,只需要修改母角色,然后通过母角色派生功能,从而批量修改子角色授权数...

willieyuan的博客 1万+

【比较】CWebBrowser2Navigate方法的一些问题

CWebBrowser2::Navigate2()之后,有时会收不到DocumentComplete事件? 这个事件在所有资源(包括链接的CSS、脚本、图片等等)下载完毕之后触发。 IE的一个版本存在这样的问题。 浏览器控件被隐藏时这个事件也不会被触发 CWebBrows

小发猫 3250

7830万用表原理图sdust.zip

电工电子实训 7830万用表原理图绘制

Microsoft Web Browser控件的常用功能

  微软的Web Browse控件使用方法,选择菜单 Project -> Add to Project -> Components and controls…,在弹出的对话框中选择Registered ActiveX Controls文件夹,然后选中列表中的Microfost Web 浏览控件。或者编辑对话框资源时,右键单击选择Insert ActiveX控件选项,也可以在列表中选择该控件

Huuyoo的专栏 4132

【小沐学C++】C++ MFC中嵌入web网页控件(WebBrowser、WebView2、CEF3)

WebBrowser控件最常见的用途之一是向应用程序添加 Internet 浏览功能。使用 IWebBrowser2 接口,可以浏览到本地文件系统、网络或万维网上的任何位置。可以使用IWebBrowser2::Navigate 方法告知控件要浏览到哪个位置。第一个参数是包含位置名称的字符串。要浏览到本地文件系统或网络上的某个位置,请指定文件系统位置的完整路径或网络上该位置的 UNC 名称。若要浏览到万维网上的某个站点,请指定该站点的 URL。╮( ̄▽ ̄)╭。

爱看书的小沐 9362

CWebBrowser2 常见的使用方法

http://blog.csdn.net/ligangok/article/details/4213955 使用方法,1.首先进入类设计视图,2.其次选择菜单 项目-> 添加类 -> MFC ACtive插件…,在弹出的对话框中选择Registered ActiveX Controls文件夹,然后选中列表中的Microfost Web 浏览控件。或者编辑对话框资源时,右键单击选择Inse

WWW0526WWW的专栏 2613

CWebBrowser2去除边框、滚动条、右键菜单

百度了一下,原来有sample的,参见:http://www.microsoft.com/en-us/download/details.aspx?id=944#filelist 自己总结了一下 添加CWebBrowser2类 右键项目-〉Add-〉Class...-〉MFC-〉MFC Class From ActiveX Control 在Available ActiveX

小龙王2010 1649

CWebBrowser2的用法

<br />Q CWebBrowser2的用法 T 我如何在一个函数中自己动态(因为我不需要对话框)创建CWebBrowser2控件,实现打印一个指定.htm文件的功能? A to print m_wndWebbrowser2.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL); to create call CWnd::CreateControl see the CHtmlView code in MFC so

sb3day的专栏 9419

在对话框中如何打印网页

首先必须在对话框中加入Microsoft Web浏览器,通过他的变量得到文档,再通过如下代码可以达到打印的目的:LPDISPATCH lpDispatch=NULL; LPOLECOMMANDTARGET lpOleCommandTarget=NULL; lpDispatch=m_IE.GetDocument(); ASSERT(lpDispatch); lpDispatch->QueryIn

1287

IE编程问题收藏

Q CWebBrowser2的用法 T  我如何在一个函数中自己动态(因为我不需要对话框)创建CWebBrowser2控件,实现打印一个指定.htm文件的功能?

张云飞的专栏 2513

HTML编程1

QCWebBrowser2的用法T 我如何在一个函数中自己动态(因为我不需要对话框)创建CWebBrowser2控件,实现打印一个指定.htm文件的功能?Ato printm_wndWebbrowser2.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL);to

1131

HTML(1):WebBrowser

http://blog.csdn.net/vcmute/archive/2005/10/31/520065.aspx Q CWebBrowser2的用法 T  我如何在一个函数中自己动态(因为我不需要对话框)创建CWebBrowser2控件,实现打印一个指定.htm文件的功能? A to printm_wndWebbrowser2.ExecWB(OLECMDID_PRINT, OLECMD

清风专栏 5212

如何对webbrowser和IE编程(七)

 加入高级功能本节将展示如何加入高级功能到你的应用程序或者ActiveX控件.将展示如何从一个ActiveX控件中访问Internet Explorer的 IWebBrowser2,以及如何从一个Web页面的frame中获得WebBrowser 对象。将会展示实现一些并非容易实现的功能.本节有一定难度.所有代码采用C++ 和COM实现,你应当有一定坚实的基础才可以完成本节的理解从Act

bird207的专栏 512

如何对webbrowser和IE编程(四)

寄宿WebBrowser 控件 我们现在开始在VB和VC中创建一些程序来寄宿(Host)WebBrowser控件。在你完成本部分的样本,你将对如何创建寄宿一个WebBrowser控件的应用程序又一个基本的了解。当你看到如此容易的加入Web浏览功能加入到你的应用程序,我相信你会立即开始实践的。 使用VB 在VB中,你可以在5分钟内开发一个全功能的自己的we...

weixin_34067049的博客 199

WebBrowser.ExecWB

CreateTime--2017年9月22日16:30:10 Author:Marydon js操作浏览器的ExecWB命令 一、准备工作: 以ie浏览器为例,需要更改IE安全级别为:"启用没有标记为安全的ActiveX控件" IE浏览器-工具菜单选项——Internet选项——安全——Internet——自定义级别——启用没有标记为安全的ActiveX控件 否则,执行...

weixin_30487201的博客 142

MFC2024年的实用价值:从原理到实战的Windows GUI编程指南

Windows GUI编程是桌面应用开发的基础领域,其核心在于理解操作系统提供的原生API与消息驱动机制。MFC(Microsoft Foundation Classes)作为一套经典的C++类库,通过面向对象方式封装了底层的Win32 API,将窗口创建、消息处理、图形绘制等复杂操作抽象为CView、CDocument等类,显著降低了开发原生Windows应用的复杂度。这一技术价值在于它提供了对Windows生态的深度访问能力,尤其适合需要开发轻量、高效、无依赖原生工具的场景。在工业控制、金融、医疗等领域

weixin_30247781的博客 360

WebBrowser 控件实现地址栏

WebBrowser 控件具有多个与导航相关的属性、方法和事件。使用下面的成员可以将控件导航到特定 URL、在导航历史记录列表中向后和向前移动,还可以加载当前用户的主页和搜索页: Url Navigate GoBack GoForward GoHome ...

weixin_34384681的博客 161

c iwebbrowser2 html,通过IWebBrowser2Navigate2来打开网页,怎样判断网页是否全部加载完毕...

1)READYSTATE r;HRESULT hr = IWebBrowser2::get_ReadyState(&r);if (SUCCEEDED(hr) && r == READYSTATE_COMPLETE) {...}2)if (SUCCEEDED(IWebBrowser2::Stop()) {...}-------------------------Navigat...

weixin_33685133的博客 341

CWebBrowser2的使用

一个CWebBrowser2包含了几个子窗口,子窗口类名分别是:Shell DocObject View,Shell Embedding,Internet Explorer_Server。如果用CWebBrowser2加载一个swf文件,还会有一个类名为MacromediaFlashPlayerActiveX的子窗口。可以通过给CWebBrowser2发送消息,弹出添加到收藏夹等IE常见功能对话框。具体方法网上一搜就有,大体方法如下:获取 Explorer_Server窗口指针或者句柄,然后给Explor

shyboy_NWPU的专栏 3084
上一篇: CListCtrl的LVCOLUMN简单使用笔记
下一篇: MFC工作学习笔记(更新ing)
13妖
博客等级 码龄17年 21粉丝 13原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值