Всем привет!
Разрабатывыю я сейчас 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.
Если что я описал непонятно, напишу подробнее, Уже бьюсь неделю никак не могу понять в чем моя ошибка.
Помогите решить проблему пожалуйста!