1、通过IWebBrowser2的Navigate2来实现快照,怎样取得整个页面的快照,而不是显示的部份?我在代码中通过Navigate2来打开网页,然后render到image中来取得网页快照,但取得的是当前显示部份的而不是整个网页的。
2、在取得有些网页的快照时有部份内容会无法显示,如http://sports.sina.com.cn/中左边的flash。还有在快照www.sina.com.cn时,由于sina会在显示时显示一个大图片,所以在快照图片中那个大图片的地方也会是一片空白,且sina首页的用户登录那一个菜单条也无法显示。
3、怎样在IWebBrowser2设置是否屏蔽java、javascript、ActiveX这种功能?这3个问题搞了两周了,请大侠们指点,多谢!

解决方案 »

  1.   

    上面总是有的地方讲得有错误,下面更正一下:
    1、对于sina首页应该是有部份内容显示不出来。2、对于flash总是,好象也不是所有flash都显示不出来,只有有部份显示不出来而已。象新浪首页有的flash就能显示。但sports.sina.com.cn中的那个就显示不出来。
      

  2.   

    还有,只要界面中有内容无法显示,那么调用以下实现滚动的代码就会失效:
    ((IHTMLDocument2 *) pDoc)->get_parentWindow(&pWin);
    pWin->scroll(0, yIndex);
      

  3.   

    1、计算文档的高度,在render时按照此高度设置DC的矩形
    2、DocumentComplete事件发生时图片可能是没有下载完成的,此时显示将是一个跟图片一样大小的空白,你可以在DocumentComplete之后设置定时器等一段时间再试
    3、不知道你是通过MFC提供的类来显示的浏览器控件还是自己实现容器接口的。用SetHostFlags来设置DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE,或者在实现的IDocHostUIHandler的GetHostInfo方法里面设置。其实更深层解决办法是在实现容器接口的同时实现IDispatch接口,在Invoke方法里面判断DISPID为DISPID_AMBIENT_DLCONTROL时返回一些控制标志即可,比如:
    DLCTL_NO_SCRIPTS
    DLCTL_NO_JAVA
    DLCTL_NO_RUNACTIVEXCTLS
      

  4.   

    ouch,why dont u use printing out in IE?
      

  5.   

    TO jameshooo:
    对于我的第一个问题,我写错了。其实不是图片显示不出来,而是页面中有部分内容显示不出来
    还有ebay(www.ebay.com)也是这样,页面的头显示不出来(logo部份)。而sports.sina.com则是有个flash无法显示我在全屏快照时,已经按你的方法来指定render的调试了,而且我等待时间是1分钟,还是得出来的是一片空白,之前不能显示的页面部份和页面的其余部份还是不能显示。我在render时指定尺寸为1024x2048
      

  6.   

    我在代码如下:
    /*
    szSrcFilename为页面URL
    szDestFilename为输出的图片名称
    srcSize为要快照的页面尺寸
    startPoint为快照的页面起始点传票
    outputSize为输出的图片大小
    */
    BOOL CCreateHTMLImage::CreateImage(LPCTSTR szSrcFilename, LPCTSTR szDestFilename, CSize srcSize, CSize startPoint, CSize outputSize)
    {
    ASSERT(GetSafeHwnd());
    ASSERT(IsWindow(GetSafeHwnd()));
    ASSERT(szSrcFilename);
    ASSERT(AfxIsValidString(szSrcFilename));
    ASSERT(szDestFilename);
    ASSERT(AfxIsValidString(szDestFilename)); CRect rect;
    CWnd m_pBrowserWnd;
    CComPtr<IWebBrowser2> m_pBrowser; if (!CWnd::Create(NULL, NULL, WS_CHILD, rect, pParent, 0, NULL))
    return FALSE; if (!m_pBrowserWnd.CreateControl(CLSID_WebBrowser, _T(""), WS_VISIBLE | WS_CHILD, rect, this, CHILDBROWSER))
    {
    DestroyWindow();
    return FALSE;
    } LPUNKNOWN lpUnk = m_pBrowserWnd.GetControlUnknown();
    HRESULT hr = lpUnk->QueryInterface(IID_IWebBrowser2, (void**) &m_pBrowser); if (!SUCCEEDED(hr))
    {
    m_pBrowser = NULL;
    m_pBrowserWnd.DestroyWindow();
    DestroyWindow();
    return FALSE;
    } CRect rect(CPoint(0, 0), srcSize); // The WebBrowswer window size must be set to our srcSize
    // else it won't render everything
    //把控件指定到要快照的网页的尺寸大小
    MoveWindow(&rect);
    m_pBrowserWnd.MoveWindow(&rect); COleVariant   vUrl(szSrcFilename, VT_BSTR),
      vFlags(long(navNoHistory | navNoReadFromCache | navNoWriteToCache), VT_I4),
      vNull(LPCTSTR(NULL), VT_BSTR);
    COleSafeArray vPostData; if (m_pBrowser->Navigate2(&vUrl, &vFlags, &vNull, &vPostData, &vNull) == S_OK)
    // We have to pump messages to ensure the event handler (DocumentComplete)
    // is called.
    //调用这句代码的作用是产生线程阻塞,直到DocumentComplete函数被高用,防止页面还没加载完就生成图片
    RunModalLoop();
    else
    return FALSE;
    // We only get here when DocumentComplete has been called, which calls EndModalLoop
    // and causes RunModalLoop to exit.
    IDispatch *pDoc = (IDispatch *) NULL;
    HRESULT   hr = m_pBrowser->get_Document(&pDoc);
    IHTMLWindow2 *pWin = (IHTMLWindow2 *)NULL;
    ((IHTMLDocument2 *) pDoc)->get_parentWindow(&pWin); pWin->scroll(startPoint.cx, startPoint.cy); if (FAILED(hr))
    return FALSE; return CreateImage((IHTMLDocument2 *) pDoc, szDestFilename, srcSize, outputSize);
    }BOOL CCreateHTMLImage::CreateImage(IHTMLDocument2 *pDoc, LPCTSTR szDestFilename, CSize srcSize, CSize outputSize)
    {
    USES_CONVERSION;
    ASSERT(szDestFilename);
    ASSERT(AfxIsValidString(szDestFilename));
    ASSERT(pDoc); // Get our interfaces before we create anything else
    IHTMLElement    *pElement = (IHTMLElement *) NULL;
    IHTMLElementRender *pRender = (IHTMLElementRender *) NULL; // Let's be paranoid...
    if (pDoc == (IHTMLDocument2 *) NULL)
    return FALSE; pDoc->get_body(&pElement); if (pElement == (IHTMLElement *) NULL)
    return FALSE; pElement->QueryInterface(IID_IHTMLElementRender, (void **) &pRender); if (pRender == (IHTMLElementRender *) NULL)
    return FALSE; CFileSpec fsDest(szDestFilename);
    CBitmapDC destDC(srcSize.cx, srcSize.cy); pRender->DrawToDC(destDC); CBitmap *pBM = destDC.Close();

    Bitmap *gdiBMP = Bitmap::FromHBITMAP(HBITMAP(pBM->GetSafeHandle()), NULL); //新建一个bmp图片   
    Image   *bitmap   =   (Image *)new   Bitmap(outputSize.cx, outputSize.cy);   
    //新建一个画板   
    Graphics *g   =   Graphics::FromImage(bitmap);   
    //设置高质量插值法   
    g->SetInterpolationMode(InterpolationModeHighQuality);   
    //设置高质量,低速度呈现平滑程度   
    g->SetSmoothingMode(SmoothingModeHighQuality);   
    //清空一下画布   
    g->Clear(Color.Blue);   
    //在指定位置画图   
    g->DrawImage(gdiBMP, 0, 0, outputSize.cx, outputSize.cy);
    //保存高清晰度的缩略图   
    bitmap->Save(A2W(((LPCSTR)(LPCTSTR)(fsDest.GetFullSpec()))),   &m_encoderClsid);    delete gdiBMP;
    delete g;
    delete bitmap;
    delete pBM; return TRUE;
    }
    下面是调用代码:
    m_pHTMLImage->CreateImage("http://www.sina.com", "c:\\sina_0-768.jpg", CSize(1024, 2048), CSize(0, 0), CSize(1024, 2048))
    我这里偷赖指定了页面大小为1024x2048,新浪的页面绝对超过这个尺寸了。
      

  7.   

    调用这个试试:
    RECT rc = {0, 0, 1024, 2048};
    OleDraw((LPUNKNOWN)m_pBrowser, DVASPECT_CONTENT, destDC, &rc);
      

  8.   

    我按你的方法,修改了代码:
    //pRender->DrawToDC(destDC);RECT rc = {0, 0, 1024, 2048}; 
    OleDraw((LPUNKNOWN)m_pBrowser, DVASPECT_CONTENT, destDC, &rc);还是不行,结果一样。页面会有部份内容无法显示的问题有解决的办法吗?
      

  9.   

    to jameshooo:
    怎样在IWebBrowser2设置是否屏蔽java、javascript、ActiveX这种功能? 能给个例子吗?
      

  10.   

    先告诉我你是在什么环境下使用浏览器控件的。MFC的CDHtmlDialog或者CHtmlView?还是其它?
      

  11.   

    是通过CHtmlView?
    顺便问一下,这些方式有什么区别?
      

  12.   

    本质上没有区别,但是如果是MFC类的话处理起来方便一点,在CHtmlView的派生类中重载下面的CWnd虚函数:
    virtual BOOL OnAmbientProperty(COleControlSite* pSite, DISPID dispid, VARIANT* pvar )
    {
      if (dispid == DISPID_AMBIENT_DLCONTROL)
      {
        V_VT(pvar) = VT_I4;
        V_I4(pvar) = DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS;
        return TRUE;
      }  return FALSE;
    }
      

  13.   

    最后一句还是改成 return CWnd::OnAmbientProperty(pSite, dispid, pval); 吧。
    里面的pvar 也改成 pval