求教一个关于通过ATL COM技术及IHTMLDocument2接口等取网页中“Input”文本框中的文本

信阳毛尖 许昌学院 码农、程序猿  2010-08-24 02:47:52
部分代码如下:
BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
{
TCHAR buf[100];

::GetClassName( hwnd, (LPTSTR)&buf, 100 );
if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
{
*(HWND*)lParam = hwnd;
return FALSE;
}
else
return TRUE;
}

void CAboutIHTMLDocument2Dlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
HWND qqMailWin = NULL;
USES_CONVERSION;

qqMailWin=::FindWindowEx(NULL,NULL,"IEFrame","QQ邮箱 - 写信 - Microsoft Internet Explorer");
//qqMailWin=::FindWindowEx( NULL, NULL, "IEFrame", "2010年河南省高校门户网站评选 - Microsoft Internet Explorer"); //
if(qqMailWin==NULL)
{
DWORD err=::GetLastError();
::AfxMessageBox("找不到写信窗口");
}


CoInitialize( NULL );
HINSTANCE hInst = ::LoadLibrary(_T("OLEACC.DLL"));
if ( hInst != NULL )
{
if( qqMailWin != NULL )
{
HWND hWndChild = NULL;
::EnumChildWindows(qqMailWin,EnumChildProc, (LPARAM)&hWndChild );
if ( hWndChild )
{
CComPtr<IHTMLDocument2> spDoc;
LRESULT lRes;

UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );

LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, (LPCSTR)"ObjectFromLresult" );
if( pfObjectFromLresult !=NULL )
{
HRESULT hr;
hr = pfObjectFromLresult( lRes,IID_IHTMLDocument2,0,(void**)&spDoc );


if ( SUCCEEDED(hr) )
{
// 获取各个控件
CComQIPtr < IHTMLElementCollection > spElementCollection;
hr = spDoc->get_forms(&spElementCollection);

long nFormCount=0; //取得表单数目
hr = spElementCollection->get_length( &nFormCount );
if (nFormCount==0)
::AfxMessageBox("表单数目为0");

for( long i=0;i<nFormCount;i++ )
{
IDispatch *pDisp = NULL; //取得第 i 项表单
hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp );
if ( FAILED( hr ) ) continue;

CComQIPtr < IHTMLFormElement > spFormElement = pDisp;
pDisp->Release();

long nElemCount=0; //取得表单中 域 的数目
hr = spFormElement->get_length( &nElemCount );
if ( FAILED( hr ) ) continue;


for(long j=0; j <nElemCount; j++)
{
CComDispatchDriver spInputElement; //取得第 j 项表单域
hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );
if ( FAILED( hr ) ) continue;

CComVariant vName,vVal,vType; //取得表单域的 名,值,类型
hr = spInputElement.GetPropertyByName( L"name", &vName );
if( FAILED( hr ) ) continue;
hr = spInputElement.GetPropertyByName( L"value", &vVal );
if( FAILED( hr ) ) continue;
hr = spInputElement.GetPropertyByName( L"type", &vType );
if( FAILED( hr ) ) continue;

LPCTSTR strTextType= _T("hidden");


LPCTSTR strElementType = vType.bstrVal ? OLE2CT( vType.bstrVal ) : _T("NULL");
LPCTSTR strElementName = vName.bstrVal ? OLE2CT( vName.bstrVal ) : _T("NULL");
LPCTSTR strValue = vVal.bstrVal ? OLE2CT(vVal.bstrVal) : _T("NULL");

if( StrCmp( strTextType,strElementType) == 0)
{
if( StrCmp( strElementName, _T("fun")))
{
::AfxMessageBox("找到输入框!!");
CComBSTR str = NULL;
CComQIPtr < IHTMLInputTextElement > spGetText(spInputElement); hr = spGetText->get_value(&str);
if( SUCCEEDED(hr) )
{
if( str.Length() != 0 )
{
CComBSTR msg=_T("输入框类容是:");
msg += str;
CString s( str );
::AfxMessageBox( s );
}
}
}
else
::AfxMessageBox("没有找到输入框!!");
}

}//for j


}//for i
}
}

}

}
::BringWindowToTop(qqMailWin);
::FreeLibrary( hInst );
}
CoUninitialize();
OnOK();
}

编译无误,单步执行的时候执行到 上文中红色字体的地方:hr = spGetText->get_value(&str);出错,就是弹出那个“Microsoft Visual C++ Debug Library”(有“终止,重试,忽略”)的框框,说是Debug Assertion Failed!我觉得是上文中蓝色字体地方CComQIPtr < IHTMLInputTextElement > spGetText(spInputElement);不准确吧,不知道这种赋值方式对不对!如果不对,那么该如何把CComDispatchDriver类型的“spInputElement”转换成(还是赋值?) IHTMLInputTextElement接口类型的“spGetText”呢? 或者,还有其他的途径取出文本框中的文本方法嘛?
...全文
110 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
信阳毛尖 2010-08-31
问题已解决,结贴啦
回复
信阳毛尖 2010-08-27
这两天杂事比较多...看了看,觉得没头绪,我想还是先得把Frame框架搞清楚再说
回复
向立天 2010-08-24
查查MSDN
看看有没有相关说明
回复
信阳毛尖 2010-08-24
我查了些资料,可能是qq写信那个网页是基于frame框架的,其中的的那个正文文本域的type好像是textarea,好了,基于form的网页控件访问已基本掌握,只是这个基于frame框架的,还没有实现,哪位大侠给看看上文的代码要是改写一下,该如何改写呀?

我只会做到
.....
.....
.....
LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, (LPCSTR)"ObjectFromLresult" );
if( pfObjectFromLresult !=NULL )
{
HRESULT hr;
hr = pfObjectFromLresult( lRes,IID_IHTMLDocument2,0,(void**)&spDoc );


if ( SUCCEEDED(hr) )
{
// 获取各个控件
//CComQIPtr < IHTMLElementCollection > spElementCollection; 把原来的这一句换成下一句
CComQIPtr < IHTMLFramesCollection2 > spElementCollection;
//hr = spDoc->get_forms(&spElementCollection); 把原来的这一句换成下一句
hr = spDoc->get_frames(&spElementCollection);

回复
信阳毛尖 2010-08-24
犯了一个错误,上文中蓝色字体地方的接口应该是CComQIPtr < IHTMLInputHiddenElement > spGetText(spInputElement),这样就不会出错了,但是取不出文本的值!!!!!这个网页就是qq写信那个网页,倘若换成其他的网页,有的可以取出来,有的也不可以,这是怎么回事?
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2010-08-24 02:47
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……