Проблема с BHO и потоком
От: ProfX  
Дата: 03.11.10 12:05
Оценка:
Всем привет!

Разрабатывыю я сейчас BHO, раньше с BHO не работал, использую чистый WinAPI и COM. За каркас Dll-ки взял исходники из этой статьи.

В ВНО (в дальнейшем плагин) перехватывается событие DocumentComplete (DISPID_DOCUMENTCOMPLETE) вот этот блок:

Этот блок — находится в методе объекта перехватывающего события, объект статический (все также как и в статье).

if(dispIdMember == DISPID_DOCUMENTCOMPLETE && wcfSrv.isValid()){
    IWebBrowser2 *piWB2;
    IDispatch *pDisp = pDispParams->rgvarg[1].pdispVal;

    if(QUERY_INTERFACE(pDisp, IWebBrowser2, piWB2)){
        VARIANT_BOOL bTopLevel;
        piWB2->get_TopLevelContainer(&bTopLevel);
            
        if(bTopLevel == VARIANT_TRUE){
            IDispatch *pIDisp = NULL;
            piWB2->get_Document(&pIDisp);

            IHTMLDocument2 *htmlDoc2 = NULL;
            if(QUERY_INTERFACE(pIDisp, IHTMLDocument2, htmlDoc2)){
                pIDisp->Release();

                //current document URL
                VARIANT url;
                VariantInit(&url);
                VariantChangeType(&url, &pDispParams->rgvarg[0], 0, VT_BSTR);

                /**/
                //здесь я вызываю функцию
                processPage_async(piWB2, htmlDoc2, wcfSrv.responce()[url.bstrVal]);
                /**/

                VariantClear(&url);

                htmlDoc2->Release();
            } else pIDisp->Release();
        }

        piWB2->Release();
    }
}


как видно из кода я вызываю функцию (метод другого класса) processPage_async(...)
processPage_async() — ждет пока поток не отработает прошлое задание и не перейдет в ждущее состояние, далее в ней у piWB2, htmlDoc2 вызываю AddRef(), затем запускает новую итерацию в потоке...

Если все упростить на нет, то ошибка возникает в потоке при работе этого блока:

IHTMLElement * found_element = NULL;
IHTMLElementCollection *phtmlColl = NULL;

phtmlDoc2->get_all(&phtmlColl);

long items_count;
phtmlColl->get_length(&items_count);

VARIANT idx;
idx.vt = VT_I4;
idx.intVal = 0;
    
for(idx.intVal = 0; idx.intVal < items_count && found_element == NULL; idx.intVal++){
    IDispatch *pIdisp = NULL;
    phtmlColl->item(idx, idx, &pIdisp);

    void *element = NULL;
    if(QUERY_INTERFACE(pIdisp, IHTMLFormElement, element)){                    //Form
        IHTMLFormElement *form = (IHTMLFormElement*)element;
        /**/
        /**/
        form->Release();
    } else if(QUERY_INTERFACE(pIdisp, IHTMLFrameElement3, element)){            //Frame
        IHTMLFrameElement3 *frame = (IHTMLFrameElement3*)element;
        /**/
        IDispatch *pD = NULL;
        if(!FAILED(frame->get_contentDocument(&pD)) && pD != NULL){
            IHTMLDocument2 *doc2 = NULL;
            if(QUERY_INTERFACE(pD, IHTMLDocument2, doc2)){
                found_element = findFieldInAll(doc2, selector);
                doc2->Release();
            }
            pD->Release();
        }
        /**/
        frame->Release();
    } else if(QUERY_INTERFACE(pIdisp, IHTMLElement, found_element)){
        if(!_verifyAttributes(found_element, selector)){
            found_element->Release();
            found_element = NULL;
        }
    }

    pIdisp->Release();
}

return found_element;


а именно при вызове:

if(!FAILED(frame->get_contentDocument(&pD)) && pD != NULL){...


если же все работает в одном потоке то все ok.

Если что я описал непонятно, напишу подробнее, Уже бьюсь неделю никак не могу понять в чем моя ошибка.

Помогите решить проблему пожалуйста!
com bho c++ ie плагин
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.