Доступ к телу (хотя бы некоторым данным) в iframe с помощью плагина IE Browser Helper Object (BHO) - PullRequest
0 голосов
/ 25 февраля 2011

Я разрабатываю плагин IE8 + BHO. Сейчас я просто пытаюсь вставить текст в iframe (class = "Al Ai Editable") , содержащийся в другом iframe (id = "canvas_frame") .

Мне удалось получить IHTMLElement фрейма, в который я хочу добавить текст (class = "Al Ai editable"). Я могу доказать это тем, что переменная el имеет тип IHTMLElement:

el->get_className(&cl); //Al Ai editable

правильно отображает класс iframe в MessageBox.

Проблема, с которой я столкнулся сейчас, заключается в том, что я не могу получить доступ к элементу тела этого соответствующего iframe.

Например, когда я пытаюсь получить доступ к телу iframe с его идентификатором, используя следующий код, это приводит к сбою браузера:

el->getElementById(L":d6", &el); // ":d6" is the id of the body inside the iframe

Также, пытаясь получить внутренний HTML или внутренний текст, я просто получаю пустую строку:

el->get_innerHTML(&htm);
MessageBox(hwnd, htm, L"BHO cl", MB_OK);

или

el->get_innerText(&htm);
MessageBox(hwnd, htm, L"BHO cl", MB_OK);

ничего не отображает ("").

Я даже попробовал метод el-> get_children , и это тоже не помогло.

Вот и вся функция:

void CgmailAdderBHO::checkIframes(HWND hwnd, IDispatch *lpDisp) {

USES_CONVERSION;

if (lpDisp) {
    IOleContainer* pContainer;

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

    if (FAILED(hr)) {
      return;
    }

   IEnumUnknown* pEnumerator;

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

   if (FAILED(hr)) {
      return;
   }

   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))
     {
         // process the iframe
         CComPtr<IDispatch> docDisp;
        pBrowser->get_Document(&docDisp);
        CComQIPtr<IHTMLDocument3> doc = docDisp;
        CComQIPtr<IHTMLElementCollection> iframes;

        HRESULT hr = doc->getElementsByTagName(SysAllocString(L"body"), &iframes);
        long length;
        iframes->get_length(&length);
        CComVariant itemIndex(0);
        CComVariant empty;
        CComQIPtr<IDispatch> htmlEl;

        iframes->item(itemIndex, empty, &htmlEl);
        CComQIPtr<IHTMLElement> el = htmlEl;
        BSTR cl;
        BSTR cln(L"cP");
        el->get_className(&cl);

        if (cl && strcmp(OLE2A(cl), "cP") == 0) {
            //this is the canvas_frame
            // check if it has any other subframes
            BSTR html;
            el->get_innerHTML(&html);

            doc->getElementsByTagName(SysAllocString(L"iframe"), &iframes);
            if (iframes) {
                iframes->get_length(&length);
                if (length > 0) {
                    //MessageBox(hwnd, L"We are on compose!", L"BHO", MB_OK);
                    //add encrypt button code here
                    iframes->item(itemIndex, empty, &htmlEl);
                    el = htmlEl;
                    el->get_className(&cl); //Al Ai editable

                    BSTR htm;
                    el->get_innerHTML(&htm);
                    MessageBox(hwnd, cl, L"BHO cl", MB_OK);
                    MessageBox(hwnd, htm, L"BHO cl", MB_OK);

                    CComQIPtr<IHTMLDocument3> docul = htmlEl;

                    //docul->getElementById(L":d6", &el);

                    break; // found iframe ; now exit for
                }
            }
        }
        pBrowser->Release();
      }
   }
   pEnumerator->Release();
}
}

1 Ответ

1 голос
/ 27 февраля 2011

Причиной ошибки является ограничение безопасности.Вы получаете доступ к вложенному iframe, поэтому вам нужно перенастроить свою функцию для рекурсивной работы, чтобы обойти ограничение.

Посмотрите, как вы получаете доступ к первому уровню фреймов с помощью

hr = pContainer->EnumObjects(OLECONTF_EMBEDDINGS, &pEnumerator);

, но затем используете

doc->getElementsByTagName(SysAllocString(L"iframe"), &iframes);'

для доступа к вложенным фреймам?Это ошибка, вам нужно получить доступ к вложенным фреймам так же, как и к первым, используя EnumObjects, а затем получить интерфейс IWebBrowser2.

...