[IE编程]枚举网页元素

  以下是对IE进行编程的一个范例, it's just a poc.

  实际使用下要注意测试对IE6/7/8/9等几个不同版本的兼容性

 

   #include  < stdio.h >
#include  < tchar.h >
#include < iostream >
#include < exdisp.h >
#include  < atlbase.h >   
#include  < atlcom.h >
#include < mshtml.h >

using   namespace  std;

void  EnumIE(  void  );
void  EnumFrame( IHTMLDocument2  *  pIHTMLDocument2 ); 
void  EnumForm ( IHTMLDocument2  *  pIHTMLDocument2 ); 



int  _tmain( int  argc, _TCHAR *  argv[])
{
    wcout.imbue(locale( " chs " )); 

    ::CoInitialize(NULL);    // 初始化COM 
   
    EnumIE();                // 枚举浏览器    
   
    ::CoUninitialize();      // 释放COM
   
    wcout << _T( " ======完成====== " ) << endl;   
    getchar();               // 等待回车    
   
    
return   0 ;  

}


void  EnumIE(  void  )   
{   
    wcout << _T( " 开始扫描系统中正在运行的浏览器实例 " ) << endl;   
   
    CComPtr < IShellWindows >  spShellWin;   
    HRESULT hr  =  spShellWin.CoCreateInstance( CLSID_ShellWindows );   
    
if  ( FAILED ( hr ) )   
    
{   
        wcout  << _T( " 获取 IShellWindows 接口错误 " ) << endl;   
        
return ;   
    }
   
   
    
long  nCount  =   0 ;         //  取得浏览器实例个数(Explorer 和 IExplorer)    
    spShellWin -> get_Count(  & nCount );   
    
if 0   ==  nCount )   
    
{   
        wcout << _T( " 没有在运行着的浏览器 " ) << endl;   
        
return ;   
    }
   
   
    
for ( int  i = 0 ; i < nCount; i ++ )
    
{  
        CComPtr < IDispatch  >  spDispIE;   
        hr = spShellWin -> Item(CComVariant( ( long )i ),  & spDispIE );   
        
if  ( FAILED ( hr ) )     continue ;   
   
        CComQIPtr < IWebBrowser2 >  spBrowser  =  spDispIE;   
        
if  (  ! spBrowser )        continue ;   
   
        CComPtr  < IDispatch >  spDispDoc;   
        hr  =  spBrowser -> get_Document(  & spDispDoc );   
        
if  ( FAILED ( hr ) )     continue ;   
   
        CComQIPtr <  IHTMLDocument2  >  spDocument2  =  spDispDoc;   
        
if  (  ! spDocument2 )      continue ;   
   
        
//  程序运行到此,已经找到了 IHTMLDocument2 的接口指针    
   
        
//  删除下行语句的注释,把浏览器的背景改变看看    
        
//  spDocument2->put_bgColor( CComVariant( "green" ) );    
           
        EnumForm( spDocument2 );         // 枚举所有的表单    
    }
   
}
   
   
void  EnumFrame( IHTMLDocument2  *  pIHTMLDocument2 )   
{   
    
if  (  ! pIHTMLDocument2 )  return ;   
   
    HRESULT hr;   
   
    CComPtr <  IHTMLFramesCollection2  >  spFramesCollection2;   
    pIHTMLDocument2 -> get_frames(  & spFramesCollection2 );  // 取得框架frame的集合    
   
    
long  nFrameCount = 0 ;              // 取得子框架个数    
    hr  =  spFramesCollection2 -> get_length(  & nFrameCount );   
    
if  ( FAILED ( hr )  ||   0   ==  nFrameCount )     return ;   
   
    
for ( long  i = 0 ; i < nFrameCount;  i ++
    
{
        CComVariant vDispWin2;
        hr = spFramesCollection2 -> item(  & CComVariant(i),  & vDispWin2 ); // 取得子框架的自动化接口" vDispWin2; CComVariant   
         if  ( FAILED ( hr ) )     continue ;   
   
        CComQIPtr <  IHTMLWindow2  >  spWin2  =  vDispWin2.pdispVal;   
        
if ! spWin2 )    continue ;    // 取得子框架的 IHTMLWindow2 接口    
   
        CComPtr  <  IHTMLDocument2  >  spDoc2;   
        spWin2 -> get_document(  & spDoc2 );  // 取得字框架的 IHTMLDocument2 接口    
   
        EnumForm( spDoc2 );          // 递归枚举当前子框架 IHTMLDocument2 上的表单form    
    }
   
}
   
   
void  EnumForm( IHTMLDocument2  *  pIHTMLDocument2 )   
{   
    
if ! pIHTMLDocument2 )   return ;   
   
    EnumFrame( pIHTMLDocument2 );    // 递归枚举当前 IHTMLDocument2 上的子框架fram    
   
    HRESULT hr;   
    CComBSTR bstrTitle;   
    pIHTMLDocument2 -> get_title(  & bstrTitle );     // 取得文档标题    
   
    USES_CONVERSION;   
    wcout  <<  _T( " ==================== " <<  endl;   
    wcout  <<  _T( " 开始枚举“ " <<  OLE2CT( bstrTitle )  <<  _T( " ”的表单 " <<  endl;   
    wcout  <<  _T( " ==================== " <<  endl;   
   
    CComQIPtr <  IHTMLElementCollection  >  spElementCollection;   
    hr  =  pIHTMLDocument2 -> get_forms(  & spElementCollection );  // 取得表单集合    
     if  ( FAILED( hr ) )   
    
{   
        wcout  <<  _T( " 获取表单的集合 IHTMLElementCollection 错误 " <<  endl;   
        
return ;   
    }
   
   
    
long  nFormCount = 0 ;               // 取得表单数目    
    hr  =  spElementCollection -> get_length(  & nFormCount );   
    
if  ( FAILED( hr ) )   
    
{   
        wcout  <<  _T( " 获取表单数目错误 " <<  endl;   
        
return ;   
    }
   
       
    
for ( long  i = 0 ; i < nFormCount;  i ++ ) // "" 项表单 i 取得第 ;
     {
    
        IDispatch   * pDisp = NULL;
         hr =  spElementCollection -> item( CComVariant( i ), CComVariant(i),  & 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 lpName  =  vName.bstrVal ?    
                    OLE2CT( vName.bstrVal ) : _T( " NULL " );    // 未知域名    
            LPCTSTR lpVal   =  vVal.bstrVal ?    
                    OLE2CT( vVal.bstrVal  ) : _T( " NULL " );    // 空值,未输入    
            LPCTSTR lpType  =  vType.bstrVal ?    
                    OLE2CT( vType.bstrVal ) : _T( " NULL " );    // 未知类型    
   
            wcout  <<  _T( " [ " <<  lpType  <<  _T( " " );   
            wcout  <<  lpName  <<  _T( "  =  " <<  lpVal  <<  endl;   
        }
   
        
// 想提交这个表单吗?删除下面语句的注释吧    
        
// pForm->submit();    
    }
   
}

 

 

 

posted @ 2011-03-25 13:18  huhu0013  阅读(850)  评论(0编辑  收藏  举报