最近编写一个BHO插件,工作是从数据库中读入url,并使用IE加载。但遇到一个问题:
对于网页中含有自动跳转功能的网页无法正确的加载,因为我是在DocumentComplete事件的消息响应函数中实现新的url加载,具体就是先用navigate加载网页A,网页A中含有meta设置的5秒自动跳转到另外一个网页B,但我在响应A的DocumentComplete事件时加载了一个新的数据库中的网页C,结果网页C正确加载,而B确没有加载。
但功能要求的是网页B也要得到加载,请问各位老师怎样实现此功能?

解决方案 »

  1.   

    起初我感觉是网页C 的加载过程覆盖了网页B 的自动加载。但后来发现B 的加载也会覆盖C 网页的加载。
    当我在DocumentComplete的响应中加入messagebox时,提示网页加载完成,出现了两种情况:
    1:当网页A 加载完成弹出messagebox,显示加载完成后,我立马点击messagebox的确定按钮,则网页C 得到加载,网页B 不会得到加载
    2:当网页A 加载完成弹出messagebox,显示加载完成后,我不点击messagebox的确定按钮,等待5秒后网页B 得到加载,当网页B 加载完成后,点击A 和B 的弹出的messagebox后C 也得不到加载。
    请问有什么办法能够实现A,B,C的顺序加载?(A 为数据库中的第一个网页,B 为A 的5秒自动跳转的网页,C 为数据库中的另外一个url)
      

  2.   

    处理OnBeforeNavigate2实践,给cancel参数赋值TRUE就可以取消
      

  3.   

    这是两个在竞争的Navigate调用,后一个调用会取消前一个调用,因为浏览器控件只能容纳一个网页。
      

  4.   

    这是两个在竞争的Navigate调用,后一个调用会取消前一个调用,因为浏览器控件只能容纳一个网页。
      

  5.   

    大哥说的我试了一下不可以,代码如下不知道错误处在哪里?void STDMETHODCALLTYPE CWebScanBHO::OnBeforeNavigate2(IDispatch *pDisp, VARIANT *pvarURL, VARIANT *pvarFlags, VARIANT *pvarTargetFrameName, VARIANT *pvarPostData, VARIANT *pvarHeaders,VARIANT_BOOL Cancel)
    {
    /*================这一块是用来输出Messagebox对话框调试信息的,应该没什么影响吧===================
            wchar_t str[1024];
    int i=wcslen( (wchar_t *)pvarURL->pcVal);
    wcscpy_s(str,(wchar_t *)pvarURL->pcVal);
    wcscat_s(str,L"wo shi haoren");
    HWND hwnd;
    HRESULT hr = m_spWebBrowser->get_HWND((LONG_PTR*)&hwnd);
    CComVariant  strUrl(str); 
    strUrl.ChangeType(VT_BSTR);
            MessageBox(hwnd,OLE2CW(strUrl.bstrVal), L"BHO", MB_OK);
            ================================================================================== */
    if(Is_AimUrl==FALSE)
         Cancel=TRUE;    //调试时跟踪显示Cancel也变成1了,但并没有取消导航,为什么??
      

  6.   

    胡老大,那我这种情况有没有方法实现A、B、C依次加载网页呢?
      

  7.   

    首先你的参数弄错了,最后一个参数应该是VARIANT_BOOL* cancel,所以应该使用这种语句:
    *cancel = VAIRANT_TRUE;A/B/C依次加载没有特别的技巧,你要判断DocumentComplete时浏览器当前的URL,当是A时不处理,当是B时才重新Navigate到C
      

  8.   

    DocumentComplete时浏览器当前的URL
    --------------本身来说,是不准确的,很多网当前的url并不是网页显示的类容。
    而且,档有多个frame的时候更复杂。我的做法是的bho中,搞一个mapfile,把当前的IE内容做一个快照,相当于全局表,从而确定加载的次序。
      

  9.   


    其实不会错,浏览器的当前URL肯定是根文档的URL,无论里面是frameset还是iframe,你取到的URL可能不是根文档,因为DocumentComplete传递的IWebBrowser2接口仅仅代表当前文档,非常可能是一个frame的文档,所以不要使用这个浏览器接口,根文档所在的IWebBrowser2应该是早就保存的,应该判断根浏览器的URL就不会错。
      

  10.   

    如果你说的正确的话,根文档的url也没有什么意义。因为主要是想确定当前主要frame的webbrowse
      

  11.   

    判断是不是根文档,我使用的是比较当前接口指针与根接口指针是不是一样,代码如下:        HRESULT hr;
    IUnknown* pUnkBrowser = NULL;
            IUnknown* pUnkDisp=NULL;
    hr = m_spWebBrowser->QueryInterface( IID_IUnknown,  (void**)&pUnkBrowser);
    if ( SUCCEEDED(hr) )
    {
    hr = pDisp->QueryInterface( IID_IUnknown,  (void**)&pUnkDisp );
    if ( SUCCEEDED(hr) )
    {
    if ( pUnkBrowser == pUnkDisp )
    {   // 这是顶层框架窗口的DocumentComplete 事件 —— 页面载入完成                            SetTimer(hwnd,1,6000,(TIMERPROC)TimerProc); ////为了实现全部加载,我在此设置了一个定时器,允许6秒
                                                                                      //之内的跳转页面,6秒之外的覆盖忽略,感觉没有其他跟好的办法了
    }
                    }
            }不过上面的比较代码是网上学到的,对于这种接口指针比较的原理还是不太懂,如果胡老大了解的话能简要介绍下吗?
      

  12.   

    上面的没回复好,再重发一遍
    代码如下:HRESULT hr;
    IUnknown* pUnkBrowser = NULL;
    IUnknown* pUnkDisp=NULL;
    hr = m_spWebBrowser->QueryInterface( IID_IUnknown,  (void**)&pUnkBrowser);
    if ( SUCCEEDED(hr) )
    {
    hr = pDisp->QueryInterface( IID_IUnknown,  (void**)&pUnkDisp );
    if ( SUCCEEDED(hr) )
    {
    if ( pUnkBrowser == pUnkDisp )
    {   // 这是顶层框架窗口的DocumentComplete 事件 —— 页面载入完成
    SetTimer(hwnd,1,6000,(TIMERPROC)TimerProc);
    //为了实现全部加载,我在此设置了一个定时器,允许6秒之内的跳转页面,6秒之外的覆盖忽略
    }
    }
    }
    不过上面的比较代码是网上学到的,对于这种接口指针比较的原理还是不太懂,如果胡老大了解的话能简要介绍下吗?实现顺序加载除了定时器还有其他的好办法吗?
      

  13.   

    不知道这位大哥的“根文档的url也没有什么意义。因为主要是想确定当前主要frame的webbrowse”的含义,判断当前的frame的url使用LocationURL获得应该对的吧,实在不行就再beforenavigate2里面获得,子frame每次也都会触发这个事件的。
      

  14.   

    1.为啥用MessageBox呢?Tracer 或OutputDebugString 吧。2.同楼上,Cancel 使用有问题。另:Cancel是全局变量,还是局部变量?仔细检查一下逻辑上是不是有问题。3.在DownloadComplete中试一下。但这样得另外加个变量记录当前状态,具体你看下MSDN的说明
      

  15.   

    谢谢楼上的提示,以后全面改用OutputDebugString,以前不知道debugview,汗一个。
    结贴,实现方法是使用定时器,在每一个主文档的frame的documentdownload事件响应函数中SetTimer,timeproc中新加载url,几秒内如果beforenavigate中有新的url,则killtimer,加载自动跳转页。