void* CrtDlg::ElemFromID(LPWSTR szID , IID nTypeIID)
{
HRESULT hr;
IHTMLDocument2* pDoc= (IHTMLDocument2*) m_axBrowser.get_Document();
IHTMLElementCollection* pAll= NULL;
hr= pDoc->get_all( &pAll );
CComVariant vElement( szID );
CComVariant vIndex(0,VT_I4);
IDispatch* pDisp;
hr= pAll->item(vElement,vIndex,&pDisp);
void* pElement;
hr= pDisp->QueryInterface( nTypeIID,(void**)&pElement);
return pElement;
}
найти input в webbrowser
вот таким образом
Код:
получаю по id или name примерно такое поле
[HTML]
<input type="password" name="Passwd" class="gaia le val" id="Passwd" size="18">
[/HTML]
Вопрос:
Как получить доступ к такому inputu
[HTML]
<input type="submit" value="Войти" class="gaia le button">
[/HTML]
ищем по id потом переводим в
Цитата: oxotnik333
ищем по id потом переводим в IHTMLInputElement
а где ты видишь там id?
сорри... тоды перебором всех элементов и сравнением их имен с заданной строкой
только перебор лучше наверное не всех элементов, а полученных с помощью
Цитата: bagie2
только перебор лучше наверное не всех элементов, а полученных с помощью IHTMLDocument3::getElementsByTagName
Можно небольшой кусочек кода, напутственный.
Код:
CComQIPtr<IHTMLDocument2> spDocument = (IHTMLDocument2*)m_axBrowser.get_Document() ;
CComQIPtr<IHTMLDocument3> spDoc3 = spDocument;
CComQIPtr<IHTMLElementCollection> spInputCollection;
HRESULT hRes = spDoc3->getElementsByTagName(CComBSTR("input"), &spInputCollection);
long Len;
hRes = spInputCollection->get_length(&Len);
for(long i = 0; i <Len; ++i)
{
// ?
}
CComQIPtr<IHTMLDocument3> spDoc3 = spDocument;
CComQIPtr<IHTMLElementCollection> spInputCollection;
HRESULT hRes = spDoc3->getElementsByTagName(CComBSTR("input"), &spInputCollection);
long Len;
hRes = spInputCollection->get_length(&Len);
for(long i = 0; i <Len; ++i)
{
// ?
}
а как теперь сравнить с моим inputom?
1/можно попробовать у каждого элемента (только привести их к IHTMLInputElement) получить значение value, defaultValue и сравнить с "Войти"
2/либо брать элемент как IHTMLElement, использовать IHTMLElement::getAttribute и получать атрибут class, который сравнивать с "gaia le button"
Вроде бы оба варианта должны работать. Можно их скомбинировать (искать по классу и начальному значению). Также, может быть, стоит проверять тип input'а
Цитата: bagie2
1/можно попробовать у каждого элемента (только привести их к IHTMLInputElement) получить значение value, defaultValue и сравнить с "Войти"
Код:
void CrtDlg::ElemFromTagName(LPWSTR szTagName)
{
CComQIPtr<IHTMLDocument2> spDocument = (IHTMLDocument2*)m_axBrowser.get_Document() ;
CComQIPtr<IHTMLDocument3> spDoc3 = spDocument;
CComQIPtr<IHTMLElementCollection> spInputCollection;
HRESULT hRes = spDoc3->getElementsByTagName(CComBSTR("input"), &spInputCollection);
long Len;
VARIANT vt;
hRes = spInputCollection->get_length(&Len);
vt.vt = VT_I4;
IHTMLElement* pSubmit = NULL;
IDispatch *pDisp = NULL;
IHTMLInputElement *pElem = NULL;
for(long i = 0; i <Len; ++i)
{
vt.intVal = i;
if((spInputCollection->item(vt,vt,&pDisp) == S_OK ))
if ((pDisp->QueryInterface (IID_IHTMLInputElement, (void**)&pElem) ==S_OK))
{
BSTR sType(L"");
BSTR sValue(L"");
pElem->get_type(&sType);
pElem->get_value(&sValue);
if(lstrcmpW(sType,L"submit") && lstrcmpW(sValue,L"Войти") )
{
pSubmit= (IHTMLElement*)pElem; pElem->
pSubmit->click();
}
}
}
}
{
CComQIPtr<IHTMLDocument2> spDocument = (IHTMLDocument2*)m_axBrowser.get_Document() ;
CComQIPtr<IHTMLDocument3> spDoc3 = spDocument;
CComQIPtr<IHTMLElementCollection> spInputCollection;
HRESULT hRes = spDoc3->getElementsByTagName(CComBSTR("input"), &spInputCollection);
long Len;
VARIANT vt;
hRes = spInputCollection->get_length(&Len);
vt.vt = VT_I4;
IHTMLElement* pSubmit = NULL;
IDispatch *pDisp = NULL;
IHTMLInputElement *pElem = NULL;
for(long i = 0; i <Len; ++i)
{
vt.intVal = i;
if((spInputCollection->item(vt,vt,&pDisp) == S_OK ))
if ((pDisp->QueryInterface (IID_IHTMLInputElement, (void**)&pElem) ==S_OK))
{
BSTR sType(L"");
BSTR sValue(L"");
pElem->get_type(&sType);
pElem->get_value(&sValue);
if(lstrcmpW(sType,L"submit") && lstrcmpW(sValue,L"Войти") )
{
pSubmit= (IHTMLElement*)pElem; pElem->
pSubmit->click();
}
}
}
}
Вроде все правильно, но выдается ошибка:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call.
Компилятор отправляет в dbghook.c
Если закоментить //pSubmit->click(); ошибки нет.
C-style cast в COM может сыграть очень плохую службу. Кастить интерфейс надо исключительно через QueryInterface
Код:
pSubmit= (IHTMLElement*)pElem
сделал
Код:
pDisp->QueryInterface(IID_IHTMLElement, (void**)&pSubmit);
Всем спасибо!