好的,由于整个工程文件太大,所以我只发了这个完整的函数,麻烦你了,必定重谢哈!
void CCountContralDlg::EnumForm(IHTMLDocument2 *pIHTMLDocument2)//遍历表单
{
if( !pIHTMLDocument2 ) return; HRESULT hr;
CComBSTR bstrTitle; pIHTMLDocument2->get_title( &bstrTitle ); //取得文档标题 USES_CONVERSION;
//cout << _T("====================") << endl;
//cout << _T("开始枚举“") << OLE2CT( bstrTitle ) << _T("”的表单") << endl;
//cout << _T("====================") << endl; CComQIPtr< IHTMLElementCollection > spElementCollection;
hr = pIHTMLDocument2->get_forms( &spElementCollection ); //取得表单集合
if ( FAILED( hr ) )
{
MessageBox("获取表单的集合 IHTMLElementCollection 错误") ;
return;
} long nFormCount=0; //取得表单数目
hr = spElementCollection->get_length( &nFormCount );
if ( FAILED( hr ) )
{
MessageBox("获取表单数目错误");
return;
}

for(int i=0; i<nFormCount; i++)
{
    int i=0;
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; IDispatch *pDisp1 = NULL;
HRESULT hr2=spFormElement->get_elements(&pDisp1);
CComQIPtr< IHTMLElementCollection > spElementCollection1;
HRESULT hr3=pDisp1->QueryInterface(IID_IHTMLElementCollection,(void**)&spElementCollection1);//获取元素集合,就是这里开始出错
CComQIPtr< IHTMLElement> spElement1;
             long left=0,top=0;//控件坐标位置
 CString str;
 IDispatch *pDisp2 = NULL; for(long j=0; j<nElemCount; j++)
{
CComDispatchDriver spInputElement; //取得第 j 项表单域
hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );
if ( FAILED( hr ) ) continue; CComVariant vName,vType;//取得表单域的 名,值,类型
hr = spInputElement.GetPropertyByName( L"name", &vName );
if( FAILED( hr ) ) continue;
hr = spInputElement.GetPropertyByName( L"type", &vType );
if( FAILED( hr ) ) continue;
         CString lpName = vName.bstrVal?
OLE2CT( vName.bstrVal ) : _T("NULL"); //未知域名
CString lpType = vType.bstrVal?
OLE2CT( vType.bstrVal ) : _T("NULL"); //未知类型     if(lpType=="button")m_nButton++;
           元       if(lpType=="checkbox")m_nCheckBox++;
if(lpType=="image")m_nImage++;
if(lpType=="password")m_nPassword++;
if(lpType=="radio")m_nRadio++;
if(lpType=="text")m_nText++;
if(lpType=="textarea")m_nTextArea++;
if(lpType=="submit")m_nButton++;
if(lpType=="reset")m_nButton++;
if(lpType=="select")m_nList++;                HRESULT hr4=spElementCollection1->item(CComVariant(j),CComVariant(),&pDisp2);
                pDisp2->QueryInterface(IID_IHTMLElement,(void**)&spElement1);
spElement1->get_offsetLeft(&left);
spElement1->get_offsetTop(&top);
str.Format("x=%d,y=%d",left,top);
MessageBox(str);
}


}

UpdateData(FALSE);
}

解决方案 »

  1.   

    乍一看还看不出问题,但是发现pDisp2[3]没有调用Release。建议全部的接口都用智能指针,例如CComPtr<IDispatch> pDisp1[2|3];你说的返回的hr3==E_NOINTERFACE这个错误真的是少见,即使form中没有任何input元素,也不该返回无接口的。
      

  2.   

    hr = spElementCollection->item( CComVariant( i ), CComVariant(), &pDisp ); 
    => 
    hr = spElementCollection->item( CComVariant( i ), CComVariant(i), &pDisp ); 
    hr = spFormElement->item( CComVariant( j ), CComVariant(), &spInputElement );
    =>  
    hr = spFormElement->item( CComVariant( j ), CComVariant(j), &spInputElement ); 
      

  3.   

    还有个问题,可能导致你的统计不完整。
    (如果你确实要忽略input type=image则OK)
    The collection retrieved by the IHTMLFormElement::elements property does not include input type=image elements from a form. To access all elements contained in a form, call QueryInterface on IHTMLFormElement and request an IHTMLElement interface. Use the IHTMLElement::children property of the IHTMLElement interface to retrieve a collection of all elements in the form.