웹, HTML

HTML frame의 웹브라우저 객체에 접근하는 방법

디버그정 2008. 9. 7. 13:42

How to get the WebBrowser object model of an HTML frame

http://support.microsoft.com/kb/q196340

IE 프로그래밍에서 제일 부딪히는 난관이 바로 이겁니다. C++, VB, Delphi 할 것 없이 프레임셋을 순회하다보면 도메인이 달라서 DOM 에 접근할 수가 없는데, 이 보안 제한을 우회해 모든 프레임을 순회하는 방법을 설명합니다. 뭐, 아래 코드만 보면 원리는 단박에 알 수 있습니다. 브라우저가 가진 제한을 상위 인터페이스로 올라가서 순회하여 보안 제한에 걸리지 않고 다시 하위 인터페이스인 브라우저로 돌아오는 방법입니다. 이것 말고 IAccessible 인터페이스를 이용할 수도 있는데 원리는 똑같습니다. 아래 예제를 이해한 다음 한번 스스로 작성해보시기 바랍니다.

// Get the IDispatch of the document
LPDISPATCH lpDisp = NULL;
lpDisp = m_webBrowser.GetDocument();

if (lpDisp)
{
   IOleContainer* pContainer;

   // Get the container
   HRESULT hr = lpDisp->QueryInterface(IID_IOleContainer,
                                       (void**)&pContainer);
   lpDisp->Release();

   if (FAILED(hr))
      return hr;

   IEnumUnknown* pEnumerator;

   // Get an enumerator for the frames
   hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);
   pContainer->Release();

   if (FAILED(hr))
      return hr;

   IUnknown* pUnk;
   ULONG uFetched;

   // Enumerate and refresh all the frames
   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))
      {
         // Refresh the frame
         pBrowser->Refresh();
         pBrowser->Release();
      }
   }

   pEnumerator->Release();
}