分享

IE WebBrowser 深度复制拷贝/三种遍历IFRAME方式

 quasiceo 2014-07-17

使用方式:

if (m_pBrowserApp != NULL)
 {
  HRESULT hr;
  LPDISPATCH lpDisp = GetHtmlDocument();
  if (lpDisp != NULL)
  {
   CComPtr<IHTMLDocument2> spDocument;
   hr = lpDisp->QueryInterface(IID_IHTMLDocument2, (void**) &spDocument);
   hr = CopySelection2Clipbord(spDocument,m_hWnd);

   lpDisp->Release();
  }
 }

//拷贝实现方式,共【三种遍历FRAME】方式:

HRESULT CopySelection2Clipbord(CComPtr<IHTMLDocument2>& spDocument, HWND hWnd)
{
 HRESULT hr, hResult = MAKE_HRESULT(1,FACILITY_NULL,0);
 long i = 0, j = 0;
 CComQIPtr<IHTMLSelectionObject> spSelection;
 hr = spDocument->get_selection(&spSelection);
 if (SUCCEEDED(hr))
 {
  CComBSTR bstrType;
  hr = spSelection->get_type(&bstrType);
  if(SUCCEEDED(hr))
  {
   CString strType = _T("text");
   if(!strType.CompareNoCase(bstrType))
   {
    CComQIPtr<IHTMLTxtRange> spRange;
    hr = spSelection->createRange((IDispatch **)&spRange);
    if(SUCCEEDED(hr))
    {
     CComQIPtr<IHTMLTxtRange> spTextRange;
     hr = spRange->QueryInterface(IID_IHTMLTxtRange, (void**)&spTextRange); 
     if (SUCCEEDED(hr))
     {
      CComBSTR bstrHtml, bstrText;
      spTextRange->get_htmlText(&bstrHtml);
      spTextRange->get_text(&bstrText);
      //写入剪贴板
      CString cliphtml = bstrHtml;
      CString cliptext = bstrText;
      CopyHtmlToClip(cliphtml, cliptext, hWnd);
      hResult = S_OK;
     }
    }
   }
  }
 }

 //iframe 跨域访问(cross frame), 由于安全性限制, 为防止跨域脚本攻击, 当frames 跨域的时候, IHTMLWindow2::get_document 调用将返回 E_ACCESSDENIED .
 //对于跨域的frame 通过 IHTMLWindow2 -> IID_IWebBrowserApp -> IHTMLWindow2 绕过了限制.

 /*//这种遍历不能跨域访问
 if(!SUCCEEDED(hResult))
 {
  CComQIPtr<IHTMLFramesCollection2> spCollection;
  HRESULT hr= spDocument->get_frames(&spCollection);
  if(SUCCEEDED(hr))
  {
   long i = 0, j = 0;
   VARIANT varindex,varresult;
   varresult.vt = VT_DISPATCH;
   varindex.vt = VT_I4;
   hr = spCollection->get_length(&j);
   if (SUCCEEDED(hr))
   {
    for (i= 0; i < j; i++)
    {
     varindex.lVal = i;
     hr = spCollection->item(&varindex, &varresult);
     if (SUCCEEDED(hr))
     {
      CComQIPtr<IHTMLWindow2> spWindow;
      CComQIPtr<IHTMLDocument2> spDocument2;
      CComQIPtr<IDispatch> spDispatch((LPDISPATCH)varresult.ppdispVal);
      if (SUCCEEDED(spDispatch->QueryInterface(IID_IHTMLWindow2,(LPVOID *)&spWindow)))
      {
       if(SUCCEEDED(spWindow->get_document(&spDocument2)))
       {
        hResult = CopySelection2Clipbord(spDocument2, hWnd);
        if(SUCCEEDED(hResult))
        {
         break;
        }
       }
      }
     }
    }
   }
  }
 }*/

 if(!SUCCEEDED(hResult))
 {
  CComQIPtr<IOleContainer> spContainer(spDocument);
        if(spContainer)
  {
   CComPtr<IEnumUnknown> spEnumerator;
   hr = spContainer->EnumObjects(OLECONTF_EMBEDDINGS, &spEnumerator);
   if(SUCCEEDED(hr))
   {
    ULONG uFetched = 0;
    CComPtr<IUnknown> spUnk;
    while (spEnumerator->Next(1, &spUnk, &uFetched) == S_OK)
    {
     CComQIPtr<IWebBrowser2, &IID_IWebBrowser2> spWB(spUnk);
     if(spWB)
     {
#if 1
      CComPtr<IDispatch> spDisp;
      hr = spWB->get_Document(&spDisp);                                       
      CComPtr<IHTMLDocument2> spDocument2;
      hr = spDisp->QueryInterface(IID_IHTMLDocument2, (void**) &spDocument2);
      hResult = CopySelection2Clipbord(spDocument2, hWnd);
#else
      hResult = spWB->ExecWB(OLECMDID_COPY, OLECMDEXECOPT_SHOWHELP, NULL, NULL);
#endif//
      if(SUCCEEDED(hResult))
      {
       break;
      }
     }
     spUnk.Release();
    }
   }
  }
 }

 /*if(!SUCCEEDED(hResult))
 {
  CComPtr<IHTMLElementCollection> spElementCollection; 
  hr = spDocument->get_all(&spElementCollection);
  if(SUCCEEDED(hr))
  {
   spElementCollection->get_length(&j);
   for(i = 0; i < j; i++)
   {
    VARIANT id, index;
    V_VT(&id) = VT_I4;
    V_I4(&id) = i;
    V_VT(&index) = VT_I4;
    V_I4(&index) = 0;
    CComPtr<IDispatch> spDispatch;
    hr = spElementCollection->item(id, index, &spDispatch);
    if(spDispatch)
    {
     CComQIPtr<IHTMLElement> spElement(spDispatch);
     if(spElement)
     {
      CComBSTR bstrTagName;
      spElement->get_tagName(&bstrTagName);
      if (lstrcmpiW(L"IFRAME", bstrTagName) == 0 || lstrcmpiW(L"FRAME", bstrTagName) == 0)
      {
       CComQIPtr<IHTMLFrameBase2> spFrameBase(spElement);
       if(spFrameBase)
       {
        CComPtr<IHTMLWindow2> spFrameWindow;
        hr = spFrameBase->get_contentWindow(&spFrameWindow);
        if(spFrameWindow)
        {
         CComPtr<IHTMLDocument2> spFrameDocument;
         hr = spFrameWindow->get_document(&spFrameDocument);
         if(!spFrameDocument)
         {
          CComQIPtr<IServiceProvider> spServiceProvider(spFrameWindow);
          if (spServiceProvider)
          {
           CComPtr<IWebBrowser2> spWebBrowser;
           hr = spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrowser);
           if(spWebBrowser)
           {
            CComQIPtr<IDispatch> spDispDocument;
            hr = spWebBrowser->get_Document(&spDispDocument);
            spFrameDocument = spDispDocument;
            //hr = spWebBrowser->ExecWB(OLECMDID_COPY, OLECMDEXECOPT_SHOWHELP, NULL, NULL);
           }
          }
         }
         if(spFrameDocument)
         {
          hResult = CopySelection2Clipbord(spFrameDocument,hWnd);
          if(SUCCEEDED(hResult))
          {
           break;
          }
         }
        }
       }
      }
     }
    }
   }
  }
 }*/

 return hResult;
}

 //拷贝实现:

BOOL CopyHtmlToClip(const CString &strHtml, const CString &strText, HWND hWnd)
{
 // 1)转换成UTF-8
 int len = strHtml.GetLength();

 if(len <= 0)
 {
  return FALSE;
 }

 char* pszU8 = new char[len * 3 + 1];
 T2C(LPCTSTR(strHtml), pszU8, len * 3 + 1, CP_UTF8);

 int nHtmlSrcLen = strlen(pszU8);

 // 2)组成剪贴板片段
 char* strHtmlClip = new char[nHtmlSrcLen + 512];
 sprintf(strHtmlClip,
   "Version:0.9\r\n"
   "StartHTML:%08u\r\n"
   "EndHTML:%08u\r\n"
   "StartFragment:%08u\r\n"
   "EndFragment:%08u\r\n"
   "<html><body>\r\n"
   "<!--StartFragment -->\r\n"
   "%s\r\n"
   "<!--EndFragment-->\r\n"
   "</body></html>",
   97, 172 + nHtmlSrcLen, 111, 136 + nHtmlSrcLen, pszU8);

 // 3)剪贴板操作
 static int cfid = 0;
 if(!cfid)
 {
  cfid = RegisterClipboardFormat(_T("HTML Format"));
 }

 if (!OpenClipboard(hWnd))
 {
  return false;
 }

 if (!EmptyClipboard())
 {
  CloseClipboard();
  return false;
 }

 len = strlen(strHtmlClip);
 HGLOBAL hClipBuffer = GlobalAlloc(GMEM_DDESHARE, len + 1);
 if (hClipBuffer == NULL)
 {
  CloseClipboard();
  return false;
 }

 char *lpExpBuffer = (char *)GlobalLock(hClipBuffer);
 if (lpExpBuffer == NULL)
 {
  GlobalFree(hClipBuffer);
  CloseClipboard();
  return false;
 }

 memcpy(lpExpBuffer, strHtmlClip, len);
 lpExpBuffer[len] = '\0';

 GlobalUnlock(hClipBuffer);
 SetClipboardData(cfid, hClipBuffer);
 CloseClipboard();   

 delete []pszU8;
 delete []strHtmlClip;

 CopyTextToClip(strText, hWnd, false);

 return TRUE;
}


BOOL CopyTextToClip(const CString &strText, HWND hWnd, bool bEmpty)
{
 if (OpenClipboard(hWnd))
 {
  HGLOBAL clipBuffer; 

  if(bEmpty)
  {
   EmptyClipboard();
  }

#ifdef _UNICODE         //复制Unicode字符串到剪贴板
  wchar_t * buffer;
  clipBuffer = GlobalAlloc(GMEM_DDESHARE, 2 * lstrlen(strText) + sizeof(wchar_t));
  buffer = (wchar_t*)GlobalLock(clipBuffer);
  wcscpy(buffer,LPCWSTR(strText));
  GlobalUnlock(clipBuffer);
  SetClipboardData(CF_UNICODETEXT,clipBuffer);
#else                         //复制ANSI字符串到剪贴板
  char *pbuff;
  clipBuffer = GlobalAlloc(GMEM_DDESHARE,strText.GetLength()+1);
  pbuff = (char*)GlobalLock(clipBuffer);
  strcpy(pbuff,LPCSTR(strText));
  GlobalUnlock(clipBuffer);
  SetClipboardData(CF_TEXT,clipBuffer);
#endif

  CloseClipboard();

  return TRUE;
 }

 return FALSE;
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多