首页 > 开发 > 综合 > 正文

两种方法访问多层嵌套的frame

2024-07-21 02:29:33
字体:
来源:转载
供稿:网友

========================================

在您的网站拜读了关于twebbrowser的使用方法,但是一直有一个问题困扰我,就是如何取得frame嵌套frame的html的原码,我只是知道单个frame如何取得源码,但是多个frame嵌套就没有办法,请教一下!

答========================================

要得到源代码,必须先得到frame。访问frame一般说来有两种方法:

  1、通过webbrowser的文档接口得到frame的集合,再逐一访问。

hresult ihtmldocument2::get_frames(ihtmlframescollection2 **p);

  由ihtmlframescollection2接口的item方法,可以以frame的索引号(从0开始)或frame的名称来访问相应的frame,pvarresult则返回一个idispatch接口(或一个idispatch接口的数组,多层嵌套的情况).

hresult item(         
    variant *pvarindex,
    variant *pvarresult
);

  例子如下,假设pwin是一个指向主窗口的有效的ihtmlwindow接口指针。

......
variant framerequested;
variant frameout;
ihtmlframescollection2* pframescol;
ihtmlwindow2* prightframewindow;
ihtmldocument2* prightdoc;

framerequested.vt = vt_bstr;//若为vt_i4则以索引号来访问
framerequested.bstrval = l"rightframe";//以名称来访问
//framerequested.vt = vt_i4;
//framerequested.bstrval = (bstr)0;

hr = pwin->get_frames(&pframescol);
hr = pframescol->item(&framerequested, &frameout);
  
hr = frameout.pdispval->queryinterface(iid_ihtmlwindow2, (void**)&prightframewindow);
hr = prightframewindow->get_document(&prightdoc);
......

  2、通过iolecontainer枚举嵌入对象的方式来访问webbrowser对象。

void cmyhtmlview::refreshframes()
{
  // 取得文档的idispatch指针
  lpdispatch lpdisp = null;
  lpdisp = gethtmldocument();

  if (lpdisp)
  {
    iolecontainer* pcontainer;
    hresult hr = lpdisp->queryinterface(iid_iolecontainer, (void**)&pcontainer);
    lpdisp->release();
    if (failed(hr))
      return hr;

    ienumunknown* penumerator;
    // 获得枚举器
    hr = pcontainer->enumobjects(olecontf_embeddings, &penumerator);
    pcontainer->release();
    if (failed(hr))
      return hr;

    iunknown* punk;
    ulong ufetched;
    // 枚举并刷新所有frame
    for (uint i = 0; s_ok == penumerator->next(1, &punk, &ufetched); i++)
    {
      iwebbrowser2* pbrowser;

      hr = punk->queryinterface(iid_iwebbrowser2, (void**)&pbrowser);
      punk->release();
      if (succeeded(hr))
      {
         pbrowser->refresh();
         pbrowser->release();
      }
    }
    penumerator->release();
}

  3、访问的多层嵌套frame

  注意每个frame又可以包含自己的frame,而上面所说的方法则是针对一个webbrowser的窗口实现的,并不会涉及到深层的frame。要实现多层嵌套frame的访问,只需要加入一点递归的操作就行了。如对1中的prightframewindow和2中的pbrowser,将函数稍加修改,在得到两个指针后作递归调用即可。

  4、访问源代码

  下面的方法来自chtmlview,是比较正规的方法(能够保持网页的原始格式)。

bool chtmlview::getsource(cstring& refstring)
{
  bool bretval = false;
  ccomptr<idispatch> spdisp = gethtmldocument();

  if (spdisp != null)
  {
    hglobal hmemory;
    hmemory = globalalloc(gmem_moveable, 0);
    if (hmemory != null)
    {
      ccomqiptr<ipersiststreaminit> sppersiststream = spdisp;
      if (sppersiststream != null)
      {
        ccomptr<istream> spstream;
        if (succeeded(createstreamonhglobal(hmemory, true, &spstream)))
        {
          sppersiststream->save(spstream, false);

          lpctstr pstr = (lpctstr) globallock(hmemory);
          if (pstr != null)
          {
            // stream is always ansi, but cstring
            // assignment operator will convert implicitly.

            bretval = true;
            try
            {
              refstring = pstr;
            }
            catch_all(e)
            {
              bretval = false;
              delete_exception(e);
            }
            end_catch_all

            if(bretval == false)
              globalfree(hmemory);
            else
              globalunlock(hmemory);
          }
        }
      }
    }
  }
 
  return bretval;
}

菜鸟学堂:
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表